Newer
Older

Angie Byron
committed
/**
* @file
* Install, update and uninstall functions for the user module.
*/
use Drupal\Core\Language\Language;

Angie Byron
committed
use Drupal\field\Field;

Dries Buytaert
committed
* Implements hook_schema().
*/
function user_schema() {

Jennifer Hodgdon
committed
// The table name here is plural, despite Drupal table naming standards,
// because "user" is a reserved word in many databases.

Angie Byron
committed
$schema['users'] = array(

Dries Buytaert
committed
'description' => 'Stores user data.',
'fields' => array(
'uid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,

Dries Buytaert
committed
'description' => 'Primary Key: Unique user ID.',
'default' => 0,

Dries Buytaert
committed
'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' => '',

Dries Buytaert
committed
'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' => '',

Dries Buytaert
committed
'description' => "User's password (hashed).",
),
'mail' => array(
'type' => 'varchar',

Dries Buytaert
committed
'length' => 254,
'not null' => FALSE,
'default' => '',

Dries Buytaert
committed
'description' => "User's e-mail address.",
),
'theme' => array(
'type' => 'varchar',
'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
'not null' => TRUE,
'default' => '',

Dries Buytaert
committed
'description' => "User's default theme.",
),
'signature' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',

Dries Buytaert
committed
'description' => "User's signature.",
'signature_format' => array(
'type' => 'varchar',
'length' => 255,

Angie Byron
committed
'not null' => FALSE,

Angie Byron
committed
'description' => 'The filter format ID of the signature.',
),
'created' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,

Dries Buytaert
committed
'description' => 'Timestamp for when user was created.',
),
'access' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,

Dries Buytaert
committed
'description' => 'Timestamp for previous time user accessed the site.',
),
'login' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,

Dries Buytaert
committed
'description' => "Timestamp for user's last login.",
),
'status' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',

Dries Buytaert
committed
'description' => 'Whether the user is active(1) or blocked(0).',
),
'timezone' => array(
'type' => 'varchar',

Angie Byron
committed
'length' => 32,
'not null' => FALSE,

Angie Byron
committed
'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.',

Dries Buytaert
committed
'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',

Dries Buytaert
committed
'length' => 254,
'not null' => FALSE,
'default' => '',

Dries Buytaert
committed
'description' => 'E-mail address used for initial account creation.',
),
'indexes' => array(
'access' => array('access'),

Gábor Hojtsy
committed
'created' => array('created'),
'mail' => array('mail'),

Dries Buytaert
committed
'unique keys' => array(

Dries Buytaert
committed
'uuid' => array('uuid'),

Dries Buytaert
committed
'name' => array('name'),
),
'primary key' => array('uid'),
'foreign keys' => array(

Dries Buytaert
committed
'signature_format' => array(
'table' => 'filter_format',
'columns' => array('signature_format' => 'format'),
),
),
$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' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
'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'),
),
);

Angie Byron
committed
$schema['users_roles'] = array(

Dries Buytaert
committed
'description' => 'Maps users to roles.',
'fields' => array(
'uid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,

Angie Byron
committed
'description' => 'Primary Key: {users}.uid for user.',
),
'rid' => array(

catch
committed
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,

Alex Pott
committed
'description' => 'Primary Key: ID for the role.',
),
'primary key' => array('uid', 'rid'),

Dries Buytaert
committed
'indexes' => array(
'rid' => array('rid'),
),
'foreign keys' => array(

Dries Buytaert
committed
'user' => array(
'table' => 'users',
'columns' => array('uid' => 'uid'),
),
);
return $schema;
}

Dries Buytaert
committed
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
/**
* 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();
}

catch
committed
/**
* Implements hook_update_dependencies().
*/
function user_update_dependencies() {
// Convert user picture to field after the fields and instances are converted
// to ConfigEntities and the tables are split.
$dependencies['user'][8011] = array(
'field' => 8006,
);
return $dependencies;
}

