Update to Drupal 8.0.0-beta15. For more information, see: https://www.drupal.org/node/2563023

This commit is contained in:
Pantheon Automation 2015-09-04 13:20:09 -07:00 committed by Greg Anderson
parent 2720a9ec4b
commit f3791f1da3
1898 changed files with 54300 additions and 11481 deletions

View file

@ -396,10 +396,12 @@ display:
hide_empty: false
empty_zero: false
hide_alter_empty: true
date_format: 'raw time ago'
custom_date_format: ''
timezone: ''
plugin_id: date
type: timestamp_ago
settings:
future_format: '@interval'
past_format: '@interval'
granularity: 2
plugin_id: field
entity_type: user
entity_field: created
access:
@ -450,10 +452,12 @@ display:
hide_empty: false
empty_zero: false
hide_alter_empty: true
date_format: 'time ago'
custom_date_format: ''
timezone: ''
plugin_id: date
type: timestamp_ago
settings:
future_format: '@interval hence'
past_format: '@interval ago'
granularity: 2
plugin_id: field
entity_type: user
entity_field: access
operations:

View file

@ -0,0 +1,9 @@
# Schema for the migrate destination plugin.
migrate.destination.entity:user:
type: migrate_destination
label: 'User'
mapping:
md5_passwords:
type: boolean
label: 'Passwords'

View file

@ -0,0 +1,47 @@
# Schema for the user module's migration source plugins.
migrate.source.d6_user:
type: migrate_source_sql
label: 'Drupal 6 user'
mapping:
constants:
type: mapping
label: 'Constants'
mapping:
key:
type: string
label: 'User data key'
module:
type: string
label: 'Module name'
migrate.source.d6_user_picture_file:
type: migrate_source_sql
label: 'Drupal 6 user picure display'
mapping:
constants:
type: mapping
label: 'Constant'
mapping:
is_public:
type: boolean
label: 'Public'
migrate.source.d6_user_picture_instance:
type: migrate_source_sql
label: 'Drupal 6 user picure display'
mapping:
provider:
type: string
label: 'Provider'
constants:
type: migrate_entity_constant
label: 'Constants'
migrate.source.profile_field:
type: migrate_source_sql
label: 'Profile field'
mapping:
constants:
type: migrate_entity_constant
label: 'Constants'

View file

@ -0,0 +1,20 @@
id: d6_profile_values
label: Drupal 6 profile values
migration_tags:
- Drupal 6
builder:
plugin: d6_profile_values
source:
plugin: d6_profile_field_values
load:
plugin: drupal_entity
process:
uid: uid
destination:
plugin: entity:user
migration_dependencies:
required:
- d6_user
- user_profile_field_instance
- user_profile_entity_display
- user_profile_entity_form_display

View file

@ -0,0 +1,38 @@
id: d6_user
label: Drupal 6 user accounts
migration_tags:
- Drupal 6
source:
plugin: d6_user
process:
uid: uid
name: name
pass: pass
mail: mail
created: created
access: access
login: login
status: status
timezone:
plugin: user_update_7002
source: timezone
preferred_langcode: language
init: init
roles:
plugin: migration
migration: d6_user_role
source: roles
user_picture:
plugin: migration
migration: d6_user_picture_file
source: uid
destination:
plugin: entity:user
md5_passwords: true
migration_dependencies:
required:
- d6_user_role
optional:
- d6_user_picture_file
- user_picture_entity_display
- user_picture_entity_form_display

View file

@ -0,0 +1,23 @@
id: d6_user_contact_settings
label: Drupal 6 user contact settings
migration_tags:
- Drupal 6
source:
plugin: d6_user
constants:
key: contact
module: contact
process:
uid: uid
key: 'constants/key'
module: 'constants/module'
settings:
plugin: skip_row_if_not_set
index: contact
source: data
destination:
plugin: user_data
migration_dependencies:
required:
- d6_user

View file

@ -0,0 +1,67 @@
id: d6_user_mail
label: User mail configuration
migration_tags:
- Drupal 6
source:
plugin: variable
variables:
- user_mail_status_activated_subject
- user_mail_status_activated_body
- user_mail_password_reset_subject
- user_mail_password_reset_body
- user_mail_status_deleted_subject
- user_mail_status_deleted_body
- user_mail_register_admin_created_subject
- user_mail_register_admin_created_body
- user_mail_register_no_approval_required_subject
- user_mail_register_no_approval_required_body
- user_mail_register_pending_approval_subject
- user_mail_register_pending_approval_body
- user_mail_status_blocked_subject
- user_mail_status_blocked_body
process:
'status_activated/subject':
plugin: convert_tokens
source: user_mail_status_activated_subject
'status_activated/body':
plugin: convert_tokens
source: user_mail_status_activated_body
'password_reset/subject':
plugin: convert_tokens
source: user_mail_password_reset_subject
'password_reset/body':
plugin: convert_tokens
source: user_mail_password_reset_body
'cancel_confirm/subject':
plugin: convert_tokens
source: user_mail_status_deleted_subject
'cancel_confirm/body':
plugin: convert_tokens
source: user_mail_status_deleted_body
'register_admin_created/subject':
plugin: convert_tokens
source: user_mail_register_admin_created_subject
'register_admin_created/body':
plugin: convert_tokens
source: user_mail_register_admin_created_body
'register_no_approval_required/subject':
plugin: convert_tokens
source: user_mail_register_no_approval_required_subject
'register_no_approval_required/body':
plugin: convert_tokens
source: user_mail_register_no_approval_required_body
'register_pending_approval/subject':
plugin: convert_tokens
source: user_mail_register_pending_approval_subject
'register_pending_approval/body':
plugin: convert_tokens
source: user_mail_register_pending_approval_body
'status_blocked/subject':
plugin: convert_tokens
source: user_mail_status_blocked_subject
'status_blocked/body':
plugin: convert_tokens
source: user_mail_status_blocked_body
destination:
plugin: config
config_name: user.mail

View file

@ -0,0 +1,26 @@
id: d6_user_picture_file
label: Drupal 6 user pictures
migration_tags:
- Drupal 6
source:
plugin: d6_user_picture_file
constants:
is_public: true
process:
filename: filename
uid: uid
uri:
plugin: file_uri
source:
- picture
- file_directory_path
- temp_directory_path
- 'constants/is_public'
destination:
plugin: entity:file
source_path_property: picture
migration_dependencies:
# Every migration that saves into {file_managed} must have the d6_file
# migration as an optional dependency to ensure it runs first.
optional:
- d6_file

View file

@ -0,0 +1,46 @@
id: d6_user_role
label: Drupal 6 user roles
migration_tags:
- Drupal 6
source:
plugin: d6_user_role
process:
id:
-
plugin: machine_name
source: name
-
plugin: dedupe_entity
entity_type: user_role
field: id
length: 32
-
plugin: user_update_8002
label: name
permissions:
-
plugin: static_map
source: permissions
bypass: true
map:
'use PHP for block visibility': 'use PHP for settings'
'administer site-wide contact form': 'administer contact forms'
'post comments without approval': 'skip comment approval'
'edit own blog entries' : 'edit own blog content'
'edit any blog entry' : 'edit any blog content'
'delete own blog entries' : 'delete own blog content'
'delete any blog entry' : 'delete any blog content'
'create forum topics' : 'create forum content'
'delete any forum topic' : 'delete any forum content'
'delete own forum topics' : 'delete own forum content'
'edit any forum topic' : 'edit any forum content'
'edit own forum topics' : 'edit own forum content'
- plugin: system_update_7000
- plugin: node_update_7008
- plugin: flatten
- plugin: filter_format_permission
destination:
plugin: entity:user_role
migration_dependencies:
required:
- d6_filter_format

View file

@ -0,0 +1,28 @@
id: d6_user_settings
label: Drupal 6 user configuration
migration_tags:
- Drupal 6
source:
plugin: variable
variables:
- user_mail_status_blocked_notify
- user_mail_status_activated_notify
- user_email_verification
- user_register
- anonymous
process:
'notify/status_blocked': user_mail_status_blocked_notify
'notify/status_activated': user_mail_status_activated_notify
verify_mail: user_email_verification
register:
plugin: static_map
source: user_register
default_value: visitors_admin_approval
map:
2: visitors_admin_approval
1: user_register
0: admin_only
anonymous: anonymous
destination:
plugin: config
config_name: user.settings

View file

@ -0,0 +1,44 @@
id: d7_user
label: Drupal 7 user accounts
migration_tags:
- Drupal 7
builder:
plugin: d7_user
source:
plugin: d7_user
process:
uid: uid
name: name
pass: pass
mail: mail
created: created
access: access
login: login
status: status
timezone: timezone
langcode: language
preferred_langcode: language
preferred_admin_langcode: language
init: init
roles:
plugin: migration
migration: d7_user_role
source: roles
user_picture:
-
plugin: default_value
source: picture
default_value: null
-
plugin: migration
migration: d7_file
destination:
plugin: entity:user
migration_dependencies:
required:
- d7_user_role
optional:
- d7_file
- user_picture_field_instance
- user_picture_entity_display
- user_picture_entity_form_display

View file

@ -0,0 +1,20 @@
id: d7_user_flood
migration_tags:
- Drupal 7
source:
plugin: variable
variables:
- user_failed_login_identifier_uid_only
- user_failed_login_ip_limit
- user_failed_login_ip_window
- user_failed_login_user_window
- user_failed_login_user_limit
process:
uid_only: user_failed_login_identifier_uid_only
ip_limit: user_failed_login_ip_limit
ip_window: user_failed_login_ip_window
user_limit: user_failed_login_user_limit
user_window: user_failed_login_user_window
destination:
plugin: config
config_name: user.flood

View file

@ -0,0 +1,39 @@
id: d7_user_mail
label: User mail configuration
migration_tags:
- Drupal 7
source:
plugin: variable
variables:
- user_mail_status_activated_subject
- user_mail_status_activated_body
- user_mail_password_reset_subject
- user_mail_password_reset_body
- user_mail_status_canceled_subject
- user_mail_status_canceled_body
- user_mail_register_admin_created_subject
- user_mail_register_admin_created_body
- user_mail_register_no_approval_required_subject
- user_mail_register_no_approval_required_body
- user_mail_register_pending_approval_subject
- user_mail_register_pending_approval_body
- user_mail_status_blocked_subject
- user_mail_status_blocked_body
process:
'status_activated/subject': user_mail_status_activated_subject
'status_activated/body': user_mail_status_activated_body
'password_reset/subject': user_mail_password_reset_subject
'password_reset/body': user_mail_password_reset_body
'cancel_confirm/subject': user_mail_status_canceled_subject
'cancel_confirm/body': user_mail_status_canceled_body
'register_admin_created/subject': user_mail_register_admin_created_subject
'register_admin_created/body': user_mail_register_admin_created_body
'register_no_approval_required/subject': user_mail_register_no_approval_required_subject
'register_no_approval_required/body': user_mail_register_no_approval_required_body
'register_pending_approval/subject': user_mail_register_pending_approval_subject
'register_pending_approval/body': user_mail_register_pending_approval_body
'status_blocked/subject': user_mail_status_blocked_subject
'status_blocked/body': user_mail_status_blocked_body
destination:
plugin: config
config_name: user.mail

View file

@ -0,0 +1,44 @@
id: d7_user_role
label: Drupal 7 user roles
migration_tags:
- Drupal 7
source:
plugin: d7_user_role
process:
id:
-
plugin: machine_name
source: name
-
plugin: dedupe_entity
entity_type: user_role
field: id
length: 32
-
plugin: user_update_8002
label: name
permissions:
-
plugin: static_map
source: permissions
bypass: true
map:
'use PHP for block visibility': 'use PHP for settings'
'administer site-wide contact form': 'administer contact forms'
'post comments without approval': 'skip comment approval'
'edit own blog entries' : 'edit own blog content'
'edit any blog entry' : 'edit any blog content'
'delete own blog entries' : 'delete own blog content'
'delete any blog entry' : 'delete any blog content'
'create forum topics' : 'create forum content'
'delete any forum topic' : 'delete any forum content'
'delete own forum topics' : 'delete own forum content'
'edit any forum topic' : 'edit any forum content'
'edit own forum topics' : 'edit own forum content'
- plugin: flatten
weight: weight
destination:
plugin: entity:user_role
migration_dependencies:
optional:
- d7_filter_format

View file

@ -0,0 +1,31 @@
id: user_picture_entity_display
label: User picture display configuration
migration_tags:
- Drupal 6
- Drupal 7
source:
plugin: user_picture_instance
constants:
entity_type: user
bundle: user
view_mode: default
name: user_picture
type: image
options:
label: hidden
settings:
image_style: ''
image_link: content
process:
entity_type: 'constants/entity_type'
bundle: 'constants/bundle'
view_mode: 'constants/view_mode'
field_name: 'constants/name'
type: 'constants/type'
options: 'constants/options'
'options/type': @type
destination:
plugin: component_entity_display
migration_dependencies:
required:
- user_picture_field_instance

View file

@ -0,0 +1,30 @@
id: user_picture_entity_form_display
label: User picture form display configuration
migration_tags:
- Drupal 6
- Drupal 7
source:
plugin: user_picture_instance
constants:
entity_type: user
bundle: user
form_mode: default
name: user_picture
type: image_image
options:
settings:
progress_indicator: throbber
preview_image_style: thumbnail
process:
entity_type: 'constants/entity_type'
bundle: 'constants/bundle'
field_name: 'constants/name'
form_mode: 'constants/form_mode'
type: 'constants/type'
options: 'constants/options'
'options/type': @type
destination:
plugin: component_entity_form_display
migration_dependencies:
required:
- user_picture_field_instance

View file

@ -0,0 +1,21 @@
id: user_picture_field
label: User picture field configuration
migration_tags:
- Drupal 6
- Drupal 7
source:
# We do an empty source and a proper destination to have an idmap for
# dependencies.
plugin: md_empty
constants:
entity_type: user
type: image
name: user_picture
cardinality: 1
process:
entity_type: 'constants/entity_type'
field_name: 'constants/name'
type: 'constants/type'
cardinality: 'constants/cardinality'
destination:
plugin: md_entity:field_storage_config

View file

@ -0,0 +1,31 @@
id: user_picture_field_instance
label: User picture field instance configuration
migration_tags:
- Drupal 6
- Drupal 7
source:
plugin: user_picture_instance
constants:
entity_type: user
bundle: user
name: user_picture
settings:
file_extensions: 'png gif jpg jpeg'
alt_field: false
title_field: false
min_resolution: ''
alt_field_required: false
title_field_required: false
process:
entity_type: 'constants/entity_type'
bundle: 'constants/bundle'
field_name: 'constants/name'
settings: 'constants/settings'
'settings/file_directory': file_directory
'settings/max_filesize': max_filesize
'settings/max_resolution': max_resolution
destination:
plugin: entity:field_config
migration_dependencies:
required:
- user_picture_field

View file

@ -0,0 +1,41 @@
id: user_profile_entity_display
label: User profile display configuration
migration_tags:
- Drupal 6
- Drupal 7
source:
plugin: profile_field
constants:
entity_type: user
bundle: user
view_mode: default
options:
label: hidden
settings: {}
process:
entity_type: 'constants/entity_type'
bundle: 'constants/bundle'
view_mode: 'constants/view_mode'
field_name: name
type:
plugin: static_map
source: type
map:
checkbox: list_default
date: datetime_default
list: text_default
selection: list_default
textfield: text_default
textarea: text_default
url: link_default
options: 'constants/options'
'options/type': @type
hidden:
plugin: static_map
source: visibility
default_value: false
map:
1: true # PROFILE_PRIVATE
4: true # PROFILE_HIDDEN
destination:
plugin: component_entity_display

View file

