updated core to 8.6.1 via composer
This commit is contained in:
@@ -6,7 +6,7 @@ use Drupal\Component\Datetime\TimeInterface;
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Core\Entity\ContentEntityForm;
|
||||
use Drupal\Core\Entity\EntityConstraintViolationListInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityRepositoryInterface;
|
||||
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
@@ -31,8 +31,8 @@ abstract class AccountForm extends ContentEntityForm {
|
||||
/**
|
||||
* Constructs a new EntityForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
|
||||
* The entity repository.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
|
||||
@@ -40,8 +40,8 @@ abstract class AccountForm extends ContentEntityForm {
|
||||
* @param \Drupal\Component\Datetime\TimeInterface $time
|
||||
* The time service.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL) {
|
||||
parent::__construct($entity_manager, $entity_type_bundle_info, $time);
|
||||
public function __construct(EntityRepositoryInterface $entity_repository, LanguageManagerInterface $language_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL) {
|
||||
parent::__construct($entity_repository, $entity_type_bundle_info, $time);
|
||||
$this->languageManager = $language_manager;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ abstract class AccountForm extends ContentEntityForm {
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager'),
|
||||
$container->get('entity.repository'),
|
||||
$container->get('language_manager'),
|
||||
$container->get('entity_type.bundle.info'),
|
||||
$container->get('datetime.time')
|
||||
@@ -347,7 +347,7 @@ abstract class AccountForm extends ContentEntityForm {
|
||||
'timezone',
|
||||
'langcode',
|
||||
'preferred_langcode',
|
||||
'preferred_admin_langcode'
|
||||
'preferred_admin_langcode',
|
||||
], parent::getEditedFieldNames($form_state));
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ abstract class AccountForm extends ContentEntityForm {
|
||||
'timezone',
|
||||
'langcode',
|
||||
'preferred_langcode',
|
||||
'preferred_admin_langcode'
|
||||
'preferred_admin_langcode',
|
||||
];
|
||||
foreach ($violations->getByFields($field_names) as $violation) {
|
||||
list($field_name) = explode('.', $violation->getPropertyPath(), 2);
|
||||
|
||||
@@ -154,13 +154,13 @@ class AccountSettingsForm extends ConfigFormBase {
|
||||
USER_REGISTER_ADMINISTRATORS_ONLY => $this->t('Administrators only'),
|
||||
USER_REGISTER_VISITORS => $this->t('Visitors'),
|
||||
USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL => $this->t('Visitors, but administrator approval is required'),
|
||||
]
|
||||
],
|
||||
];
|
||||
$form['registration_cancellation']['user_email_verification'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Require email verification when a visitor creates an account'),
|
||||
'#default_value' => $config->get('verify_mail'),
|
||||
'#description' => $this->t('New users will be required to validate their email address prior to logging into the site, and will be assigned a system-generated password. With this setting disabled, users will be logged in immediately upon registering, and may select their own passwords during registration.')
|
||||
'#description' => $this->t('New users will be required to validate their email address prior to logging into the site, and will be assigned a system-generated password. With this setting disabled, users will be logged in immediately upon registering, and may select their own passwords during registration.'),
|
||||
];
|
||||
$form['registration_cancellation']['user_password_strength'] = [
|
||||
'#type' => 'checkbox',
|
||||
|
||||
@@ -4,9 +4,8 @@ namespace Drupal\user\ContextProvider;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Plugin\Context\Context;
|
||||
use Drupal\Core\Plugin\Context\ContextDefinition;
|
||||
use Drupal\Core\Plugin\Context\ContextProviderInterface;
|
||||
use Drupal\Core\Plugin\Context\EntityContext;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
|
||||
@@ -56,7 +55,7 @@ class CurrentUserContext implements ContextProviderInterface {
|
||||
$current_user->_skipProtectedUserFieldConstraint = TRUE;
|
||||
}
|
||||
|
||||
$context = new Context(new ContextDefinition('entity:user', $this->t('Current user')), $current_user);
|
||||
$context = EntityContext::fromEntity($current_user, $this->t('Current user'));
|
||||
$cacheability = new CacheableMetadata();
|
||||
$cacheability->setCacheContexts(['user']);
|
||||
$context->addCacheableDependency($cacheability);
|
||||
|
||||
@@ -120,12 +120,17 @@ class UserController extends ControllerBase {
|
||||
else {
|
||||
/** @var \Drupal\user\UserInterface $reset_link_user */
|
||||
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">log out</a> and try using the link again.',
|
||||
['%other_user' => $account->getUsername(), '%resetting_user' => $reset_link_user->getUsername(), ':logout' => $this->url('user.logout')]), 'warning');
|
||||
$this->messenger()
|
||||
->addWarning($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">log out</a> and try using the link again.',
|
||||
[
|
||||
'%other_user' => $account->getUsername(),
|
||||
'%resetting_user' => $reset_link_user->getUsername(),
|
||||
':logout' => $this->url('user.logout'),
|
||||
]));
|
||||
}
|
||||
else {
|
||||
// Invalid one-time link specifies an unknown user.
|
||||
drupal_set_message($this->t('The one-time login link you clicked is invalid.'), 'error');
|
||||
$this->messenger()->addError($this->t('The one-time login link you clicked is invalid.'));
|
||||
}
|
||||
return $this->redirect('<front>');
|
||||
}
|
||||
@@ -218,13 +223,13 @@ class UserController extends ControllerBase {
|
||||
$timeout = $this->config('user.settings')->get('password_reset_timeout');
|
||||
// No time out for first time login.
|
||||
if ($user->getLastLoginTime() && $current - $timestamp > $timeout) {
|
||||
drupal_set_message($this->t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'), 'error');
|
||||
$this->messenger()->addError($this->t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'));
|
||||
return $this->redirect('user.pass');
|
||||
}
|
||||
elseif ($user->isAuthenticated() && ($timestamp >= $user->getLastLoginTime()) && ($timestamp <= $current) && Crypt::hashEquals($hash, user_pass_rehash($user, $timestamp))) {
|
||||
user_login_finalize($user);
|
||||
$this->logger->notice('User %name used one-time login link at time %timestamp.', ['%name' => $user->getDisplayName(), '%timestamp' => $timestamp]);
|
||||
drupal_set_message($this->t('You have just used your one-time login link. It is no longer necessary to use this link to log in. Please change your password.'));
|
||||
$this->messenger()->addStatus($this->t('You have just used your one-time login link. It is no longer necessary to use this link to log in. Please change your password.'));
|
||||
// Let the user's password be changed without the current password
|
||||
// check.
|
||||
$token = Crypt::randomBytesBase64(55);
|
||||
@@ -239,7 +244,7 @@ class UserController extends ControllerBase {
|
||||
);
|
||||
}
|
||||
|
||||
drupal_set_message($this->t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'error');
|
||||
$this->messenger()->addError($this->t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'));
|
||||
return $this->redirect('user.pass');
|
||||
}
|
||||
|
||||
@@ -268,7 +273,7 @@ class UserController extends ControllerBase {
|
||||
* NULL.
|
||||
*/
|
||||
public function userTitle(UserInterface $user = NULL) {
|
||||
return $user ? ['#markup' => $user->getUsername(), '#allowed_tags' => Xss::getHtmlTagList()] : '';
|
||||
return $user ? ['#markup' => $user->getDisplayName(), '#allowed_tags' => Xss::getHtmlTagList()] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -312,10 +317,10 @@ class UserController extends ControllerBase {
|
||||
// Since user_cancel() is not invoked via Form API, batch processing
|
||||
// needs to be invoked manually and should redirect to the front page
|
||||
// after completion.
|
||||
return batch_process('');
|
||||
return batch_process('<front>');
|
||||
}
|
||||
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.'), 'error');
|
||||
$this->messenger()->addError($this->t('You have tried to use an account cancellation link that has expired. Please request a new one using the form below.'));
|
||||
return $this->redirect('entity.user.cancel_form', ['user' => $user->id()], ['absolute' => TRUE]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,13 @@ use Drupal\user\RoleInterface;
|
||||
* @ConfigEntityType(
|
||||
* id = "user_role",
|
||||
* label = @Translation("Role"),
|
||||
* label_collection = @Translation("Roles"),
|
||||
* label_singular = @Translation("role"),
|
||||
* label_plural = @Translation("roles"),
|
||||
* label_count = @PluralTranslation(
|
||||
* singular = "@count role",
|
||||
* plural = "@count roles",
|
||||
* ),
|
||||
* handlers = {
|
||||
* "storage" = "Drupal\user\RoleStorage",
|
||||
* "access" = "Drupal\user\RoleAccessControlHandler",
|
||||
|
||||
@@ -22,6 +22,13 @@ use Drupal\user\UserInterface;
|
||||
* @ContentEntityType(
|
||||
* id = "user",
|
||||
* label = @Translation("User"),
|
||||
* label_collection = @Translation("Users"),
|
||||
* label_singular = @Translation("user"),
|
||||
* label_plural = @Translation("users"),
|
||||
* label_count = @PluralTranslation(
|
||||
* singular = "@count user",
|
||||
* plural = "@count users",
|
||||
* ),
|
||||
* handlers = {
|
||||
* "storage" = "Drupal\user\UserStorage",
|
||||
* "storage_schema" = "Drupal\user\UserStorageSchema",
|
||||
@@ -348,6 +355,7 @@ class User extends ContentEntityBase implements UserInterface {
|
||||
public function isAuthenticated() {
|
||||
return $this->id() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -420,7 +428,7 @@ class User extends ContentEntityBase implements UserInterface {
|
||||
'name' => [LanguageInterface::LANGCODE_DEFAULT => ''],
|
||||
// Explicitly set the langcode to ensure that field definitions do not
|
||||
// need to be fetched to figure out a default.
|
||||
'langcode' => [LanguageInterface::LANGCODE_DEFAULT => LanguageInterface::LANGCODE_NOT_SPECIFIED]
|
||||
'langcode' => [LanguageInterface::LANGCODE_DEFAULT => LanguageInterface::LANGCODE_NOT_SPECIFIED],
|
||||
], $entity_type->id());
|
||||
}
|
||||
return clone static::$anonymousUser;
|
||||
|
||||
@@ -139,7 +139,7 @@ class UserCancelForm extends ContentEntityConfirmFormBase {
|
||||
$this->entity->user_cancel_notify = $form_state->getValue('user_cancel_notify');
|
||||
$this->entity->save();
|
||||
_user_mail_notify('cancel_confirm', $this->entity);
|
||||
drupal_set_message($this->t('A confirmation request to cancel your account has been sent to your email address.'));
|
||||
$this->messenger()->addStatus($this->t('A confirmation request to cancel your account has been sent to your email address.'));
|
||||
$this->logger('user')->notice('Sent account cancellation request to %name %email.', ['%name' => $this->entity->label(), '%email' => '<' . $this->entity->getEmail() . '>']);
|
||||
|
||||
$form_state->setRedirect(
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Drupal\user\Form;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\TempStore\PrivateTempStoreFactory;
|
||||
use Drupal\user\UserStorageInterface;
|
||||
@@ -132,7 +133,7 @@ class UserMultipleCancelConfirm extends ConfirmFormBase {
|
||||
if (isset($root)) {
|
||||
$redirect = (count($accounts) == 1);
|
||||
$message = $this->t('The user account %name cannot be canceled.', ['%name' => $root->label()]);
|
||||
drupal_set_message($message, $redirect ? 'error' : 'warning');
|
||||
$this->messenger()->addMessage($message, $redirect ? MessengerInterface::TYPE_ERROR : MessengerInterface::TYPE_WARNING);
|
||||
// If only user 1 was selected, redirect to the overview.
|
||||
if ($redirect) {
|
||||
return $this->redirect('entity.user.collection');
|
||||
|
||||
@@ -140,7 +140,7 @@ class UserPasswordForm extends FormBase {
|
||||
$mail = _user_mail_notify('password_reset', $account, $langcode);
|
||||
if (!empty($mail)) {
|
||||
$this->logger('user')->notice('Password reset instructions mailed to %name at %email.', ['%name' => $account->getUsername(), '%email' => $account->getEmail()]);
|
||||
drupal_set_message($this->t('Further instructions have been sent to your email address.'));
|
||||
$this->messenger()->addStatus($this->t('Further instructions have been sent to your email address.'));
|
||||
}
|
||||
|
||||
$form_state->setRedirect('user.page');
|
||||
|
||||
@@ -216,7 +216,7 @@ class UserPermissionsForm extends FormBase {
|
||||
user_role_change_permissions($role_name, (array) $form_state->getValue($role_name));
|
||||
}
|
||||
|
||||
drupal_set_message($this->t('The changes have been saved.'));
|
||||
$this->messenger()->addStatus($this->t('The changes have been saved.'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\user\Plugin\Validation\Constraint;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
@@ -53,7 +52,7 @@ class UserNameConstraintValidator extends ConstraintValidator {
|
||||
) {
|
||||
$this->context->addViolation($constraint->illegalMessage);
|
||||
}
|
||||
if (Unicode::strlen($name) > USERNAME_MAX_LENGTH) {
|
||||
if (mb_strlen($name) > USERNAME_MAX_LENGTH) {
|
||||
$this->context->addViolation($constraint->tooLongMessage, ['%name' => $name, '%max' => USERNAME_MAX_LENGTH]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace Drupal\user\Plugin\migrate;
|
||||
|
||||
use Drupal\migrate\Exception\RequirementsException;
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\migrate\MigrateSkipRowException;
|
||||
use Drupal\migrate\Plugin\Migration;
|
||||
|
||||
/**
|
||||
@@ -31,11 +33,28 @@ class ProfileValues extends Migration {
|
||||
$definition['idMap']['plugin'] = 'null';
|
||||
try {
|
||||
$profile_field_migration = $this->migrationPluginManager->createStubMigration($definition);
|
||||
$migrate_executable = new MigrateExecutable($profile_field_migration);
|
||||
$source_plugin = $profile_field_migration->getSourcePlugin();
|
||||
$source_plugin->checkRequirements();
|
||||
foreach ($source_plugin as $row) {
|
||||
$name = $row->getSourceProperty('name');
|
||||
$this->process[$name] = $name;
|
||||
$fid = $row->getSourceProperty('fid');
|
||||
// The user profile field name can be greater than 32 characters. Use
|
||||
// the migrated profile field name in the process pipeline.
|
||||
$configuration =
|
||||
[
|
||||
'migration' => 'user_profile_field',
|
||||
'source_ids' => $fid,
|
||||
];
|
||||
$plugin = $this->processPluginManager->createInstance('migration_lookup', $configuration, $profile_field_migration);
|
||||
$new_value = $plugin->transform($fid, $migrate_executable, $row, 'tmp');
|
||||
if (isset($new_value[1])) {
|
||||
// Set the destination to the migrated profile field name.
|
||||
$this->process[$new_value[1]] = $name;
|
||||
}
|
||||
else {
|
||||
throw new MigrateSkipRowException("Can't migrate source field $name.");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RequirementsException $e) {
|
||||
|
||||
@@ -37,7 +37,7 @@ class User extends FieldMigration {
|
||||
}
|
||||
$info = $row->getSource();
|
||||
$this->fieldPluginCache[$field_type]
|
||||
->processFieldValues($this, $field_name, $info);
|
||||
->defineValueProcessPipeline($this, $field_name, $info);
|
||||
}
|
||||
else {
|
||||
if ($this->cckPluginManager->hasDefinition($field_type)) {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\destination;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
@@ -15,6 +14,52 @@ use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a destination plugin for migrating user entities.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* The example below migrates users and preserves original passwords from a
|
||||
* source that has passwords as MD5 hashes without salt. The passwords will be
|
||||
* salted and re-hashed before they are saved to the destination Drupal
|
||||
* database. The MD5 hash used in the example is a hash of 'password'.
|
||||
*
|
||||
* The example uses the EmbeddedDataSource source plugin for the sake of
|
||||
* simplicity. The mapping between old user_ids and new Drupal uids is saved in
|
||||
* the migration map table.
|
||||
* @code
|
||||
* id: custom_user_migration
|
||||
* label: Custom user migration
|
||||
* source:
|
||||
* plugin: embedded_data
|
||||
* data_rows:
|
||||
* -
|
||||
* user_id: 1
|
||||
* name: johnsmith
|
||||
* mail: johnsmith@example.com
|
||||
* hash: '5f4dcc3b5aa765d61d8327deb882cf99'
|
||||
* ids:
|
||||
* user_id:
|
||||
* type: integer
|
||||
* process:
|
||||
* name: name
|
||||
* mail: mail
|
||||
* pass: hash
|
||||
* status:
|
||||
* plugin: default_value
|
||||
* default_value: 1
|
||||
* destination:
|
||||
* plugin: entity:user
|
||||
* md5_passwords: true
|
||||
* @endcode
|
||||
*
|
||||
* For configuration options inherited from the parent class, refer to
|
||||
* \Drupal\migrate\Plugin\migrate\destination\EntityContentBase.
|
||||
*
|
||||
* The example above is about migrating an MD5 password hash. For more examples
|
||||
* on different password hash types and a list of other user properties, refer
|
||||
* to the handbook documentation:
|
||||
* @see https://www.drupal.org/docs/8/api/migrate-api/migrate-destination-plugins-examples/migrating-users
|
||||
*
|
||||
* @MigrateDestination(
|
||||
* id = "entity:user"
|
||||
* )
|
||||
@@ -122,8 +167,8 @@ class EntityUser extends EntityContentBase {
|
||||
if (is_array($name)) {
|
||||
$name = reset($name);
|
||||
}
|
||||
if (Unicode::strlen($name) > USERNAME_MAX_LENGTH) {
|
||||
$row->setDestinationProperty('name', Unicode::substr($name, 0, USERNAME_MAX_LENGTH));
|
||||
if (mb_strlen($name) > USERNAME_MAX_LENGTH) {
|
||||
$row->setDestinationProperty('name', mb_substr($name, 0, USERNAME_MAX_LENGTH));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class UserLangcode extends ProcessPluginBase implements ContainerFactoryPluginIn
|
||||
return 'en';
|
||||
}
|
||||
}
|
||||
// If the user's language does not exists, use the default language.
|
||||
// If the user's language does not exist, use the default language.
|
||||
elseif ($this->languageManager->getLanguage($value) === NULL) {
|
||||
return $this->languageManager->getDefaultLanguage()->getId();
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ class UserUpdate7002 extends ProcessPluginBase implements ContainerFactoryPlugin
|
||||
$container->get('config.factory')->get('system.date')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -33,14 +33,6 @@ class User extends DrupalSqlBase {
|
||||
// Add roles field.
|
||||
$fields['roles'] = $this->t('Roles');
|
||||
|
||||
// Profile fields.
|
||||
if ($this->moduleExists('profile')) {
|
||||
$fields += $this->select('profile_fields', 'pf')
|
||||
->fields('pf', ['name', 'title'])
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ class UserPicture extends DrupalSqlBase {
|
||||
'picture' => "Path to the user's uploaded picture.",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -68,6 +68,7 @@ class UserPictureFile extends DrupalSqlBase {
|
||||
'filename' => 'The picture filename.',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -62,18 +62,32 @@ class User extends FieldableEntity {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$uid = $row->getSourceProperty('uid');
|
||||
|
||||
$roles = $this->select('users_roles', 'ur')
|
||||
->fields('ur', ['rid'])
|
||||
->condition('ur.uid', $row->getSourceProperty('uid'))
|
||||
->condition('ur.uid', $uid)
|
||||
->execute()
|
||||
->fetchCol();
|
||||
$row->setSourceProperty('roles', $roles);
|
||||
|
||||
$row->setSourceProperty('data', unserialize($row->getSourceProperty('data')));
|
||||
|
||||
// If this entity was translated using Entity Translation, we need to get
|
||||
// its source language to get the field values in the right language.
|
||||
// The translations will be migrated by the d7_user_entity_translation
|
||||
// migration.
|
||||
$entity_translatable = $this->isEntityTranslatable('user');
|
||||
$source_language = $this->getEntityTranslationSourceLanguage('user', $uid);
|
||||
$language = $entity_translatable && $source_language ? $source_language : $row->getSourceProperty('language');
|
||||
$row->setSourceProperty('entity_language', $language);
|
||||
|
||||
// Get Field API field values.
|
||||
foreach (array_keys($this->getFields('user')) as $field) {
|
||||
$row->setSourceProperty($field, $this->getFieldValues('user', $field, $row->getSourceProperty('uid')));
|
||||
foreach ($this->getFields('user') as $field_name => $field) {
|
||||
// Ensure we're using the right language if the entity and the field are
|
||||
// translatable.
|
||||
$field_language = $entity_translatable && $field['translatable'] ? $language : NULL;
|
||||
$row->setSourceProperty($field_name, $this->getFieldValues('user', $field_name, $uid, NULL, $field_language));
|
||||
}
|
||||
|
||||
// Get profile field values. This code is lifted directly from the D6
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\user\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
|
||||
|
||||
/**
|
||||
* Provides Drupal 7 user entity translations source plugin.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_user_entity_translation",
|
||||
* source_module = "entity_translation"
|
||||
* )
|
||||
*/
|
||||
class UserEntityTranslation extends FieldableEntity {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('entity_translation', 'et')
|
||||
->fields('et')
|
||||
->condition('et.entity_type', 'user')
|
||||
->condition('et.source', '', '<>');
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$uid = $row->getSourceProperty('entity_id');
|
||||
$language = $row->getSourceProperty('language');
|
||||
|
||||
// Get Field API field values.
|
||||
foreach ($this->getFields('user') as $field_name => $field) {
|
||||
// Ensure we're using the right language if the entity is translatable.
|
||||
$field_language = $field['translatable'] ? $language : NULL;
|
||||
$row->setSourceProperty($field_name, $this->getFieldValues('user', $field_name, $uid, NULL, $field_language));
|
||||
}
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return [
|
||||
'entity_type' => $this->t('The entity type this translation relates to'),
|
||||
'entity_id' => $this->t('The entity id this translation relates to'),
|
||||
'revision_id' => $this->t('The entity revision id this translation relates to'),
|
||||
'language' => $this->t('The target language for this translation.'),
|
||||
'source' => $this->t('The source language from which this translation was created.'),
|
||||
'uid' => $this->t('The author of this translation.'),
|
||||
'status' => $this->t('Boolean indicating whether the translation is published (visible to non-administrators).'),
|
||||
'translate' => $this->t('A boolean indicating whether this translation needs to be updated.'),
|
||||
'created' => $this->t('The Unix timestamp when the translation was created.'),
|
||||
'changed' => $this->t('The Unix timestamp when the translation was most recently saved.'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return [
|
||||
'entity_id' => [
|
||||
'type' => 'integer',
|
||||
],
|
||||
'language' => [
|
||||
'type' => 'string',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -100,7 +100,6 @@ class Permission extends AccessPluginBase implements CacheableDependencyInterfac
|
||||
return $this->t($this->options['perm']);
|
||||
}
|
||||
|
||||
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['perm'] = ['default' => 'access content'];
|
||||
|
||||
@@ -96,7 +96,6 @@ class Role extends AccessPluginBase implements CacheableDependencyInterface {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['role'] = ['default' => []];
|
||||
|
||||
@@ -23,7 +23,7 @@ class Uid extends NumericArgument {
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
* Constructs a \Drupal\user\Plugin\views\argument\Uid object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
||||
@@ -33,7 +33,7 @@ class Permissions extends PrerenderList {
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
* Constructs a \Drupal\user\Plugin\views\field\Permissions object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
||||
@@ -25,7 +25,7 @@ class Roles extends PrerenderList {
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
* Constructs a \Drupal\user\Plugin\views\field\Roles object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
@@ -82,7 +82,7 @@ class Roles extends PrerenderList {
|
||||
$ordered_roles = array_flip(array_keys($roles));
|
||||
foreach ($this->items as &$user_roles) {
|
||||
// Create an array of rids that the user has in the role weight order.
|
||||
$sorted_keys = array_intersect_key($ordered_roles, $user_roles);
|
||||
$sorted_keys = array_intersect_key($ordered_roles, $user_roles);
|
||||
// Merge with the unsorted array of role information which has the
|
||||
// effect of sorting it.
|
||||
$user_roles = array_merge($sorted_keys, $user_roles);
|
||||
|
||||
@@ -34,7 +34,6 @@ class UserData extends FieldPluginBase {
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -37,7 +37,7 @@ class Users extends WizardPluginBase {
|
||||
'plugin_id' => 'boolean',
|
||||
'entity_type' => 'user',
|
||||
'entity_field' => 'status',
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,7 +38,7 @@ class ProfileForm extends AccountForm {
|
||||
$account->save();
|
||||
$form_state->setValue('uid', $account->id());
|
||||
|
||||
drupal_set_message($this->t('The changes have been saved.'));
|
||||
$this->messenger()->addStatus($this->t('The changes have been saved.'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -103,28 +103,28 @@ 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.', [':url' => $account->url(), '%name' => $account->getUsername()]));
|
||||
$this->messenger()->addStatus($this->t('Created a new user account for <a href=":url">%name</a>. No email has been sent.', [':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()) {
|
||||
_user_mail_notify('register_no_approval_required', $account);
|
||||
user_login_finalize($account);
|
||||
drupal_set_message($this->t('Registration successful. You are now logged in.'));
|
||||
$this->messenger()->addStatus($this->t('Registration successful. You are now logged in.'));
|
||||
$form_state->setRedirect('<front>');
|
||||
}
|
||||
// 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.', [':url' => $account->url(), '%name' => $account->getUsername()]));
|
||||
$this->messenger()->addStatus($this->t('The new user <a href=":url">%name</a> was created without an email address, so no welcome message was sent.', [':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>.', [':url' => $account->url(), '%name' => $account->getUsername()]));
|
||||
$this->messenger()->addStatus($this->t('A welcome message with further instructions has been emailed to the new user <a href=":url">%name</a>.', [':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.'));
|
||||
$this->messenger()->addStatus($this->t('A welcome message with further instructions has been sent to your email address.'));
|
||||
$form_state->setRedirect('<front>');
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ class RegisterForm extends AccountForm {
|
||||
// Administrator approval required.
|
||||
else {
|
||||
_user_mail_notify('register_pending_approval', $account);
|
||||
drupal_set_message($this->t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.<br />In the meantime, a welcome message with further instructions has been sent to your email address.'));
|
||||
$this->messenger()->addStatus($this->t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.<br />In the meantime, a welcome message with further instructions has been sent to your email address.'));
|
||||
$form_state->setRedirect('<front>');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,11 +57,11 @@ class RoleForm extends EntityForm {
|
||||
|
||||
$edit_link = $this->entity->link($this->t('Edit'));
|
||||
if ($status == SAVED_UPDATED) {
|
||||
drupal_set_message($this->t('Role %label has been updated.', ['%label' => $entity->label()]));
|
||||
$this->messenger()->addStatus($this->t('Role %label has been updated.', ['%label' => $entity->label()]));
|
||||
$this->logger('user')->notice('Role %label has been updated.', ['%label' => $entity->label(), 'link' => $edit_link]);
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('Role %label has been added.', ['%label' => $entity->label()]));
|
||||
$this->messenger()->addStatus($this->t('Role %label has been added.', ['%label' => $entity->label()]));
|
||||
$this->logger('user')->notice('Role %label has been added.', ['%label' => $entity->label(), 'link' => $edit_link]);
|
||||
}
|
||||
$form_state->setRedirect('entity.user_role.collection');
|
||||
|
||||
@@ -4,7 +4,11 @@ namespace Drupal\user;
|
||||
|
||||
use Drupal\Core\Config\Entity\DraggableListBuilder;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a class to build a listing of user role entities.
|
||||
@@ -13,6 +17,41 @@ use Drupal\Core\Form\FormStateInterface;
|
||||
*/
|
||||
class RoleListBuilder extends DraggableListBuilder {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* RoleListBuilder constructor.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entityType
|
||||
* The entity type definition.
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
|
||||
* The entity storage class.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(EntityTypeInterface $entityType,
|
||||
EntityStorageInterface $storage,
|
||||
MessengerInterface $messenger) {
|
||||
parent::__construct($entityType, $storage);
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
|
||||
return new static(
|
||||
$entity_type,
|
||||
$container->get('entity.manager')->getStorage($entity_type->id()),
|
||||
$container->get('messenger')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -58,7 +97,7 @@ class RoleListBuilder extends DraggableListBuilder {
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
parent::submitForm($form, $form_state);
|
||||
|
||||
drupal_set_message(t('The role settings have been updated.'));
|
||||
$this->messenger->addStatus($this->t('The role settings have been updated.'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+7
-21
@@ -1,10 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\user\Tests;
|
||||
namespace Drupal\user\Tests\Functional;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Test\AssertMailTrait;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\system\Tests\Cache\PageCacheTagsTestBase;
|
||||
use Drupal\Tests\system\Functional\Cache\PageCacheTagsTestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
@@ -14,16 +15,9 @@ use Drupal\user\Entity\User;
|
||||
*/
|
||||
class UserPasswordResetTest extends PageCacheTagsTestBase {
|
||||
|
||||
/**
|
||||
* The profile to install as a basis for testing.
|
||||
*
|
||||
* This test uses the standard profile to test the password reset in
|
||||
* combination with an ajax request provided by the user picture configuration
|
||||
* in the standard profile.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = 'standard';
|
||||
use AssertMailTrait {
|
||||
getMails as drupalGetMails;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user object to test password resetting.
|
||||
@@ -54,7 +48,7 @@ class UserPasswordResetTest extends PageCacheTagsTestBase {
|
||||
$this->drupalLogin($account);
|
||||
|
||||
$this->account = User::load($account->id());
|
||||
$this->account->pass_raw = $account->pass_raw;
|
||||
$this->account->passRaw = $account->passRaw;
|
||||
$this->drupalLogout();
|
||||
|
||||
// Set the last login time that is used to generate the one-time link so
|
||||
@@ -114,14 +108,6 @@ class UserPasswordResetTest extends PageCacheTagsTestBase {
|
||||
$this->assertLink(t('Log out'));
|
||||
$this->assertTitle(t('@name | @site', ['@name' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name')]), 'Logged in using password reset link.');
|
||||
|
||||
// Make sure the ajax request from uploading a user picture does not
|
||||
// invalidate the reset token.
|
||||
$image = current($this->drupalGetTestFiles('image'));
|
||||
$edit = [
|
||||
'files[user_picture_0]' => \Drupal::service('file_system')->realpath($image->uri),
|
||||
];
|
||||
$this->drupalPostAjaxForm(NULL, $edit, 'user_picture_0_upload_button');
|
||||
|
||||
// Change the forgotten password.
|
||||
$password = user_password();
|
||||
$edit = ['pass[pass1]' => $password, 'pass[pass2]' => $password];
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\user\Tests\FunctionalJavascript;
|
||||
|
||||
use Drupal\Core\Test\AssertMailTrait;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
use Drupal\Tests\TestFileCreationTrait;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Ensure that password reset methods work as expected.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserPasswordResetTest extends WebDriverTestBase {
|
||||
|
||||
use AssertMailTrait {
|
||||
getMails as drupalGetMails;
|
||||
}
|
||||
|
||||
use TestFileCreationTrait {
|
||||
getTestFiles as drupalGetTestFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* The profile to install as a basis for testing.
|
||||
*
|
||||
* This test uses the standard profile to test the password reset in
|
||||
* combination with an ajax request provided by the user picture configuration
|
||||
* in the standard profile.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = 'standard';
|
||||
|
||||
/**
|
||||
* The user object to test password resetting.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a user.
|
||||
$account = $this->drupalCreateUser();
|
||||
|
||||
// Activate user by logging in.
|
||||
$this->drupalLogin($account);
|
||||
|
||||
$this->account = User::load($account->id());
|
||||
$this->account->pass_raw = $account->pass_raw;
|
||||
$this->drupalLogout();
|
||||
|
||||
// Set the last login time that is used to generate the one-time link so
|
||||
// that it is definitely over a second ago.
|
||||
$account->login = REQUEST_TIME - mt_rand(10, 100000);
|
||||
db_update('users_field_data')
|
||||
->fields(['login' => $account->getLastLoginTime()])
|
||||
->condition('uid', $account->id())
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests password reset functionality with an AJAX form.
|
||||
*
|
||||
* Make sure the ajax request from uploading a user picture does not
|
||||
* invalidate the reset token.
|
||||
*/
|
||||
public function testUserPasswordResetWithAdditionalAjaxForm() {
|
||||
$this->drupalGet(Url::fromRoute('user.reset.form', ['uid' => $this->account->id()]));
|
||||
|
||||
// Try to reset the password for an invalid account.
|
||||
$this->drupalGet('user/password');
|
||||
|
||||
// Reset the password by username via the password reset page.
|
||||
$edit['name'] = $this->account->getUsername();
|
||||
$this->drupalPostForm(NULL, $edit, t('Submit'));
|
||||
|
||||
$resetURL = $this->getResetURL();
|
||||
$this->drupalGet($resetURL);
|
||||
|
||||
// Login
|
||||
$this->drupalPostForm(NULL, NULL, t('Log in'));
|
||||
|
||||
// Generate file.
|
||||
$image_file = current($this->drupalGetTestFiles('image'));
|
||||
$image_path = \Drupal::service('file_system')->realpath($image_file->uri);
|
||||
|
||||
// Upload file.
|
||||
$this->getSession()->getPage()->attachFileToField('Picture', $image_path);
|
||||
$this->assertSession()->waitForButton('Remove');
|
||||
|
||||
// Change the forgotten password.
|
||||
$password = user_password();
|
||||
$edit = ['pass[pass1]' => $password, 'pass[pass2]' => $password];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
|
||||
// Verify that the password reset session has been destroyed.
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
// Password needed to make profile changes.
|
||||
$this->assertSession()->pageTextContains("Your current password is missing or incorrect; it's required to change the Password.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves password reset email and extracts the login link.
|
||||
*/
|
||||
public function getResetURL() {
|
||||
// Assume the most recent email.
|
||||
$_emails = $this->drupalGetMails();
|
||||
$email = end($_emails);
|
||||
$urls = [];
|
||||
preg_match('#.+user/reset/.+#', $email['body'], $urls);
|
||||
|
||||
return $urls[0];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Drupal\user\Tests;
|
||||
|
||||
use Drupal\system\Tests\System\SystemConfigFormTestBase;
|
||||
use Drupal\KernelTests\ConfigFormTestBase;
|
||||
use Drupal\user\AccountSettingsForm;
|
||||
|
||||
/**
|
||||
@@ -10,8 +10,16 @@ use Drupal\user\AccountSettingsForm;
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserAdminSettingsFormTest extends SystemConfigFormTestBase {
|
||||
class UserAdminSettingsFormTest extends ConfigFormTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['user', 'system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
|
||||
@@ -121,38 +121,6 @@ class UserBlocksTest extends WebTestBase {
|
||||
$this->assertNoText(t('Unrecognized username or password. Forgot your password?'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Who's Online block.
|
||||
*/
|
||||
public function testWhosOnlineBlock() {
|
||||
$block = $this->drupalPlaceBlock('views_block:who_s_online-who_s_online_block');
|
||||
|
||||
// Generate users.
|
||||
$user1 = $this->drupalCreateUser(['access user profiles']);
|
||||
$user2 = $this->drupalCreateUser([]);
|
||||
$user3 = $this->drupalCreateUser([]);
|
||||
|
||||
// Update access of two users to be within the active timespan.
|
||||
$this->updateAccess($user1->id());
|
||||
$this->updateAccess($user2->id(), REQUEST_TIME + 1);
|
||||
|
||||
// Insert an inactive user who should not be seen in the block, and ensure
|
||||
// that the admin user used in setUp() does not appear.
|
||||
$inactive_time = REQUEST_TIME - (15 * 60) - 1;
|
||||
$this->updateAccess($user3->id(), $inactive_time);
|
||||
$this->updateAccess($this->adminUser->id(), $inactive_time);
|
||||
|
||||
// Test block output.
|
||||
\Drupal::currentUser()->setAccount($user1);
|
||||
$content = entity_view($block, 'block');
|
||||
$this->setRawContent(\Drupal::service('renderer')->renderRoot($content));
|
||||
$this->assertRaw(t('2 users'), 'Correct number of online users (2 users).');
|
||||
$this->assertText($user1->getUsername(), 'Active user 1 found in online list.');
|
||||
$this->assertText($user2->getUsername(), 'Active user 2 found in online list.');
|
||||
$this->assertNoText($user3->getUsername(), 'Inactive user not found in online list.');
|
||||
$this->assertTrue(strpos($this->getRawContent(), $user1->getUsername()) > strpos($this->getRawContent(), $user2->getUsername()), 'Online users are ordered correctly.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the access column for a user.
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Drupal\user\Tests;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
@@ -273,11 +273,11 @@ class UserRegistrationTest extends WebTestBase {
|
||||
|
||||
$edit = ['mail' => 'test@example.com', 'name' => $account->getUsername()];
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertRaw(SafeMarkup::format('The username %value is already taken.', ['%value' => $account->getUsername()]));
|
||||
$this->assertRaw(new FormattableMarkup('The username %value is already taken.', ['%value' => $account->getUsername()]));
|
||||
|
||||
$edit = ['mail' => $account->getEmail(), 'name' => $this->randomString()];
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertRaw(SafeMarkup::format('The email address %value is already taken.', ['%value' => $account->getEmail()]));
|
||||
$this->assertRaw(new FormattableMarkup('The email address %value is already taken.', ['%value' => $account->getEmail()]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,35 +348,27 @@ class UserRegistrationTest extends WebTestBase {
|
||||
// Check that the 'add more' button works.
|
||||
$field_storage->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
|
||||
$field_storage->save();
|
||||
foreach (['js', 'nojs'] as $js) {
|
||||
$this->drupalGet('user/register');
|
||||
$this->assertRegistrationFormCacheTagsWithUserFields();
|
||||
// Add two inputs.
|
||||
$value = rand(1, 255);
|
||||
$edit = [];
|
||||
$edit['test_user_field[0][value]'] = $value;
|
||||
if ($js == 'js') {
|
||||
$this->drupalPostAjaxForm(NULL, $edit, 'test_user_field_add_more');
|
||||
$this->drupalPostAjaxForm(NULL, $edit, 'test_user_field_add_more');
|
||||
}
|
||||
else {
|
||||
$this->drupalPostForm(NULL, $edit, t('Add another item'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Add another item'));
|
||||
}
|
||||
// Submit with three values.
|
||||
$edit['test_user_field[1][value]'] = $value + 1;
|
||||
$edit['test_user_field[2][value]'] = $value + 2;
|
||||
$edit['name'] = $name = $this->randomMachineName();
|
||||
$edit['mail'] = $mail = $edit['name'] . '@example.com';
|
||||
$this->drupalPostForm(NULL, $edit, t('Create new account'));
|
||||
// Check user fields.
|
||||
$accounts = $this->container->get('entity_type.manager')->getStorage('user')
|
||||
->loadByProperties(['name' => $name, 'mail' => $mail]);
|
||||
$new_user = reset($accounts);
|
||||
$this->assertEqual($new_user->test_user_field[0]->value, $value, format_string('@js : The field value was correctly saved.', ['@js' => $js]));
|
||||
$this->assertEqual($new_user->test_user_field[1]->value, $value + 1, format_string('@js : The field value was correctly saved.', ['@js' => $js]));
|
||||
$this->assertEqual($new_user->test_user_field[2]->value, $value + 2, format_string('@js : The field value was correctly saved.', ['@js' => $js]));
|
||||
}
|
||||
$this->drupalGet('user/register');
|
||||
$this->assertRegistrationFormCacheTagsWithUserFields();
|
||||
// Add two inputs.
|
||||
$value = rand(1, 255);
|
||||
$edit = [];
|
||||
$edit['test_user_field[0][value]'] = $value;
|
||||
$this->drupalPostForm(NULL, $edit, t('Add another item'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Add another item'));
|
||||
// Submit with three values.
|
||||
$edit['test_user_field[1][value]'] = $value + 1;
|
||||
$edit['test_user_field[2][value]'] = $value + 2;
|
||||
$edit['name'] = $name = $this->randomMachineName();
|
||||
$edit['mail'] = $mail = $edit['name'] . '@example.com';
|
||||
$this->drupalPostForm(NULL, $edit, t('Create new account'));
|
||||
// Check user fields.
|
||||
$accounts = $this->container->get('entity_type.manager')->getStorage('user')
|
||||
->loadByProperties(['name' => $name, 'mail' => $mail]);
|
||||
$new_user = reset($accounts);
|
||||
$this->assertEqual($new_user->test_user_field[0]->value, $value, 'The field value was correctly saved.');
|
||||
$this->assertEqual($new_user->test_user_field[1]->value, $value + 1, 'The field value was correctly saved.');
|
||||
$this->assertEqual($new_user->test_user_field[2]->value, $value + 2, 'The field value was correctly saved.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -106,7 +106,7 @@ class UserAccessControlHandler extends EntityAccessControlHandler {
|
||||
return AccessResult::allowed()->cachePerPermissions()->cachePerUser();
|
||||
}
|
||||
else {
|
||||
return AccessResult::forbidden();
|
||||
return AccessResult::neutral();
|
||||
}
|
||||
|
||||
case 'preferred_langcode':
|
||||
@@ -116,7 +116,7 @@ class UserAccessControlHandler extends EntityAccessControlHandler {
|
||||
// Allow view access to own mail address and other personalization
|
||||
// settings.
|
||||
if ($operation == 'view') {
|
||||
return $is_own_account ? AccessResult::allowed()->cachePerUser() : AccessResult::forbidden();
|
||||
return $is_own_account ? AccessResult::allowed()->cachePerUser() : AccessResult::neutral();
|
||||
}
|
||||
// Anyone that can edit the user can also edit this field.
|
||||
return AccessResult::allowed()->cachePerPermissions();
|
||||
@@ -127,14 +127,14 @@ class UserAccessControlHandler extends EntityAccessControlHandler {
|
||||
|
||||
case 'created':
|
||||
// Allow viewing the created date, but not editing it.
|
||||
return ($operation == 'view') ? AccessResult::allowed() : AccessResult::forbidden();
|
||||
return ($operation == 'view') ? AccessResult::allowed() : AccessResult::neutral();
|
||||
|
||||
case 'roles':
|
||||
case 'status':
|
||||
case 'access':
|
||||
case 'login':
|
||||
case 'init':
|
||||
return AccessResult::forbidden();
|
||||
return AccessResult::neutral();
|
||||
}
|
||||
|
||||
return parent::checkFieldAccess($operation, $field_definition, $account, $items);
|
||||
|
||||
@@ -21,7 +21,7 @@ class UserStorage extends SqlContentEntityStorage implements UserStorageInterfac
|
||||
// The anonymous user account is saved with the fixed user ID of 0.
|
||||
// Therefore we need to check for NULL explicitly.
|
||||
if ($entity->id() === NULL) {
|
||||
$entity->uid->value = $this->database->nextId($this->database->query('SELECT MAX(uid) FROM {users}')->fetchField());
|
||||
$entity->uid->value = $this->database->nextId($this->database->query('SELECT MAX(uid) FROM {' . $this->getBaseTable() . '}')->fetchField());
|
||||
$entity->enforceIsNew();
|
||||
}
|
||||
return parent::doSaveFieldItems($entity, $names);
|
||||
@@ -39,7 +39,7 @@ class UserStorage extends SqlContentEntityStorage implements UserStorageInterfac
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function updateLastLoginTimestamp(UserInterface $account) {
|
||||
$this->database->update('users_field_data')
|
||||
$this->database->update($this->getDataTable())
|
||||
->fields(['login' => $account->getLastLoginTime()])
|
||||
->condition('uid', $account->id())
|
||||
->execute();
|
||||
@@ -51,7 +51,7 @@ class UserStorage extends SqlContentEntityStorage implements UserStorageInterfac
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function updateLastAccessTimestamp(AccountInterface $account, $timestamp) {
|
||||
$this->database->update('users_field_data')
|
||||
$this->database->update($this->getDataTable())
|
||||
->fields([
|
||||
'access' => $timestamp,
|
||||
])
|
||||
|
||||
@@ -17,9 +17,11 @@ class UserStorageSchema extends SqlContentEntityStorageSchema {
|
||||
protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) {
|
||||
$schema = parent::getEntitySchema($entity_type, $reset);
|
||||
|
||||
$schema['users_field_data']['unique keys'] += [
|
||||
'user__name' => ['name', 'langcode'],
|
||||
];
|
||||
if ($data_table = $this->storage->getDataTable()) {
|
||||
$schema[$data_table]['unique keys'] += [
|
||||
'user__name' => ['name', 'langcode'],
|
||||
];
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class UserViewsData extends EntityViewsData {
|
||||
'argument field' => 'uid',
|
||||
'base' => 'node_field_data',
|
||||
'field' => 'nid',
|
||||
'relationship' => 'node_field_data:uid'
|
||||
'relationship' => 'node_field_data:uid',
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user