Update to drupal 8.0.0-rc1. For more information, see https://www.drupal.org/node/2582663

This commit is contained in:
Greg Anderson 2015-10-08 11:40:12 -07:00
parent eb34d130a8
commit f32e58e4b1
8476 changed files with 211648 additions and 170042 deletions

View file

@ -104,7 +104,7 @@ abstract class AccountForm extends ContentEntityForm {
'#type' => 'textfield',
'#title' => $this->t('Username'),
'#maxlength' => USERNAME_MAX_LENGTH,
'#description' => $this->t('Spaces are allowed; punctuation is not allowed except for periods, hyphens, apostrophes, and underscores.'),
'#description' => $this->t("Several special characters are allowed, including space, period (.), hyphen (-), apostrophe ('), underscore (_), and the @ sign."),
'#required' => TRUE,
'#attributes' => array(
'class' => array('username'),
@ -133,42 +133,30 @@ abstract class AccountForm extends ContentEntityForm {
$form_state->set('user_pass_reset', $user_pass_reset);
}
$protected_values = array();
$current_pass_description = '';
// The user may only change their own password without their current
// password if they logged in via a one-time login link.
if (!$form_state->get('user_pass_reset')) {
$protected_values['mail'] = $form['account']['mail']['#title'];
$protected_values['pass'] = $this->t('Password');
$request_new = $this->l($this->t('Reset your password'), new Url('user.pass',
array(), array('attributes' => array('title' => $this->t('Send password reset instructions via e-mail.'))))
);
$current_pass_description = $this->t('Required if you want to change the %mail or %pass below. !request_new.',
array(
'%mail' => $protected_values['mail'],
'%pass' => $protected_values['pass'],
'!request_new' => $request_new,
)
);
}
// The user must enter their current password to change to a new one.
if ($user->id() == $account->id()) {
$form['account']['current_pass'] = array(
'#type' => 'password',
'#title' => $this->t('Current password'),
'#size' => 25,
'#access' => !empty($protected_values),
'#description' => $current_pass_description,
'#access' => !$form_state->get('user_pass_reset'),
'#weight' => -5,
// Do not let web browsers remember this password, since we are
// trying to confirm that the person submitting the form actually
// knows the current one.
'#attributes' => array('autocomplete' => 'off'),
);
$form_state->set('user', $account);
// The user may only change their own password without their current
// password if they logged in via a one-time login link.
if (!$form_state->get('user_pass_reset')) {
$form['account']['current_pass']['#description'] = $this->t('Required if you want to change the %mail or %pass below. <a href=":request_new_url" title="Send password reset instructions via email.">Reset your password</a>.', array(
'%mail' => $form['account']['mail']['#title'],
'%pass' => $this->t('Password'),
':request_new_url' => $this->url('user.pass'),
));
}
}
}
elseif (!$config->get('verify_mail') || $admin) {
@ -190,11 +178,11 @@ abstract class AccountForm extends ContentEntityForm {
}
}
if ($admin) {
$status = $account->isActive();
if ($admin || !$register) {
$status = $account->get('status')->value;
}
else {
$status = $register ? $config->get('register') == USER_REGISTER_VISITORS : $account->isActive();
$status = $config->get('register') == USER_REGISTER_VISITORS ? 1 : 0;
}
$form['account']['status'] = array(
@ -205,7 +193,7 @@ abstract class AccountForm extends ContentEntityForm {
'#access' => $admin,
);
$roles = array_map(array('\Drupal\Component\Utility\SafeMarkup', 'checkPlain'), user_role_names(TRUE));
$roles = array_map(array('\Drupal\Component\Utility\Html', 'escape'), user_role_names(TRUE));
$form['account']['roles'] = array(
'#type' => 'checkboxes',
@ -345,7 +333,8 @@ abstract class AccountForm extends ContentEntityForm {
}
// Set existing password if set in the form state.
if ($current_pass = $form_state->getValue('current_pass')) {
$current_pass = trim($form_state->getValue('current_pass'));
if (strlen($current_pass) > 0) {
$account->setExistingPassword($current_pass);
}

View file

@ -174,7 +174,7 @@ class AccountSettingsForm extends ConfigFormBase {
'#type' => 'radios',
'#title' => $this->t('When cancelling a user account'),
'#default_value' => $config->get('cancel_method'),
'#description' => $this->t('Users with the %select-cancel-method or %administer-users <a href="@permissions-url">permissions</a> can override this default method.', array('%select-cancel-method' => $this->t('Select method for cancelling account'), '%administer-users' => $this->t('Administer users'), '@permissions-url' => $this->url('user.admin_permissions'))),
'#description' => $this->t('Users with the %select-cancel-method or %administer-users <a href=":permissions-url">permissions</a> can override this default method.', array('%select-cancel-method' => $this->t('Select method for cancelling account'), '%administer-users' => $this->t('Administer users'), ':permissions-url' => $this->url('user.admin_permissions'))),
);
$form['registration_cancellation']['user_cancel_method'] += user_cancel_methods();
foreach (Element::children($form['registration_cancellation']['user_cancel_method']) as $key) {
@ -201,7 +201,7 @@ class AccountSettingsForm extends ConfigFormBase {
);
// These email tokens are shared for all settings, so just define
// the list once to help ensure they stay in sync.
$email_token_help = $this->t('Available variables are: [site:name], [site:url], [user:name], [user:mail], [site:login-url], [site:url-brief], [user:edit-url], [user:one-time-login-url], [user:cancel-url].');
$email_token_help = $this->t('Available variables are: [site:name], [site:url], [user:display-name], [user:account-name], [user:mail], [site:login-url], [site:url-brief], [user:edit-url], [user:one-time-login-url], [user:cancel-url].');
$form['email_admin_created'] = array(
'#type' => 'details',

View file

@ -55,8 +55,7 @@ class CurrentUserContext implements ContextProviderInterface {
public function getRuntimeContexts(array $unqualified_context_ids) {
$current_user = $this->userStorage->load($this->account->id());
$context = new Context(new ContextDefinition('entity:user', $this->t('Current user')));
$context->setContextValue($current_user);
$context = new Context(new ContextDefinition('entity:user', $this->t('Current user')), $current_user);
$cacheability = new CacheableMetadata();
$cacheability->setCacheContexts(['user']);
$context->addCacheableDependency($cacheability);

View file

@ -9,7 +9,7 @@ namespace Drupal\user\Controller;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Datetime\DateFormatter;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\user\UserDataInterface;
use Drupal\user\UserInterface;
use Drupal\user\UserStorageInterface;
@ -24,7 +24,7 @@ class UserController extends ControllerBase {
/**
* The date formatter service.
*
* @var \Drupal\Core\Datetime\DateFormatter
* @var \Drupal\Core\Datetime\DateFormatterInterface
*/
protected $dateFormatter;
@ -45,14 +45,14 @@ class UserController extends ControllerBase {
/**
* Constructs a UserController object.
*
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
* The date formatter service.
* @param \Drupal\user\UserStorageInterface $user_storage
* The user storage.
* @param \Drupal\user\UserDataInterface $user_data
* The user data service.
*/
public function __construct(DateFormatter $date_formatter, UserStorageInterface $user_storage, UserDataInterface $user_data) {
public function __construct(DateFormatterInterface $date_formatter, UserStorageInterface $user_storage, UserDataInterface $user_data) {
$this->dateFormatter = $date_formatter;
$this->userStorage = $user_storage;
$this->userData = $user_data;
@ -98,12 +98,12 @@ class UserController extends ControllerBase {
// A different user is already logged in on the computer.
else {
if ($reset_link_user = $this->userStorage->load($uid)) {
drupal_set_message($this->t('Another user (%other_user) is already logged into the site on this computer, but you tried to use a one-time link for user %resetting_user. Please <a href="@logout">logout</a> and try using the link again.',
array('%other_user' => $account->getUsername(), '%resetting_user' => $reset_link_user->getUsername(), '@logout' => $this->url('user.logout'))), 'warning');
drupal_set_message($this->t('Another user (%other_user) is already logged into the site on this computer, but you tried to use a one-time link for user %resetting_user. Please <a href=":logout">logout</a> and try using the link again.',
array('%other_user' => $account->getUsername(), '%resetting_user' => $reset_link_user->getUsername(), ':logout' => $this->url('user.logout'))), 'warning');
}
else {
// Invalid one-time link specifies an unknown user.
drupal_set_message($this->t('The one-time login link you clicked is invalid.'));
drupal_set_message($this->t('The one-time login link you clicked is invalid.'), 'error');
}
return $this->redirect('<front>');
}
@ -209,7 +209,7 @@ class UserController extends ControllerBase {
return batch_process('');
}
else {
drupal_set_message(t('You have tried to use an account cancellation link that has expired. Please request a new one using the form below.'));
drupal_set_message(t('You have tried to use an account cancellation link that has expired. Please request a new one using the form below.'), 'error');
return $this->redirect('entity.user.cancel_form', ['user' => $user->id()], ['absolute' => TRUE]);
}
}

View file

@ -362,7 +362,21 @@ class User extends ContentEntityBase implements UserInterface {
* {@inheritdoc}
*/
public function getUsername() {
$name = $this->get('name')->value ?: \Drupal::config('user.settings')->get('anonymous');
return $this->getAccountName();
}
/**
* {@inheritdoc}
*/
public function getAccountName() {
return $this->get('name')->value ?: '';
}
/**
* {@inheritdoc}
*/
public function getDisplayName() {
$name = $this->getAccountName() ?: \Drupal::config('user.settings')->get('anonymous');
\Drupal::moduleHandler()->alter('user_format_name', $name, $this);
return $name;
}
@ -375,13 +389,6 @@ class User extends ContentEntityBase implements UserInterface {
return $this;
}
/**
* {@inheritdoc}
*/
public function getChangedTime() {
return $this->get('changed')->value;
}
/**
* {@inheritdoc}
*/
@ -393,7 +400,7 @@ class User extends ContentEntityBase implements UserInterface {
* {@inheritdoc}
*/
public function checkExistingPassword(UserInterface $account_unchanged) {
return !empty($this->get('pass')->existing) && \Drupal::service('password')->check(trim($this->get('pass')->existing), $account_unchanged->getPassword());
return strlen($this->get('pass')->existing) > 0 && \Drupal::service('password')->check(trim($this->get('pass')->existing), $account_unchanged->getPassword());
}
/**
@ -411,7 +418,10 @@ class User extends ContentEntityBase implements UserInterface {
$entity_type = $entity_manager->getDefinition('user');
$class = $entity_type->getClass();
static::$anonymousUser = new $class(['uid' => [LanguageInterface::LANGCODE_DEFAULT => 0]], $entity_type->id());
static::$anonymousUser = new $class([
'uid' => [LanguageInterface::LANGCODE_DEFAULT => 0],
'name' => [LanguageInterface::LANGCODE_DEFAULT => ''],
], $entity_type->id());
}
return clone static::$anonymousUser;
}

View file

@ -167,7 +167,7 @@ class UserLoginForm extends FormBase {
public function validateAuthentication(array &$form, FormStateInterface $form_state) {
$password = trim($form_state->getValue('pass'));
$flood_config = $this->config('user.flood');
if (!$form_state->isValueEmpty('name') && !empty($password)) {
if (!$form_state->isValueEmpty('name') && strlen($password) > 0) {
// Do not allow any login from the current user's IP if the limit has been
// reached. Default is 50 failed attempts allowed in one hour. This is
// independent of the per-user limit to catch attempts from one IP to log
@ -224,15 +224,15 @@ class UserLoginForm extends FormBase {
if ($flood_control_triggered = $form_state->get('flood_control_triggered')) {
if ($flood_control_triggered == 'user') {
$form_state->setErrorByName('name', $this->formatPlural($flood_config->get('user_limit'), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => $this->url('user.pass'))));
$form_state->setErrorByName('name', $this->formatPlural($flood_config->get('user_limit'), 'There has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href=":url">request a new password</a>.', 'There have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href=":url">request a new password</a>.', array(':url' => $this->url('user.pass'))));
}
else {
// We did not find a uid, so the limit is IP-based.
$form_state->setErrorByName('name', $this->t('Sorry, too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => $this->url('user.pass'))));
$form_state->setErrorByName('name', $this->t('Too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or <a href=":url">request a new password</a>.', array(':url' => $this->url('user.pass'))));
}
}
else {
$form_state->setErrorByName('name', $this->t('Sorry, unrecognized username or password. <a href="@password">Have you forgotten your password?</a>', array('@password' => $this->url('user.pass', [], array('query' => array('name' => $form_state->getValue('name')))))));
$form_state->setErrorByName('name', $this->t('Unrecognized username or password. <a href=":password">Have you forgotten your password?</a>', array(':password' => $this->url('user.pass', [], array('query' => array('name' => $form_state->getValue('name')))))));
$accounts = $this->userStorage->loadByProperties(array('name' => $form_state->getValue('name')));
if (!empty($accounts)) {
$this->logger('user')->notice('Login attempt failed for %user.', array('%user' => $form_state->getValue('name')));

View file

@ -99,7 +99,7 @@ class UserPasswordForm extends FormBase {
else {
$form['mail'] = array(
'#prefix' => '<p>',
'#markup' => $this->t('Password reset instructions will be sent to your registered e-mail address.'),
'#markup' => $this->t('Password reset instructions will be sent to your registered email address.'),
'#suffix' => '</p>',
);
$form['name']['#default_value'] = $this->getRequest()->query->get('name');
@ -132,7 +132,7 @@ class UserPasswordForm extends FormBase {
}
}
else {
$form_state->setErrorByName('name', $this->t('Sorry, %name is not recognized as a username or an email address.', array('%name' => $name)));
$form_state->setErrorByName('name', $this->t('%name is not recognized as a username or an email address.', array('%name' => $name)));
}
}

View file

@ -77,7 +77,7 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
*/
protected function blockAccess(AccountInterface $account) {
$route_name = $this->routeMatch->getRouteName();
if ($account->isAnonymous() && !in_array($route_name, array('user.register', 'user.login', 'user.logout'))) {
if ($account->isAnonymous() && !in_array($route_name, array('user.login', 'user.logout'))) {
return AccessResult::allowed()
->addCacheContexts(['route.name', 'user.roles:anonymous']);
}
@ -112,7 +112,7 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
}
$items['request_password'] = \Drupal::l($this->t('Reset your password'), new Url('user.pass', array(), array(
'attributes' => array(
'title' => $this->t('Send password reset instructions via e-mail.'),
'title' => $this->t('Send password reset instructions via email.'),
'class' => array('request-password-link'),
),
)));
@ -125,13 +125,4 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
);
}
/**
* {@inheritdoc}
*
* @todo Make cacheable once https://www.drupal.org/node/2351015 lands.
*/
public function getCacheMaxAge() {
return 0;
}
}

View file

@ -33,7 +33,7 @@ class UserRole extends ConditionPluginBase {
'#type' => 'checkboxes',
'#title' => $this->t('When the user has the following roles'),
'#default_value' => $this->configuration['roles'],
'#options' => array_map('\Drupal\Component\Utility\SafeMarkup::checkPlain', user_role_names()),
'#options' => array_map('\Drupal\Component\Utility\Html::escape', user_role_names()),
'#description' => $this->t('If you select no roles, the condition will evaluate to TRUE for all users.'),
);
return parent::buildConfigurationForm($form, $form_state);

View file

@ -10,7 +10,7 @@ namespace Drupal\user\Plugin\EntityReferenceSelection;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
@ -28,7 +28,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
* weight = 1
* )
*/
class UserSelection extends SelectionBase {
class UserSelection extends DefaultSelection {
/**
* The database connection.
@ -120,7 +120,7 @@ class UserSelection extends SelectionBase {
$form['filter']['settings'] = array(
'#type' => 'container',
'#attributes' => array('class' => array('entity_reference-settings')),
'#process' => array('_entity_reference_form_process_merge_parent'),
'#process' => array(array('\Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem', 'formProcessMergeParent')),
);
if ($selection_handler_settings['filter']['type'] == 'role') {
@ -202,7 +202,7 @@ class UserSelection extends SelectionBase {
$value_part->condition('anonymous_name', $condition['value'], $condition['operator']);
$value_part->compile($this->connection, $query);
$or->condition(db_and()
->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + array(':anonymous_name' => user_format_name($this->userStorage->load(0))))
->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + array(':anonymous_name' => \Drupal::config('user.settings')->get('anonymous')))
->condition('base_table.uid', 0)
);
$query->condition($or);

View file

@ -30,10 +30,10 @@ class AuthorFormatter extends EntityReferenceFormatterBase {
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items) {
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = array();
foreach ($this->getEntitiesToView($items) as $delta => $entity) {
foreach ($this->getEntitiesToView($items, $langcode) as $delta => $entity) {
/** @var $referenced_user \Drupal\user\UserInterface */
$elements[$delta] = array(
'#theme' => 'username',

View file

@ -54,7 +54,7 @@ class UserNameFormatter extends FormatterBase {
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items) {
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];
foreach ($items as $delta => $item) {
@ -72,7 +72,7 @@ class UserNameFormatter extends FormatterBase {
}
else {
$elements[$delta] = [
'#markup' => $user->getUsername(),
'#markup' => $user->getDisplayName(),
'#cache' => [
'tags' => $user->getCacheTags(),
],

View file

@ -0,0 +1,91 @@
<?php
/**
* @file
* Contains \Drupal\user\Plugin\Menu\MyAccountMenuLink.
*/
namespace Drupal\user\Plugin\Menu;
use Drupal\Core\Menu\MenuLinkDefault;
use Drupal\Core\Menu\StaticMenuLinkOverridesInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* A menu link that shows "Log in" or "Log out" as appropriate.
*/
class LoginLogoutMenuLink extends MenuLinkDefault {
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* Constructs a new LoginLogoutMenuLink.
*
* @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\Core\Menu\StaticMenuLinkOverridesInterface $static_override
* The static override storage.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, StaticMenuLinkOverridesInterface $static_override, AccountInterface $current_user) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $static_override);
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('menu_link.static.overrides'),
$container->get('current_user')
);
}
/**
* {@inheritdoc}
*/
public function getTitle() {
if ($this->currentUser->isAuthenticated()) {
return $this->t('Log out');
}
else {
return $this->t('Log in');
}
}
/**
* {@inheritdoc}
*/
public function getRouteName() {
if ($this->currentUser->isAuthenticated()) {
return 'user.logout';
}
else {
return 'user.login';
}
}
/**
* {@inheritdoc}
*/
public function getCacheContexts() {
return ['user.roles:authenticated'];
}
}

View file

@ -93,6 +93,8 @@ class UserSearch extends SearchPluginBase implements AccessibleInterface {
$this->moduleHandler = $module_handler;
$this->currentUser = $current_user;
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->addCacheTags(['user_list']);
}
/**
@ -148,12 +150,13 @@ class UserSearch extends SearchPluginBase implements AccessibleInterface {
foreach ($accounts as $account) {
$result = array(
'title' => $account->getUsername(),
'title' => $account->getDisplayName(),
'link' => $account->url('canonical', array('absolute' => TRUE)),
);
if ($this->currentUser->hasPermission('administer users')) {
$result['title'] .= ' (' . $account->getEmail() . ')';
}
$this->addCacheableDependency($account);
$results[] = $result;
}

View file

@ -34,7 +34,7 @@ class UserMailRequired extends Constraint implements ConstraintValidatorInterfac
*
* @var string
*/
public $message = '!name field is required.';
public $message = '@name field is required.';
/**
* @var \Symfony\Component\Validator\ExecutionContextInterface
@ -73,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, ['!name' => Html::escape($account->getFieldDefinition('mail')->getLabel())]);
$this->context->addViolation($this->message, ['@name' => $account->getFieldDefinition('mail')->getLabel()]);
}
}

View file

@ -7,7 +7,7 @@
namespace Drupal\user\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
use Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldConstraint;
/**
* Checks if a user's email address is unique on the site.
@ -17,14 +17,8 @@ use Symfony\Component\Validator\Constraint;
* label = @Translation("User email unique", context = "Validation")
* )
*/
class UserMailUnique extends Constraint {
class UserMailUnique extends UniqueFieldConstraint {
public $message = 'The email address %value is already taken.';
/**
* {@inheritdoc}
*/
public function validatedBy() {
return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
}
}

View file

@ -7,7 +7,7 @@
namespace Drupal\user\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
use Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldConstraint;
/**
* Checks if a user name is unique on the site.
@ -17,14 +17,8 @@ use Symfony\Component\Validator\Constraint;
* label = @Translation("User name unique", context = "Validation"),
* )
*/
class UserNameUnique extends Constraint {
class UserNameUnique extends UniqueFieldConstraint {
public $message = 'The username %value is already taken.';
/**
* {@inheritdoc}
*/
public function validatedBy() {
return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
}
}

View file

@ -40,6 +40,13 @@ class ConvertTokens extends ProcessPluginBase {
'!password' => '',
);
// Given that our source is a database column that could hold a NULL
// value, sometimes that filters down to here. str_replace() cannot
// handle NULLs as the subject, so we reset to an empty string.
if (is_null($value)) {
$value = '';
}
if (is_string($value)) {
return str_replace(array_keys($tokens), $tokens, $value);
}

View file

@ -36,15 +36,6 @@ class UserPictureInstance extends DrupalSqlBase {
)));
}
/**
* {@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}
*/

View file

@ -7,11 +7,12 @@
namespace Drupal\user\Plugin\views\access;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\PermissionHandlerInterface;
use Drupal\views\Plugin\CacheablePluginInterface;
use Drupal\views\Plugin\views\access\AccessPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\Route;
@ -27,7 +28,7 @@ use Symfony\Component\Routing\Route;
* help = @Translation("Access will be granted to users with the specified permission string.")
* )
*/
class Permission extends AccessPluginBase implements CacheablePluginInterface {
class Permission extends AccessPluginBase implements CacheableDependencyInterface {
/**
* Overrides Drupal\views\Plugin\Plugin::$usesOptions.
@ -135,8 +136,8 @@ class Permission extends AccessPluginBase implements CacheablePluginInterface {
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -146,4 +147,11 @@ class Permission extends AccessPluginBase implements CacheablePluginInterface {
return ['user.permissions'];
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}

View file

@ -8,9 +8,10 @@
namespace Drupal\user\Plugin\views\access;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\RoleStorageInterface;
use Drupal\views\Plugin\CacheablePluginInterface;
use Drupal\views\Plugin\views\access\AccessPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\Route;
@ -27,7 +28,7 @@ use Drupal\Core\Session\AccountInterface;
* help = @Translation("Access will be granted to users with any of the specified roles.")
* )
*/
class Role extends AccessPluginBase implements CacheablePluginInterface {
class Role extends AccessPluginBase implements CacheableDependencyInterface {
/**
* Overrides Drupal\views\Plugin\Plugin::$usesOptions.
@ -97,7 +98,7 @@ class Role extends AccessPluginBase implements CacheablePluginInterface {
else {
$rids = user_role_names();
$rid = reset($this->options['role']);
return SafeMarkup::checkPlain($rids[$rid]);
return $rids[$rid];
}
}
@ -115,7 +116,7 @@ class Role extends AccessPluginBase implements CacheablePluginInterface {
'#type' => 'checkboxes',
'#title' => $this->t('Role'),
'#default_value' => $this->options['role'],
'#options' => array_map('\Drupal\Component\Utility\SafeMarkup::checkPlain', user_role_names()),
'#options' => array_map('\Drupal\Component\Utility\Html::escape', user_role_names()),
'#description' => $this->t('Only the checked roles will be able to access this display.'),
);
}
@ -149,8 +150,8 @@ class Role extends AccessPluginBase implements CacheablePluginInterface {
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**
@ -160,5 +161,12 @@ class Role extends AccessPluginBase implements CacheablePluginInterface {
return ['user.roles'];
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return [];
}
}

View file

@ -7,7 +7,8 @@
namespace Drupal\user\Plugin\views\argument_default;
use Drupal\views\Plugin\CacheablePluginInterface;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
/**
@ -20,7 +21,7 @@ use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
* title = @Translation("User ID from logged in user")
* )
*/
class CurrentUser extends ArgumentDefaultPluginBase implements CacheablePluginInterface {
class CurrentUser extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {
public function getArgument() {
return \Drupal::currentUser()->id();
@ -29,8 +30,8 @@ class CurrentUser extends ArgumentDefaultPluginBase implements CacheablePluginIn
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**

View file

@ -7,9 +7,10 @@
namespace Drupal\user\Plugin\views\argument_default;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\views\Plugin\CacheablePluginInterface;
use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
@ -24,7 +25,7 @@ use Drupal\node\NodeInterface;
* title = @Translation("User ID from route context")
* )
*/
class User extends ArgumentDefaultPluginBase implements CacheablePluginInterface {
class User extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {
/**
* The route match.
@ -108,8 +109,8 @@ class User extends ArgumentDefaultPluginBase implements CacheablePluginInterface
/**
* {@inheritdoc}
*/
public function isCacheable() {
return TRUE;
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
/**

View file

@ -65,7 +65,7 @@ class User extends Entity {
$form['roles'] = array(
'#type' => 'checkboxes',
'#title' => $this->t('Restrict to the selected roles'),
'#options' => array_map(array('\Drupal\Component\Utility\SafeMarkup', 'checkPlain'), user_role_names(TRUE)),
'#options' => array_map(array('\Drupal\Component\Utility\Html', 'escape'), user_role_names(TRUE)),
'#default_value' => $this->options['roles'],
'#description' => $this->t('If no roles are selected, users from any role will be allowed.'),
'#states' => array(

View file

@ -7,7 +7,6 @@
namespace Drupal\user\Plugin\views\field;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Database\Connection;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\ViewExecutable;
@ -81,7 +80,7 @@ class Roles extends PrerenderList {
$roles = user_roles();
$result = $this->database->query('SELECT u.entity_id as uid, u.roles_target_id as rid FROM {user__roles} u WHERE u.entity_id IN ( :uids[] ) AND u.roles_target_id IN ( :rids[] )', array(':uids[]' => $uids, ':rids[]' => array_keys($roles)));
foreach ($result as $role) {
$this->items[$role->uid][$role->rid]['role'] = SafeMarkup::checkPlain($roles[$role->rid]->label());
$this->items[$role->uid][$role->rid]['role'] = $roles[$role->rid]->label();
$this->items[$role->uid][$role->rid]['rid'] = $role->rid;
}
// Sort the roles for each user by role weight.

View file

@ -7,7 +7,7 @@
namespace Drupal\user\Plugin\views\filter;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\user\PermissionHandlerInterface;
use Drupal\views\Plugin\views\filter\ManyToOne;
@ -76,7 +76,7 @@ class Permissions extends ManyToOne {
foreach ($permissions as $perm => $perm_item) {
$provider = $perm_item['provider'];
$display_name = $this->moduleHandler->getName($provider);
$this->valueOptions[$display_name][$perm] = SafeMarkup::checkPlain(strip_tags($perm_item['title']));
$this->valueOptions[$display_name][$perm] = Html::escape(strip_tags($perm_item['title']));
}
}
else {

View file

@ -116,7 +116,7 @@ class RegisterForm extends AccountForm {
// New administrative account without notification.
if ($admin && !$notify) {
drupal_set_message($this->t('Created a new user account for <a href="@url">%name</a>. No email has been sent.', array('@url' => $account->url(), '%name' => $account->getUsername())));
drupal_set_message($this->t('Created a new user account for <a href=":url">%name</a>. No email has been sent.', array(':url' => $account->url(), '%name' => $account->getUsername())));
}
// No email verification required; log in user immediately.
elseif (!$admin && !\Drupal::config('user.settings')->get('verify_mail') && $account->isActive()) {
@ -128,13 +128,13 @@ class RegisterForm extends AccountForm {
// No administrator approval required.
elseif ($account->isActive() || $notify) {
if (!$account->getEmail() && $notify) {
drupal_set_message($this->t('The new user <a href="@url">%name</a> was created without an email address, so no welcome message was sent.', array('@url' => $account->url(), '%name' => $account->getUsername())));
drupal_set_message($this->t('The new user <a href=":url">%name</a> was created without an email address, so no welcome message was sent.', array(':url' => $account->url(), '%name' => $account->getUsername())));
}
else {
$op = $notify ? 'register_admin_created' : 'register_no_approval_required';
if (_user_mail_notify($op, $account)) {
if ($notify) {
drupal_set_message($this->t('A welcome message with further instructions has been emailed to the new user <a href="@url">%name</a>.', array('@url' => $account->url(), '%name' => $account->getUsername())));
drupal_set_message($this->t('A welcome message with further instructions has been emailed to the new user <a href=":url">%name</a>.', array(':url' => $account->url(), '%name' => $account->getUsername())));
}
else {
drupal_set_message($this->t('A welcome message with further instructions has been sent to your email address.'));

View file

@ -22,7 +22,7 @@ class RoleAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
switch ($operation) {
case 'delete':
if ($entity->id() == RoleInterface::ANONYMOUS_ID || $entity->id() == RoleInterface::AUTHENTICATED_ID) {
@ -30,7 +30,7 @@ class RoleAccessControlHandler extends EntityAccessControlHandler {
}
default:
return parent::checkAccess($entity, $operation, $langcode, $account);
return parent::checkAccess($entity, $operation, $account);
}
}

View file

@ -87,7 +87,17 @@ class UserNameFormatterTest extends KernelTestBase {
$this->assertEqual(spl_object_hash($user), spl_object_hash($result[0]['#account']));
$result = $user->{$this->fieldName}->view(['type' => 'user_name', 'settings' => ['link_to_entity' => FALSE]]);
$this->assertEqual($user->getUsername(), $result[0]['#markup']);
$this->assertEqual($user->getDisplayName(), $result[0]['#markup']);
$user = User::getAnonymousUser();
$result = $user->{$this->fieldName}->view(['type' => 'user_name']);
$this->assertEqual('username', $result[0]['#theme']);
$this->assertEqual(spl_object_hash($user), spl_object_hash($result[0]['#account']));
$result = $user->{$this->fieldName}->view(['type' => 'user_name', 'settings' => ['link_to_entity' => FALSE]]);
$this->assertEqual($user->getDisplayName(), $result[0]['#markup']);
$this->assertEqual($this->config('user.settings')->get('anonymous'), $result[0]['#markup']);
}
}

View file

@ -7,6 +7,7 @@
namespace Drupal\user\Tests\Migrate;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
/**
@ -17,11 +18,9 @@ use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
class MigrateUserPictureEntityDisplayTest extends MigrateDrupal7TestBase {
/**
* Modules to enable.
*
* @var array
* {@inheritdoc}
*/
static $modules = array('file', 'image');
public static $modules = ['file', 'image'];
/**
* {@inheritdoc}
@ -29,16 +28,18 @@ class MigrateUserPictureEntityDisplayTest extends MigrateDrupal7TestBase {
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');
$this->executeMigrations([
'user_picture_field',
'user_picture_field_instance',
'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');
$component = EntityViewDisplay::load('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

@ -7,6 +7,7 @@
namespace Drupal\user\Tests\Migrate;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
/**
@ -16,23 +17,25 @@ use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
*/
class MigrateUserPictureEntityFormDisplayTest extends MigrateDrupal7TestBase {
static $modules = array('image', 'file');
public static $modules = ['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');
$this->executeMigrations([
'user_picture_field',
'user_picture_field_instance',
'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');
$component = EntityFormDisplay::load('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

@ -18,15 +18,17 @@ use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
*/
class MigrateUserPictureFieldInstanceTest extends MigrateDrupal7TestBase {
static $modules = array('image', 'file');
public static $modules = ['image', 'file'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('user_picture_field');
$this->executeMigration('user_picture_field_instance');
$this->executeMigrations([
'user_picture_field',
'user_picture_field_instance',
]);
}
/**

View file

@ -18,7 +18,7 @@ use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
*/
class MigrateUserPictureFieldTest extends MigrateDrupal7TestBase {
static $modules = array('image', 'file');
public static $modules = ['image', 'file'];
/**
* {@inheritdoc}

View file

@ -7,7 +7,7 @@
namespace Drupal\user\Tests\Migrate;
use Drupal\Core\Database\Database;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
@ -17,86 +17,23 @@ use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
*/
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');
$this->executeMigrations([
'user_profile_field',
'user_profile_field_instance',
'user_profile_entity_display',
]);
}
/**
* Tests migration of user profile fields.
*/
public function testUserProfileFields() {
$display = entity_get_display('user', 'user', 'default');
$display = EntityViewDisplay::load('user.user.default');
// Test a text field.
$component = $display->getComponent('profile_color');

View file

@ -7,7 +7,7 @@
namespace Drupal\user\Tests\Migrate;
use Drupal\Core\Database\Database;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
@ -17,81 +17,23 @@ use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
*/
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');
$this->executeMigrations([
'user_profile_field',
'user_profile_field_instance',
'user_profile_entity_form_display',
]);
}
/**
* Tests migration of user profile fields.
*/
public function testUserProfileEntityFormDisplay() {
$display = entity_get_form_display('user', 'user', 'default');
$display = EntityFormDisplay::load('user.user.default');
// Test a text field.
$component = $display->getComponent('profile_color');

View file

@ -17,22 +17,20 @@ use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
*/
class MigrateUserProfileFieldInstanceTest extends MigrateDrupal6TestBase {
static $modules = array('field', 'link', 'options', 'datetime', 'text');
/**
* {@inheritdoc}
*/
public static $modules = ['field'];
/**
* {@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');
$this->executeMigrations([
'user_profile_field',
'user_profile_field_instance',
]);
}
/**
@ -64,12 +62,10 @@ class MigrateUserProfileFieldInstanceTest extends MigrateDrupal6TestBase {
$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.");
*/
$this->assertIdentical('Blog', $field->label());
$this->assertIdentical("Paste the full URL, including http://, of your personal blog.", $field->getDescription());
// Migrated date field.
$field = FieldConfig::load('user.user.profile_birthdate');
@ -82,27 +78,4 @@ class MigrateUserProfileFieldInstanceTest extends MigrateDrupal6TestBase {
$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

@ -17,8 +17,6 @@ use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
*/
class MigrateUserProfileFieldTest extends MigrateDrupal6TestBase {
static $modules = array('link', 'options', 'datetime', 'text');
/**
* {@inheritdoc}
*/
@ -64,11 +62,9 @@ class MigrateUserProfileFieldTest extends MigrateDrupal6TestBase {
$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');

View file

@ -24,8 +24,7 @@ class MigrateUserConfigsTest extends MigrateDrupal6TestBase {
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d6_user_mail');
$this->executeMigration('d6_user_settings');
$this->executeMigrations(['d6_user_mail', 'd6_user_settings']);
}
/**

View file

@ -26,18 +26,8 @@ class MigrateUserContactSettingsTest extends MigrateDrupal6TestBase {
*/
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->migrateUsers(FALSE);
$this->installSchema('user', ['users_data']);
$this->executeMigration('d6_user_contact_settings');
}

View file

@ -8,6 +8,7 @@
namespace Drupal\user\Tests\Migrate\d6;
use Drupal\file\Entity\File;
use Drupal\migrate\Entity\Migration;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
@ -17,13 +18,6 @@ use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
*/
class MigrateUserPictureFileTest extends MigrateDrupal6TestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('file');
/**
* {@inheritdoc}
*/
@ -33,7 +27,7 @@ class MigrateUserPictureFileTest extends MigrateDrupal6TestBase {
$this->installEntitySchema('file');
/** @var \Drupal\migrate\Entity\MigrationInterface $migration */
$migration = entity_load('migration', 'd6_user_picture_file');
$migration = Migration::load('d6_user_picture_file');
$source = $migration->get('source');
$source['site_path'] = 'core/modules/simpletest';
$migration->set('source', $source);
@ -45,7 +39,7 @@ class MigrateUserPictureFileTest extends MigrateDrupal6TestBase {
*/
public function testUserPictures() {
$file_ids = array();
foreach (entity_load('migration', 'd6_user_picture_file')->getIdMap() as $destination_ids) {
foreach ($this->migration->getIdMap() as $destination_ids) {
$file_ids[] = reset($destination_ids);
}
$files = File::loadMultiple($file_ids);

View file

@ -8,7 +8,6 @@
namespace Drupal\user\Tests\Migrate\d6;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
use Drupal\Core\Database\Database;
use Drupal\user\Entity\User;
/**
@ -18,118 +17,19 @@ use Drupal\user\Entity\User;
*/
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->executeMigrations([
'user_profile_field',
'user_profile_field_instance',
'user_profile_entity_display',
'user_profile_entity_form_display',
]);
$this->migrateUsers(FALSE);
$this->executeMigration('d6_profile_values');
}

View file

@ -7,6 +7,7 @@
namespace Drupal\user\Tests\Migrate\d6;
use Drupal\migrate\Entity\Migration;
use Drupal\user\Entity\Role;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
@ -17,27 +18,12 @@ use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
*/
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');
$this->executeMigrations(['d6_filter_format', 'd6_user_role']);
}
/**
@ -45,22 +31,22 @@ class MigrateUserRoleTest extends MigrateDrupal6TestBase {
*/
public function testUserRole() {
/** @var \Drupal\migrate\entity\Migration $migration */
$migration = entity_load('migration', 'd6_user_role');
$id_map = Migration::load('d6_user_role')->getIdMap();
$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)));
$this->assertIdentical(array($rid), $id_map->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)));
$this->assertIdentical(array($rid), $id_map->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)));
$this->assertIdentical(array('migrate test role 1 test permission', 'use text format full_html', 'use text format php_code'), $migrate_test_role_1->getPermissions());
$this->assertIdentical(array($rid), $id_map->lookupDestinationId(array(3)));
$rid = 'migrate_test_role_2';
$migrate_test_role_2 = Role::load($rid);
$this->assertIdentical(array(
@ -79,13 +65,14 @@ class MigrateUserRoleTest extends MigrateDrupal6TestBase {
'edit own forum content',
'administer nodes',
'access content overview',
'use text format php_code',
), $migrate_test_role_2->getPermissions());
$this->assertIdentical($rid, $migrate_test_role_2->id());
$this->assertIdentical(array($rid), $migration->getIdMap()->lookupDestinationId(array(4)));
$this->assertIdentical(array($rid), $id_map->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)));
$this->assertIdentical(array($rid), $id_map->lookupDestinationId(array(5)));
}
}

View file

@ -7,6 +7,7 @@
namespace Drupal\user\Tests\Migrate\d6;
use Drupal\migrate\Entity\Migration;
use Drupal\user\Entity\User;
use Drupal\file\Entity\File;
use Drupal\Core\Database\Database;
@ -20,20 +21,6 @@ use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
*/
class MigrateUserTest extends MigrateDrupal6TestBase {
/**
* The modules to be enabled during the test.
*
* @var array
*/
static $modules = array(
'link',
'options',
'datetime',
'text',
'file',
'image',
);
/**
* {@inheritdoc}
*/
@ -43,23 +30,7 @@ class MigrateUserTest extends MigrateDrupal6TestBase {
$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(
$file = File::create(array(
'fid' => 2,
'uid' => 2,
'filename' => 'image-test.jpg',
@ -73,7 +44,7 @@ class MigrateUserTest extends MigrateDrupal6TestBase {
file_put_contents($file->getFileUri(), file_get_contents('core/modules/simpletest/files/image-1.png'));
$file->save();
$file = entity_create('file', array(
$file = File::create(array(
'fid' => 8,
'uid' => 8,
'filename' => 'image-test.png',
@ -87,29 +58,7 @@ class MigrateUserTest extends MigrateDrupal6TestBase {
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');
$this->migrateUsers();
}
/**
@ -119,6 +68,7 @@ class MigrateUserTest extends MigrateDrupal6TestBase {
$users = Database::getConnection('default', 'migrate')
->select('users', 'u')
->fields('u')
->condition('uid', 1, '>')
->execute()
->fetchAll();
@ -131,9 +81,9 @@ class MigrateUserTest extends MigrateDrupal6TestBase {
->execute()
->fetchCol();
$roles = array(RoleInterface::AUTHENTICATED_ID);
$migration_role = entity_load('migration', 'd6_user_role');
$id_map = Migration::load('d6_user_role')->getIdMap();
foreach ($rids as $rid) {
$role = $migration_role->getIdMap()->lookupDestinationId(array($rid));
$role = $id_map->lookupDestinationId(array($rid));
$roles[] = reset($role);
}

View file

@ -14,8 +14,6 @@ use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
*/
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.

View file

@ -16,13 +16,6 @@ use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
*/
class MigrateUserFloodTest extends MigrateDrupal7TestBase {
/**
* The modules to be enabled during the test.
*
* @var array
*/
static $modules = array('system');
/**
* {@inheritdoc}
*/

View file

@ -19,13 +19,6 @@ use Drupal\user\RoleInterface;
*/
class MigrateUserRoleTest extends MigrateDrupal7TestBase {
/**
* The modules to be enabled during the test.
*
* @var array
*/
static $modules = array('user');
/**
* {@inheritdoc}
*/

View file

@ -20,11 +20,9 @@ use Drupal\user\UserInterface;
class MigrateUserTest extends MigrateDrupal7TestBase {
/**
* The modules to be enabled during the test.
*
* @var array
* {@inheritdoc}
*/
static $modules = array('file', 'image', 'user');
public static $modules = ['file', 'image'];
/**
* {@inheritdoc}
@ -34,11 +32,12 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
// 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');
$this->executeMigrations([
'user_picture_field',
'user_picture_field_instance',
'd7_user_role',
'd7_user',
]);
}
/**
@ -49,7 +48,7 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
* @param string $label
* The username.
* @param string $mail
* The user's e-mail address.
* The user's email address.
* @param int $access
* The last access time.
* @param int $login
@ -59,7 +58,7 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
* @param string $langcode
* The user account's language code.
* @param string $init
* The user's initial e-mail address.
* The user's initial email address.
* @param string[] $roles
* Role IDs the user account is expected to have.
* @param bool $has_picture

View file

@ -14,8 +14,6 @@ use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
*/
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.

View file

@ -65,11 +65,13 @@ class UserAccountLinksTest extends WebTestBase {
$this->drupalLogout();
$this->drupalGet('<front>');
// For a logged-out user, expect no secondary links.
$menu = $this->xpath('//ul[@class=:menu_class]', array(
// For a logged-out user, expect the secondary menu to have a "Log in" link.
$link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', array(
':menu_class' => 'menu',
':href' => 'user/login',
':text' => 'Log in',
));
$this->assertEqual(count($menu), 0, 'The secondary links menu is not rendered, because none of its menu links are accessible for the anonymous user.');
$this->assertEqual(count($link), 1, 'Log in link is in secondary menu.');
}
/**

View file

@ -39,19 +39,34 @@ class UserBlocksTest extends WebTestBase {
$this->drupalLogout($this->adminUser);
}
/**
* Tests that user login block is hidden from user/login.
*/
function testUserLoginBlockVisibility() {
// Array keyed list where key being the URL address and value being expected
// visibility as boolean type.
$paths = [
'node' => TRUE,
'user/login' => FALSE,
'user/register' => TRUE,
'user/password' => TRUE,
];
foreach ($paths as $path => $expected_visibility) {
$this->drupalGet($path);
$elements = $this->xpath('//div[contains(@class,"block-user-login-block") and @role="form"]');
if ($expected_visibility) {
$this->assertTrue(!empty($elements), 'User login block in path "' . $path . '" should be visible');
}
else {
$this->assertTrue(empty($elements), 'User login block in path "' . $path . '" should not be visible');
}
}
}
/**
* Test the user login block.
*/
function testUserLoginBlock() {
// Make sure the validation error is displayed when try to login with
// invalid username/password.
$edit['name'] = $this->randomMachineName();
$edit['pass'] = $this->randomMachineName();
$this->drupalPostForm('node', $edit, t('Log in'));
$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.
$user = $this->drupalCreateUser(array('administer permissions'));

View file

@ -367,7 +367,7 @@ class UserCancelTest extends WebTestBase {
$storage->resetCache(array($comment->id()));
$test_comment = $storage->load($comment->id());
$this->assertTrue(($test_comment->getOwnerId() == 0 && $test_comment->isPublished()), 'Comment of the user has been attributed to anonymous user.');
$this->assertEqual($test_comment->getAuthorName(), $anonymous_user->getUsername(), 'Comment of the user has been attributed to anonymous user name.');
$this->assertEqual($test_comment->getAuthorName(), $anonymous_user->getDisplayName(), 'Comment of the user has been attributed to anonymous user name.');
// Confirm that the confirmation message made it through to the end user.
$this->assertRaw(t('%name has been deleted.', array('%name' => $account->getUsername())), "Confirmation message displayed to user.");
@ -535,7 +535,7 @@ class UserCancelTest extends WebTestBase {
$this->drupalPostForm(NULL, NULL, t('Cancel accounts'));
$status = TRUE;
foreach ($users as $account) {
$status = $status && (strpos($this->content, t('%name has been deleted.', array('%name' => $account->getUsername()))) !== FALSE);
$status = $status && (strpos($this->content, $account->getUsername() . '</em> has been deleted.') !== FALSE);
$user_storage->resetCache(array($account->id()));
$status = $status && !$user_storage->load($account->id());
}

View file

@ -114,5 +114,19 @@ class UserCreateTest extends WebTestBase {
$user = user_load_by_name($name);
$this->assertEqual($user->isActive(), 'User is not blocked');
}
// Test that the password '0' is considered a password.
// @see https://www.drupal.org/node/2563751.
$name = $this->randomMachineName();
$edit = array(
'name' => $name,
'mail' => $this->randomMachineName() . '@example.com',
'pass[pass1]' => 0,
'pass[pass2]' => 0,
'notify' => FALSE,
);
$this->drupalPostForm('admin/people/create', $edit, t('Create new account'));
$this->assertText("Created a new user account for $name. No email has been sent");
$this->assertNoText('Password field is required');
}
}

View file

@ -85,6 +85,45 @@ class UserEditTest extends WebTestBase {
$config->set('password_strength', FALSE)->save();
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
$this->assertNoRaw(t('Password strength:'), 'The password strength indicator is not displayed.');
// Check that the user status field has the correct value and that it is
// properly displayed.
$admin_user = $this->drupalCreateUser(array('administer users'));
$this->drupalLogin($admin_user);
$this->drupalGet('user/' . $user1->id() . '/edit');
$this->assertNoFieldChecked('edit-status-0');
$this->assertFieldChecked('edit-status-1');
$edit = array('status' => 0);
$this->drupalPostForm('user/' . $user1->id() . '/edit', $edit, t('Save'));
$this->assertText(t('The changes have been saved.'));
$this->assertFieldChecked('edit-status-0');
$this->assertNoFieldChecked('edit-status-1');
$edit = array('status' => 1);
$this->drupalPostForm('user/' . $user1->id() . '/edit', $edit, t('Save'));
$this->assertText(t('The changes have been saved.'));
$this->assertNoFieldChecked('edit-status-0');
$this->assertFieldChecked('edit-status-1');
}
/**
* Tests setting the password to "0".
*
* We discovered in https://www.drupal.org/node/2563751 that logging in with a
* password that is literally "0" was not possible. This test ensures that
* this regression can't happen again.
*/
public function testUserWith0Password() {
$admin = $this->drupalCreateUser(['administer users']);
$this->drupalLogin($admin);
// Create a regular user.
$user1 = $this->drupalCreateUser([]);
$edit = ['pass[pass1]' => '0', 'pass[pass2]' => '0'];
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
$this->assertRaw(t("The changes have been saved."));
}
/**

View file

@ -16,6 +16,13 @@ use Drupal\simpletest\WebTestBase;
*/
class UserEditedOwnAccountTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('user_form_test');
function testUserEditedOwnAccount() {
// Change account setting 'Who can register accounts?' to Administrators
// only.

View file

@ -22,7 +22,7 @@ class UserEntityCallbacksTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('user');
public static $modules = array('user', 'user_hooks_test');
/**
* An authenticated user to use for testing.
@ -55,6 +55,14 @@ class UserEntityCallbacksTest extends WebTestBase {
$name = $this->randomMachineName();
$this->config('user.settings')->set('anonymous', $name)->save();
$this->assertEqual($this->anonymous->label(), $name, 'The variable anonymous should be used for name of uid 0');
$this->assertEqual($this->anonymous->getDisplayName(), $name, 'The variable anonymous should be used for display name of uid 0');
$this->assertEqual($this->anonymous->getUserName(), '', 'The raw anonymous user name should be empty string');
// Set to test the altered username.
\Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE);
$this->assertEqual($this->account->getDisplayName(), '<em>' . $this->account->id() . '</em>', 'The user display name should be altered.');
$this->assertEqual($this->account->getUsername(), $this->account->name->value, 'The user name should not be altered.');
}
}

View file

@ -7,7 +7,7 @@
namespace Drupal\user\Tests;
use Drupal\entity_reference\Tests\EntityReferenceTestTrait;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\field\Entity\FieldConfig;
use Drupal\system\Tests\Entity\EntityUnitTestBase;
@ -34,13 +34,6 @@ class UserEntityReferenceTest extends EntityUnitTestBase {
*/
protected $role2;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('entity_reference', 'user');
/**
* {@inheritdoc}
*/

View file

@ -169,15 +169,15 @@ class UserLoginTest extends WebTestBase {
$this->assertNoFieldByXPath("//input[@name='pass' and @value!='']", NULL, 'Password value attribute is blank.');
if (isset($flood_trigger)) {
if ($flood_trigger == 'user') {
$this->assertRaw(\Drupal::translation()->formatPlural($this->config('user.flood')->get('user_limit'), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => \Drupal::url('user.pass'))));
$this->assertRaw(\Drupal::translation()->formatPlural($this->config('user.flood')->get('user_limit'), 'There has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href=":url">request a new password</a>.', 'There have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href=":url">request a new password</a>.', array(':url' => \Drupal::url('user.pass'))));
}
else {
// No uid, so the limit is IP-based.
$this->assertRaw(t('Sorry, too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => \Drupal::url('user.pass'))));
$this->assertRaw(t('Too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or <a href=":url">request a new password</a>.', array(':url' => \Drupal::url('user.pass'))));
}
}
else {
$this->assertText(t('Sorry, unrecognized username or password. Have you forgotten your password?'));
$this->assertText(t('Unrecognized username or password. Have you forgotten your password?'));
}
}
}

View file

@ -79,7 +79,7 @@ class UserPasswordResetTest extends PageCacheTagsTestBase {
$edit = array('name' => $this->randomMachineName(32));
$this->drupalPostForm(NULL, $edit, t('Submit'));
$this->assertText(t('Sorry, @name is not recognized as a username or an email address.', array('@name' => $edit['name'])), 'Validation error message shown when trying to request password for invalid account.');
$this->assertText(t('@name is not recognized as a username or an email address.', array('@name' => $edit['name'])), 'Validation error message shown when trying to request password for invalid account.');
$this->assertEqual(count($this->drupalGetMails(array('id' => 'user_password_reset'))), 0, 'No email was sent when requesting a password for an invalid account.');
// Reset the password by username via the password reset page.
@ -220,8 +220,8 @@ class UserPasswordResetTest extends PageCacheTagsTestBase {
'pass' => $this->randomMachineName(),
);
$this->drupalPostForm('user/login', $edit, t('Log in'));
$this->assertRaw(t('Sorry, unrecognized username or password. <a href="@password">Have you forgotten your password?</a>',
array('@password' => \Drupal::url('user.pass', [], array('query' => array('name' => $edit['name']))))));
$this->assertRaw(t('Unrecognized username or password. <a href=":password">Have you forgotten your password?</a>',
array(':password' => \Drupal::url('user.pass', [], array('query' => array('name' => $edit['name']))))));
unset($edit['pass']);
$this->drupalGet('user/password', array('query' => array('name' => $edit['name'])));
$this->assertFieldByName('name', $edit['name'], 'User name found.');

View file

@ -7,6 +7,7 @@
namespace Drupal\user\Tests;
use Drupal\image\Entity\ImageStyle;
use Drupal\simpletest\WebTestBase;
use Drupal\file\Entity\File;
@ -97,9 +98,15 @@ class UserPictureTest extends WebTestBase {
// Enable user pictures on nodes.
$this->config('system.theme.global')->set('features.node_user_picture', TRUE)->save();
// Verify that the image is displayed on the user account page.
$image_style_id = $this->config('core.entity_view_display.user.user.compact')->get('content.user_picture.settings.image_style');
$style = ImageStyle::load($image_style_id);
$image_url = $style->buildUrl($file->getfileUri());
$alt_text = 'Profile picture for user ' . $this->webUser->getUsername();
// Verify that the image is displayed on the node page.
$this->drupalGet('node/' . $node->id());
$this->assertRaw(file_uri_target($file->getFileUri()), 'User picture found on node page.');
$elements = $this->cssSelect('.node__meta .field--name-user-picture img[alt="' . $alt_text . '"][src="' . $image_url . '"]');
$this->assertEqual(count($elements), 1, 'User picture with alt text found on node page.');
// Enable user pictures on comments, instead of nodes.
$this->config('system.theme.global')
@ -111,7 +118,8 @@ class UserPictureTest extends WebTestBase {
'comment_body[0][value]' => $this->randomString(),
);
$this->drupalPostForm('comment/reply/node/' . $node->id() . '/comment', $edit, t('Save'));
$this->assertRaw(file_uri_target($file->getFileUri()), 'User picture found on comment.');
$elements = $this->cssSelect('.comment__meta .field--name-user-picture img[alt="' . $alt_text . '"][src="' . $image_url . '"]');
$this->assertEqual(count($elements), 1, 'User picture with alt text found on the comment.');
// Disable user pictures on comments and nodes.
$this->config('system.theme.global')

View file

@ -58,7 +58,7 @@ class UserRolesAssignmentTest extends WebTestBase {
"roles[$rid]" => $rid,
);
$this->drupalPostForm('admin/people/create', $edit, t('Create new account'));
$this->assertText(t('Created a new user account for !name.', array('!name' => $edit['name'])));
$this->assertText(t('Created a new user account for @name.', array('@name' => $edit['name'])));
// Get the newly added user.
$account = user_load_by_name($edit['name']);

View file

@ -7,7 +7,7 @@
namespace Drupal\user\Tests;
use Drupal\Component\Utility\Html;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\simpletest\WebTestBase;
@ -26,8 +26,11 @@ class UserTokenReplaceTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('language');
public static $modules = array('language', 'user_hooks_test');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
ConfigurableLanguage::createFromLangcode('de')->save();
@ -44,6 +47,9 @@ class UserTokenReplaceTest extends WebTestBase {
'language' => $language_interface,
);
\Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE);
\Drupal::state()->set('user_hooks_test_user_format_name_alter_safe', TRUE);
// Create two users and log them in one after another.
$user1 = $this->drupalCreateUser(array());
$user2 = $this->drupalCreateUser(array());
@ -54,23 +60,29 @@ class UserTokenReplaceTest extends WebTestBase {
$account = User::load($user1->id());
$global_account = User::load(\Drupal::currentUser()->id());
// Generate and test sanitized tokens.
// Generate and test tokens.
$tests = array();
$tests['[user:uid]'] = $account->id();
$tests['[user:name]'] = Html::escape(user_format_name($account));
$tests['[user:mail]'] = Html::escape($account->getEmail());
$tests['[user:name]'] = $account->getAccountName();
$tests['[user:account-name]'] = $account->getAccountName();
$tests['[user:display-name]'] = $account->getDisplayName();
$tests['[user:mail]'] = $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]'] = Html::escape(user_format_name($global_account));
$tests['[current-user:name]'] = $global_account->getAccountName();
$tests['[current-user:account-name]'] = $global_account->getAccountName();
$tests['[current-user:display-name]'] = $global_account->getDisplayName();
$base_bubbleable_metadata = BubbleableMetadata::createFromObject($account);
$metadata_tests = [];
$metadata_tests['[user:uid]'] = $base_bubbleable_metadata;
$metadata_tests['[user:name]'] = $base_bubbleable_metadata;
$metadata_tests['[user:account-name]'] = $base_bubbleable_metadata;
$metadata_tests['[user:display-name]'] = $base_bubbleable_metadata;
$metadata_tests['[user:mail]'] = $base_bubbleable_metadata;
$metadata_tests['[user:url]'] = $base_bubbleable_metadata;
$metadata_tests['[user:edit-url]'] = $base_bubbleable_metadata;
@ -86,14 +98,16 @@ class UserTokenReplaceTest extends WebTestBase {
$metadata_tests['[user:created]'] = $bubbleable_metadata;
$metadata_tests['[user:created:short]'] = $bubbleable_metadata;
$metadata_tests['[current-user:name]'] = $base_bubbleable_metadata->merge(BubbleableMetadata::createFromObject($global_account)->addCacheContexts(['user']));
$metadata_tests['[current-user:account-name]'] = $base_bubbleable_metadata->merge(BubbleableMetadata::createFromObject($global_account)->addCacheContexts(['user']));
$metadata_tests['[current-user:display-name]'] = $base_bubbleable_metadata->merge(BubbleableMetadata::createFromObject($global_account)->addCacheContexts(['user']));
// Test to make sure that we generated something for each token.
$this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
foreach ($tests as $input => $expected) {
$bubbleable_metadata = new BubbleableMetadata();
$output = $token_service->replace($input, array('user' => $account), array('langcode' => $language_interface->getId()), $bubbleable_metadata);
$this->assertEqual($output, $expected, format_string('Sanitized user token %token replaced.', array('%token' => $input)));
$output = $token_service->replace($input, ['user' => $account], ['langcode' => $language_interface->getId()], $bubbleable_metadata);
$this->assertEqual($output, $expected, new FormattableMarkup('User token %token replaced.', ['%token' => $input]));
$this->assertEqual($bubbleable_metadata, $metadata_tests[$input]);
}
@ -101,14 +115,14 @@ class UserTokenReplaceTest extends WebTestBase {
$anonymous_user = User::load(0);
$tests = [];
$tests['[user:uid]'] = t('not yet assigned');
$tests['[user:name]'] = Html::escape(user_format_name($anonymous_user));
$tests['[user:display-name]'] = $anonymous_user->getDisplayName();
$base_bubbleable_metadata = BubbleableMetadata::createFromObject($anonymous_user);
$metadata_tests = [];
$metadata_tests['[user:uid]'] = $base_bubbleable_metadata;
$bubbleable_metadata = clone $base_bubbleable_metadata;
$bubbleable_metadata->addCacheableDependency(\Drupal::config('user.settings'));
$metadata_tests['[user:name]'] = $bubbleable_metadata;
$metadata_tests['[user:display-name]'] = $bubbleable_metadata;
foreach ($tests as $input => $expected) {
$bubbleable_metadata = new BubbleableMetadata();
@ -117,17 +131,6 @@ class UserTokenReplaceTest extends WebTestBase {
$this->assertEqual($bubbleable_metadata, $metadata_tests[$input]);
}
// Generate and test unsanitized tokens.
$tests = [];
$tests['[user:name]'] = user_format_name($account);
$tests['[user:mail]'] = $account->getEmail();
$tests['[current-user:name]'] = user_format_name($global_account);
foreach ($tests as $input => $expected) {
$output = $token_service->replace($input, array('user' => $account), array('langcode' => $language_interface->getId(), 'sanitize' => FALSE));
$this->assertEqual($output, $expected, format_string('Unsanitized user token %token replaced.', array('%token' => $input)));
}
// Generate login and cancel link.
$tests = array();
$tests['[user:one-time-login-url]'] = user_pass_reset_url($account);
@ -136,7 +139,7 @@ class UserTokenReplaceTest extends WebTestBase {
// Generate tokens with interface language.
$link = \Drupal::url('user.page', [], array('absolute' => TRUE));
foreach ($tests as $input => $expected) {
$output = $token_service->replace($input, array('user' => $account), array('langcode' => $language_interface->getId(), 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
$output = $token_service->replace($input, ['user' => $account], ['langcode' => $language_interface->getId(), 'callback' => 'user_mail_tokens', 'clear' => TRUE]);
$this->assertTrue(strpos($output, $link) === 0, 'Generated URL is in interface language.');
}
@ -145,7 +148,7 @@ class UserTokenReplaceTest extends WebTestBase {
$account->save();
$link = \Drupal::url('user.page', [], array('language' => \Drupal::languageManager()->getLanguage($account->getPreferredLangcode()), 'absolute' => TRUE));
foreach ($tests as $input => $expected) {
$output = $token_service->replace($input, array('user' => $account), array('callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
$output = $token_service->replace($input, ['user' => $account], ['callback' => 'user_mail_tokens', 'clear' => TRUE]);
$this->assertTrue(strpos($output, $link) === 0, "Generated URL is in the user's preferred language.");
}
@ -153,9 +156,17 @@ class UserTokenReplaceTest extends WebTestBase {
$link = \Drupal::url('user.page', [], array('language' => \Drupal::languageManager()->getLanguage('de'), 'absolute' => TRUE));
foreach ($tests as $input => $expected) {
foreach (array($user1, $user2) as $account) {
$output = $token_service->replace($input, array('user' => $account), array('langcode' => 'de', 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
$output = $token_service->replace($input, ['user' => $account], ['langcode' => 'de', 'callback' => 'user_mail_tokens', 'clear' => TRUE]);
$this->assertTrue(strpos($output, $link) === 0, "Generated URL in in the requested language.");
}
}
// Generate user display name tokens when safe markup is returned.
// @see user_hooks_test_user_format_name_alter()
\Drupal::state()->set('user_hooks_test_user_format_name_alter_safe', TRUE);
$input = '[user:display-name] [current-user:display-name]';
$expected = "<em>{$user1->id()}</em> <em>{$user2->id()}</em>";
$output = $token_service->replace($input, ['user' => $user1]);
$this->assertEqual($output, $expected, new FormattableMarkup('User token %token does not escape safe markup.', ['%token' => 'display-name']));
}
}

View file

@ -134,9 +134,9 @@ class UserValidationTest extends KernelTestBase {
$this->assertEqual($violations[0]->getMessage(), t('The email address %mail is already taken.', array('%mail' => 'existing@example.com')));
$user->set('mail', NULL);
$violations = $user->validate();
$this->assertEqual(count($violations), 1, 'E-mail addresses may not be removed');
$this->assertEqual(count($violations), 1, 'Email addresses may not be removed');
$this->assertEqual($violations[0]->getPropertyPath(), 'mail');
$this->assertEqual($violations[0]->getMessage(), t('!name field is required.', array('!name' => $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

@ -7,6 +7,7 @@
namespace Drupal\user\Tests\Views;
use Drupal\Core\Cache\Cache;
use Drupal\user\Plugin\views\access\Role;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Views;
@ -43,7 +44,7 @@ class AccessRoleTest extends AccessTestBase {
'config' => ['user.role.' . $this->normalRole],
'module' => ['user'],
];
$this->assertIdentical($expected, $view->calculateDependencies());
$this->assertIdentical($expected, $view->calculateDependencies()->getDependencies());
$executable = Views::executableFactory()->get($view);
$executable->setDisplay('page_1');
@ -58,10 +59,12 @@ class AccessRoleTest extends AccessTestBase {
$this->drupalLogin($this->webUser);
$this->drupalGet('test-role');
$this->assertResponse(403);
$this->assertCacheContext('user.roles');
$this->drupalLogin($this->normalUser);
$this->drupalGet('test-role');
$this->assertResponse(200);
$this->assertCacheContext('user.roles');
// Test allowing multiple roles.
$view = Views::getView('test_access_role')->storage;
@ -81,16 +84,19 @@ class AccessRoleTest extends AccessTestBase {
'config' => $roles,
'module' => ['user'],
];
$this->assertIdentical($expected, $view->calculateDependencies());
$this->assertIdentical($expected, $view->calculateDependencies()->getDependencies());
$this->drupalLogin($this->webUser);
$this->drupalGet('test-role');
$this->assertResponse(403);
$this->assertCacheContext('user.roles');
$this->drupalLogout();
$this->drupalGet('test-role');
$this->assertResponse(200);
$this->assertCacheContext('user.roles');
$this->drupalLogin($this->normalUser);
$this->drupalGet('test-role');
$this->assertResponse(200);
$this->assertCacheContext('user.roles');
}
/**
@ -112,17 +118,25 @@ class AccessRoleTest extends AccessTestBase {
/** @var \Drupal\Core\Session\AccountSwitcherInterface $account_switcher */
$account_switcher = \Drupal::service('account_switcher');
// First access as user without access.
// First access as user with access.
$build = DisplayPluginBase::buildBasicRenderable('test_access_role', 'default');
$account_switcher->switchTo($this->normalUser);
$result = $renderer->renderPlain($build);
$this->assertTrue(in_array('user.roles', $build['#cache']['contexts']));
$this->assertEqual(['config:views.view.test_access_role'], $build['#cache']['tags']);
$this->assertEqual(Cache::PERMANENT, $build['#cache']['max-age']);
$this->assertNotEqual($result, '');
// Then with access.
// Then without access.
$build = DisplayPluginBase::buildBasicRenderable('test_access_role', 'default');
$account_switcher->switchTo($this->webUser);
$result = $renderer->renderPlain($build);
// @todo Fix this in https://www.drupal.org/node/2551037,
// DisplayPluginBase::applyDisplayCachablityMetadata() is not invoked when
// using buildBasicRenderable() and a Views access plugin returns FALSE.
//$this->assertTrue(in_array('user.roles', $build['#cache']['contexts']));
//$this->assertEqual([], $build['#cache']['tags']);
$this->assertEqual(Cache::PERMANENT, $build['#cache']['max-age']);
$this->assertEqual($result, '');
}

View file

@ -0,0 +1,73 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Views\FilterPermissionUiTest.
*/
namespace Drupal\user\Tests\Views;
use Drupal\views\Tests\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
/**
* Tests the permission field handler ui.
*
* @group user
* @see \Drupal\user\Plugin\views\filter\Permissions
*/
class FilterPermissionUiTest extends ViewTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['test_filter_permission'];
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['user', 'user_test_views', 'views_ui'];
protected function setUp() {
parent::setUp(TRUE);
ViewTestData::createTestViews(get_class($this), array('user_test_views'));
$this->enableViewsTestModule();
}
/**
* Tests basic filter handler settings in the UI.
*/
public function testHandlerUI() {
$this->drupalLogin($this->drupalCreateUser(['administer views', 'administer users']));
$this->drupalGet('admin/structure/views/view/test_filter_permission/edit/default');
// Verify that the handler summary is correctly displaying the selected
// permission.
$this->assertLink('User: Permission (= View user information)');
$this->drupalPostForm(NULL, [], 'Save');
// Verify that we can save the view.
$this->assertNoText('No valid values found on filter: User: Permission.');
$this->assertText('The view test_filter_permission has been saved.');
// Verify that the handler summary is also correct when multiple values are
// selected in the filter.
$edit = [
'options[value][]' => [
'access user profiles',
'administer views',
],
];
$this->drupalPostForm('admin/structure/views/nojs/handler/test_filter_permission/default/filter/permission', $edit, 'Apply');
$this->assertLink('User: Permission (or View us…)');
$this->drupalPostForm(NULL, [], 'Save');
// Verify that we can save the view.
$this->assertNoText('No valid values found on filter: User: Permission.');
$this->assertText('The view test_filter_permission has been saved.');
}
}

View file

@ -7,6 +7,7 @@
namespace Drupal\user\Tests\Views;
use Drupal\Component\Utility\Html;
use Drupal\views\Views;
use Drupal\user\Entity\User;
@ -28,7 +29,7 @@ class HandlerFieldRoleTest extends UserTestBase {
public function testRole() {
// Create a couple of roles for the view.
$rolename_a = 'a' . $this->randomMachineName(8);
$this->drupalCreateRole(array('access content'), $rolename_a, $rolename_a, 9);
$this->drupalCreateRole(array('access content'), $rolename_a, '<em>' . $rolename_a . '</em>', 9);
$rolename_b = 'b' . $this->randomMachineName(8);
$this->drupalCreateRole(array('access content'), $rolename_b, $rolename_b, 8);
@ -42,16 +43,10 @@ class HandlerFieldRoleTest extends UserTestBase {
$user->addRole($rolename_b);
$user->save();
debug(db_query('SELECT * FROM {user__roles}')->fetchAll());
$view = Views::getView('test_views_handler_field_role');
$this->executeView($view);
// The role field is populated during preRender.
$view->field['roles_target_id']->preRender($view->result);
$render = $view->field['roles_target_id']->advancedRender($view->result[0]);
$this->assertEqual($rolename_b . $rolename_a, $render, 'View test_views_handler_field_role renders role assigned to user in the correct order.');
$this->assertFalse(strpos($render, $rolename_not_assigned), 'View test_views_handler_field_role does not render a role not assigned to a user.');
$this->drupalLogin($this->createUser(['access user profiles']));
$this->drupalGet('/test-views-handler-field-role');
$this->assertText($rolename_b . Html::escape('<em>' . $rolename_a . '</em>'), 'View test_views_handler_field_role renders role assigned to user in the correct order and markup in role names is escaped.');
$this->assertNoText($rolename_not_assigned, 'View test_views_handler_field_role does not render a role not assigned to a user.');
}
}

View file

@ -29,7 +29,8 @@ class HandlerFieldUserNameTest extends UserTestBase {
/** @var \Drupal\Core\Render\RendererInterface $renderer */
$renderer = \Drupal::service('renderer');
$this->drupalLogin($this->drupalCreateUser(array('access user profiles')));
$new_user = $this->drupalCreateUser(array('access user profiles'));
$this->drupalLogin($new_user);
// Set defaults.
$view = Views::getView('test_views_handler_field_user_name');
@ -48,24 +49,18 @@ class HandlerFieldUserNameTest extends UserTestBase {
});
$this->assertTrue(strpos($render, $anon_name) !== FALSE, 'For user 0 it should use the default anonymous name by default.');
$username = $this->randomMachineName();
$view->result[0]->_entity->setUsername($username);
$view->result[0]->_entity->uid->value = 1;
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
return $view->field['name']->advancedRender($view->result[0]);
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view, $new_user) {
return $view->field['name']->advancedRender($view->result[$new_user->id()]);
});
$this->assertTrue(strpos($render, $username) !== FALSE, 'If link to user is checked the username should be part of the output.');
$this->assertTrue(strpos($render, 'user/1') !== FALSE, 'If link to user is checked the link to the user should appear as well.');
$this->assertTrue(strpos($render, $new_user->getDisplayName()) !== FALSE, 'If link to user is checked the username should be part of the output.');
$this->assertTrue(strpos($render, 'user/' . $new_user->id()) !== FALSE, 'If link to user is checked the link to the user should appear as well.');
$view->field['name']->options['link_to_user'] = FALSE;
$view->field['name']->options['type'] = 'string';
$username = $this->randomMachineName();
$view->result[0]->_entity->setUsername($username);
$view->result[0]->_entity->uid->value = 1;
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
return $view->field['name']->advancedRender($view->result[0]);
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view, $new_user) {
return $view->field['name']->advancedRender($view->result[$new_user->id()]);
});
$this->assertEqual($render, $username, 'If the user is not linked the username should be printed out for a normal user.');
$this->assertEqual($render, $new_user->getDisplayName(), 'If the user is not linked the username should be printed out for a normal user.');
}

View file

@ -24,7 +24,7 @@ class UserAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** @var \Drupal\user\UserInterface $entity*/
// The anonymous user's profile can neither be viewed, updated nor deleted.

View file

@ -48,7 +48,7 @@ class UserAuth implements UserAuthInterface {
public function authenticate($username, $password) {
$uid = FALSE;
if (!empty($username) && !empty($password)) {
if (!empty($username) && strlen($password) > 0) {
$account_search = $this->entityManager->getStorage('user')->loadByProperties(array('name' => $username));
if ($account = reset($account_search)) {

View file

@ -7,7 +7,7 @@
namespace Drupal\user;
use Drupal\Core\Datetime\DateFormatter;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityListBuilder;
use Drupal\Core\Entity\EntityStorageInterface;
@ -33,7 +33,7 @@ class UserListBuilder extends EntityListBuilder {
/**
* The date formatter service.
*
* @var \Drupal\Core\Datetime\DateFormatter
* @var \Drupal\Core\Datetime\DateFormatterInterface
*/
protected $dateFormatter;
@ -53,12 +53,12 @@ class UserListBuilder extends EntityListBuilder {
* The entity storage class.
* @param \Drupal\Core\Entity\Query\QueryFactory $query_factory
* The entity query factory.
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
* The date formatter service.
* @param \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination
* The redirect destination service.
*/
public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, QueryFactory $query_factory, DateFormatter $date_formatter, RedirectDestinationInterface $redirect_destination) {
public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, QueryFactory $query_factory, DateFormatterInterface $date_formatter, RedirectDestinationInterface $redirect_destination) {
parent::__construct($entity_type, $storage);
$this->queryFactory = $query_factory;
$this->dateFormatter = $date_formatter;