@ -0,0 +1,50 @@
id: user_profile_entity_form_display
label: User profile form display configuration
migration_tags:
- Drupal 6
- Drupal 7
source:
plugin: profile_field
constants:
empty: {}
entity_type: user
bundle: user
form_mode: default
process:
entity_type: 'constants/entity_type'
bundle: 'constants/bundle'
field_name: name
form_mode: 'constants/form_mode'
type:
plugin: static_map
source: type
map:
checkbox: boolean_checkbox
date: datetime_default
list: text_textfield
selection: options_select
textfield: text_textfield
textarea: text_textarea
url: link_default
options: 'constants/options'
'options/type': @type
'options/settings':
plugin: field_instance_widget_settings
source:
- @type
- 'constants/empty' # we don't have any settings.
'options/settings/display_label': # Single on/off checkboxes need to have display_label = true otherwise their label doesn't show.
plugin: static_map
default_value: false
source: type
map:
checkbox: true
hidden:
plugin: static_map
source: visibility
default_value: false
map:
1: true # PROFILE_PRIVATE
4: true # PROFILE_HIDDEN
destination:
plugin: component_entity_form_display

View file

@ -0,0 +1,35 @@
id: user_profile_field
label: User profile field configuration
migration_tags:
- Drupal 6
- Drupal 7
source:
plugin: profile_field
constants:
entity_type: user
process:
entity_type: 'constants/entity_type'
field_name: name
type:
plugin: static_map
source: type
map:
checkbox: boolean
date: datetime
list: text
selection: list_string
textfield: text
textarea: text_long
url: link
settings:
plugin: profile_field_settings
source: type
'settings/allowed_values': options
cardinality:
plugin: static_map
default_value: 1
source: type
map:
list: -1
destination:
plugin: md_entity:field_storage_config

View file

@ -0,0 +1,22 @@
id: user_profile_field_instance
label: User profile field instance configuration
migration_tags:
- Drupal 6
- Drupal 7
source:
plugin: profile_field
constants:
entity_type: user
bundle: user
process:
entity_type: 'constants/entity_type'
bundle: 'constants/bundle'
label: title
description: explanation
field_name: name
required: required
destination:
plugin: entity:field_config
migration_dependencies:
required:
- user_profile_field

View file

@ -7,7 +7,6 @@
namespace Drupal\user\Controller;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Datetime\DateFormatter;
@ -158,11 +157,12 @@ class UserController extends ControllerBase {
* @param \Drupal\user\UserInterface $user
* The user account.
*
* @return string
* The user account name.
* @return string|array
* The user account name as a render array or an empty string if $user is
* NULL.
*/
public function userTitle(UserInterface $user = NULL) {
return $user ? SafeMarkup::xssFilter($user->getUsername()) : '';
return $user ? ['#markup' => $user->getUsername(), '#allowed_tags' => Xss::getHtmlTagList()] : '';
}
/**

View file

@ -463,13 +463,14 @@ class User extends ContentEntityBase implements UserInterface {
$fields['name'] = BaseFieldDefinition::create('string')
->setLabel(t('Name'))
->setDescription(t('The name of this user.'))
->setDefaultValue('')
->setRequired(TRUE)
->setConstraints(array(
// No Length constraint here because the UserName constraint also covers
// that.
'UserName' => array(),
'UserNameUnique' => array(),
));
$fields['name']->getItemDefinition()->setClass('\Drupal\user\UserNameItem');
$fields['pass'] = BaseFieldDefinition::create('password')
->setLabel(t('Password'))

View file

@ -38,8 +38,9 @@ interface EntityOwnerInterface {
/**
* Returns the entity owner's user ID.
*
* @return int
* The owner user ID.
* @return int|null
* The owner user ID, or NULL in case the user ID field has not been set on
* the entity.
*/
public function getOwnerId();

View file

@ -7,7 +7,6 @@
namespace Drupal\user\Form;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
@ -94,7 +93,7 @@ class UserPermissionsForm extends FormBase {
$admin_roles = array();
foreach ($this->getRoles() as $role_name => $role) {
// Retrieve role names for columns.
$role_names[$role_name] = SafeMarkup::checkPlain($role->label());
$role_names[$role_name] = $role->label();
// Fetch permissions for the roles.
$role_permissions[$role_name] = $role->getPermissions();
$admin_roles[$role_name] = $role->isAdmin();

View file

@ -0,0 +1,94 @@
<?php
/**
* @file
* Contains \Drupal\user\MigratePassword.
*/
namespace Drupal\user;
use Drupal\Core\Password\PasswordInterface;
/**
* Replaces the original 'password' service in order to prefix the MD5 re-hashed
* passwords with the 'U' flag. The new salted hash is recreated on first login
* similarly to the D6->D7 upgrade path.
*/
class MigratePassword implements PasswordInterface {
/**
* The original password service.
*
* @var \Drupal\Core\Password\PasswordInterface
*/
protected $originalPassword;
/**
* Indicates if MD5 password prefixing is enabled.
*/
protected $enabled = FALSE;
/**
* Builds the replacement password service class.
*
* @param \Drupal\Core\Password\PasswordInterface $original_password
* The password object.
*/
public function __construct(PasswordInterface $original_password) {
$this->originalPassword = $original_password;
}
/**
* {@inheritdoc}
*/
public function check($password, $hash) {
return $this->originalPassword->check($password, $hash);
}
/**
* {@inheritdoc}
*/
public function needsRehash($hash) {
return $this->originalPassword->needsRehash($hash);
}
/**
* {@inheritdoc}
*/
public function hash($password) {
$hash = $this->originalPassword->hash($password);
// Allow prefixing only if the service was asked to prefix. Check also if
// the $password pattern is conforming to a MD5 result.
if ($this->enabled && preg_match('/^[0-9a-f]{32}$/', $password)) {
$hash = 'U' . $hash;
}
return $hash;
}
/**
* Enables the MD5 password prefixing.
*/
public function enableMd5Prefixing() {
$this->enabled = TRUE;
}
/**
* Disables the MD5 password prefixing.
*/
public function disableMd5Prefixing() {
$this->enabled = FALSE;
}
/**
* Implements the PhpassHashedPassword::getCountLog2() method.
*
* @todo: Revisit this whole alternate password service:
* https://www.drupal.org/node/2540594.
*/
public function getCountLog2($setting) {
return $this->originalPassword->getCountLog2($setting);
}
}

View file

@ -90,8 +90,13 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
public function build() {
$form = \Drupal::formBuilder()->getForm('Drupal\user\Form\UserLoginForm');
unset($form['name']['#attributes']['autofocus']);
// When unsetting field descriptions, also unset aria-describedby attributes
// to avoid introducing an accessibility bug.
// @todo Do this automatically in https://www.drupal.org/node/2547063.
unset($form['name']['#description']);
unset($form['name']['#attributes']['aria-describedby']);
unset($form['pass']['#description']);
unset($form['pass']['#attributes']['aria-describedby']);
$form['name']['#size'] = 15;
$form['pass']['#size'] = 15;
$form['#action'] = $this->url('<current>', [], ['query' => $this->getDestinationArray(), 'external' => FALSE]);

View file

@ -7,7 +7,7 @@
namespace Drupal\user\Plugin\Validation\Constraint;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidatorInterface;
use Symfony\Component\Validator\ExecutionContextInterface;
@ -29,6 +29,9 @@ class UserMailRequired extends Constraint implements ConstraintValidatorInterfac
/**
* Violation message. Use the same message as FormValidator.
*
* Note that the name argument is not sanitized so that translators only have
* one string to translate. The name is sanitized in self::validate().
*
* @var string
*/
public $message = '!name field is required.';
@ -70,7 +73,7 @@ class UserMailRequired extends Constraint implements ConstraintValidatorInterfac
$required = !(!$existing_value && \Drupal::currentUser()->hasPermission('administer users'));
if ($required && (!isset($items) || $items->isEmpty())) {
$this->context->addViolation($this->message, array('!name' => SafeMarkup::placeholder($account->getFieldDefinition('mail')->getLabel())));
$this->context->addViolation($this->message, ['!name' => Html::escape($account->getFieldDefinition('mail')->getLabel())]);
}
}

View file

@ -0,0 +1,42 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\builder\d6\ProfileValues.
*/
namespace Drupal\user\Plugin\migrate\builder\d6;
use Drupal\migrate\Entity\Migration;
use Drupal\migrate\Exception\RequirementsException;
use Drupal\migrate\Plugin\migrate\builder\BuilderBase;
/**
* @PluginID("d6_profile_values")
*/
class ProfileValues extends BuilderBase {
/**
* {@inheritdoc}
*/
public function buildMigrations(array $template) {
$migration = Migration::create($template);
// @TODO The source plugin should accept a database connection.
// @see https://www.drupal.org/node/2552791
$source_plugin = $this->getSourcePlugin('profile_field', $template['source']);
try {
$source_plugin->checkRequirements();
}
catch (RequirementsException $e) {
return [];
}
foreach ($source_plugin as $field) {
$migration->setProcessOfProperty($field->getSourceProperty('name'), $field->getSourceProperty('name'));
}
return [$migration];
}
}

View file

@ -0,0 +1,90 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\builder\d7\User.
*/
namespace Drupal\user\Plugin\migrate\builder\d7;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\Entity\Migration;
use Drupal\migrate\Exception\RequirementsException;
use Drupal\migrate\Plugin\migrate\builder\BuilderBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* @PluginID("d7_user")
*/
class User extends BuilderBase implements ContainerFactoryPluginInterface {
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Constructs a d7_user builder plugin instance.
*
* @param array $configuration
* The plugin configuration.
* @param string $plugin_id
* The plugin ID.
* @param mixed $plugin_definition
* The plugin definition.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->moduleHandler = $module_handler;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('module_handler')
);
}
/**
* {@inheritdoc}
*/
public function buildMigrations(array $template) {
$migration = Migration::create($template);
if ($this->moduleHandler->moduleExists('field')) {
$template['source']['entity_type'] = 'user';
$source_plugin = $this->getSourcePlugin('d7_field_instance', $template['source']);
foreach ($source_plugin as $field) {
$field_name = $field->getSourceProperty('field_name');
$migration->setProcessOfProperty($field_name, $field_name);
}
}
try {
$profile_fields = $this->getSourcePlugin('profile_field', $template['source']);
// Ensure that Profile is enabled in the source DB.
$profile_fields->checkRequirements();
foreach ($profile_fields as $field) {
$field_name = $field->getSourceProperty('name');
$migration->setProcessOfProperty($field_name, $field_name);
}
}
catch (RequirementsException $e) {
// Profile is not enabled in the source DB, so don't do anything.
}
return [$migration];
}
}

View file

@ -0,0 +1,101 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\destination\EntityUser.
*/
namespace Drupal\user\Plugin\migrate\destination;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Password\PasswordInterface;
use Drupal\migrate\Entity\MigrationInterface;
use Drupal\migrate\MigrateException;
use Drupal\user\MigratePassword;
use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* @MigrateDestination(
* id = "entity:user"
* )
*/
class EntityUser extends EntityContentBase {
/**
* The password service class.
*
* @var \Drupal\Core\Password\PasswordInterface
*/
protected $password;
/**
* Builds an user entity destination.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param MigrationInterface $migration
* The migration.
* @param EntityStorageInterface $storage
* The storage for this entity type.
* @param array $bundles
* The list of bundles this entity type has.
* @param \Drupal\migrate\Plugin\MigratePluginManager $plugin_manager
* The migrate plugin manager.
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager service.
* @param \Drupal\Core\Password\PasswordInterface $password
* The password service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, PasswordInterface $password) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager);
if (isset($configuration['md5_passwords'])) {
$this->password = $password;
}
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
$entity_type = static::getEntityTypeId($plugin_id);
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$migration,
$container->get('entity.manager')->getStorage($entity_type),
array_keys($container->get('entity.manager')->getBundleInfo($entity_type)),
$container->get('entity.manager'),
$container->get('password')
);
}
/**
* {@inheritdoc}
* @throws \Drupal\migrate\MigrateException
*/
public function import(Row $row, array $old_destination_id_values = array()) {
if ($this->password) {
if ($this->password instanceof MigratePassword) {
$this->password->enableMd5Prefixing();
}
else {
throw new MigrateException('Password service has been altered by another module, aborting.');
}
}
$ids = parent::import($row, $old_destination_id_values);
if ($this->password) {
$this->password->disableMd5Prefixing();
}
return $ids;
}
}

View file

@ -0,0 +1,95 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\destination\UserData.
*/
namespace Drupal\user\Plugin\migrate\destination;
use Drupal\migrate\Entity\MigrationInterface;
use Drupal\user\UserData as UserDataStorage;
use Drupal\migrate\Row;
use Drupal\migrate\Plugin\migrate\destination\DestinationBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
/**
* @MigrateDestination(
* id = "user_data"
* )
*/
class UserData extends DestinationBase implements ContainerFactoryPluginInterface {
/**
* @var \Drupal\user\UserData
*/
protected $userData;
/**
* Builds an user data entity destination.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\migrate\Entity\MigrationInterface $migration
* The migration.
* @param \Drupal\user\UserData $user_data
* The user data service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, UserDataStorage $user_data) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration);
$this->userData = $user_data;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$migration,
$container->get('user.data')
);
}
/**
* {@inheritdoc}
*/
public function import(Row $row, array $old_destination_id_values = array()) {
$uid = $row->getDestinationProperty('uid');
$module = $row->getDestinationProperty('module');
$key = $row->getDestinationProperty('key');
$this->userData->set($module, $uid, $key, $row->getDestinationProperty('settings'));
return [$uid, $module, $key];
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['uid']['type'] = 'integer';
$ids['module']['type'] = 'string';
$ids['key']['type'] = 'string';
return $ids;
}
/**
* {@inheritdoc}
*/
public function fields(MigrationInterface $migration = NULL) {
return [
'uid' => 'The user id.',
'module' => 'The module name responsible for the settings.',
'key' => 'The setting key to save under.',
'settings' => 'The settings to save.',
];
}
}

View file

@ -0,0 +1,51 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\process\ConvertTokens.
*/
namespace Drupal\user\Plugin\migrate\process;
use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/**
* Plugin to replace !tokens with [tokens].
*
* @MigrateProcessPlugin(
* id = "convert_tokens",
* handle_multiples = TRUE
* )
*/
class ConvertTokens extends ProcessPluginBase {
/**
* {@inheritdoc}
*
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
$tokens = array(
'!site' => '[site:name]',
'!username' => '[user:name]',
'!mailto' => '[user:mail]',
'!login_uri' => '[site:login-url]',
'!uri_brief' => '[site:url-brief]',
'!edit_uri' => '[user:edit-url]',
'!login_url' => '[user:one-time-login-url]',
'!uri' => '[site:url]',
'!date' => '[date:medium]',
'!password' => '',
);
if (is_string($value)) {
return str_replace(array_keys($tokens), $tokens, $value);
}
else {
throw new MigrateException('Value must be a string.');
}
}
}

View file

@ -0,0 +1,34 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\process\ProfileFieldSettings.
*/
namespace Drupal\user\Plugin\migrate\process;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/**
* @MigrateProcessPlugin(
* id = "profile_field_settings"
* )
*/
class ProfileFieldSettings extends ProcessPluginBase {
/**
* {@inheritdoc}
*/
public function transform($type, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
$settings = array();
switch ($type) {
case 'date':
$settings['datetime_type'] = 'date';
break;
}
return $settings;
}
}

View file

@ -0,0 +1,37 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\process\UserUpdate8002.
*/
namespace Drupal\user\Plugin\migrate\process;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/**
* Keep the predefined roles for rid 1 and 2.
*
* @MigrateProcessPlugin(
* id = "user_update_8002"
* )
*/
class UserUpdate8002 extends ProcessPluginBase {
/**
* {@inheritdoc}
*
* Keep the predefined roles for rid 1 and 2.
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
$rid = $row->getSourceProperty('rid');
$map = array(
1 => 'anonymous',
2 => 'authenticated',
);
return isset($map[$rid]) ? $map[$rid] : $value;
}
}

View file

@ -0,0 +1,85 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\process\d6\UserUpdate7002.
*/
namespace Drupal\user\Plugin\migrate\process\d6;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
use Drupal\Core\Config\Config;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Converts user time zones from time zone offsets to time zone names.
*
* @MigrateProcessPlugin(
* id = "user_update_7002"
* )
*/
class UserUpdate7002 extends ProcessPluginBase implements ContainerFactoryPluginInterface {
/**
* System timezones.
*
* @var array
*/
protected static $timezones;
/**
* Contains the system.theme configuration object.
*
* @var \Drupal\Core\Config\Config
*/
protected $dateConfig;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition, Config $date_config) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->dateConfig = $date_config;
if (!isset(static::$timezones)) {
static::$timezones = system_time_zones();
}
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('config.factory')->get('system.date')
);
}
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
$timezone = NULL;
if ($row->hasSourceProperty('timezone_name')) {
if (isset(static::$timezones[$row->getSourceProperty('timezone_name')])) {
$timezone = $row->getSourceProperty('timezone_name');
}
}
if (!$timezone && $row->hasSourceProperty('event_timezone')) {
if (isset(static::$timezones[$row->getSourceProperty('event_timezone')])) {
$timezone = $row->getSourceProperty('event_timezone');
}
}
if ($timezone === NULL) {
$timezone = $this->dateConfig->get('timezone.default');
}
return $timezone;
}
}

