'Stores user data.', 'fields' => array( 'uid' => array( 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'description' => 'Primary Key: Unique user ID.', 'default' => 0, ), 'uuid' => array( 'description' => 'Unique Key: Universally unique identifier for this entity.', 'type' => 'varchar', 'length' => 128, 'not null' => FALSE, ), 'name' => array( 'type' => 'varchar', 'length' => 60, 'not null' => TRUE, 'default' => '', 'description' => 'Unique user name.', ), 'langcode' => array( 'type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => '', 'description' => "The {language}.langcode of the user's profile.", ), 'pass' => array( 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '', 'description' => "User's password (hashed).", ), 'mail' => array( 'type' => 'varchar', 'length' => 254, 'not null' => FALSE, 'default' => '', 'description' => "User's e-mail address.", ), 'theme' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => "User's default theme.", ), 'signature' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => "User's signature.", ), 'signature_format' => array( 'type' => 'varchar', 'length' => 255, 'not null' => FALSE, 'description' => 'The filter format ID of the signature.', ), 'created' => array( 'type' => 'int', 'not null' => TRUE, 'default' => 0, 'description' => 'Timestamp for when user was created.', ), 'access' => array( 'type' => 'int', 'not null' => TRUE, 'default' => 0, 'description' => 'Timestamp for previous time user accessed the site.', ), 'login' => array( 'type' => 'int', 'not null' => TRUE, 'default' => 0, 'description' => "Timestamp for user's last login.", ), 'status' => array( 'type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny', 'description' => 'Whether the user is active(1) or blocked(0).', ), 'timezone' => array( 'type' => 'varchar', 'length' => 32, 'not null' => FALSE, 'description' => "User's time zone.", ), 'preferred_langcode' => array( 'type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => '', 'description' => 'The {language}.langcode that the user prefers for receiving emails and viewing the site.', ), 'preferred_admin_langcode' => array( 'type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => '', 'description' => 'The {language}.langcode that the user prefers for viewing administration pages.', ), 'init' => array( 'type' => 'varchar', 'length' => 254, 'not null' => FALSE, 'default' => '', 'description' => 'E-mail address used for initial account creation.', ), ), 'indexes' => array( 'access' => array('access'), 'created' => array('created'), 'mail' => array('mail'), ), 'unique keys' => array( 'uuid' => array('uuid'), 'name' => array('name'), ), 'primary key' => array('uid'), 'foreign keys' => array( 'signature_format' => array( 'table' => 'filter_format', 'columns' => array('signature_format' => 'format'), ), ), ); $schema['role_permission'] = array( 'description' => 'Stores the permissions assigned to user roles.', 'fields' => array( 'rid' => array( 'type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'description' => 'Foreign Key: {role}.rid.', ), 'permission' => array( 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '', 'description' => 'A single permission granted to the role identified by rid.', ), 'module' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => "The module declaring the permission.", ), ), 'primary key' => array('rid', 'permission'), 'indexes' => array( 'permission' => array('permission'), ), 'foreign keys' => array( 'role' => array( 'table' => 'role', 'columns' => array('rid' => 'rid'), ), ), ); $schema['users_data'] = array( 'description' => 'Stores module data as key/value pairs per user.', 'fields' => array( 'uid' => array( 'description' => 'Primary key: {users}.uid for user.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), 'module' => array( 'description' => 'The name of the module declaring the variable.', 'type' => 'varchar', 'length' => 204, 'not null' => TRUE, 'default' => '', ), 'name' => array( 'description' => 'The identifier of the data.', 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '', ), 'value' => array( 'description' => 'The value.', 'type' => 'blob', 'not null' => FALSE, 'size' => 'big', ), 'serialized' => array( 'description' => 'Whether value is serialized.', 'type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'default' => 0, ), ), 'primary key' => array('uid', 'module', 'name'), 'indexes' => array( 'module' => array('module'), 'name' => array('name'), ), 'foreign keys' => array( 'uid' => array('users' => 'uid'), ), ); $schema['users_roles'] = array( 'description' => 'Maps users to roles.', 'fields' => array( 'uid' => array( 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'Primary Key: {users}.uid for user.', ), 'rid' => array( 'type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'description' => 'Primary Key: {role}.rid for role.', ), ), 'primary key' => array('uid', 'rid'), 'indexes' => array( 'rid' => array('rid'), ), 'foreign keys' => array( 'user' => array( 'table' => 'users', 'columns' => array('uid' => 'uid'), ), 'role' => array( 'table' => 'role', 'columns' => array('rid' => 'rid'), ), ), ); return $schema; } /** * Implements hook_install(). */ function user_install() { // Insert a row for the anonymous user. db_insert('users') ->fields(array( 'uid' => 0, 'name' => '', 'mail' => '', )) ->execute(); // We need some placeholders here as name and mail are uniques and data is // presumed to be a serialized array. This will be changed by the settings // form in the installer. db_insert('users') ->fields(array( 'uid' => 1, 'name' => 'placeholder-for-uid-1', 'mail' => 'placeholder-for-uid-1', 'created' => REQUEST_TIME, 'status' => 1, )) ->execute(); } /** * Creates a user picture image field for the User entity. * * This is only used in core's standard.install, but is kept as a separate * helper function so that other install profiles can reuse it. */ function user_install_picture_field() { $t = get_t(); $field = array( 'field_name' => 'user_picture', 'module' => 'image', 'type' => 'image', 'cardinality' => 1, 'locked' => FALSE, 'indexes' => array('fid' => array('fid')), 'settings' => array( 'uri_scheme' => 'public', 'default_image' => FALSE, ), 'storage' => array( 'type' => 'field_sql_storage', 'settings' => array(), ), ); $field = field_create_field($field); $instance = array( 'field_name' => 'user_picture', 'entity_type' => 'user', 'label' => 'Picture', 'bundle' => 'user', 'description' => $t('Your virtual face or picture.'), 'required' => FALSE, 'settings' => array( 'file_extensions' => 'png gif jpg jpeg', 'file_directory' => 'pictures', 'max_filesize' => '30 KB', 'alt_field' => 0, 'title_field' => 0, 'max_resolution' => '85x85', 'min_resolution' => '', 'default_image' => 0, ), 'widget' => array( 'module' => 'image', 'type' => 'image_image', 'settings' => array( 'progress_indicator' => 'throbber', 'preview_image_style' => 'thumbnail', ), 'weight' => -1, ), ); field_create_instance($instance); // Assign display settings for the 'default' and 'compact' view modes. entity_get_display('user', 'user', 'default') ->setComponent('user_picture', array( 'label' => 'hidden', 'type' => 'image', 'settings' => array( 'image_style' => 'thumbnail', 'image_link' => 'content', ), )) ->save(); entity_get_display('user', 'user', 'compact') ->setComponent('user_picture', array( 'label' => 'hidden', 'type' => 'image', 'settings' => array( 'image_style' => 'thumbnail', 'image_link' => 'content', ), )) // Additionally, hide 'summary' pseudo-field from compact view mode.. ->removeComponent('member_for') ->save(); } /** * @addtogroup updates-7.x-to-8.x * @{ */ /** * The 'Member for' extra field has moved one level up in the array. */ function user_update_8000() { $settings = field_bundle_settings('user', 'user'); if (isset($settings['extra_fields']['display']['summary'])) { $settings['extra_fields']['display']['member_for'] = $settings['extra_fields']['display']['summary']; unset($settings['extra_fields']['display']['summary']); field_bundle_settings('user', 'user', $settings); } } /** * Splits {users}.language field to langcode and preferred_langcode. * * @see http://drupal.org/node/1454538 */ function user_update_8001() { // The former language field is the language preference of the user. Rename // this to preferred_langcode in order to distinguish it from the langcode // field common to all entity types, used for identifying the language of the // entity itself. $preferred_langcode_field = array( 'type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => '', 'description' => 'The {language}.langcode that the user prefers for receiving emails and viewing the site.', ); db_change_field('users', 'language', 'preferred_langcode', $preferred_langcode_field); // Add the langcode field. $langcode_field = array( 'type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => '', 'description' => "The {language}.langcode of the user's profile.", ); db_add_field('users', 'langcode', $langcode_field); // Since distinguishing the language of the user entity from the user's // preferred language is a new feature in Drupal 8, assume that for updated // sites, existing user entities are in the user's preferred language. db_update('users')->expression('langcode', 'preferred_langcode')->execute(); } /** * Replace serial role IDs with machine name strings. */ function user_update_8002() { // Change serial rid columns into strings. $column = array( 'type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'description' => 'Primary Key: Unique role ID.', ); db_change_field('role', 'rid', 'rid', $column); $column['description'] = 'Foreign Key: {role}.rid.'; db_change_field('role_permission', 'rid', 'rid', $column); $column['description'] = 'Primary Key: {role}.rid for role.'; db_change_field('users_roles', 'rid', 'rid', $column); // Enlarge the role name (label) column. $column = array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'Role label.', 'translatable' => TRUE, ); db_change_field('role', 'name', 'name', $column); // Remove unique index. db_drop_unique_key('role', 'name'); // Rename the built-in serial role IDs into the hardcoded machine names. db_update('role') ->fields(array('rid' => DRUPAL_ANONYMOUS_RID)) ->condition('rid', 1) ->execute(); db_update('role') ->fields(array('rid' => DRUPAL_AUTHENTICATED_RID)) ->condition('rid', 2) ->execute(); db_update('role_permission') ->fields(array('rid' => DRUPAL_ANONYMOUS_RID)) ->condition('rid', 1) ->execute(); db_update('role_permission') ->fields(array('rid' => DRUPAL_AUTHENTICATED_RID)) ->condition('rid', 2) ->execute(); db_update('users_roles') ->fields(array('rid' => DRUPAL_ANONYMOUS_RID)) ->condition('rid', 1) ->execute(); db_update('users_roles') ->fields(array('rid' => DRUPAL_AUTHENTICATED_RID)) ->condition('rid', 2) ->execute(); } /** * Create a UUID column for users. */ function user_update_8003() { $spec = array( 'description' => 'Unique Key: Universally unique identifier for this entity.', 'type' => 'varchar', 'length' => 128, 'not null' => FALSE, ); $keys = array( 'unique keys' => array( 'uuid' => array('uuid'), ), ); // Account for sites having the contributed UUID module installed. if (db_field_exists('users', 'uuid')) { db_change_field('users', 'uuid', 'uuid', $spec, $keys); } else { db_add_field('users', 'uuid', $spec, $keys); } } /** * Moves account settings from variable to config. * * @ingroup config_upgrade */ function user_update_8004() { update_variables_to_config('user.settings', array( 'anonymous' => 'anonymous', 'user_admin_role' => 'admin_role', 'user_register' => 'register', 'user_signatures' => 'signatures', 'user_cancel_method' => 'cancel_method', 'user_mail_status_activated_notify' => 'notify.status_activated', 'user_mail_status_blocked_notify' => 'notify.status_blocked', 'user_mail_status_cancelled_notify' => 'notify.status_cancelled', 'user_email_verification' => 'verify_mail', 'user_password_reset_timeout' => 'password_reset_timeout', )); // Convert the user.settings:register numeric value to text value. $map = array( '0' => 'admin_only', '1' => 'visitors', '2' => 'visitors_admin_approval', ); $config = config('user.settings'); $user_register = $config->get('register'); $user_cancel_method = $config->get('cancel_method'); if (is_numeric($user_register) && isset($map[$user_register])) { $config->set('register', $map[$user_register])->save(); } // Convert user.settings:cancel_method numeric value to text value. $cancel_map = array( '0' => 'user_cancel_block', '1' => 'user_cancel_block_unpublish', '2' => 'user_cancel_block_reassign', '3' => 'user_cancel_block_delete', ); if (is_numeric($user_cancel_method) && isset($cancel_map[$user_cancel_method])) { $config->set('cancel_method', $$cancel_map[$user_cancel_method])->save(); } } /** * Creates a preferred_admin_langcode column. */ function user_update_8005() { $spec = array( 'description' => 'The {language}.langcode that the user prefers for viewing administration pages.', 'type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => '', ); db_add_field('users', 'preferred_admin_langcode', $spec); } /** * Moves user mail settings from variable to config. * * @ingroup config_upgrade */ function user_update_8006() { update_variables_to_config('user.mail', array( 'register_admin_created_subject' => 'register_admin_created.subject', 'register_admin_created_body' => 'register_admin_created.body', 'register_pending_approval_subject' => 'register_pending_approval.subject', 'register_pending_approval_body' => 'register_pending_approval.body', 'register_no_approval_required_subject' => 'register_no_approval_required.subject', 'register_no_approval_required_body' => 'register_no_approval_required.body', 'password_reset_subject' => 'password_reset.subject', 'password_reset_body' => 'password_reset.body', 'status_activated_subject' => 'status_activated.subject', 'status_activated_body' => 'status_activated.body', 'status_blocked_subject' => 'status_blocked.subject', 'status_blocked_body' => 'status_blocked.body', 'cancel_confirm_subject' => 'cancel_confirm.subject', 'cancel_confirm_body' => 'cancel_confirm.body', 'status_canceled_subject' => 'status_canceled.subject', 'status_canceled_body' => 'status_canceled.body', )); } /** * Moves login flood settings from variable to config. * * @ingroup config_upgrade */ function user_update_8007() { update_variables_to_config('user.flood', array( 'user_failed_login_identifier_uid_only' => 'uid_only', 'user_failed_login_ip_limit' => 'ip_limit', 'user_failed_login_ip_window' => 'ip_window', 'user_failed_login_user_limit' => 'user_limit', 'user_failed_login_user_window' => 'user_window', )); } /** * Make *id fields unsigned. */ function user_update_8008() { db_change_field('authmap', 'uid', 'uid', array( 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => "User's {users}.uid.", ) ); } /** * Generate a UUID for all users. */ function user_update_8009(&$sandbox) { if (!isset($sandbox['progress'])) { $sandbox['progress'] = 0; // The first user id is 0, so it needs to start with -1. $sandbox['last'] = -1; $sandbox['max'] = db_query('SELECT COUNT(uid) FROM {users} WHERE uuid IS NULL')->fetchField(); } $uids = db_query_range('SELECT uid FROM {users} WHERE uid > :uid AND uuid IS NULL ORDER BY uid ASC', 0, 10, array(':uid' => $sandbox['last']))->fetchCol(); update_add_uuids($sandbox, 'users', 'uid', $uids); $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); } /** * Create user picture field. */ function user_update_8011() { global $user; // User pictures can only be migrated to the new user picture image field // if Image module is installed. if (!module_exists('image')) { module_enable(array('image')); } if ($default_image = update_variable_get('user_picture_default', '')) { $picture_directory = update_variable_get('file_default_scheme', 'public') . '://' . update_variable_get('user_picture_path', 'pictures'); file_prepare_directory($picture_directory, FILE_CREATE_DIRECTORY); $destination = file_stream_wrapper_uri_normalize($picture_directory . '/' . drupal_basename($default_image)); // The file entity needs to be created manually as entities can not be // created/saved during the upgrade path. Attempt to replicate the behavior // of file_save_data() by updating an eventually existing record for that // file. file_unmanaged_save_data($default_image, $destination, FILE_EXISTS_REPLACE); $uuid = new Uuid(); db_merge('file_managed') ->key(array( 'uri' => $destination, )) ->fields(array( 'uid' => $user->uid, 'status' => FILE_STATUS_PERMANENT, 'filename' => drupal_basename($destination), 'uuid' => $uuid->generate(), 'langcode' => LANGUAGE_NOT_SPECIFIED, 'filesize' => filesize($destination), 'filemime' => file_get_mimetype($destination), 'timestamp' => REQUEST_TIME, )) ->execute(); $default_image_fid = db_query('SELECT fid FROM {file_managed} WHERE uri = :uri', array(':uri' => $destination))->fetchField(); } // Create the field and instance. $field = array( 'field_name' => 'user_picture', 'module' => 'image', 'type' => 'image', 'cardinality' => 1, 'locked' => FALSE, 'indexes' => array('fid' => array('fid')), 'settings' => array( 'uri_scheme' => 'public', 'default_image' => FALSE, ), 'storage' => array( 'type' => 'field_sql_storage', 'settings' => array(), ), ); _update_7000_field_create_field($field); $instance = array( 'field_name' => 'user_picture', 'entity_type' => 'user', 'label' => 'Picture', 'bundle' => 'user', 'description' => update_variable_get('user_picture_guidelines', ''), 'required' => FALSE, 'settings' => array( 'file_extensions' => 'png gif jpg jpeg', 'file_directory' => update_variable_get('user_picture_path', 'pictures'), 'max_filesize' => update_variable_get('user_picture_file_size', '30') . ' KB', 'alt_field' => 0, 'title_field' => 0, 'max_resolution' => update_variable_get('user_picture_dimensions', '85x85'), 'min_resolution' => '', 'default_image' => !empty($default_image_fid) ? $default_image_fid : 0, ), 'widget' => array( 'module' => 'image', 'type' => 'image_image', 'settings' => array( 'progress_indicator' => 'throbber', 'preview_image_style' => 'thumbnail', ), 'weight' => -1, ), ); _update_7000_field_create_instance($field, $instance); // Assign display settings for the 'default' and 'compact' view modes. In D7, // user pictures did not require Image module to work. Image module only // allowed usage of an image style to format user pictures in the output. // The 'user_pictures' variable had a global effect on the presence of the // user picture functionality before. The new user picture image field is // created regardless of that global setting, which means the field appears // on the user account form after migration, even if user pictures were // disabled previously. The picture is only hidden in the output. $formatter = update_variable_get('user_pictures', 0) ? 'image' : 'hidden'; module_load_install('entity'); $display = _update_8000_entity_get_display('user', 'user', 'default'); $display->set('content.user_picture', array( 'label' => 'hidden', 'type' => $formatter, 'settings' => array( 'image_style' => 'thumbnail', 'image_link' => 'content', ), 'weight' => 0, )) ->save(); update_config_manifest_add('entity.display', array($display->get('id'))); $display = _update_8000_entity_get_display('user', 'user', 'compact'); $display->set('content.user_picture', array( 'label' => 'hidden', 'type' => $formatter, 'settings' => array( 'image_style' => update_variable_get('user_picture_style', ''), 'image_link' => 'content', ), 'weight' => 0, )) ->save(); update_config_manifest_add('entity.display', array($display->get('id'))); // Add file usage for the default field. if (!empty($default_image_fid)) { db_insert('file_usage') ->fields(array( 'fid' => $default_image_fid, 'module' => 'image', 'type' => 'default_image', 'id' => $field['id'], 'count' => 1, )) ->execute(); } // Update the user bundle settings and hide the member_for extra field. $settings = update_variable_get('field_bundle_settings_user__user'); $settings['extra_fields']['display']['member_for']['compact'] = array( 'weight' => 0, 'visible' => FALSE, ); update_variable_set('field_bundle_settings_user__user', $settings); // Delete old variables. update_variable_del('user_pictures'); update_variable_del('user_picture_path'); update_variable_del('user_picture_default'); update_variable_del('user_picture_style'); update_variable_del('user_picture_dimensions'); update_variable_del('user_picture_file_size'); update_variable_del('user_picture_guidelines'); } /** * Migrate {users}.picture to 'user_picture' image field. */ function user_update_8012(&$sandbox) { // Initialize total values to process. if (!isset($sandbox['total'])) { $sandbox['total'] = (int) db_query('SELECT COUNT(picture) FROM {users} WHERE picture > 0')->fetchField(); $sandbox['processed'] = 0; } if ($sandbox['total']) { // Retrieve next 20 rows to migrate. $rows = db_query_range('SELECT uid, picture FROM {users} WHERE picture > 0', 0, 20)->fetchAllKeyed(); foreach ($rows as $uid => $fid) { // Add a row to the field data and revision tables. db_insert('field_data_user_picture') ->fields(array( 'entity_type' => 'user', 'bundle' => 'user', 'entity_id' => $uid, 'revision_id' => $uid, 'langcode' => LANGUAGE_NOT_SPECIFIED, 'delta' => 0, 'user_picture_fid' => $fid, )) ->execute(); db_insert('field_revision_user_picture') ->fields(array( 'entity_type' => 'user', 'bundle' => 'user', 'entity_id' => $uid, 'revision_id' => $uid, 'langcode' => LANGUAGE_NOT_SPECIFIED, 'delta' => 0, 'user_picture_fid' => $fid, )) ->execute(); // Update file usage from user to file module. // @see file_field_insert() // Old: file_usage_add($picture, 'user', 'user', $entity->uid); // New: file_usage_add(file_load($item['fid']), 'file', $entity_type, $id); db_update('file_usage') ->condition('fid', $fid) ->condition('module', 'user') ->condition('type', 'user') ->condition('id', $uid) ->fields(array( 'module' => 'file', )) ->execute(); } // Set picture column of the migrated users to 0. db_update('users') ->fields(array( 'picture' => 0, )) ->condition('uid', array_keys($rows)) ->execute(); // Report status. $sandbox['processed'] += count($rows); } $sandbox['#finished'] = $sandbox['total'] ? $sandbox['processed'] / $sandbox['total'] : 1; } /** * Deletes {users}.picture field. */ function user_update_8013() { db_drop_field('users', 'picture'); } /** * Create new {users_data} table. */ function user_update_8014() { // Create the {users_data} table. db_create_table('users_data', array( 'description' => 'Stores module data as key/value pairs per user.', 'fields' => array( 'uid' => array( 'description' => 'Primary key: {users}.uid for user.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), 'module' => array( 'description' => 'The name of the module declaring the variable.', 'type' => 'varchar', 'length' => 204, 'not null' => TRUE, 'default' => '', ), 'name' => array( 'description' => 'The identifier of the data.', 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '', ), 'value' => array( 'description' => 'The value.', 'type' => 'blob', 'not null' => FALSE, 'size' => 'big', ), 'serialized' => array( 'description' => 'Whether value is serialized.', 'type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'default' => 0, ), ), 'primary key' => array('uid', 'module', 'name'), 'indexes' => array( 'module' => array('module'), 'name' => array('name'), ), 'foreign keys' => array( 'uid' => array('users' => 'uid'), ), )); // Create backup table for data migration. // Since the origin/owner of individual values in {users}.data is unknown, // other modules need to migrate their existing values from {_d7_users_data}. db_create_table('_d7_users_data', array( 'description' => 'Backup of {users}.data for migration.', 'fields' => array( 'uid' => array( 'description' => 'Primary Key: {users}.uid for user.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), 'name' => array( 'description' => 'The name of the variable.', 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '', ), 'value' => array( 'description' => 'The serialized value of the variable.', 'type' => 'blob', 'not null' => FALSE, 'size' => 'big', 'serialize' => TRUE, ), ), 'primary key' => array('uid', 'name'), 'foreign keys' => array( 'uid' => array('users' => 'uid'), ), )); } /** * Move existing {users}.data into {_d7_users_data} migration table. */ function user_update_8015(&$sandbox) { if (!isset($sandbox['progress'])) { $sandbox['progress'] = 0; // The anonymous user cannot have data, so start with uid 1. $sandbox['last'] = 0; $sandbox['max'] = db_query('SELECT COUNT(uid) FROM {users} WHERE uid > 0')->fetchField(); } // Process 20 user records at a time. E.g., if there are 10 data keys per user // record, that leads to an insert query with 200 values. $result = db_query_range('SELECT uid, data FROM {users} WHERE uid > :uid ORDER BY uid ASC', 0, 20, array(':uid' => $sandbox['last']))->fetchAllKeyed(); $query = db_insert('_d7_users_data')->fields(array('uid', 'name', 'value')); $has_values = FALSE; foreach ($result as $uid => $data) { $sandbox['progress']++; $sandbox['last'] = $uid; if (empty($data)) { continue; } $data = unserialize($data); if (!empty($data) && is_array($data)) { $has_values = TRUE; foreach ($data as $name => $value) { $query->values(array( 'uid' => $uid, 'name' => $name, 'value' => serialize($value), )); } } } if ($has_values) { $query->execute(); } $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); } /** * Drop {users}.data column. */ function user_update_8016() { db_drop_field('users', 'data'); } /** * Migrate user roles into configuration. * * @ingroup config_upgrade */ function user_update_8017() { $uuid = new Uuid(); $roles = db_select('role', 'r') ->fields('r') ->execute() ->fetchAll(); foreach ($roles as $role) { config('user.role.' . $role->rid) ->set('id', $role->rid) ->set('uuid', $uuid->generate()) ->set('label', $role->name) ->set('weight', $role->weight) ->set('langcode', LANGUAGE_NOT_SPECIFIED) ->save(); } update_config_manifest_add('user.role', array_map(function ($role) { return $role->rid; }, $roles)); } /** * @} End of "addtogroup updates-7.x-to-8.x". */