catch
committed
/**
* @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 = update_variable_get('field_bundle_settings_user__user', array());

catch
committed
if (isset($settings['extra_fields']['display']['summary'])) {
$settings['extra_fields']['display']['member_for'] = $settings['extra_fields']['display']['summary'];
unset($settings['extra_fields']['display']['summary']);
update_variable_set('field_bundle_settings_user__user', $settings);

catch
committed
}
}
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/**
* 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();
}

catch
committed
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/**
* 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'] = '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.',
);
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.
foreach (array(1, 2) as $rid) {
db_update('role')
->fields(array('rid' => _user_update_map_rid($rid)))
->condition('rid', $rid)
->execute();
db_update('users_roles')
->fields(array('rid' => _user_update_map_rid($rid)))
->condition('rid', $rid)
->execute();
}

catch
committed
}

Dries Buytaert
committed
/**
* 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);
}
}

Angie Byron
committed
/**
* 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',

catch
committed
'user_cancel_method' => 'cancel_method',

Angie Byron
committed
'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',

Dries Buytaert
committed
'user_password_reset_timeout' => 'password_reset_timeout',

Angie Byron
committed
));
// Convert the user.settings:register numeric value to text value.
$map = array(
'0' => 'admin_only',
'1' => 'visitors',
'2' => 'visitors_admin_approval',
);

catch
committed
$config = \Drupal::config('user.settings');

Angie Byron
committed
$user_register = $config->get('register');

catch
committed
$user_cancel_method = $config->get('cancel_method');

Angie Byron
committed
if (is_numeric($user_register) && isset($map[$user_register])) {
$config->set('register', $map[$user_register])->save();
}

catch
committed
// 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();
}

Angie Byron
committed
}

Dries Buytaert
committed
/**
* 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);
}

Angie Byron
committed
/**
* 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_pending_approval_admin_body' => 'register_pending_approval_admin.body',
'register_pending_approval_admin_subject' => 'register_pending_approval_admin.subject',

Angie Byron
committed
'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',
));
}

Dries Buytaert
committed
/**
* 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',
));
}

Dries Buytaert
committed
/**
* 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 (!\Drupal::moduleHandler()->moduleExists('image')) {

Alex Pott
committed
$old_schema = \Drupal::moduleHandler()->install(array('image'));
if ($old_schema['image'] == SCHEMA_UNINSTALLED) {

Alex Pott
committed
// Install image.module with schema version 8003 as a previous version

Alex Pott
committed
// would have to create tables that would be removed again.

Alex Pott
committed
update_set_schema('image', 8003);
// Inlined version of image_install(), make sure that the styles
// directory exists.
$directory = update_variable_get('file_default_scheme', 'public') . '://styles';
file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
}
}
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 = \Drupal::service('uuid');
db_merge('file_managed')
->key(array(
'uri' => $destination,
))
->fields(array(

Dries Buytaert
committed
'uid' => $user->id(),
'status' => FILE_STATUS_PERMANENT,
'filename' => drupal_basename($destination),
'uuid' => $uuid->generate(),
'langcode' => Language::LANGCODE_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(
'name' => 'user_picture',
'entity_type' => 'user',
'module' => 'image',
'type' => 'image',
'cardinality' => 1,
'locked' => FALSE,

Dries Buytaert
committed
'indexes' => array('target_id' => array('target_id')),
'settings' => array(
'uri_scheme' => 'public',
'default_image' => FALSE,
),
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
'schema' => array(
'columns' => array(
'target_id' => array(
'description' => 'The ID of the target entity.',
'type' => 'int',
'not null' => TRUE,
'unsigned' => TRUE,
),
'alt' => array(
'description' => "Alternative image text, for the image's 'alt' attribute.",
'type' => 'varchar',
'length' => 512,
'not null' => FALSE,
),
'title' => array(
'description' => "Image title text, for the image's 'title' attribute.",
'type' => 'varchar',
'length' => 1024,
'not null' => FALSE,
),
'width' => array(
'description' => 'The width of the image in pixels.',
'type' => 'int',
'unsigned' => TRUE,
),
'height' => array(
'description' => 'The height of the image in pixels.',
'type' => 'int',
'unsigned' => TRUE,
),
),
'indexes' => array(
'target_id' => array('target_id'),
),
'foreign keys' => array(
'target_id' => array(
'table' => 'file_managed',
'columns' => array('target_id' => 'fid'),
),
),
),
);
_update_8003_field_create_field($field);
$instance = array(
'entity_type' => 'user',
'bundle' => 'user',
'label' => 'Picture',
'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' => '',

Alex Pott
committed
'default_image' => !empty($default_image_fid) ? $default_image_fid : 0,

Alex Pott
committed
);
_update_8003_field_create_instance($field, $instance);

Alex Pott
committed
module_load_install('entity');
if (update_variable_get('user_pictures', 0)) {
$formatter = 'image';
$widget = 'image_image';
}
else {
$formatter = $widget = 'hidden';
}
// Assign form settings for the 'default' form mode.
$form_display = _update_8000_entity_get_form_display('user', 'user', 'default', TRUE);

Alex Pott
committed
$form_display->set('content.user_picture', array(
'type' => $widget,
'settings' => array(
'progress_indicator' => 'throbber',
'preview_image_style' => 'thumbnail',
),
'weight' => -1,

Alex Pott
committed
))
->set('status', 1)

Alex Pott
committed
->save();

Alex Pott
committed
// Assign display settings for the 'default' and 'compact' view modes.
$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,
))
->set('status', 1)
->save();
$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,
))
->set('status', 1)
->set('content.member_for', array(
'visible' => FALSE,
));
$display->save();
// 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['uuid'],
'count' => 1,
))
->execute();
}
// 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('user__user_picture')
->fields(array(
'bundle' => 'user',
'entity_id' => $uid,
'revision_id' => $uid,
'langcode' => Language::LANGCODE_NOT_SPECIFIED,
'delta' => 0,

Dries Buytaert
committed
'user_picture_target_id' => $fid,
))
->execute();
db_insert('user_revision__user_picture')
->fields(array(
'bundle' => 'user',
'entity_id' => $uid,
'revision_id' => $uid,
'langcode' => Language::LANGCODE_NOT_SPECIFIED,
'delta' => 0,

Dries Buytaert
committed
'user_picture_target_id' => $fid,
))
->execute();
// Update file usage from user to file module.
// @see file_field_insert()

Dries Buytaert
committed
// Old: file_usage_add($picture, 'user', 'user', $entity->id();
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
// 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,
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
'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');
}
/**
* Grant "administer account settings" to roles with "administer users."
*/
function user_update_8017() {
$rids = db_query("SELECT rid FROM {role_permission} WHERE permission = :perm", array(':perm' => 'administer users'))->fetchCol();
// None found.
if (empty($rids)) {
return;
}
$insert = db_insert('role_permission')->fields(array('rid', 'permission', 'module'));
foreach ($rids as $rid) {
$insert->values(array(
'rid' => $rid,
'permission' => 'administer account settings',
'module' => 'user'
));
}
$insert->execute();
}
/**
* Migrate user roles into configuration.
*
* @ingroup config_upgrade
*/
function user_update_8018() {
$uuid = \Drupal::service('uuid');
$roles = db_select('role', 'r')
->fields('r')
->execute()
->fetchAll();
foreach ($roles as $role) {
\Drupal::config('user.role.' . $role->rid)
->set('id', $role->rid)
->set('uuid', $uuid->generate())
->set('label', $role->name)
->set('weight', $role->weight)
->set('langcode', Language::LANGCODE_NOT_SPECIFIED)
->save();
}
}
/**
* Use the maximum allowed module name length in module name database fields.
*/
function user_update_8019() {
if (db_field_exists('role_permission', 'module')) {
$spec = array(
'type' => 'varchar',
'length' => 50,
'not null' => TRUE,
'default' => '',
'description' => 'The module declaring the permission.',
);
db_change_field('role_permission', 'module', 'module', $spec);
}
if (db_field_exists('users_data', 'module')) {
$spec = array(
'description' => 'The name of the module declaring the variable.',
'type' => 'varchar',
'length' => 50,
'not null' => TRUE,
'default' => '',
);