summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/field/tests/field.test16
-rw-r--r--modules/field_ui/field_ui.admin.inc1
-rw-r--r--modules/user/user.js21
-rw-r--r--modules/user/user.module88
-rw-r--r--modules/user/user.test89
5 files changed, 210 insertions, 5 deletions
diff --git a/modules/field/tests/field.test b/modules/field/tests/field.test
index 30b1d8699..57c4837af 100644
--- a/modules/field/tests/field.test
+++ b/modules/field/tests/field.test
@@ -988,11 +988,12 @@ class FieldInfoTestCase extends FieldTestCase {
*/
function testFieldInfo() {
// Test that field_test module's fields, widgets, and formatters show up.
- $field_test_info = field_test_field_info();
- $formatter_info = field_test_field_formatter_info();
- $widget_info = field_test_field_widget_info();
- $storage_info = field_test_field_storage_info();
+ $field_test_info = field_test_field_info();
+ // We need to account for the existence of user_field_info_alter().
+ foreach (array_keys($field_test_info) as $name) {
+ $field_test_info[$name]['instance_settings']['user_register_form'] = FALSE;
+ }
$info = field_info_field_types();
foreach ($field_test_info as $t_key => $field_type) {
foreach ($field_type as $key => $val) {
@@ -1001,6 +1002,7 @@ class FieldInfoTestCase extends FieldTestCase {
$this->assertEqual($info[$t_key]['module'], 'field_test', t("Field type field_test module appears"));
}
+ $formatter_info = field_test_field_formatter_info();
$info = field_info_formatter_types();
foreach ($formatter_info as $f_key => $formatter) {
foreach ($formatter as $key => $val) {
@@ -1009,6 +1011,7 @@ class FieldInfoTestCase extends FieldTestCase {
$this->assertEqual($info[$f_key]['module'], 'field_test', t("Formatter type field_test module appears"));
}
+ $widget_info = field_test_field_widget_info();
$info = field_info_widget_types();
foreach ($widget_info as $w_key => $widget) {
foreach ($widget as $key => $val) {
@@ -1017,6 +1020,7 @@ class FieldInfoTestCase extends FieldTestCase {
$this->assertEqual($info[$w_key]['module'], 'field_test', t("Widget type field_test module appears"));
}
+ $storage_info = field_test_field_storage_info();
$info = field_info_storage_types();
foreach ($storage_info as $s_key => $storage) {
foreach ($storage as $key => $val) {
@@ -1180,6 +1184,10 @@ class FieldInfoTestCase extends FieldTestCase {
*/
function testSettingsInfo() {
$info = field_test_field_info();
+ // We need to account for the existence of user_field_info_alter().
+ foreach (array_keys($info) as $name) {
+ $info[$name]['instance_settings']['user_register_form'] = FALSE;
+ }
foreach ($info as $type => $data) {
$this->assertIdentical(field_info_field_settings($type), $data['settings'], "field_info_field_settings returns {$type}'s field settings");
$this->assertIdentical(field_info_instance_settings($type), $data['instance_settings'], "field_info_field_settings returns {$type}'s field instance settings");
diff --git a/modules/field_ui/field_ui.admin.inc b/modules/field_ui/field_ui.admin.inc
index 9d36400e0..fdddb018a 100644
--- a/modules/field_ui/field_ui.admin.inc
+++ b/modules/field_ui/field_ui.admin.inc
@@ -1731,6 +1731,7 @@ function field_ui_field_edit_form($form, &$form_state, $instance) {
drupal_set_title($instance['label']);
$form['#field'] = $field;
+ $form['#instance'] = $instance;
if (!empty($field['locked'])) {
$form['locked'] = array(
diff --git a/modules/user/user.js b/modules/user/user.js
index 50bb84981..14302621d 100644
--- a/modules/user/user.js
+++ b/modules/user/user.js
@@ -173,4 +173,25 @@ Drupal.evaluatePasswordStrength = function (password, translate) {
};
+/**
+ * Field instance settings screen: force the 'Display on registration form'
+ * checkbox checked whenever 'Required' is checked.
+ */
+Drupal.behaviors.fieldUserRegistration = {
+ attach: function (context, settings) {
+ var $checkbox = $('form#field-ui-field-edit-form input#edit-instance-settings-user-register-form');
+
+ if ($checkbox.size()) {
+ $('input#edit-instance-required', context).once('user-register-form-checkbox', function () {
+ $(this).bind('change', function (e) {
+ if ($(this).attr('checked')) {
+ $checkbox.attr('checked', true);
+ }
+ });
+ });
+
+ }
+ }
+};
+
})(jQuery);
diff --git a/modules/user/user.module b/modules/user/user.module
index d01e70f58..4a636dad1 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -177,6 +177,18 @@ function user_uri($user) {
}
/**
+ * Implements hook_field_info_alter().
+ */
+function user_field_info_alter(&$info) {
+ // Add the 'user_register_form' instance setting to all field types.
+ foreach ($info as $field_type => $field_type_info) {
+ $info[$field_type]['instance_settings'] += array(
+ 'user_register_form' => FALSE,
+ );
+ }
+}
+
+/**
* Implements hook_field_extra_fields().
*/
function user_field_extra_fields() {
@@ -3539,6 +3551,55 @@ function user_block_user_action(&$entity, $context = array()) {
}
/**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Add a checkbox for the 'user_register_form' instance settings on the 'Edit
+ * field instance' form.
+ */
+function user_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) {
+ $instance = $form['#instance'];
+
+ if ($instance['entity_type'] == 'user') {
+ $form['instance']['settings']['user_register_form'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Display on user registration form.'),
+ '#description' => t("This is compulsory for 'required' fields."),
+ // Field instances created in D7 beta releases before the setting was
+ // introduced might be set as 'required' and 'not shown on user_register
+ // form'. We make sure the checkbox comes as 'checked' for those.
+ '#default_value' => $instance['settings']['user_register_form'] || $instance['required'],
+ // Display just below the 'required' checkbox.
+ '#weight' => $form['instance']['required']['#weight'] + .1,
+ // Disabled when the 'required' checkbox is checked.
+ '#states' => array(
+ 'enabled' => array('input[name="instance[required]"]' => array('checked' => FALSE)),
+ ),
+ // Checked when the 'required' checkbox is checked. This is done through
+ // a custom behavior, since the #states system would also synchronize on
+ // uncheck.
+ '#attached' => array(
+ 'js' => array(drupal_get_path('module', 'user') . '/user.js'),
+ ),
+ );
+
+ array_unshift($form['#submit'], 'user_form_field_ui_field_edit_form_submit');
+ }
+}
+
+/**
+ * Additional submit handler for the 'Edit field instance' form.
+ *
+ * Make sure the 'user_register_form' setting is set for required fields.
+ */
+function user_form_field_ui_field_edit_form_submit($form, &$form_state) {
+ $instance = $form_state['values']['instance'];
+
+ if (!empty($instance['required'])) {
+ form_set_value($form['instance']['settings']['user_register_form'], 1, $form_state);
+ }
+}
+
+/**
* Form builder; the user registration form.
*
* @ingroup forms
@@ -3565,6 +3626,15 @@ function user_register_form($form, &$form_state) {
// Start with the default user account fields.
user_account_form($form, $form_state);
+ // Attach field widgets, and hide the ones where the 'user_register_form'
+ // setting is not on.
+ field_attach_form('user', $form['#user'], $form, $form_state);
+ foreach (field_info_instances('user', 'user') as $field_name => $instance) {
+ if (empty($instance['settings']['user_register_form'])) {
+ $form[$field_name]['#access'] = FALSE;
+ }
+ }
+
if ($admin) {
// Redirect back to page which initiated the create request;
// usually admin/people/create.
@@ -3577,6 +3647,7 @@ function user_register_form($form, &$form_state) {
'#value' => t('Create new account'),
);
+ $form['#validate'][] = 'user_register_validate';
// Add the final user registration form submit handler.
$form['#submit'][] = 'user_register_submit';
@@ -3584,6 +3655,13 @@ function user_register_form($form, &$form_state) {
}
/**
+ * Validation function for the user registration form.
+ */
+function user_register_validate($form, &$form_state) {
+ entity_form_field_validate('user', $form, $form_state);
+}
+
+/**
* Submit handler for the user registration form.
*
* This function is shared by the installation form and the normal registration form,
@@ -3602,13 +3680,21 @@ function user_register_submit($form, &$form_state) {
}
$notify = !empty($form_state['values']['notify']);
+ // Remove unneeded values.
form_state_values_clean($form_state);
$form_state['values']['pass'] = $pass;
$form_state['values']['init'] = $form_state['values']['mail'];
$account = $form['#user'];
- $account = user_save($account, $form_state['values']);
+
+ entity_form_submit_build_entity('user', $account, $form, $form_state);
+
+ // Populate $edit with the properties of $account, which have been edited on
+ // this form by taking over all values, which appear in the form values too.
+ $edit = array_intersect_key((array) $account, $form_state['values']);
+ $account = user_save($account, $edit);
+
// Terminate if an error occurred during user_save().
if (!$account) {
drupal_set_message(t("Error saving user account."), 'error');
diff --git a/modules/user/user.test b/modules/user/user.test
index a15e22c0f..32b074ef6 100644
--- a/modules/user/user.test
+++ b/modules/user/user.test
@@ -10,6 +10,10 @@ class UserRegistrationTestCase extends DrupalWebTestCase {
);
}
+ function setUp() {
+ parent::setUp('field_test');
+ }
+
function testRegistrationWithEmailVerification() {
// Require e-mail verification.
variable_set('user_email_verification', TRUE);
@@ -137,6 +141,91 @@ class UserRegistrationTestCase extends DrupalWebTestCase {
$this->assertEqual($new_user->picture, '', t('Correct picture field.'));
$this->assertEqual($new_user->init, $mail, t('Correct init field.'));
}
+
+ /**
+ * Tests Field API fields on user registration forms.
+ */
+ function testRegistrationWithUserFields() {
+ // Create a field, and an instance on 'user' entity type.
+ $field = array(
+ 'type' => 'test_field',
+ 'field_name' => 'test_user_field',
+ 'cardinality' => 1,
+ );
+ field_create_field($field);
+ $instance = array(
+ 'field_name' => 'test_user_field',
+ 'entity_type' => 'user',
+ 'label' => 'Some user field',
+ 'bundle' => 'user',
+ 'required' => TRUE,
+ 'settings' => array('user_register_form' => FALSE),
+ );
+ field_create_instance($instance);
+
+ // Check that the field does not appear on the registration form.
+ $this->drupalGet('user/register');
+ $this->assertNoText($instance['label'], t('The field does not appear on user registration form'));
+
+ // Have the field appear on the registration form.
+ $instance['settings']['user_register_form'] = TRUE;
+ field_update_instance($instance);
+ $this->drupalGet('user/register');
+ $this->assertText($instance['label'], t('The field appears on user registration form'));
+
+ // Check that validation errors are correctly reported.
+ $edit = array();
+ $edit['name'] = $name = $this->randomName();
+ $edit['mail'] = $mail = $edit['name'] . '@example.com';
+ // Missing input in required field.
+ $edit['test_user_field[und][0][value]'] = '';
+ $this->drupalPost(NULL, $edit, t('Create new account'));
+ $this->assertRaw(t('@name field is required.', array('@name' => $instance['label'])), t('Field validation error was correctly reported.'));
+ // Invalid input.
+ $edit['test_user_field[und][0][value]'] = '-1';
+ $this->drupalPost(NULL, $edit, t('Create new account'));
+ $this->assertRaw(t('%name does not accept the value -1.', array('%name' => $instance['label'])), t('Field validation error was correctly reported.'));
+
+ // Submit with valid data.
+ $value = rand(1, 255);
+ $edit['test_user_field[und][0][value]'] = $value;
+ $this->drupalPost(NULL, $edit, t('Create new account'));
+ // Check user fields.
+ $accounts = user_load_multiple(array(), array('name' => $name, 'mail' => $mail));
+ $new_user = reset($accounts);
+ $this->assertEqual($new_user->test_user_field[LANGUAGE_NONE][0]['value'], $value, t('The field value was correclty saved.'));
+
+ // Check that the 'add more' button works.
+ $field['cardinality'] = FIELD_CARDINALITY_UNLIMITED;
+ field_update_field($field);
+ foreach (array('js', 'nojs') as $js) {
+ $this->drupalGet('user/register');
+ // Add two inputs.
+ $value = rand(1, 255);
+ $edit = array();
+ $edit['test_user_field[und][0][value]'] = $value;
+ if ($js == 'js') {
+ $this->drupalPostAJAX(NULL, $edit, 'test_user_field_add_more');
+ $this->drupalPostAJAX(NULL, $edit, 'test_user_field_add_more');
+ }
+ else {
+ $this->drupalPost(NULL, $edit, t('Add another item'));
+ $this->drupalPost(NULL, $edit, t('Add another item'));
+ }
+ // Submit with three values.
+ $edit['test_user_field[und][1][value]'] = $value + 1;
+ $edit['test_user_field[und][2][value]'] = $value + 2;
+ $edit['name'] = $name = $this->randomName();
+ $edit['mail'] = $mail = $edit['name'] . '@example.com';
+ $this->drupalPost(NULL, $edit, t('Create new account'));
+ // Check user fields.
+ $accounts = user_load_multiple(array(), array('name' => $name, 'mail' => $mail));
+ $new_user = reset($accounts);
+ $this->assertEqual($new_user->test_user_field[LANGUAGE_NONE][0]['value'], $value, t('@js : The field value was correclty saved.', array('@js' => $js)));
+ $this->assertEqual($new_user->test_user_field[LANGUAGE_NONE][1]['value'], $value + 1, t('@js : The field value was correclty saved.', array('@js' => $js)));
+ $this->assertEqual($new_user->test_user_field[LANGUAGE_NONE][2]['value'], $value + 2, t('@js : The field value was correclty saved.', array('@js' => $js)));
+ }
+ }
}
class UserValidationTestCase extends DrupalWebTestCase {