View file

@ -0,0 +1,113 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\source\ProfileField.
*/
namespace Drupal\user\Plugin\migrate\source;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
use Drupal\migrate\Row;
/**
* Profile field source from database.
*
* @MigrateSource(
* id = "profile_field",
* source_provider = "profile"
* )
*/
class ProfileField extends DrupalSqlBase {
/**
* The source table containing profile field info.
*
* @var string
*/
protected $fieldTable;
/**
* The source table containing the profile values.
*
* @var string
*/
protected $valueTable;
/**
* {@inheritdoc}
*/
public function query() {
if (empty($this->fieldTable) || empty($this->valueTable)) {
if ($this->getModuleSchemaVersion('system') >= 7000) {
$this->fieldTable = 'profile_field';
$this->valueTable = 'profile_value';
}
else {
$this->fieldTable = 'profile_fields';
$this->valueTable = 'profile_values';
}
}
return $this->select($this->fieldTable, 'pf')->fields('pf');
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
if ($row->getSourceProperty('type') == 'selection') {
// Get the current options.
$current_options = preg_split("/[\r\n]+/", $row->getSourceProperty('options'));
// Select the list values from the profile_values table to ensure we get
// them all since they can get out of sync with profile_fields.
$options = $this->select($this->valueTable, 'pv')
->distinct()
->fields('pv', ['value'])
->condition('fid', $row->getSourceProperty('fid'))
->execute()
->fetchCol();
$options = array_merge($current_options, $options);
// array_combine() takes care of any duplicates options.
$row->setSourceProperty('options', array_combine($options, $options));
}
if ($row->getSourceProperty('type') == 'checkbox') {
// D6 profile checkboxes values are always 0 or 1 (with no labels), so we
// need to create two label-less options that will get 0 and 1 for their
// keys.
$row->setSourceProperty('options', array(NULL, NULL));
}
return parent::prepareRow($row);
}
/**
* {@inheritdoc}
*/
public function fields() {
return array(
'fid' => $this->t('Primary Key: Unique profile field ID.'),
'title' => $this->t('Title of the field shown to the end user.'),
'name' => $this->t('Internal name of the field used in the form HTML and URLs.'),
'explanation' => $this->t('Explanation of the field to end users.'),
'category' => $this->t('Profile category that the field will be grouped under.'),
'page' => $this->t("Title of page used for browsing by the field's value"),
'type' => $this->t('Type of form field.'),
'weight' => $this->t('Weight of field in relation to other profile fields.'),
'required' => $this->t('Whether the user is required to enter a value. (0 = no, 1 = yes)'),
'register' => $this->t('Whether the field is visible in the user registration form. (1 = yes, 0 = no)'),
'visibility' => $this->t('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' => $this->t('Whether form auto-completion is enabled. (0 = disabled, 1 = enabled)'),
'options' => $this->t('List of options to be used in a list selection field.'),
);
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['fid']['type'] = 'integer';
return $ids;
}
}

View file

@ -0,0 +1,67 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\source\UserPictureInstance.
*/
namespace Drupal\user\Plugin\migrate\source;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
use Drupal\migrate\Plugin\migrate\source\DummyQueryTrait;
/**
* User picture field instance source.
*
* @todo Support default picture?
*
* @MigrateSource(
* id = "user_picture_instance"
* )
*/
class UserPictureInstance extends DrupalSqlBase {
use DummyQueryTrait;
/**
* {@inheritdoc}
*/
public function initializeIterator() {
return new \ArrayIterator(array(
array(
'id' => '',
'file_directory' => $this->variableGet('user_picture_path', 'pictures'),
'max_filesize' => $this->variableGet('user_picture_file_size', '30') . 'KB',
'max_resolution' => $this->variableGet('user_picture_dimensions', '85x85'),
)));
}
/**
* {@inheritdoc}
*/
public function count() {
// This source provides a single row, corresponding to a single picture
// field to be added to the user entity.
return 1;
}
/**
* {@inheritdoc}
*/
public function fields() {
return array(
'file_directory' => 'The directory to store images..',
'max_filesize' => 'The maximum allowed file size in KBs.',
'max_resolution' => "The maximum resolution.",
);
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['id']['type'] = 'string';
return $ids;
}
}

View file

@ -0,0 +1,99 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\source\d6\ProfileFieldValues.
*/
namespace Drupal\user\Plugin\migrate\source\d6;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
/**
* Drupal 6 profile fields values source.
*
* @MigrateSource(
* id = "d6_profile_field_values",
* source_provider = "profile"
* )
*/
class ProfileFieldValues extends DrupalSqlBase {
/**
* {@inheritdoc}
*/
public function query() {
$query = $this->select('profile_values', 'pv')
->distinct()
->fields('pv', array('fid', 'uid'));
return $query;
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
// Find profile values for this row.
$query = $this->select('profile_values', 'pv')
->fields('pv', array('fid', 'value'));
$query->leftJoin('profile_fields', 'pf', 'pf.fid=pv.fid');
$query->fields('pf', array('name', 'type'));
$query->condition('uid', $row->getSourceProperty('uid'));
$results = $query->execute();
foreach ($results as $profile_value) {
// Check special case for date. We need to unserialize.
if ($profile_value['type'] == 'date') {
$date = unserialize($profile_value['value']);
$date = date('Y-m-d', mktime(0, 0, 0, $date['month'], $date['day'], $date['year']));
$row->setSourceProperty($profile_value['name'], array('value' => $date));
}
elseif ($profile_value['type'] == 'list') {
// Explode by newline and comma.
$row->setSourceProperty($profile_value['name'], preg_split("/[\r\n,]+/", $profile_value['value']));
}
else {
$row->setSourceProperty($profile_value['name'], array($profile_value['value']));
}
}
return parent::prepareRow($row);
}
/**
* {@inheritdoc}
*/
public function fields() {
$fields = array(
'fid' => $this->t('Unique profile field ID.'),
'uid' => $this->t('The user Id.'),
'value' => $this->t('The value for this field.'),
);
$query = $this->select('profile_values', 'pv')
->fields('pv', array('fid', 'value'));
$query->leftJoin('profile_fields', 'pf', 'pf.fid=pv.fid');
$query->fields('pf', array('name', 'title'));
$results = $query->execute();
foreach ($results as $profile) {
$fields[$profile['name']] = $this->t($profile['title']);
}
return $fields;
}
/**
* {@inheritdoc}
*/
public function getIds() {
return array(
'uid' => array(
'type' => 'integer',
'alias' => 'pv',
),
);
}
}

View file

@ -0,0 +1,92 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\source\d6\Role.
*/
namespace Drupal\user\Plugin\migrate\source\d6;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
/**
* Drupal 6 role source from database.
*
* @MigrateSource(
* id = "d6_user_role"
* )
*/
class Role extends DrupalSqlBase {
/**
* List of filter IDs per role IDs.
*
* @var array
*/
protected $filterPermissions = array();
/**
* {@inheritdoc}
*/
public function query() {
$query = $this->select('role', 'r')
->fields('r', array('rid', 'name'))
->orderBy('rid');
return $query;
}
/**
* {@inheritdoc}
*/
public function fields() {
return array(
'rid' => $this->t('Role ID.'),
'name' => $this->t('The name of the user role.'),
);
}
/**
* {@inheritdoc}
*/
protected function initializeIterator() {
$filter_roles = $this->select('filter_formats', 'f')
->fields('f', array('format', 'roles'))
->execute()
->fetchAllKeyed();
foreach ($filter_roles as $format => $roles) {
// Drupal 6 code: $roles = ','. implode(',', $roles) .',';
// Remove the beginning and ending comma.
foreach (explode(',', trim($roles, ',')) as $rid) {
$this->filterPermissions[$rid][] = $format;
}
}
return parent::initializeIterator();
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
$rid = $row->getSourceProperty('rid');
$permissions = $this->select('permission', 'p')
->fields('p', array('perm'))
->condition('rid', $rid)
->execute()
->fetchField();
$row->setSourceProperty('permissions', explode(', ', $permissions));
if (isset($this->filterPermissions[$rid])) {
$row->setSourceProperty("filter_permissions:$rid", $this->filterPermissions[$rid]);
}
return parent::prepareRow($row);
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['rid']['type'] = 'integer';
return $ids;
}
}

View file

@ -0,0 +1,136 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\source\d6\User.
*/
namespace Drupal\user\Plugin\migrate\source\d6;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
/**
* Drupal 6 user source from database.
*
* @MigrateSource(
* id = "d6_user"
* )
*/
class User extends DrupalSqlBase {
/**
* {@inheritdoc}
*/
public function query() {
return $this->select('users', 'u')
->fields('u', array_keys($this->baseFields()))
->condition('uid', 1, '>');
}
/**
* {@inheritdoc}
*/
public function fields() {
$fields = $this->baseFields();
// Add roles field.
$fields['roles'] = $this->t('Roles');
// Profile fields.
if ($this->moduleExists('profile')) {
$fields += $this->select('profile_fields', 'pf')
->fields('pf', array('name', 'title'))
->execute()
->fetchAllKeyed();
}
return $fields;
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
// User roles.
$roles = $this->select('users_roles', 'ur')
->fields('ur', array('rid'))
->condition('ur.uid', $row->getSourceProperty('uid'))
->execute()
->fetchCol();
$row->setSourceProperty('roles', $roles);
// We are adding here the Event contributed module column.
// @see https://api.drupal.org/api/drupal/modules%21user%21user.install/function/user_update_7002/7
if ($row->hasSourceProperty('timezone_id') && $row->getSourceProperty('timezone_id')) {
if ($this->getDatabase()->schema()->tableExists('event_timezones')) {
$event_timezone = $this->select('event_timezones', 'e')
->fields('e', array('name'))
->condition('e.timezone', $row->getSourceProperty('timezone_id'))
->execute()
->fetchField();
if ($event_timezone) {
$row->setSourceProperty('event_timezone', $event_timezone);
}
}
}
// Unserialize Data.
$row->setSourceProperty('data', unserialize($row->getSourceProperty('data')));
return parent::prepareRow($row);
}
/**
* {@inheritdoc}
*/
public function getIds() {
return array(
'uid' => array(
'type' => 'integer',
'alias' => 'u',
),
);
}
/**
* Returns the user base fields to be migrated.
*
* @return array
* Associative array having field name as key and description as value.
*/
protected function baseFields() {
$fields = array(
'uid' => $this->t('User ID'),
'name' => $this->t('Username'),
'pass' => $this->t('Password'),
'mail' => $this->t('Email address'),
'signature' => $this->t('Signature'),
'signature_format' => $this->t('Signature format'),
'created' => $this->t('Registered timestamp'),
'access' => $this->t('Last access timestamp'),
'login' => $this->t('Last login timestamp'),
'status' => $this->t('Status'),
'timezone' => $this->t('Timezone'),
'language' => $this->t('Language'),
'picture' => $this->t('Picture'),
'init' => $this->t('Init'),
'data' => $this->t('User data'),
);
// Possible field added by Date contributed module.
// @see https://api.drupal.org/api/drupal/modules%21user%21user.install/function/user_update_7002/7
if ($this->getDatabase()->schema()->fieldExists('users', 'timezone_name')) {
$fields['timezone_name'] = $this->t('Timezone (Date)');
}
// Possible field added by Event contributed module.
// @see https://api.drupal.org/api/drupal/modules%21user%21user.install/function/user_update_7002/7
if ($this->getDatabase()->schema()->fieldExists('users', 'timezone_id')) {
$fields['timezone_id'] = $this->t('Timezone (Event)');
}
return $fields;
}
}

View file

@ -0,0 +1,52 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\source\d6\UserPicture.
*/
namespace Drupal\user\Plugin\migrate\source\d6;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
/**
* Drupal 6 user picture source from database.
*
* @todo Support default picture?
*
* @MigrateSource(
* id = "d6_user_picture"
* )
*/
class UserPicture extends DrupalSqlBase {
/**
* {@inheritdoc}
*/
public function query() {
$query = $this->select('users', 'u')
->condition('picture', '', '<>')
->fields('u', array('uid', 'access', 'picture'))
->orderBy('access');
return $query;
}
/**
* {@inheritdoc}
*/
public function fields() {
return array(
'uid' => 'Primary Key: Unique user ID.',
'access' => 'Timestamp for previous time user accessed the site.',
'picture' => "Path to the user's uploaded picture.",
);
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['uid']['type'] = 'integer';
return $ids;
}
}

View file

@ -0,0 +1,83 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\source\d6\UserPictureFile.
*/
namespace Drupal\user\Plugin\migrate\source\d6;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
use Drupal\migrate\Row;
/**
* Drupal 6 user picture source from database.
*
* @MigrateSource(
* id = "d6_user_picture_file"
* )
*/
class UserPictureFile extends DrupalSqlBase {
/**
* The file directory path.
*
* @var string
*/
protected $filePath;
/**
* The temporary file path.
*
* @var string
*/
protected $tempFilePath;
/**
* {@inheritdoc}
*/
public function query() {
$query = $this->select('users', 'u')
->condition('picture', '', '<>')
->fields('u', array('uid', 'picture'));
return $query;
}
/**
* {@inheritdoc}
*/
public function initializeIterator() {
$site_path = isset($this->configuration['site_path']) ? $this->configuration['site_path'] : 'sites/default';
$this->filePath = $this->variableGet('file_directory_path', $site_path . '/files') . '/';
$this->tempFilePath = $this->variableGet('file_directory_temp', '/tmp') . '/';
return parent::initializeIterator();
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
$row->setSourceProperty('filename', basename($row->getSourceProperty('picture')));
$row->setSourceProperty('file_directory_path', $this->filePath);
$row->setSourceProperty('temp_directory_path', $this->tempFilePath);
return parent::prepareRow($row);
}
/**
* {@inheritdoc}
*/
public function fields() {
return array(
'picture' => "Path to the user's uploaded picture.",
'filename' => 'The picture filename.',
);
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['uid']['type'] = 'integer';
return $ids;
}
}

View file

@ -0,0 +1,62 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\source\d7\Role.
*/
namespace Drupal\user\Plugin\migrate\source\d7;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
/**
* Drupal 7 role source from database.
*
* @MigrateSource(
* id = "d7_user_role"
* )
*/
class Role extends DrupalSqlBase {
/**
* {@inheritdoc}
*/
public function query() {
return $this->select('role', 'r')->fields('r');
}
/**
* {@inheritdoc}
*/
public function fields() {
return array(
'rid' => $this->t('Role ID.'),
'name' => $this->t('The name of the user role.'),
'weight' => $this->t('The weight of the role.'),
);
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
$permissions = $this->select('role_permission', 'rp')
->fields('rp', ['permission'])
->condition('rid', $row->getSourceProperty('rid'))
->execute()
->fetchCol();
$row->setSourceProperty('permissions', $permissions);
return parent::prepareRow($row);
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['rid']['type'] = 'integer';
return $ids;
}
}

View file

@ -0,0 +1,124 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\migrate\source\d7\User.
*/
namespace Drupal\user\Plugin\migrate\source\d7;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
/**
* Drupal 7 user source from database.
*
* @MigrateSource(
* id = "d7_user"
* )
*/
class User extends FieldableEntity {
/**
* {@inheritdoc}
*/
public function query() {
return $this->select('users', 'u')
->fields('u')
->condition('uid', 1, '>');
}
/**
* {@inheritdoc}
*/
public function fields() {
$fields = array(
'uid' => $this->t('User ID'),
'name' => $this->t('Username'),
'pass' => $this->t('Password'),
'mail' => $this->t('Email address'),
'signature' => $this->t('Signature'),
'signature_format' => $this->t('Signature format'),
'created' => $this->t('Registered timestamp'),
'access' => $this->t('Last access timestamp'),
'login' => $this->t('Last login timestamp'),
'status' => $this->t('Status'),
'timezone' => $this->t('Timezone'),
'language' => $this->t('Language'),
'picture' => $this->t('Picture'),
'init' => $this->t('Init'),
'data' => $this->t('User data'),
'roles' => $this->t('Roles'),
);
// Profile fields.
if ($this->moduleExists('profile')) {
$fields += $this->select('profile_fields', 'pf')
->fields('pf', array('name', 'title'))
->execute()
->fetchAllKeyed();
}
return $fields;
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
$roles = $this->select('users_roles', 'ur')
->fields('ur', ['rid'])
->condition('ur.uid', $row->getSourceProperty('uid'))
->execute()
->fetchCol();
$row->setSourceProperty('roles', $roles);
$row->setSourceProperty('data', unserialize($row->getSourceProperty('data')));
// Get Field API field values.
foreach (array_keys($this->getFields('user')) as $field) {
$row->setSourceProperty($field, $this->getFieldValues('user', $field, $row->getSourceProperty('uid')));
}
// Get profile field values. This code is lifted directly from the D6
// ProfileFieldValues plugin.
if ($this->getDatabase()->schema()->tableExists('profile_value')) {
$query = $this->select('profile_value', 'pv')
->fields('pv', array('fid', 'value'));
$query->leftJoin('profile_field', 'pf', 'pf.fid=pv.fid');
$query->fields('pf', array('name', 'type'));
$query->condition('uid', $row->getSourceProperty('uid'));
$results = $query->execute();
foreach ($results as $profile_value) {
if ($profile_value['type'] == 'date') {
$date = unserialize($profile_value['value']);
$date = date('Y-m-d', mktime(0, 0, 0, $date['month'], $date['day'], $date['year']));
$row->setSourceProperty($profile_value['name'], array('value' => $date));
}
elseif ($profile_value['type'] == 'list') {
// Explode by newline and comma.
$row->setSourceProperty($profile_value['name'], preg_split("/[\r\n,]+/", $profile_value['value']));
}
else {
$row->setSourceProperty($profile_value['name'], array($profile_value['value']));
}
}
}
return parent::prepareRow($row);
}
/**
* {@inheritdoc}
*/
public function getIds() {
return array(
'uid' => array(
'type' => 'integer',
'alias' => 'u',
),
);
}
}

View file

@ -7,7 +7,6 @@
namespace Drupal\user\Plugin\views\access;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
@ -121,7 +120,7 @@ class Permission extends AccessPluginBase implements CacheablePluginInterface {
foreach ($permissions as $perm => $perm_item) {
$provider = $perm_item['provider'];
$display_name = $this->moduleHandler->getName($provider);
$perms[$display_name][$perm] = SafeMarkup::checkPlain(strip_tags($perm_item['title']));
$perms[$display_name][$perm] = strip_tags($perm_item['title']);
}
$form['perm'] = array(

View file

@ -7,7 +7,6 @@
namespace Drupal\user\Plugin\views\argument;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\views\Plugin\views\argument\ManyToOne;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -56,11 +55,11 @@ class RolesRid extends ManyToOne {
/**
* {@inheritdoc}
*/
public function title_query() {
public function titleQuery() {
$entities = $this->roleStorage->loadMultiple($this->value);
$titles = array();
foreach ($entities as $entity) {
$titles[] = SafeMarkup::checkPlain($entity->label());
$titles[] = $entity->label();
}
return $titles;
}

View file

@ -7,7 +7,6 @@
namespace Drupal\user\Plugin\views\argument;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\views\Plugin\views\argument\NumericArgument;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -61,7 +60,7 @@ class Uid extends NumericArgument {
*/
public function titleQuery() {
return array_map(function($account) {
return SafeMarkup::checkPlain($account->label());
return $account->label();
}, $this->storage->loadMultiple($this->value));
}

View file

@ -101,14 +101,14 @@ class Roles extends PrerenderList {
}
protected function documentSelfTokens(&$tokens) {
$tokens['[' . $this->options['id'] . '-role' . ']'] = $this->t('The name of the role.');
$tokens['[' . $this->options['id'] . '-rid' . ']'] = $this->t('The role machine-name of the role.');
$tokens['{{ ' . $this->options['id'] . '__role' . ' }}'] = $this->t('The name of the role.');
$tokens['{{ ' . $this->options['id'] . '__rid' . ' }}'] = $this->t('The role machine-name of the role.');
}
protected function addSelfTokens(&$tokens, $item) {
if (!empty($item['role'])) {
$tokens['[' . $this->options['id'] . '-role' . ']'] = $item['role'];
$tokens['[' . $this->options['id'] . '-rid' . ']'] = $item['rid'];
$tokens['{{ ' . $this->options['id'] . '__role' . ' }}'] = $item['role'];
$tokens['{{ ' . $this->options['id'] . '__rid' . ' }}'] = $item['rid'];
}
}

View file

@ -37,7 +37,7 @@ class RoleListBuilder extends DraggableListBuilder {
* {@inheritdoc}
*/
public function buildRow(EntityInterface $entity) {
$row['label'] = $this->getLabel($entity);
$row['label'] = $entity->label();
return $row + parent::buildRow($entity);
}

View file

@ -88,6 +88,7 @@ class UserRoleConditionTest extends KernelTestBase {
// Setup an anonymous user for our tests.
$this->anonymous = User::create(array(
'name' => '',
'uid' => 0,
));
$this->anonymous->save();

View file

@ -0,0 +1,47 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\MigrateUserPictureEntityDisplayTest.
*/
namespace Drupal\user\Tests\Migrate;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
/**
* User picture entity display.
*
* @group user
*/
class MigrateUserPictureEntityDisplayTest extends MigrateDrupal7TestBase {
/**
* Modules to enable.
*
* @var array
*/
static $modules = array('file', 'image');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('file');
$this->executeMigration('user_picture_field');
$this->executeMigration('user_picture_field_instance');
$this->executeMigration('user_picture_entity_display');
}
/**
* Tests the Drupal 7 user picture to Drupal 8 entity display migration.
*/
public function testUserPictureEntityDisplay() {
$component = entity_get_display('user', 'user', 'default')->getComponent('user_picture');
$this->assertIdentical('image', $component['type']);
$this->assertIdentical('', $component['settings']['image_style']);
$this->assertIdentical('content', $component['settings']['image_link']);
}
}

View file

@ -0,0 +1,41 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\MigrateUserPictureEntityFormDisplayTest.
*/
namespace Drupal\user\Tests\Migrate;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
/**
* Tests migration of the user_picture field's entity form display settings.
*
* @group user
*/
class MigrateUserPictureEntityFormDisplayTest extends MigrateDrupal7TestBase {
static $modules = array('image', 'file');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('user_picture_field');
$this->executeMigration('user_picture_field_instance');
$this->executeMigration('user_picture_entity_form_display');
}
/**
* Tests the field's entity form display settings.
*/
public function testEntityFormDisplaySettings() {
$component = entity_get_form_display('user', 'user', 'default')->getComponent('user_picture');
$this->assertIdentical('image_image', $component['type']);
$this->assertIdentical('throbber', $component['settings']['progress_indicator']);
$this->assertIdentical('thumbnail', $component['settings']['preview_image_style']);
}
}

View file

@ -0,0 +1,44 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\MigrateUserPictureFieldInstanceTest.
*/
namespace Drupal\user\Tests\Migrate;
use Drupal\Core\Field\FieldConfigInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
/**
* User picture field instance migration.
*
* @group user
*/
class MigrateUserPictureFieldInstanceTest extends MigrateDrupal7TestBase {
static $modules = array('image', 'file');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('user_picture_field');
$this->executeMigration('user_picture_field_instance');
}
/**
* Test the user picture field migration.
*/
public function testUserPictureField() {
/** @var \Drupal\field\FieldConfigInterface $field */
$field = FieldConfig::load('user.user.user_picture');
$this->assertTrue($field instanceof FieldConfigInterface);
$this->assertIdentical('user', $field->getTargetEntityTypeId());
$this->assertIdentical('user', $field->getTargetBundle());
$this->assertIdentical('user_picture', $field->getName());
}
}

View file

@ -0,0 +1,43 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\MigrateUserPictureFieldTest.
*/
namespace Drupal\user\Tests\Migrate;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\FieldStorageConfigInterface;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
/**
* User picture field migration.
*
* @group user
*/
class MigrateUserPictureFieldTest extends MigrateDrupal7TestBase {
static $modules = array('image', 'file');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('user_picture_field');
}
/**
* Test the user picture field migration.
*/
public function testUserPictureField() {
/** @var \Drupal\field\FieldStorageConfigInterface $field_storage */
$field_storage = FieldStorageConfig::load('user.user_picture');
$this->assertTrue($field_storage instanceof FieldStorageConfigInterface);
$this->assertIdentical('user.user_picture', $field_storage->id());
$this->assertIdentical('image', $field_storage->getType());
$this->assertIdentical('user', $field_storage->getTargetEntityTypeId());
}
}

View file

@ -0,0 +1,120 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\MigrateUserProfileEntityDisplayTest.
*/
namespace Drupal\user\Tests\Migrate;
use Drupal\Core\Database\Database;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* Tests the user profile entity display migration.
*
* @group migrate_drupal_6
*/
class MigrateUserProfileEntityDisplayTest extends MigrateDrupal6TestBase {
/**
* Modules to enable.
*
* @var array
*/
static $modules = array('link', 'options', 'datetime', 'text');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create some fields so the data gets stored.
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_color',
'type' => 'text',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_biography',
'type' => 'text_long',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_sell_address',
'type' => 'boolean',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_sold_to',
'type' => 'list_string',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_bands',
'type' => 'text',
'cardinality' => -1,
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_blog',
'type' => 'link',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_birthdate',
'type' => 'datetime',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_love_migrations',
'type' => 'boolean',
))->save();
$field_data = Database::getConnection('default', 'migrate')
->select('profile_fields', 'u')
->fields('u')
->execute()
->fetchAll();
foreach ($field_data as $field) {
entity_create('field_config', array(
'label' => $field->title,
'description' => '',
'field_name' => $field->name,
'entity_type' => 'user',
'bundle' => 'user',
'required' => 1,
))->save();
}
$this->executeMigration('user_profile_entity_display');
}
/**
* Tests migration of user profile fields.
*/
public function testUserProfileFields() {
$display = entity_get_display('user', 'user', 'default');
// Test a text field.
$component = $display->getComponent('profile_color');
$this->assertIdentical('text_default', $component['type']);
// Test a list field.
$component = $display->getComponent('profile_bands');
$this->assertIdentical('text_default', $component['type']);
// Test a date field.
$component = $display->getComponent('profile_birthdate');
$this->assertIdentical('datetime_default', $component['type']);
// Test PROFILE_PRIVATE field is hidden.
$this->assertNull($display->getComponent('profile_sell_address'));
// Test PROFILE_HIDDEN field is hidden.
$this->assertNull($display->getComponent('profile_sold_to'));
}
}

View file

@ -0,0 +1,120 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\MigrateUserProfileEntityFormDisplayTest.
*/
namespace Drupal\user\Tests\Migrate;
use Drupal\Core\Database\Database;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* Tests the user profile entity form display migration.
*
* @group migrate_drupal_6
*/
class MigrateUserProfileEntityFormDisplayTest extends MigrateDrupal6TestBase {
static $modules = array('link', 'options', 'datetime', 'text');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create some fields so the data gets stored.
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_color',
'type' => 'text',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_biography',
'type' => 'text_long',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_sell_address',
'type' => 'boolean',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_sold_to',
'type' => 'list_string',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_bands',
'type' => 'text',
'cardinality' => -1,
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_blog',
'type' => 'link',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_birthdate',
'type' => 'datetime',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_love_migrations',
'type' => 'boolean',
))->save();
$field_data = Database::getConnection('default', 'migrate')
->select('profile_fields', 'u')
->fields('u')
->execute()
->fetchAll();
foreach ($field_data as $field) {
entity_create('field_config', array(
'label' => $field->title,
'description' => '',
'field_name' => $field->name,
'entity_type' => 'user',
'bundle' => 'user',
'required' => 1,
))->save();
}
$this->executeMigration('user_profile_entity_form_display');
}
/**
* Tests migration of user profile fields.
*/
public function testUserProfileEntityFormDisplay() {
$display = entity_get_form_display('user', 'user', 'default');
// Test a text field.
$component = $display->getComponent('profile_color');
$this->assertIdentical('text_textfield', $component['type']);
// Test a list field.
$component = $display->getComponent('profile_bands');
$this->assertIdentical('text_textfield', $component['type']);
// Test a date field.
$component = $display->getComponent('profile_birthdate');
$this->assertIdentical('datetime_default', $component['type']);
// Test PROFILE_PRIVATE field is hidden.
$this->assertNull($display->getComponent('profile_sell_address'));
// Test PROFILE_HIDDEN field is hidden.
$this->assertNull($display->getComponent('profile_sold_to'));
// Test that a checkbox field has the proper display label setting.
$component = $display->getComponent('profile_love_migrations');
$this->assertIdentical('boolean_checkbox', $component['type']);
$this->assertIdentical(true, $component['settings']['display_label']);
}
}

