=== modified file 'modules/system/system.install'
--- modules/system/system.install 2009-08-29 11:00:03 +0000
+++ modules/system/system.install 2009-09-05 13:49:06 +0000
@@ -2459,6 +2459,130 @@
}
/**
+ * Change profile.module fields into Field API fields.
+ */
+function system_update_7038() {
+ $ret = array();
+ $fields = array();
+
+ if (!db_table_exists('profile_field')) {
+ return $ret;
+ }
+ // Get all profile fields.
+ $old_fields = db_query('SELECT * FROM {profile_field} ORDER BY category, weight');
+
+ foreach ($old_fields as $old_field) {
+ // Create new fields using the field API.
+ $field = array(
+ 'field_name' => strtolower(str_replace('-', '_', $old_field->name)),
+ 'cardinality' => 1,
+ );
+
+ // Create field instance on the user bundle.
+ $instance = array(
+ 'field_name' => $field['field_name'],
+ 'bundle' => 'user',
+ 'description' => $old_field->explanation,
+ 'label' => $old_field->title,
+ 'required' => $old_field->required,
+ 'widget' => array(
+ 'weight' => $old_field->weight,
+ ),
+ 'display' => array(
+ 'full' => array(
+ 'weight' => $old_field->weight,
+ ),
+ ),
+ 'settings' => array(
+ 'user_register' => $old_field->register,
+ ),
+ );
+
+ switch ($old_field->type) {
+ case 'textfield':
+ $field['type'] = 'text';
+ $instance['widget']['type'] = 'text_textfield';
+
+ // Only allow plain text.
+ $instance['settings']['text_processing'] = 0;
+ break;
+
+ case 'textarea':
+ $field['type'] = 'text_long';
+ $instance['widget']['type'] = 'text_textarea';
+ // Use the default text format.
+ $instance['settings']['text_processing'] = variable_get('filter_default_format', 1);
+ break;
+
+ case 'checkbox':
+ $field['type'] = 'list_boolean';
+ $instance['widget']['type'] = 'options_onoff';
+ $field['settings']['allowed_values'] = "0\n1|" . $old_field->title;
+ break;
+
+ case 'selection':
+ $field['type'] = 'list_text';
+ $instance['widget']['type'] = 'options_select';
+ $field['settings']['allowed_values'] = $old_field->options;
+ break;
+
+ case 'list':
+ $field['type'] = 'text';
+ $field['cardinality'] = FIELD_CARDINALITY_UNLIMITED;
+ break;
+
+ case 'date':
+ $ret[] = array('success' => TRUE, 'query' => 'To migrate date fields from the profile module, install the date module.');
+ continue 2;
+
+ case 'url':
+ $ret[] = array('success' => TRUE, 'query' => 'To migrate URL fields from the profile module, install the link module.');
+ continue 2;
+ }
+
+ try {
+ field_create_field($field);
+ field_create_instance($instance);
+ $fields[$old_field->fid] = $field;
+ }
+ catch (Exception $e) {
+ $ret[] = array('success' => FALSE, 'query' => t('There was a problem creating field %label: @message.', array('%label' => $instance['label'], '@message' => $e->getMessage())));
+ }
+ }
+
+ // Get old field values from the profile.module table.
+ $results = db_query('SELECT uid, fid, value FROM {profile_value} WHERE value IS NOT NULL');
+
+ $accounts = array();
+ foreach ($results as $result) {
+ $field_name = $fields[$result->fid]['field_name'];
+ $accounts[$result->uid]['uid'] = $result->uid;
+
+ if ($fields[$result->fid]['type'] == 'text' && $fields[$result->fid]['cardinality'] == FIELD_CARDINALITY_UNLIMITED) {
+ $values = array_filter(array_map('trim', preg_split("/[,\n\r]/", $result->value)));
+ $delta = 0;
+ foreach ($values as $value) {
+ $accounts[$result->uid][$field_name][FIELD_LANGUAGE_NONE][$delta]['value'] = $value;
+ $delta++;
+ }
+ }
+ else {
+ $accounts[$result->uid][$field_name][FIELD_LANGUAGE_NONE][0]['value'] = $result->value;
+ }
+ }
+
+ // Set new field values using the field API.
+ foreach ($accounts as $account) {
+ $account = (object) $account;
+ field_attach_update('user', $account);
+ }
+
+ $ret[] = array('success' => TRUE, 'query' => 'The profile module has been replaced by the new Fields UI. For additional functionality such as adding fields to the registration form, install the Retro Profile module.');
+
+ return $ret;
+}
+
+/**
* @} End of "defgroup updates-6.x-to-7.x"
* The next series of updates should start at 8000.
*/
=== modified file 'modules/system/system.test'
--- modules/system/system.test 2009-09-01 17:00:02 +0000
+++ modules/system/system.test 2009-09-05 14:50:52 +0000
@@ -1227,3 +1227,248 @@
$this->assertFalse(strcmp($generated['[node:title]'], $node->title), t('Unsanitized token generated properly.'));
}
}
+
+class SystemUpdateTestCase extends DrupalWebTestCase {
+ /**
+ * Implement getInfo().
+ */
+ public static function getInfo() {
+ return array(
+ 'name' => 'Update path',
+ 'description' => 'Test the update path from older version of Drupal.',
+ 'group' => 'System'
+ );
+ }
+
+ function testSystemUpdate7038() {
+ // Create a user and an array for field_attach_load().
+ $profile_user = $this->drupalCreateUser();
+
+ // Create some old profile field data to test the update.
+ $old_schema = $this->profileSchema();
+ db_create_table($ret, 'profile_field', $old_schema['profile_field']);
+ db_create_table($ret, 'profile_value', $old_schema['profile_value']);
+
+ $old_fields['textfield'] = array(
+ 'title' => $this->randomName(),
+ 'name' => $this->randomName(),
+ 'explanation' => $this->randomName(50),
+ 'category' => $this->randomName(),
+ 'page' => NULL,
+ 'type' => 'textfield',
+ 'weight' => rand(-10, 10),
+ 'required' => 1,
+ 'register' => 1,
+ 'visibility' => 0,
+ 'autocomplete' => 0,
+ 'options' => NULL,
+ );
+ $old_fields['textarea'] = array(
+ 'title' => $this->randomName(),
+ 'name' => $this->randomName(),
+ 'type' => 'textarea',
+ 'required' => 0,
+ );
+ $old_fields['checkbox'] = array(
+ 'title' => $this->randomName(),
+ 'name' => $this->randomName(),
+ 'type' => 'checkbox',
+ );
+
+ $fid = 1;
+ foreach ($old_fields as $field_name => $old_field) {
+ // Create the configuration for the profile.module field.
+ $old_field['fid'] = $fid;
+ db_insert('profile_field')->fields($old_field)->execute();
+
+ // Set profile.module field values for $profile_user.
+ $old_field_value = array(
+ 'fid' => $fid,
+ 'uid' => $profile_user->uid,
+ );
+ switch ($old_field['type']) {
+ case 'textfield':
+ case 'textarea':
+ $old_field_value['value'] = $this->randomName();
+ break;
+
+ case 'checkbox':
+ $old_field_value['value'] = rand(0, 1);
+ break;
+ }
+ db_insert('profile_value')->fields($old_field_value)->execute();
+ $old_fields[$field_name]['value'] = $old_field_value['value'];
+ $fid++;
+ }
+
+ // Run the update.
+ system_update_7038();
+
+ // Reload the user with the new fields.
+ $profile_user = user_load($profile_user->uid, TRUE);
+
+ // Check the migration of textfield fields and well as basic settings.
+ $field_name = strtolower(str_replace('-', '_', $old_fields['textfield']['name']));
+ $field = field_info_field($field_name);
+ $this->assertNotNull($field, t('The user field has been created.'));
+ $this->assertEqual($field['type'], 'text', t('Textfields are mapped to fields of type text.'));
+
+ $instance = field_info_instance($field_name, 'user');
+ $this->assertNotNull($instance, t('The field has an instance attached to users.'));
+ $this->assertEqual($old_fields['textfield']['title'], $instance['label'], t('Field label is preserved.'));
+ $this->assertEqual($old_fields['textfield']['explanation'], $instance['description'], t('Field description is preserved.'));
+ $this->assertTrue($instance['required'], t('Required fields are preserved.'));
+ $this->assertEqual($old_fields['textfield']['weight'], $instance['widget']['weight'], t('Weight gets preserved for widgets.'));
+ $this->assertEqual($old_fields['textfield']['weight'], $instance['display']['full']['weight'], t('Weight gets preserved when displaying fields.'));
+ $this->assertEqual($old_fields['textfield']['value'], $profile_user->{$field_name}[FIELD_LANGUAGE_NONE][0]['value'], t('Textfield values are migrated.'));
+
+ // Check the migration of textarea fields.
+ $field_name = strtolower(str_replace('-', '_', $old_fields['textarea']['name']));
+ $field = field_info_field($field_name);
+ $this->assertNotNull($field, t('The user field has been created.'));
+ $this->assertEqual($field['type'], 'text_long', t('Textareas are mapped to fields of type text_long.'));
+
+ $instance = field_info_instance($field_name, 'user');
+ $this->assertFalse($instance['required'], t('Not required fields are preserved.'));
+ $this->assertEqual($old_fields['textarea']['value'], $profile_user->{$field_name}[FIELD_LANGUAGE_NONE][0]['value'], t('Textarea values are migrated.'));
+
+ // Check the migration of checkbox fields.
+ $field_name = strtolower(str_replace('-', '_', $old_fields['checkbox']['name']));
+ $field = field_info_field($field_name);
+ $this->assertNotNull($field, t('The user field has been created.'));
+ $this->assertEqual($field['type'], 'list_boolean', t('Checkboxes are mapped to fields of type list_boolean.'));
+ $this->assertEqual($old_fields['checkbox']['value'], $profile_user->{$field_name}[FIELD_LANGUAGE_NONE][0]['value'], t('Checkbox values are migrated.'));
+ }
+
+ // This is an exact copy of the profile_schema.
+ function profileSchema() {
+ $schema['profile_field'] = array(
+ 'description' => 'Stores profile field information.',
+ 'fields' => array(
+ 'fid' => array(
+ 'type' => 'serial',
+ 'not null' => TRUE,
+ 'description' => 'Primary Key: Unique profile field ID.',
+ ),
+ 'title' => array(
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => FALSE,
+ 'description' => 'Title of the field shown to the end user.',
+ ),
+ 'name' => array(
+ 'type' => 'varchar',
+ 'length' => 128,
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'Internal name of the field used in the form HTML and URLs.',
+ ),
+ 'explanation' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => 'Explanation of the field to end users.',
+ ),
+ 'category' => array(
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => FALSE,
+ 'description' => 'Profile category that the field will be grouped under.',
+ ),
+ 'page' => array(
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => FALSE,
+ 'description' => "Title of page used for browsing by the field's value",
+ ),
+ 'type' => array(
+ 'type' => 'varchar',
+ 'length' => 128,
+ 'not null' => FALSE,
+ 'description' => 'Type of form field.',
+ ),
+ 'weight' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'size' => 'tiny',
+ 'description' => 'Weight of field in relation to other profile fields.',
+ ),
+ 'required' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'size' => 'tiny',
+ 'description' => 'Whether the user is required to enter a value. (0 = no, 1 = yes)',
+ ),
+ 'register' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'size' => 'tiny',
+ 'description' => 'Whether the field is visible in the user registration form. (1 = yes, 0 = no)',
+ ),
+ 'visibility' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'size' => 'tiny',
+ 'description' => 'The level of visibility for the field. (0 = hidden, 1 = private, 2 = public on profile but not member list pages, 3 = public on profile and list pages)',
+ ),
+ 'autocomplete' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'size' => 'tiny',
+ 'description' => 'Whether form auto-completion is enabled. (0 = disabled, 1 = enabled)',
+ ),
+ 'options' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => 'List of options to be used in a list selection field.',
+ ),
+ ),
+ 'indexes' => array(
+ 'category' => array('category'),
+ ),
+ 'unique keys' => array(
+ 'name' => array('name'),
+ ),
+ 'primary key' => array('fid'),
+ );
+
+ $schema['profile_value'] = array(
+ 'description' => 'Stores values for profile fields.',
+ 'fields' => array(
+ 'fid' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => 'The {profile_field}.fid of the field.',
+ ),
+ 'uid' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => 'The {users}.uid of the profile user.',
+ ),
+ 'value' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => 'The value for the field.',
+ ),
+ ),
+ 'primary key' => array('uid', 'fid'),
+ 'indexes' => array(
+ 'fid' => array('fid'),
+ ),
+ 'foreign keys' => array(
+ 'fid' => array('profile_field' => 'fid'),
+ 'uid' => array('users' => 'uid'),
+ ),
+ );
+
+ return $schema;
+ }
+}