View file

@ -0,0 +1,108 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\MigrateUserProfileFieldInstanceTest.
*/
namespace Drupal\user\Tests\Migrate;
use Drupal\field\Entity\FieldConfig;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* Tests the user profile field instance migration.
*
* @group migrate_drupal_6
*/
class MigrateUserProfileFieldInstanceTest extends MigrateDrupal6TestBase {
static $modules = array('field', 'link', 'options', 'datetime', 'text');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Add some id mappings for the dependant migrations.
$id_mappings = array(
'user_profile_field' => array(
array(array(1), array('user', 'profile_color')),
),
);
$this->prepareMigrations($id_mappings);
$this->createFields();
$this->executeMigration('user_profile_field_instance');
}
/**
* Tests migration of user profile fields.
*/
public function testUserProfileFields() {
// Migrated a text field.
$field = FieldConfig::load('user.user.profile_color');
$this->assertIdentical('Favorite color', $field->label());
$this->assertIdentical('List your favorite color', $field->getDescription());
// Migrated a textarea.
$field = FieldConfig::load('user.user.profile_biography');
$this->assertIdentical('Biography', $field->label());
$this->assertIdentical('Tell people a little bit about yourself', $field->getDescription());
// Migrated checkbox field.
$field = FieldConfig::load('user.user.profile_sell_address');
$this->assertIdentical('Sell your email address?', $field->label());
$this->assertIdentical("If you check this box, we'll sell your address to spammers to help line the pockets of our shareholders. Thanks!", $field->getDescription());
// Migrated selection field.
$field = FieldConfig::load('user.user.profile_sold_to');
$this->assertIdentical('Sales Category', $field->label());
$this->assertIdentical("Select the sales categories to which this user's address was sold.", $field->getDescription());
// Migrated list field.
$field = FieldConfig::load('user.user.profile_bands');
$this->assertIdentical('Favorite bands', $field->label());
$this->assertIdentical("Enter your favorite bands. When you've saved your profile, you'll be able to find other people with the same favorites.", $field->getDescription());
/*
// Migrated URL field.
$field = FieldConfig::load('user.user.profile_blog');
$this->assertIdentical('Your blog', $field->label());
$this->assertIdentical("Paste the full URL, $field->getDescription(), including http://, of your personal blog.");
*/
// Migrated date field.
$field = FieldConfig::load('user.user.profile_birthdate');
$this->assertIdentical('Birthdate', $field->label());
$this->assertIdentical("Enter your birth date and we'll send you a coupon.", $field->getDescription());
// Another migrated checkbox field, with a different source visibility setting.
$field = FieldConfig::load('user.user.profile_love_migrations');
$this->assertIdentical('I love migrations', $field->label());
$this->assertIdentical("If you check this box, you love migrations.", $field->getDescription());
}
/**
* Helper to create fields.
*/
protected function createFields() {
$fields = array(
'profile_color' => 'text',
'profile_biography' => 'text_long',
'profile_sell_address' => 'boolean',
'profile_sold_to' => 'list_string',
'profile_bands' => 'text',
'profile_blog' => 'link',
'profile_birthdate' => 'datetime',
'profile_love_migrations' => 'boolean',
);
foreach ($fields as $name => $type) {
entity_create('field_storage_config', array(
'field_name' => $name,
'entity_type' => 'user',
'type' => $type,
))->save();
}
}
}

View file

@ -0,0 +1,79 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\MigrateUserProfileFieldTest.
*/
namespace Drupal\user\Tests\Migrate;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* Tests the user profile field migration.
*
* @group migrate_drupal_6
*/
class MigrateUserProfileFieldTest extends MigrateDrupal6TestBase {
static $modules = array('link', 'options', 'datetime', 'text');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('user_profile_field');
}
/**
* Tests migration of user profile fields.
*/
public function testUserProfileFields() {
// Migrated a text field.
$field_storage = FieldStorageConfig::load('user.profile_color');
$this->assertIdentical('text', $field_storage->getType(), 'Field type is text.');
$this->assertIdentical(1, $field_storage->getCardinality(), 'Text field has correct cardinality');
// Migrated a textarea.
$field_storage = FieldStorageConfig::load('user.profile_biography');
$this->assertIdentical('text_long', $field_storage->getType(), 'Field type is text_long.');
// Migrated checkbox field.
$field_storage = FieldStorageConfig::load('user.profile_sell_address');
$this->assertIdentical('boolean', $field_storage->getType(), 'Field type is boolean.');
// Migrated selection field.
$field_storage = FieldStorageConfig::load('user.profile_sold_to');
$this->assertIdentical('list_string', $field_storage->getType(), 'Field type is list_string.');
$settings = $field_storage->getSettings();
$this->assertEqual($settings['allowed_values'], array(
'Pill spammers' => 'Pill spammers',
'Fitness spammers' => 'Fitness spammers',
'Back\slash' => 'Back\slash',
'Forward/slash' => 'Forward/slash',
'Dot.in.the.middle' => 'Dot.in.the.middle',
'Faithful servant' => 'Faithful servant',
'Anonymous donor' => 'Anonymous donor',
));
$this->assertIdentical('list_string', $field_storage->getType(), 'Field type is list_string.');
// Migrated list field.
$field_storage = FieldStorageConfig::load('user.profile_bands');
$this->assertIdentical('text', $field_storage->getType(), 'Field type is text.');
$this->assertIdentical(-1, $field_storage->getCardinality(), 'List field has correct cardinality');
/*
// Migrated URL field.
$field_storage = FieldStorageConfig::load('user.profile_blog');
$this->assertIdentical('link', $field_storage->getType(), 'Field type is link.');
*/
// Migrated date field.
$field_storage = FieldStorageConfig::load('user.profile_birthdate');
$this->assertIdentical('datetime', $field_storage->getType(), 'Field type is datetime.');
$this->assertIdentical('date', $field_storage->getSettings()['datetime_type']);
}
}

View file

@ -0,0 +1,66 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d6\MigrateUserConfigsTest.
*/
namespace Drupal\user\Tests\Migrate\d6;
use Drupal\config\Tests\SchemaCheckTestTrait;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* Upgrade variables to user.*.yml.
*
* @group migrate_drupal_6
*/
class MigrateUserConfigsTest extends MigrateDrupal6TestBase {
use SchemaCheckTestTrait;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d6_user_mail');
$this->executeMigration('d6_user_settings');
}
/**
* Tests migration of user variables to user.mail.yml.
*/
public function testUserMail() {
$config = $this->config('user.mail');
$this->assertIdentical('Account details for [user:name] at [site:name] (approved)', $config->get('status_activated.subject'));
$this->assertIdentical("[user:name],\n\nYour account at [site:name] has been activated.\n\nYou may now log in by clicking on this link or copying and pasting it in your browser:\n\n[user:one-time-login-url]\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to [user:edit-url] so you can change your password.\n\nOnce you have set your own password, you will be able to log in to [site:login-url] in the future using:\n\nusername: [user:name]\n", $config->get('status_activated.body'));
$this->assertIdentical('Replacement login information for [user:name] at [site:name]', $config->get('password_reset.subject'));
$this->assertIdentical("[user:name],\n\nA request to reset the password for your account has been made at [site:name].\n\nYou may now log in to [site:url-brief] by clicking on this link or copying and pasting it in your browser:\n\n[user:one-time-login-url]\n\nThis is a one-time login, so it can be used only once. It expires after one day and nothing will happen if it's not used.\n\nAfter logging in, you will be redirected to [user:edit-url] so you can change your password." , $config->get('password_reset.body'));
$this->assertIdentical('Account details for [user:name] at [site:name] (deleted)', $config->get('cancel_confirm.subject'));
$this->assertIdentical("[user:name],\n\nYour account on [site:name] has been deleted.", $config->get('cancel_confirm.body'));
$this->assertIdentical('An administrator created an account for you at [site:name]', $config->get('register_admin_created.subject'));
$this->assertIdentical("[user:name],\n\nA site administrator at [site:name] has created an account for you. You may now log in to [site:login-url] using the following username and password:\n\nusername: [user:name]\npassword: \n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n[user:one-time-login-url]\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to [user:edit-url] so you can change your password.\n\n\n-- [site:name] team", $config->get('register_admin_created.body'));
$this->assertIdentical('Account details for [user:name] at [site:name]', $config->get('register_no_approval_required.subject'));
$this->assertIdentical("[user:name],\n\nThank you for registering at [site:name]. You may now log in to [site:login-url] using the following username and password:\n\nusername: [user:name]\npassword: \n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n[user:one-time-login-url]\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to [user:edit-url] so you can change your password.\n\n\n-- [site:name] team", $config->get('register_no_approval_required.body'));
$this->assertIdentical('Account details for [user:name] at [site:name] (pending admin approval)', $config->get('register_pending_approval.subject'));
$this->assertIdentical("[user:name],\n\nThank you for registering at [site:name]. Your application for an account is currently pending approval. Once it has been approved, you will receive another email containing information about how to log in, set your password, and other details.\n\n\n-- [site:name] team", $config->get('register_pending_approval.body'));
$this->assertIdentical('Account details for [user:name] at [site:name] (blocked)', $config->get('status_blocked.subject'));
$this->assertIdentical("[user:name],\n\nYour account on [site:name] has been blocked.", $config->get('status_blocked.body'));
$this->assertConfigSchema(\Drupal::service('config.typed'), 'user.mail', $config->get());
}
/**
* Tests migration of user variables to user.settings.yml.
*/
public function testUserSettings() {
$config = $this->config('user.settings');
$this->assertIdentical(TRUE, $config->get('notify.status_blocked'));
$this->assertIdentical(FALSE, $config->get('notify.status_activated'));
$this->assertIdentical(FALSE, $config->get('verify_mail'));
$this->assertIdentical('admin_only', $config->get('register'));
$this->assertIdentical('Guest', $config->get('anonymous'));
}
}

View file

@ -0,0 +1,63 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d6\MigrateUserContactSettingsTest.
*/
namespace Drupal\user\Tests\Migrate\d6;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* Users contact settings migration.
*
* @group migrate_drupal_6
*/
class MigrateUserContactSettingsTest extends MigrateDrupal6TestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['contact'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installSchema('user', array('users_data'));
$id_mappings = array(
'd6_user' => array(
array(array(2), array(2)),
array(array(8), array(8)),
array(array(15), array(15)),
),
);
$this->prepareMigrations($id_mappings);
$this->executeMigration('d6_user_contact_settings');
}
/**
* Tests the Drupal6 user contact settings migration.
*/
public function testUserContactSettings() {
$user_data = \Drupal::service('user.data');
$module = $key = 'contact';
$uid = 2;
$setting = $user_data->get($module, $uid, $key);
$this->assertIdentical('1', $setting);
$uid = 8;
$setting = $user_data->get($module, $uid, $key);
$this->assertIdentical('0', $setting);
$uid = 15;
$setting = $user_data->get($module, $uid, $key);
$this->assertIdentical(NULL, $setting);
}
}

View file

@ -0,0 +1,67 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d6\MigrateUserPictureFileTest.
*/
namespace Drupal\user\Tests\Migrate\d6;
use Drupal\file\Entity\File;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* User pictures migration.
*
* @group migrate_drupal_6
*/
class MigrateUserPictureFileTest extends MigrateDrupal6TestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('file');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('file');
/** @var \Drupal\migrate\Entity\MigrationInterface $migration */
$migration = entity_load('migration', 'd6_user_picture_file');
$source = $migration->get('source');
$source['site_path'] = 'core/modules/simpletest';
$migration->set('source', $source);
$this->executeMigration($migration);
}
/**
* Tests the Drupal 6 user pictures to Drupal 8 migration.
*/
public function testUserPictures() {
$file_ids = array();
foreach (entity_load('migration', 'd6_user_picture_file')->getIdMap() as $destination_ids) {
$file_ids[] = reset($destination_ids);
}
$files = File::loadMultiple($file_ids);
/** @var \Drupal\file\FileInterface $file */
$file = array_shift($files);
$this->assertIdentical('image-test.jpg', $file->getFilename());
$this->assertIdentical('public://image-test.jpg', $file->getFileUri());
$this->assertIdentical('2', $file->getOwnerId());
$this->assertIdentical('1901', $file->getSize());
$this->assertIdentical('image/jpeg', $file->getMimeType());
$file = array_shift($files);
$this->assertIdentical('image-test.png', $file->getFilename());
$this->assertIdentical('public://image-test.png', $file->getFileUri());
$this->assertIdentical('8', $file->getOwnerId());
$this->assertFalse($files);
}
}

View file

@ -0,0 +1,165 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d6\MigrateUserProfileValuesTest.
*/
namespace Drupal\user\Tests\Migrate\d6;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
use Drupal\Core\Database\Database;
use Drupal\user\Entity\User;
/**
* User profile values migration.
*
* @group migrate_drupal_6
*/
class MigrateUserProfileValuesTest extends MigrateDrupal6TestBase {
/**
* The modules to be enabled during the test.
*
* @var array
*/
static $modules = array(
'link',
'options',
'datetime',
'text',
'file',
'image',
);
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create some fields so the data gets stored.
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_color',
'type' => 'text',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_biography',
'type' => 'text_long',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_sell_address',
'type' => 'boolean',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_sold_to',
'type' => 'list_string',
'settings' => array(
'allowed_values' => array(
'Pill spammers' => 'Pill spammers',
'Fitness spammers' => 'Fitness spammers',
)
)
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_bands',
'type' => 'text',
'cardinality' => -1,
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_blog',
'type' => 'link',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_birthdate',
'type' => 'datetime',
))->save();
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'profile_love_migrations',
'type' => 'boolean',
))->save();
// Add some id mappings for the dependant migrations.
$id_mappings = array(
'user_profile_field_instance' => array(
array(array(1), array('user', 'user', 'fieldname')),
),
'user_profile_entity_display' => array(
array(array(1), array('user', 'user', 'default', 'fieldname')),
),
'user_profile_entity_form_display' => array(
array(array(1), array('user', 'user', 'default', 'fieldname')),
),
'd6_user' => array(
array(array(2), array(2)),
array(array(8), array(8)),
array(array(15), array(15)),
),
);
$this->prepareMigrations($id_mappings);
$field_data = Database::getConnection('default', 'migrate')
->select('profile_fields', 'u')
->fields('u')
->execute()
->fetchAll();
// Create the field instances.
foreach ($field_data as $field) {
entity_create('field_config', array(
'label' => $field->title,
'description' => '',
'field_name' => $field->name,
'entity_type' => 'user',
'bundle' => 'user',
'required' => 0,
))->save();
}
// Create our users for the node authors.
$query = Database::getConnection('default', 'migrate')->query('SELECT * FROM {users} WHERE uid NOT IN (0, 1)');
while(($row = $query->fetchAssoc()) !== FALSE) {
$user = entity_create('user', $row);
$user->enforceIsNew();
$user->save();
}
$this->executeMigration('d6_profile_values');
}
/**
* Tests Drupal 6 profile values to Drupal 8 migration.
*/
public function testUserProfileValues() {
$user = User::load(2);
$this->assertFalse(is_null($user));
$this->assertIdentical('red', $user->profile_color->value);
$expected = <<<EOT
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam nulla sapien, congue nec risus ut, adipiscing aliquet felis. Maecenas quis justo vel nulla varius euismod. Quisque metus metus, cursus sit amet sem non, bibendum vehicula elit. Cras dui nisl, eleifend at iaculis vitae, lacinia ut felis. Nullam aliquam ligula volutpat nulla consectetur accumsan. Maecenas tincidunt molestie diam, a accumsan enim fringilla sit amet. Morbi a tincidunt tellus. Donec imperdiet scelerisque porta. Sed quis sem bibendum eros congue sodales. Vivamus vel fermentum est, at rutrum orci. Nunc consectetur purus ut dolor pulvinar, ut volutpat felis congue. Cras tincidunt odio sed neque sollicitudin, vehicula tempor metus scelerisque.
EOT;
$this->assertIdentical($expected, $user->profile_biography->value);
$this->assertIdentical('1', $user->profile_sell_address->value);
$this->assertIdentical('Back\slash', $user->profile_sold_to->value);
$this->assertIdentical('AC/DC', $user->profile_bands[0]->value);
$this->assertIdentical('Eagles', $user->profile_bands[1]->value);
$this->assertIdentical('Elton John', $user->profile_bands[2]->value);
$this->assertIdentical('Lemonheads', $user->profile_bands[3]->value);
$this->assertIdentical('Rolling Stones', $user->profile_bands[4]->value);
$this->assertIdentical('Queen', $user->profile_bands[5]->value);
$this->assertIdentical('The White Stripes', $user->profile_bands[6]->value);
$this->assertIdentical('1974-06-02', $user->profile_birthdate->value);
$user = User::load(8);
$this->assertIdentical('Forward/slash', $user->profile_sold_to->value);
$user = User::load(15);
$this->assertIdentical('Dot.in.the.middle', $user->profile_sold_to->value);
}
}

View file

@ -0,0 +1,91 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d6\MigrateUserRoleTest.
*/
namespace Drupal\user\Tests\Migrate\d6;
use Drupal\user\Entity\Role;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* Upgrade user roles to user.role.*.yml.
*
* @group migrate_drupal_6
*/
class MigrateUserRoleTest extends MigrateDrupal6TestBase {
/**
* The modules to be enabled during the test.
*
* @var array
*/
static $modules = array('filter', 'node');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// We need some sample data so we can use the Migration process plugin.
$id_mappings = array(
'd6_filter_format' => array(
array(array(1), array('filtered_html')),
array(array(2), array('full_html'))
),
);
$this->prepareMigrations($id_mappings);
$this->executeMigration('d6_user_role');
}
/**
* Tests user role migration.
*/
public function testUserRole() {
/** @var \Drupal\migrate\entity\Migration $migration */
$migration = entity_load('migration', 'd6_user_role');
$rid = 'anonymous';
$anonymous = Role::load($rid);
$this->assertIdentical($rid, $anonymous->id());
$this->assertIdentical(array('migrate test anonymous permission', 'use text format filtered_html'), $anonymous->getPermissions());
$this->assertIdentical(array($rid), $migration->getIdMap()->lookupDestinationId(array(1)));
$rid = 'authenticated';
$authenticated = Role::load($rid);
$this->assertIdentical($rid, $authenticated->id());
$this->assertIdentical(array('migrate test authenticated permission', 'use text format filtered_html'), $authenticated->getPermissions());
$this->assertIdentical(array($rid), $migration->getIdMap()->lookupDestinationId(array(2)));
$rid = 'migrate_test_role_1';
$migrate_test_role_1 = Role::load($rid);
$this->assertIdentical($rid, $migrate_test_role_1->id());
$this->assertIdentical(array(0 => 'migrate test role 1 test permission', 'use text format full_html'), $migrate_test_role_1->getPermissions());
$this->assertIdentical(array($rid), $migration->getIdMap()->lookupDestinationId(array(3)));
$rid = 'migrate_test_role_2';
$migrate_test_role_2 = Role::load($rid);
$this->assertIdentical(array(
'migrate test role 2 test permission',
'use PHP for settings',
'administer contact forms',
'skip comment approval',
'edit own blog content',
'edit any blog content',
'delete own blog content',
'delete any blog content',
'create forum content',
'delete any forum content',
'delete own forum content',
'edit any forum content',
'edit own forum content',
'administer nodes',
'access content overview',
), $migrate_test_role_2->getPermissions());
$this->assertIdentical($rid, $migrate_test_role_2->id());
$this->assertIdentical(array($rid), $migration->getIdMap()->lookupDestinationId(array(4)));
$rid = 'migrate_test_role_3_that_is_long';
$migrate_test_role_3 = Role::load($rid);
$this->assertIdentical($rid, $migrate_test_role_3->id());
$this->assertIdentical(array($rid), $migration->getIdMap()->lookupDestinationId(array(5)));
}
}

View file

@ -0,0 +1,172 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d6\MigrateUserTest.
*/
namespace Drupal\user\Tests\Migrate\d6;
use Drupal\user\Entity\User;
use Drupal\file\Entity\File;
use Drupal\Core\Database\Database;
use Drupal\user\RoleInterface;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* Users migration.
*
* @group migrate_drupal_6
*/
class MigrateUserTest extends MigrateDrupal6TestBase {
/**
* The modules to be enabled during the test.
*
* @var array
*/
static $modules = array(
'link',
'options',
'datetime',
'text',
'file',
'image',
);
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('file');
$this->installSchema('file', ['file_usage']);
// Create the user profile field and instance.
entity_create('field_storage_config', array(
'entity_type' => 'user',
'field_name' => 'user_picture',
'type' => 'image',
'translatable' => '0',
))->save();
entity_create('field_config', array(
'label' => 'User Picture',
'description' => '',
'field_name' => 'user_picture',
'entity_type' => 'user',
'bundle' => 'user',
'required' => 0,
))->save();
$file = entity_create('file', array(
'fid' => 2,
'uid' => 2,
'filename' => 'image-test.jpg',
'uri' => "public://image-test.jpg",
'filemime' => 'image/jpeg',
'created' => 1,
'changed' => 1,
'status' => FILE_STATUS_PERMANENT,
));
$file->enforceIsNew();
file_put_contents($file->getFileUri(), file_get_contents('core/modules/simpletest/files/image-1.png'));
$file->save();
$file = entity_create('file', array(
'fid' => 8,
'uid' => 8,
'filename' => 'image-test.png',
'uri' => "public://image-test.png",
'filemime' => 'image/png',
'created' => 1,
'changed' => 1,
'status' => FILE_STATUS_PERMANENT,
));
$file->enforceIsNew();
file_put_contents($file->getFileUri(), file_get_contents('core/modules/simpletest/files/image-2.jpg'));
$file->save();
$id_mappings = array(
'd6_user_role' => array(
array(array(1), array('anonymous user')),
array(array(2), array('authenticated user')),
array(array(3), array('migrate test role 1')),
array(array(4), array('migrate test role 2')),
array(array(5), array('migrate test role 3')),
),
'user_picture_entity_display' => array(
array(array(1), array('user', 'user', 'default', 'user_picture')),
),
'user_picture_entity_form_display' => array(
array(array(1), array('user', 'user', 'default', 'user_picture')),
),
'd6_user_picture_file' => array(
array(array(2), array(2)),
array(array(8), array(8)),
),
);
$this->prepareMigrations($id_mappings);
$this->executeMigration('d6_user');
}
/**
* Tests the Drupal6 user to Drupal 8 migration.
*/
public function testUser() {
$users = Database::getConnection('default', 'migrate')
->select('users', 'u')
->fields('u')
->execute()
->fetchAll();
foreach ($users as $source) {
// Get roles directly from the source.
$rids = Database::getConnection('default', 'migrate')
->select('users_roles', 'ur')
->fields('ur', array('rid'))
->condition('ur.uid', $source->uid)
->execute()
->fetchCol();
$roles = array(RoleInterface::AUTHENTICATED_ID);
$migration_role = entity_load('migration', 'd6_user_role');
foreach ($rids as $rid) {
$role = $migration_role->getIdMap()->lookupDestinationId(array($rid));
$roles[] = reset($role);
}
/** @var \Drupal\user\UserInterface $user */
$user = User::load($source->uid);
$this->assertIdentical($source->uid, $user->id());
$this->assertIdentical($source->name, $user->label());
$this->assertIdentical($source->mail, $user->getEmail());
$this->assertIdentical($source->created, $user->getCreatedTime());
$this->assertIdentical($source->access, $user->getLastAccessedTime());
$this->assertIdentical($source->login, $user->getLastLoginTime());
$is_blocked = $source->status == 0;
$this->assertIdentical($is_blocked, $user->isBlocked());
// $user->getPreferredLangcode() might fallback to default language if the
// user preferred language is not configured on the site. We just want to
// test if the value was imported correctly.
$this->assertIdentical($source->language, $user->preferred_langcode->value);
$expected_timezone_name = $source->timezone_name ?: $this->config('system.date')->get('timezone.default');
$this->assertIdentical($expected_timezone_name, $user->getTimeZone());
$this->assertIdentical($source->init, $user->getInitialEmail());
$this->assertIdentical($roles, $user->getRoles());
// We have one empty picture in the data so don't try load that.
if (!empty($source->picture)) {
// Test the user picture.
$file = File::load($user->user_picture->target_id);
$this->assertIdentical(basename($source->picture), $file->getFilename());
}
// Use the API to check if the password has been salted and re-hashed to
// conform the Drupal >= 7.
$this->assertTrue(\Drupal::service('password')->check($source->pass_plain, $user->getPassword()));
}
}
}

View file

@ -0,0 +1,36 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d6\ProfileValuesBuilderTest.
*/
namespace Drupal\user\Tests\Migrate\d6;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* @group user
*/
class ProfileValuesBuilderTest extends MigrateDrupal6TestBase {
public static $modules = ['migrate', 'migrate_drupal', 'user'];
/**
* Tests that profile fields are merged into the d6_profile_values migration's
* process pipeline by the d6_profile_values builder.
*/
public function testBuilder() {
$template = \Drupal::service('migrate.template_storage')
->getTemplateByName('d6_profile_values');
/** @var \Drupal\migrate\Entity\MigrationInterface[] $migrations */
$migrations = \Drupal::service('plugin.manager.migrate.builder')
->createInstance('d6_profile_values')
->buildMigrations($template);
$this->assertIdentical('d6_profile_values', $migrations[0]->id());
$process = $migrations[0]->getProcess();
$this->assertIdentical('profile_color', $process['profile_color'][0]['source']);
}
}

View file

@ -0,0 +1,49 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d7\MigrateUserFloodTest.
*/
namespace Drupal\user\Tests\Migrate\d7;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
/**
* Migrates user flood control configuration.
*
* @group user
*/
class MigrateUserFloodTest extends MigrateDrupal7TestBase {
/**
* The modules to be enabled during the test.
*
* @var array
*/
static $modules = array('system');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(['user']);
$this->executeMigration('d7_user_flood');
}
/**
* Tests the migration.
*/
public function testMigration() {
$expected = [
'uid_only' => TRUE,
'ip_limit' => 30,
'ip_window' => 7200,
'user_limit' => 22,
'user_window' => 86400,
];
$this->assertIdentical($expected, $this->config('user.flood')->get());
}
}

View file

@ -0,0 +1,49 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d7\MigrateUserMailTest.
*/
namespace Drupal\user\Tests\Migrate\d7;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
/**
* Migrates user mail configuration.
*
* @group user
*/
class MigrateUserMailTest extends MigrateDrupal7TestBase {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(['user']);
$this->executeMigration('d7_user_mail');
}
/**
* Tests the migration.
*/
public function testMigration() {
$config = $this->config('user.mail');
$this->assertIdentical('Your account is approved!', $config->get('status_activated.subject'));
$this->assertIdentical('Your account was activated, and there was much rejoicing.', $config->get('status_activated.body'));
$this->assertIdentical('Fix your password', $config->get('password_reset.subject'));
$this->assertIdentical("Nope! You're locked out forever.", $config->get('password_reset.body'));
$this->assertIdentical('So long, bub', $config->get('cancel_confirm.subject'));
$this->assertIdentical('The gates of Drupal are closed to you. Now you will work in the salt mines.', $config->get('cancel_confirm.body'));
$this->assertIdentical('Gawd made you an account', $config->get('register_admin_created.subject'));
$this->assertIdentical('...and she could take it away.', $config->get('register_admin_created.body'));
$this->assertIdentical('Welcome!', $config->get('register_no_approval_required.subject'));
$this->assertIdentical('You can now log in if you can figure out how to use Drupal!', $config->get('register_no_approval_required.body'));
$this->assertIdentical('Soon...', $config->get('register_pending_approval.subject'));
$this->assertIdentical('...you will join our Circle. Let the Drupal flow through you.', $config->get('register_pending_approval.body'));
$this->assertIdentical('BEGONE!', $config->get('status_blocked.subject'));
$this->assertIdentical('You no longer please the robot overlords. Go to your room and chill out.', $config->get('status_blocked.body'));
}
}

View file

@ -0,0 +1,73 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d7\MigrateUserRoleTest.
*/
namespace Drupal\user\Tests\Migrate\d7;
use Drupal\Core\Database\Database;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
/**
* Upgrade user roles to user.role.*.yml.
*
* @group user
*/
class MigrateUserRoleTest extends MigrateDrupal7TestBase {
/**
* The modules to be enabled during the test.
*
* @var array
*/
static $modules = array('user');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d7_user_role');
}
/**
* Asserts aspects of a user role config entity.
*
* @param string $id
* The role ID.
* @param string $label
* The role's expected label.
* @param int|NULL $original_rid
* The original (integer) ID of the role, to check permissions.
*/
protected function assertEntity($id, $label, $original_rid) {
/** @var \Drupal\user\RoleInterface $entity */
$entity = Role::load($id);
$this->assertTrue($entity instanceof RoleInterface);
$this->assertIdentical($label, $entity->label());
if (isset($original_rid)) {
$permissions = Database::getConnection('default', 'migrate')
->select('role_permission', 'rp')
->fields('rp', ['permission'])
->condition('rid', $original_rid)
->execute()
->fetchCol();
$this->assertIdentical($permissions, $entity->getPermissions());
}
}
/**
* Tests user role migration.
*/
public function testUserRole() {
$this->assertEntity('anonymous', 'anonymous user', 1);
$this->assertEntity('authenticated', 'authenticated user', 2);
$this->assertEntity('administrator', 'administrator', 3);
}
}

View file

@ -0,0 +1,95 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d7\MigrateUserTest.
*/
namespace Drupal\user\Tests\Migrate\d7;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
use Drupal\user\Entity\User;
use Drupal\user\RoleInterface;
use Drupal\user\UserInterface;
/**
* Users migration.
*
* @group user
*/
class MigrateUserTest extends MigrateDrupal7TestBase {
/**
* The modules to be enabled during the test.
*
* @var array
*/
static $modules = array('file', 'image', 'user');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Prepare to migrate user pictures as well.
$this->installEntitySchema('file');
$this->executeMigration('user_picture_field');
$this->executeMigration('user_picture_field_instance');
$this->executeMigration('d7_user_role');
$this->executeMigration('d7_user');
}
/**
* Asserts various aspects of a user account.
*
* @param string $id
* The user ID.
* @param string $label
* The username.
* @param string $mail
* The user's e-mail address.
* @param int $access
* The last access time.
* @param int $login
* The last login time.
* @param bool $blocked
* Whether or not the account is blocked.
* @param string $langcode
* The user account's language code.
* @param string $init
* The user's initial e-mail address.
* @param string[] $roles
* Role IDs the user account is expected to have.
* @param bool $has_picture
* Whether the user is expected to have a picture attached.
*/
protected function assertEntity($id, $label, $mail, $access, $login, $blocked, $langcode, $init, array $roles = [RoleInterface::AUTHENTICATED_ID], $has_picture = FALSE) {
/** @var \Drupal\user\UserInterface $user */
$user = User::load($id);
$this->assertTrue($user instanceof UserInterface);
$this->assertIdentical($label, $user->label());
$this->assertIdentical($mail, $user->getEmail());
$this->assertIdentical($access, $user->getLastAccessedTime());
$this->assertIdentical($login, $user->getLastLoginTime());
$this->assertIdentical($blocked, $user->isBlocked());
// $user->getPreferredLangcode() might fallback to default language if the
// user preferred language is not configured on the site. We just want to
// test if the value was imported correctly.
$this->assertIdentical($langcode, $user->langcode->value);
$this->assertIdentical($langcode, $user->preferred_langcode->value);
$this->assertIdentical($langcode, $user->preferred_admin_langcode->value);
$this->assertIdentical($init, $user->getInitialEmail());
$this->assertIdentical($roles, $user->getRoles());
$this->assertIdentical($has_picture, !$user->user_picture->isEmpty());
}
/**
* Tests the Drupal 7 user to Drupal 8 migration.
*/
public function testUser() {
$this->assertEntity(2, 'Odo', 'odo@local.host', '0', '0', FALSE, '', 'odo@local.host');
}
}

View file

@ -0,0 +1,36 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Migrate\d7\UserMigrationBuilderTest.
*/
namespace Drupal\user\Tests\Migrate\d7;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
/**
* @group user
*/
class UserMigrationBuilderTest extends MigrateDrupal7TestBase {
public static $modules = ['migrate', 'migrate_drupal', 'user'];
/**
* Tests that profile fields are merged into the d6_profile_values migration's
* process pipeline by the d6_profile_values builder.
*/
public function testBuilder() {
$template = \Drupal::service('migrate.template_storage')
->getTemplateByName('d7_user');
/** @var \Drupal\migrate\Entity\MigrationInterface[] $migrations */
$migrations = \Drupal::service('plugin.manager.migrate.builder')
->createInstance('d7_user')
->buildMigrations($template);
$this->assertIdentical('d7_user', $migrations[0]->id());
$process = $migrations[0]->getProcess();
$this->assertIdentical('field_file', $process['field_file'][0]['source']);
}
}

View file

@ -7,7 +7,6 @@
namespace Drupal\user\Tests;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\simpletest\WebTestBase;
/**
@ -49,9 +48,8 @@ class UserBlocksTest extends WebTestBase {
$edit['name'] = $this->randomMachineName();
$edit['pass'] = $this->randomMachineName();
$this->drupalPostForm('node', $edit, t('Log in'));
$this->assertRaw(\Drupal::translation()->formatPlural(1, '1 error has been found: !errors', '@count errors have been found: !errors', [
'!errors' => SafeMarkup::set('<a href="#edit-name">Username</a>')
]));
$this->assertRaw('1 error has been found:');
$this->assertRaw('<a href="#edit-name">Username</a>');
$this->assertText(t('Sorry, unrecognized username or password.'));
// Create a user with some permission that anonymous users lack.

View file

@ -25,9 +25,20 @@ class UserRoleAdminTest extends WebTestBase {
*/
protected $adminUser;
/**
* Modules to enable.
*
* @var string[]
*/
public static $modules = ['block'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->adminUser = $this->drupalCreateUser(array('administer permissions', 'administer users'));
$this->drupalPlaceBlock('local_tasks_block');
}
/**

View file

@ -42,8 +42,9 @@ class UserRoleDeleteTest extends KernelTestBase {
// Create user and assign both test roles.
$values = array(
'uid' => 1,
'roles' => array('test_role_one', 'test_role_two'),
'uid' => 1,
'name' => $this->randomString(),
'roles' => array('test_role_one', 'test_role_two'),
);
$user = User::create($values);
$user->save();

View file

@ -7,7 +7,7 @@
namespace Drupal\user\Tests;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\simpletest\WebTestBase;
@ -57,15 +57,15 @@ class UserTokenReplaceTest extends WebTestBase {
// Generate and test sanitized tokens.
$tests = array();
$tests['[user:uid]'] = $account->id();
$tests['[user:name]'] = SafeMarkup::checkPlain(user_format_name($account));
$tests['[user:mail]'] = SafeMarkup::checkPlain($account->getEmail());
$tests['[user:name]'] = Html::escape(user_format_name($account));
$tests['[user:mail]'] = Html::escape($account->getEmail());
$tests['[user:url]'] = $account->url('canonical', $url_options);
$tests['[user:edit-url]'] = $account->url('edit-form', $url_options);
$tests['[user:last-login]'] = format_date($account->getLastLoginTime(), 'medium', '', NULL, $language_interface->getId());
$tests['[user:last-login:short]'] = format_date($account->getLastLoginTime(), 'short', '', NULL, $language_interface->getId());
$tests['[user:created]'] = format_date($account->getCreatedTime(), 'medium', '', NULL, $language_interface->getId());
$tests['[user:created:short]'] = format_date($account->getCreatedTime(), 'short', '', NULL, $language_interface->getId());
$tests['[current-user:name]'] = SafeMarkup::checkPlain(user_format_name($global_account));
$tests['[current-user:name]'] = Html::escape(user_format_name($global_account));
$base_bubbleable_metadata = BubbleableMetadata::createFromObject($account);
$metadata_tests = [];
@ -101,7 +101,7 @@ class UserTokenReplaceTest extends WebTestBase {
$anonymous_user = User::load(0);
$tests = [];
$tests['[user:uid]'] = t('not yet assigned');
$tests['[user:name]'] = SafeMarkup::checkPlain(user_format_name($anonymous_user));
$tests['[user:name]'] = Html::escape(user_format_name($anonymous_user));
$base_bubbleable_metadata = BubbleableMetadata::createFromObject($anonymous_user);
$metadata_tests = [];

View file

@ -136,7 +136,7 @@ class UserValidationTest extends KernelTestBase {
$violations = $user->validate();
$this->assertEqual(count($violations), 1, 'E-mail addresses may not be removed');
$this->assertEqual($violations[0]->getPropertyPath(), 'mail');
$this->assertEqual($violations[0]->getMessage(), t('!name field is required.', array('!name' => SafeMarkup::placeholder($user->getFieldDefinition('mail')->getLabel()))));
$this->assertEqual($violations[0]->getMessage(), t('!name field is required.', array('!name' => $user->getFieldDefinition('mail')->getLabel())));
$user->set('mail', 'someone@example.com');
$user->set('timezone', $this->randomString(33));

View file

@ -8,8 +8,6 @@
namespace Drupal\user\Tests\Views;
use Drupal\views\Views;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Tests\ViewUnitTestBase;
/**
* Tests the permission field handler.
@ -17,7 +15,7 @@ use Drupal\views\Tests\ViewUnitTestBase;
* @group user
* @see \Drupal\user\Plugin\views\field\Permissions
*/
class HandlerFieldPermissionTest extends UserUnitTestBase {
class HandlerFieldPermissionTest extends UserKernelTestBase {
/**
* Views used by this test.

View file

@ -41,6 +41,8 @@ class HandlerFieldUserNameTest extends UserTestBase {
$this->executeView($view);
$anon_name = $this->config('user.settings')->get('anonymous');
$view->result[0]->_entity->setUsername('');
$view->result[0]->_entity->uid->value = 0;
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
return $view->field['name']->advancedRender($view->result[0]);
});
@ -63,7 +65,7 @@ class HandlerFieldUserNameTest extends UserTestBase {
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
return $view->field['name']->advancedRender($view->result[0]);
});
$this->assertIdentical($render, $username, 'If the user is not linked the username should be printed out for a normal user.');
$this->assertEqual($render, $username, 'If the user is not linked the username should be printed out for a normal user.');
}

View file

@ -7,8 +7,7 @@
namespace Drupal\user\Tests\Views;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\user\Tests\Views\UserUnitTestBase;
use Drupal\Component\Utility\Html;
use Drupal\views\Views;
/**
@ -17,7 +16,7 @@ use Drupal\views\Views;
* @group user
* @see \Drupal\user\Plugin\views\filter\Permissions
*/
class HandlerFilterPermissionTest extends UserUnitTestBase {
class HandlerFilterPermissionTest extends UserKernelTestBase {
/**
* Views used by this test.
@ -87,7 +86,7 @@ class HandlerFilterPermissionTest extends UserUnitTestBase {
}
foreach (array('system' => 'System', 'user' => 'User') as $module => $title) {
$expected = array_map(function ($permission) {
return SafeMarkup::checkPlain(strip_tags($permission['title']));
return Html::escape(strip_tags($permission['title']));
}, $permission_by_module[$module]);
$this->assertEqual($expected, $value_options[$title], 'Ensure the all permissions are available');

View file

@ -8,7 +8,6 @@
namespace Drupal\user\Tests\Views;
use Drupal\user\Entity\Role;
use Drupal\user\Tests\Views\UserUnitTestBase;
use Drupal\views\Entity\View;
use Drupal\views\Views;
@ -19,7 +18,7 @@ use Drupal\views\Views;
*
* @see \Drupal\user\Plugin\views\filter\Roles
*/
class HandlerFilterRolesTest extends UserUnitTestBase {
class HandlerFilterRolesTest extends UserKernelTestBase {
/**
* Views used by this test.

View file

@ -0,0 +1,38 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Views\RolesRidArgumentTest.
*/
namespace Drupal\user\Tests\Views;
/**
* Tests the handler of the user: roles argument.
*
* @group user
* @see \Drupal\user\Plugin\views\argument\RolesRid
*/
class RolesRidArgumentTest extends UserTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_user_roles_rid');
/**
* Tests the generated title of a user: roles argument.
*/
public function testArgumentTitle() {
$role_id = $this->createRole([], 'markup_role_name', '<em>Role name with markup</em>');
$user = $this->createUser();
$user->addRole($role_id);
$user->save();
$this->drupalGet('/user_roles_rid_test/markup_role_name');
$this->assertEscaped('<em>Role name with markup</em>');
}
}

View file

@ -0,0 +1,95 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Views\UserKernelTestBase.
*/
namespace Drupal\user\Tests\Views;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Tests\ViewKernelTestBase;
/**
* Provides a common test base for user views tests.
*/
abstract class UserKernelTestBase extends ViewKernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('user_test_views', 'user', 'system', 'field');
/**
* Users to use during this test.
*
* @var array
*/
protected $users = array();
/**
* The entity storage for roles.
*
* @var \Drupal\user\RoleStorage
*/
protected $roleStorage;
/**
* The entity storage for users.
*
* @var \Drupal\user\UserStorage
*/
protected $userStorage;
protected function setUp() {
parent::setUp();
ViewTestData::createTestViews(get_class($this), array('user_test_views'));
$this->installEntitySchema('user');
$entity_manager = $this->container->get('entity.manager');
$this->roleStorage = $entity_manager->getStorage('user_role');
$this->userStorage = $entity_manager->getStorage('user');
}
/**
* Set some test data for permission related tests.
*/
protected function setupPermissionTestData() {
// Setup a role without any permission.
$this->roleStorage->create(array('id' => 'authenticated'))
->save();
$this->roleStorage->create(array('id' => 'no_permission'))
->save();
// Setup a role with just one permission.
$this->roleStorage->create(array('id' => 'one_permission'))
->save();
user_role_grant_permissions('one_permission', array('administer permissions'));
// Setup a role with multiple permissions.
$this->roleStorage->create(array('id' => 'multiple_permissions'))
->save();
user_role_grant_permissions('multiple_permissions', array('administer permissions', 'administer users', 'access user profiles'));
// Setup a user without an extra role.
$this->users[] = $account = $this->userStorage->create(['name' => $this->randomString()]);
$account->save();
// Setup a user with just the first role (so no permission beside the
// ones from the authenticated role).
$this->users[] = $account = $this->userStorage->create(array('name' => 'first_role'));
$account->addRole('no_permission');
$account->save();
// Setup a user with just the second role (so one additional permission).
$this->users[] = $account = $this->userStorage->create(array('name' => 'second_role'));
$account->addRole('one_permission');
$account->save();
// Setup a user with both the second and the third role.
$this->users[] = $account = $this->userStorage->create(array('name' => 'second_third_role'));
$account->addRole('one_permission');
$account->addRole('multiple_permissions');
$account->save();
}
}

View file

@ -138,7 +138,7 @@ class UserListBuilder extends EntityListBuilder {
);
$row['status'] = $entity->isActive() ? $this->t('active') : $this->t('blocked');
$roles = array_map('\Drupal\Component\Utility\SafeMarkup::checkPlain', user_role_names(TRUE));
$roles = user_role_names(TRUE);
unset($roles[RoleInterface::AUTHENTICATED_ID]);
$users_roles = array();
foreach ($entity->getRoles() as $role) {

View file

@ -0,0 +1,31 @@
<?php
/**
* @file
* Contains \Drupal\user\UserNameItem.
*/
namespace Drupal\user;
use Drupal\Core\Field\Plugin\Field\FieldType\StringItem;
/**
* Defines a custom field item class for the 'name' user entity field.
*/
class UserNameItem extends StringItem {
/**
* {@inheritdoc}
*/
public function isEmpty() {
$value = $this->get('value')->getValue();
// Take into account that the name of the anonymous user is an empty string.
if ($this->getEntity()->isAnonymous()) {
return $value === NULL;
}
return $value === NULL || $value === '';
}
}

View file

@ -0,0 +1,30 @@
<?php
/**
* @file
* Contains \Drupal\user\UserServiceProvider.
*/
namespace Drupal\user;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
/**
* Swaps the original 'password' service in order to handle password hashing for
* user migrations that have passwords hashed to MD5.
*
* @see \Drupal\migrate\MigratePassword
* @see \Drupal\Core\Password\PhpassHashedPassword
*/
class UserServiceProvider implements ServiceModifierInterface {
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
$container->setDefinition('password_original', $container->getDefinition('password'));
$container->setDefinition('password', $container->getDefinition('password_migrate'));
}
}

View file

@ -245,7 +245,7 @@ class UserViewsData extends EntityViewsData {
'allow empty' => TRUE,
),
'argument' => array(
'id' => 'user__roles_target_id',
'id' => 'user__roles_rid',
'name table' => 'role',
'name field' => 'name',
'empty field name' => t('No role'),

View file

@ -38,8 +38,12 @@ display:
table: users_field_data
field: changed
label: 'Updated date'
date_format: html_date
plugin_id: date
plugin_id: field
type: timestamp
settings:
date_format: html_date
custom_date_format: ''
timezone: ''
entity_type: user
entity_field: changed
filters: { }

View file

@ -0,0 +1,220 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_user_roles_rid
label: test_user_roles_rid
module: views
description: ''
tag: ''
base_table: users_field_data
base_field: uid
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: none
options: { }
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: full
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: ' previous'
next: 'next '
first: '« first'
last: 'last »'
quantity: 9
style:
type: default
options:
grouping: { }
row_class: ''
default_row_class: true
uses_fields: false
row:
type: fields
options:
inline: { }
separator: ''
hide_empty: false
default_field_elements: true
fields:
name:
id: name
table: users_field_data
field: name
entity_type: user
entity_field: name
label: ''
alter:
alter_text: false
make_link: false
absolute: false
trim: false
word_boundary: false
ellipsis: false
strip_tags: false
html: false
hide_empty: false
empty_zero: false
plugin_id: field
relationship: none
group_type: group
admin_label: ''
exclude: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_alter_empty: true
click_sort_column: value
type: user_name
settings: { }
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
filters:
status:
value: true
table: users_field_data
field: status
plugin_id: boolean
entity_type: user
entity_field: status
id: status
expose:
operator: ''
group: 1
sorts:
uid:
id: uid
table: users
field: uid
relationship: none
group_type: group
admin_label: ''
order: ASC
exposed: false
expose:
label: ''
entity_type: user
entity_field: uid
plugin_id: standard
header: { }
footer: { }
empty: { }
relationships: { }
arguments:
roles_target_id:
id: roles_target_id
table: user__roles
field: roles_target_id
relationship: none
group_type: group
admin_label: ''
default_action: empty
exception:
value: all
title_enable: false
title: All
title_enable: true
title: '%1'
default_argument_type: fixed
default_argument_options:
argument: ''
default_argument_skip_url: false
summary_options:
base_path: ''
count: true
items_per_page: 25
override: false
summary:
sort_order: asc
number_of_records: 0
format: default_summary
specify_validation: false
validate:
type: none
fail: 'not found'
validate_options: { }
break_phrase: false
add_table: false
require_value: false
reduce_duplicates: false
plugin_id: user__roles_rid
display_extenders: { }
cache_metadata:
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- user.permissions
cacheable: false
page_1:
display_plugin: page
id: page_1
display_title: Page
position: 1
display_options:
display_extenders: { }
path: user_roles_rid_test
cache_metadata:
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- user.permissions
cacheable: false

View file

@ -0,0 +1,90 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Migrate\ProfileFieldTest.
*/
namespace Drupal\Tests\user\Unit\Migrate;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests profile_field source plugin.
*
* @group user
*/
class ProfileFieldTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\user\Plugin\migrate\source\ProfileField';
protected $migrationConfiguration = [
'id' => 'test_profile_fields',
'source' => [
'plugin' => 'd6_profile_field',
],
];
// We need to set up the database contents; it's easier to do that below.
// These are sample result queries.
// @todo Add multiple cases.
protected $expectedResults = [
[
'fid' => 1,
'title' => 'First name',
'name' => 'profile_first_name',
'explanation' => 'First name user',
'category' => 'profile',
'page' => '',
'type' => 'textfield',
'weight' => 0,
'required' => 1,
'register' => 0,
'visibility' => 2,
'autocomplete' => 0,
'options' => [],
],
[
'fid' => 2,
'title' => 'Last name',
'name' => 'profile_last_name',
'explanation' => 'Last name user',
'category' => 'profile',
'page' => '',
'type' => 'textfield',
'weight' => 0,
'required' => 0,
'register' => 0,
'visibility' => 2,
'autocomplete' => 0,
'options' => [],
],
[
'fid' => 3,
'title' => 'Policy',
'name' => 'profile_policy',
'explanation' => 'A checkbox that say if you accept policy of website',
'category' => 'profile',
'page' => '',
'type' => 'checkbox',
'weight' => 0,
'required' => 1,
'register' => 1,
'visibility' => 2,
'autocomplete' => 0,
'options' => [],
],
];
/**
* Prepopulate contents with results.
*/
protected function setUp() {
$this->databaseContents['profile_fields'] = $this->expectedResults;
foreach ($this->databaseContents['profile_fields'] as &$row) {
$row['options'] = serialize([]);
}
parent::setUp();
}
}

View file

@ -0,0 +1,86 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Migrate\d6\RoleTest.
*/
namespace Drupal\Tests\user\Unit\Migrate\d6;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D6 role source plugin.
*
* @group user
*/
class RoleTest extends MigrateSqlSourceTestCase {
// The plugin system is not working during unit testing so the source plugin
// class needs to be manually specified.
const PLUGIN_CLASS = 'Drupal\user\Plugin\migrate\source\d6\Role';
// The fake Migration configuration entity.
protected $migrationConfiguration = array(
// The ID of the entity, can be any string.
'id' => 'test',
// This needs to be the identifier of the actual key: cid for comment, nid
// for node and so on.
'source' => array(
'plugin' => 'd6_user_role',
),
);
protected $expectedResults = array(
array(
'rid' => 1,
'name' => 'anonymous user',
'permissions' => array(
'access content',
),
),
array(
'rid' => 2,
'name' => 'authenticated user',
'permissions' => array(
'access comments',
'access content',
'post comments',
'post comments without approval',
),
),
array(
'rid' => 3,
'name' => 'administrator',
'permissions' => array(
'access comments',
'administer comments',
'post comments',
'post comments without approval',
'access content',
'administer content types',
'administer nodes',
),
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
foreach ($this->expectedResults as $row) {
$this->databaseContents['permission'][] = array(
'perm' => implode(', ', $row['permissions']),
'rid' => $row['rid'],
);
unset($row['permissions']);
$this->databaseContents['role'][] = $row;
}
$this->databaseContents['filter_formats'][] = array(
'format' => 1,
'roles' => '',
);
parent::setUp();
}
}

View file

@ -0,0 +1,49 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Migrate\d6\UserPictureTest.
*/
namespace Drupal\Tests\user\Unit\Migrate\d6;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D6 user picture source plugin.
*
* @group user
*/
class UserPictureTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\user\Plugin\migrate\source\d6\UserPicture';
protected $migrationConfiguration = array(
'id' => 'test_user_picture',
'source' => array(
'plugin' => 'd6_user_picture',
),
);
protected $expectedResults = array(
array(
'uid' => 1,
'access' => 1382835435,
'picture' => 'sites/default/files/pictures/picture-1.jpg',
),
array(
'uid' => 2,
'access' => 1382835436,
'picture' => 'sites/default/files/pictures/picture-2.jpg',
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['users'] = $this->expectedResults;
parent::setUp();
}
}

View file

@ -0,0 +1,88 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Migrate\d6\UserTest.
*/
namespace Drupal\Tests\user\Unit\Migrate\d6;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D6 user source plugin.
*
* @group user
*/
class UserTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\user\Plugin\migrate\source\d6\User';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd6_user',
),
);
protected $expectedResults = array(
array(
'uid' => 2,
'name' => 'admin',
// @todo d6 hash?
'pass' => '1234',
'mail' => 'admin@example.com',
'theme' => '',
'signature' => '',
'signature_format' => 0,
'created' => 1279402616,
'access' => 1322981278,
'login' => 1322699994,
'status' => 0,
'timezone' => 'America/Lima',
'language' => 'en',
// @todo Add the file when needed.
'picture' => 'sites/default/files/pictures/picture-1.jpg',
'init' => 'admin@example.com',
'data' => NULL,
),
array(
'uid' => 4,
'name' => 'alice',
// @todo d6 hash?
'pass' => '1234',
'mail' => 'alice@example.com',
'theme' => '',
'signature' => '',
'signature_format' => 0,
'created' => 1322981368,
'access' => 1322982419,
'login' => 132298140,
'status' => 0,
'timezone' => 'America/Lima',
'language' => 'en',
'picture' => '',
'init' => 'alice@example.com',
'data' => NULL,
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
foreach ($this->expectedResults as $k => $row) {
$this->databaseContents['users'][$k] = $row;
}
// getDatabase() will not create empty tables, so we need to insert data
// even if it's irrelevant to the test.
$this->databaseContents['users_roles'] = array(
array(
'uid' => 99,
'rid' => 99,
),
);
parent::setUp();
}
}

View file

@ -11,6 +11,8 @@ use Drupal\Core\Access\AccessResult;
use Drupal\Tests\UnitTestCase;
use Drupal\user\Access\PermissionAccessCheck;
use Symfony\Component\Routing\Route;
use Drupal\Core\Cache\Context\CacheContextsManager;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* @coversDefaultClass \Drupal\user\Access\PermissionAccessCheck
@ -26,12 +28,24 @@ class PermissionAccessCheckTest extends UnitTestCase {
*/
public $accessCheck;
/**
* The dependency injection container.
*
* @var \Symfony\Component\DependencyInjection\ContainerBuilder
*/
protected $container;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->container = new ContainerBuilder();
$cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
$this->container->set('cache_contexts_manager', $cache_contexts_manager);
\Drupal::setContainer($this->container);
$this->accessCheck = new PermissionAccessCheck();
}
@ -41,15 +55,13 @@ class PermissionAccessCheckTest extends UnitTestCase {
* @return array
*/
public function providerTestAccess() {
$allowed = AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions']);
$neutral = AccessResult::allowedIf(FALSE)->addCacheContexts(['user.permissions']);
return [
[[], AccessResult::allowedIf(FALSE)],
[['_permission' => 'allowed'], $allowed],
[['_permission' => 'denied'], $neutral],
[['_permission' => 'allowed+denied'], $allowed],
[['_permission' => 'allowed+denied+other'], $allowed],
[['_permission' => 'allowed,denied'], $neutral],
[[], FALSE],
[['_permission' => 'allowed'], TRUE, ['user.permissions']],
[['_permission' => 'denied'], FALSE, ['user.permissions']],
[['_permission' => 'allowed+denied'], TRUE, ['user.permissions']],
[['_permission' => 'allowed+denied+other'], TRUE, ['user.permissions']],
[['_permission' => 'allowed,denied'], FALSE, ['user.permissions']],
];
}
@ -59,7 +71,8 @@ class PermissionAccessCheckTest extends UnitTestCase {
* @dataProvider providerTestAccess
* @covers ::access
*/
public function testAccess($requirements, $access) {
public function testAccess($requirements, $access, array $contexts = []) {
$access_result = AccessResult::allowedIf($access)->addCacheContexts($contexts);
$user = $this->getMock('Drupal\Core\Session\AccountInterface');
$user->expects($this->any())
->method('hasPermission')
@ -71,7 +84,7 @@ class PermissionAccessCheckTest extends UnitTestCase {
));
$route = new Route('', [], $requirements);
$this->assertEquals($access, $this->accessCheck->access($route, $user));
$this->assertEquals($access_result, $this->accessCheck->access($route, $user));
}
}

View file

@ -0,0 +1,78 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Plugin\migrate\source\d7\RoleTest.
*/
namespace Drupal\Tests\user\Unit\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D7 role source plugin.
*
* @group user
*/
class RoleTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\user\Plugin\migrate\source\d7\Role';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd7_user_role',
),
);
protected $expectedResults = array(
array(
'rid' => 1,
'name' => 'anonymous user',
'permissions' => array(
'access content',
),
),
array(
'rid' => 2,
'name' => 'authenticated user',
'permissions' => array(
'access comments',
'access content',
'post comments',
'post comments without approval',
),
),
array(
'rid' => 3,
'name' => 'administrator',
'permissions' => array(
'access comments',
'administer comments',
'post comments',
'post comments without approval',
'access content',
'administer content types',
'administer nodes',
),
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
foreach ($this->expectedResults as $row) {
foreach ($row['permissions'] as $permission) {
$this->databaseContents['role_permission'][] = array(
'permission' => $permission,
'rid' => $row['rid'],
);
}
unset($row['permissions']);
$this->databaseContents['role'][] = $row;
}
parent::setUp();
}
}

View file

@ -0,0 +1,117 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Plugin\migrate\source\d7\UserTest.
*/
namespace Drupal\Tests\user\Unit\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D7 user source plugin.
*
* @group user
*/
class UserTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\user\Plugin\migrate\source\d7\User';
protected $migrationConfiguration = [
'id' => 'test',
'source' => [
'plugin' => 'd7_user',
],
];
protected $expectedResults = [
[
'uid' => '2',
'name' => 'Odo',
'pass' => '$S$DVpvPItXvnsmF3giVEe7Jy2lG.SCoEs8uKwpHsyPvdeNAaNZYxZ8',
'mail' => 'odo@local.host',
'signature' => '',
'signature_format' => 'filtered_html',
'created' => '1432750741',
'access' => '0',
'login' => '0',
'status' => '1',
'timezone' => 'America/Chicago',
'language' => '',
'picture' => '0',
'init' => 'odo@local.host',
'roles' => [2],
'data' => [
'contact' => 1,
],
'field_file' => [
[
'fid' => 99,
'display' => 1,
'description' => 'None',
],
],
],
];
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['users'][] = [
'uid' => '2',
'name' => 'Odo',
'pass' => '$S$DVpvPItXvnsmF3giVEe7Jy2lG.SCoEs8uKwpHsyPvdeNAaNZYxZ8',
'mail' => 'odo@local.host',
'theme' => '',
'signature' => '',
'signature_format' => 'filtered_html',
'created' => '1432750741',
'access' => '0',
'login' => '0',
'status' => '1',
'timezone' => 'America/Chicago',
'language' => '',
'picture' => '0',
'init' => 'odo@local.host',
'data' => 'a:1:{s:7:"contact";i:1;}',
];
$this->databaseContents['users_roles'][] = [
'uid' => 2,
'rid' => 2,
];
$this->databaseContents['role'][] = [
'rid' => 2,
'name' => 'authenticated user',
'weight' => 0,
];
$this->databaseContents['field_config_instance'] = [
[
'id' => '33',
'field_id' => '11',
'field_name' => 'field_file',
'entity_type' => 'user',
'bundle' => 'user',
'data' => 'a:0:{}',
'deleted' => '0',
],
];
$this->databaseContents['field_data_field_file'] = [
[
'entity_type' => 'user',
'bundle' => 'user',
'deleted' => 0,
'entity_id' => 2,
'revision_id' => NULL,
'language' => 'und',
'delta' => 0,
'field_file_fid' => 99,
'field_file_display' => 1,
'field_file_description' => 'None',
],
];
parent::setUp();
}
}

View file

@ -7,8 +7,9 @@
namespace Drupal\Tests\user\Unit;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\Context\CacheContextsManager;
use Drupal\Core\DependencyInjection\Container;
use Drupal\Tests\UnitTestCase;
use Drupal\user\UserAccessControlHandler;
@ -62,6 +63,12 @@ class UserAccessControlHandlerTest extends UnitTestCase {
*/
public function setUp() {
parent::setUp();
$cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
$container = new Container();
$container->set('cache_contexts_manager', $cache_contexts_manager);
\Drupal::setContainer($container);
$this->viewer = $this->getMock('\Drupal\Core\Session\AccountInterface');
$this->viewer
->expects($this->any())
@ -125,13 +132,8 @@ class UserAccessControlHandlerTest extends UnitTestCase {
->will($this->returnValue($this->{$target}));
foreach (array('view' => $view, 'edit' => $edit) as $operation => $result) {
$message = SafeMarkup::format("User @field field access returns @result with operation '@op' for @account accessing @target", array(
'@field' => $field,
'@result' => !isset($result) ? 'null' : ($result ? 'true' : 'false'),
'@op' => $operation,
'@account' => $viewer,
'@target' => $target,
));
$result_text = !isset($result) ? 'null' : ($result ? 'true' : 'false');
$message = "User '$field' field access returns '$result_text' with operation '$operation' for '$viewer' accessing '$target'";
$this->assertSame($result, $this->accessControlHandler->fieldAccess($operation, $field_definition, $this->{$viewer}, $this->items), $message);
}
}

View file

@ -7,7 +7,6 @@
namespace Drupal\Tests\user\Unit\Views\Argument;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Tests\UnitTestCase;
use Drupal\user\Entity\Role;
@ -20,9 +19,9 @@ use Drupal\user\Plugin\views\argument\RolesRid;
class RolesRidTest extends UnitTestCase {
/**
* Tests the title_query method.
* Tests the titleQuery method.
*
* @see \Drupal\user\Plugin\views\argument\RolesRid::title_query()
* @covers ::titleQuery
*/
public function testTitleQuery() {
$role1 = new Role(array(
@ -72,16 +71,16 @@ class RolesRidTest extends UnitTestCase {
$roles_rid_argument = new RolesRid(array(), 'user__roles_rid', array(), $entity_manager);
$roles_rid_argument->value = array();
$titles = $roles_rid_argument->title_query();
$titles = $roles_rid_argument->titleQuery();
$this->assertEquals(array(), $titles);
$roles_rid_argument->value = array('test_rid_1');
$titles = $roles_rid_argument->title_query();
$titles = $roles_rid_argument->titleQuery();
$this->assertEquals(array('test rid 1'), $titles);
$roles_rid_argument->value = array('test_rid_1', 'test_rid_2');
$titles = $roles_rid_argument->title_query();
$this->assertEquals(array('test rid 1', SafeMarkup::checkPlain('test <strong>rid 2</strong>')), $titles);
$titles = $roles_rid_argument->titleQuery();
$this->assertEquals(array('test rid 1', 'test <strong>rid 2</strong>'), $titles);
}
}

View file

@ -70,6 +70,7 @@ function user_install() {
->create(array(
'uid' => 0,
'status' => 0,
'name' => '',
))
->save();

View file

@ -12,6 +12,10 @@
* check that its confirmation is correct.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
* Attaches password strength indicator and other relevant validation to
* password fields.
*/
Drupal.behaviors.password = {
attach: function (context, settings) {
@ -31,7 +35,7 @@
$passwordInputParentWrapper
.find('input.js-password-confirm')
.parent()
.append('<div class="password-confirm js-password-confirm">' + translate.confirmTitle + ' <span></span></div>')
.append('<div aria-live="polite" aria-atomic="true" class="password-confirm js-password-confirm">' + translate.confirmTitle + ' <span></span></div>')
.addClass('confirm-parent');
var $confirmInput = $passwordInputParentWrapper.find('input.js-password-confirm');
@ -40,7 +44,7 @@
// If the password strength indicator is enabled, add its markup.
if (settings.password.showStrengthIndicator) {
var passwordMeter = '<div class="password-strength"><div class="password-strength__meter"><div class="password-strength__indicator js-password-strength__indicator"></div></div><div class="password-strength__title">' + translate.strengthTitle + ' </div><div class="password-strength__text js-password-strength__text" aria-live="assertive"></div></div>';
var passwordMeter = '<div class="password-strength"><div class="password-strength__meter"><div class="password-strength__indicator js-password-strength__indicator"></div></div><div aria-live="polite" aria-atomic="true" class="password-strength__title">' + translate.strengthTitle + ' <span class="password-strength__text js-password-strength__text"></span></div></div>';
$confirmInput.parent().after('<div class="password-suggestions description"></div>');
$passwordInputParent.append(passwordMeter);
$passwordSuggestions = $passwordInputParentWrapper.find('div.password-suggestions').hide();
@ -104,9 +108,12 @@
* Returns the estimated strength and the relevant output message.
*
* @param {string} password
* The password to evaluate.
* @param {object} translate
* An object containing the text to display for each strength level.
*
* @return {object}
* An object containing strength, message, indicatorText and indicatorClass.
*/
Drupal.evaluatePasswordStrength = function (password, translate) {
password = password.trim();

Some files were not shown because too many files have changed in this diff Show more