upgrades core to 8.4.2
This commit is contained in:
@@ -26,7 +26,11 @@ class LoginStatusCheck implements AccessInterface {
|
||||
public function access(AccountInterface $account, Route $route) {
|
||||
$required_status = filter_var($route->getRequirement('_user_is_logged_in'), FILTER_VALIDATE_BOOLEAN);
|
||||
$actual_status = $account->isAuthenticated();
|
||||
return AccessResult::allowedIf($required_status === $actual_status)->addCacheContexts(['user.roles:authenticated']);
|
||||
$access_result = AccessResult::allowedIf($required_status === $actual_status)->addCacheContexts(['user.roles:authenticated']);
|
||||
if (!$access_result->isAllowed()) {
|
||||
$access_result->setReason($required_status === TRUE ? 'This route can only be accessed by authenticated users.' : 'This route can only be accessed by anonymous users.');
|
||||
}
|
||||
return $access_result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ abstract class AccountForm extends ContentEntityForm {
|
||||
'#type' => 'email',
|
||||
'#title' => $this->t('Email address'),
|
||||
'#description' => $this->t('A valid email address. All emails from the system will be sent to this address. The email address is not made public and will only be used if you wish to receive a new password or wish to receive certain news or notifications by email.'),
|
||||
'#required' => !(!$account->getEmail() && $user->hasPermission('administer users')),
|
||||
'#required' => !(!$account->getEmail() && $admin),
|
||||
'#default_value' => (!$register ? $account->getEmail() : ''),
|
||||
];
|
||||
|
||||
@@ -222,7 +222,7 @@ abstract class AccountForm extends ContentEntityForm {
|
||||
'#open' => TRUE,
|
||||
// Display language selector when either creating a user on the admin
|
||||
// interface or editing a user account.
|
||||
'#access' => !$register || $user->hasPermission('administer users'),
|
||||
'#access' => !$register || $admin,
|
||||
];
|
||||
|
||||
$form['language']['preferred_langcode'] = [
|
||||
|
||||
@@ -10,6 +10,7 @@ use Drupal\Core\Routing\RouteProviderInterface;
|
||||
use Drupal\user\UserAuthInterface;
|
||||
use Drupal\user\UserInterface;
|
||||
use Drupal\user\UserStorageInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
@@ -86,6 +87,13 @@ class UserAuthenticationController extends ControllerBase implements ContainerIn
|
||||
*/
|
||||
protected $serializerFormats = [];
|
||||
|
||||
/**
|
||||
* A logger instance.
|
||||
*
|
||||
* @var \Psr\Log\LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Constructs a new UserAuthenticationController object.
|
||||
*
|
||||
@@ -103,8 +111,10 @@ class UserAuthenticationController extends ControllerBase implements ContainerIn
|
||||
* The serializer.
|
||||
* @param array $serializer_formats
|
||||
* The available serialization formats.
|
||||
* @param \Psr\Log\LoggerInterface $logger
|
||||
* A logger instance.
|
||||
*/
|
||||
public function __construct(FloodInterface $flood, UserStorageInterface $user_storage, CsrfTokenGenerator $csrf_token, UserAuthInterface $user_auth, RouteProviderInterface $route_provider, Serializer $serializer, array $serializer_formats) {
|
||||
public function __construct(FloodInterface $flood, UserStorageInterface $user_storage, CsrfTokenGenerator $csrf_token, UserAuthInterface $user_auth, RouteProviderInterface $route_provider, Serializer $serializer, array $serializer_formats, LoggerInterface $logger) {
|
||||
$this->flood = $flood;
|
||||
$this->userStorage = $user_storage;
|
||||
$this->csrfToken = $csrf_token;
|
||||
@@ -112,6 +122,7 @@ class UserAuthenticationController extends ControllerBase implements ContainerIn
|
||||
$this->serializer = $serializer;
|
||||
$this->serializerFormats = $serializer_formats;
|
||||
$this->routeProvider = $route_provider;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,7 +146,8 @@ class UserAuthenticationController extends ControllerBase implements ContainerIn
|
||||
$container->get('user.auth'),
|
||||
$container->get('router.route_provider'),
|
||||
$serializer,
|
||||
$formats
|
||||
$formats,
|
||||
$container->get('logger.factory')->get('user')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -207,6 +219,56 @@ class UserAuthenticationController extends ControllerBase implements ContainerIn
|
||||
throw new BadRequestHttpException('Sorry, unrecognized username or password.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets a user password.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* The response object.
|
||||
*/
|
||||
public function resetPassword(Request $request) {
|
||||
$format = $this->getRequestFormat($request);
|
||||
|
||||
$content = $request->getContent();
|
||||
$credentials = $this->serializer->decode($content, $format);
|
||||
|
||||
// Check if a name or mail is provided.
|
||||
if (!isset($credentials['name']) && !isset($credentials['mail'])) {
|
||||
throw new BadRequestHttpException('Missing credentials.name or credentials.mail');
|
||||
}
|
||||
|
||||
// Load by name if provided.
|
||||
if (isset($credentials['name'])) {
|
||||
$users = $this->userStorage->loadByProperties(['name' => trim($credentials['name'])]);
|
||||
}
|
||||
elseif (isset($credentials['mail'])) {
|
||||
$users = $this->userStorage->loadByProperties(['mail' => trim($credentials['mail'])]);
|
||||
}
|
||||
|
||||
/** @var \Drupal\Core\Session\AccountInterface $account */
|
||||
$account = reset($users);
|
||||
if ($account && $account->id()) {
|
||||
if ($this->userIsBlocked($account->getAccountName())) {
|
||||
throw new BadRequestHttpException('The user has not been activated or is blocked.');
|
||||
}
|
||||
|
||||
// Send the password reset email.
|
||||
$mail = _user_mail_notify('password_reset', $account, $account->getPreferredLangcode());
|
||||
if (empty($mail)) {
|
||||
throw new BadRequestHttpException('Unable to send email. Contact the site administrator if the problem persists.');
|
||||
}
|
||||
else {
|
||||
$this->logger->notice('Password reset instructions mailed to %name at %email.', ['%name' => $account->getAccountName(), '%email' => $account->getEmail()]);
|
||||
return new Response();
|
||||
}
|
||||
}
|
||||
|
||||
// Error if no users found with provided name or mail.
|
||||
throw new BadRequestHttpException('Unrecognized username or email address.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if the user is blocked.
|
||||
*
|
||||
|
||||
@@ -173,7 +173,7 @@ class Role extends ConfigEntityBase implements RoleInterface {
|
||||
|
||||
if (!isset($this->weight) && ($roles = $storage->loadMultiple())) {
|
||||
// Set a role weight to make this new role last.
|
||||
$max = array_reduce($roles, function($max, $role) {
|
||||
$max = array_reduce($roles, function ($max, $role) {
|
||||
return $max > $role->weight ? $max : $role->weight;
|
||||
});
|
||||
$this->weight = $max + 1;
|
||||
|
||||
@@ -60,9 +60,6 @@ class UserPasswordForm extends FormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object.
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form['name'] = [
|
||||
|
||||
@@ -129,14 +129,16 @@ class UserPermissionsForm extends FormBase {
|
||||
|
||||
foreach ($permissions_by_provider as $provider => $permissions) {
|
||||
// Module name.
|
||||
$form['permissions'][$provider] = [[
|
||||
'#wrapper_attributes' => [
|
||||
'colspan' => count($role_names) + 1,
|
||||
'class' => ['module'],
|
||||
'id' => 'module-' . $provider,
|
||||
$form['permissions'][$provider] = [
|
||||
[
|
||||
'#wrapper_attributes' => [
|
||||
'colspan' => count($role_names) + 1,
|
||||
'class' => ['module'],
|
||||
'id' => 'module-' . $provider,
|
||||
],
|
||||
'#markup' => $this->moduleHandler->getName($provider),
|
||||
],
|
||||
'#markup' => $this->moduleHandler->getName($provider),
|
||||
]];
|
||||
];
|
||||
foreach ($permissions as $perm => $perm_item) {
|
||||
// Fill in default values for the permission.
|
||||
$perm_item += [
|
||||
|
||||
@@ -25,10 +25,14 @@ class UserPermissionsRoleSpecificForm extends UserPermissionsForm {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Builds the user permissions administration form for a specific role.
|
||||
*
|
||||
* @param string $role_id
|
||||
* The user role ID used for this form.
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
* @param \Drupal\user\RoleInterface|null $user_role
|
||||
* (optional) The user role used for this form. Defaults to NULL.
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, RoleInterface $user_role = NULL) {
|
||||
$this->userRole = $user_role;
|
||||
|
||||
@@ -6,7 +6,6 @@ use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Routing\RedirectDestinationTrait;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Routing\UrlGeneratorTrait;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Block\BlockBase;
|
||||
@@ -23,7 +22,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
*/
|
||||
class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
use UrlGeneratorTrait;
|
||||
use RedirectDestinationTrait;
|
||||
|
||||
/**
|
||||
@@ -94,7 +92,24 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
|
||||
unset($form['pass']['#attributes']['aria-describedby']);
|
||||
$form['name']['#size'] = 15;
|
||||
$form['pass']['#size'] = 15;
|
||||
$form['#action'] = $this->url('<current>', [], ['query' => $this->getDestinationArray(), 'external' => FALSE]);
|
||||
|
||||
// Instead of setting an actual action URL, we set the placeholder, which
|
||||
// will be replaced at the very last moment. This ensures forms with
|
||||
// dynamically generated action URLs don't have poor cacheability.
|
||||
// Use the proper API to generate the placeholder, when we have one. See
|
||||
// https://www.drupal.org/node/2562341. The placholder uses a fixed string
|
||||
// that is
|
||||
// Crypt::hashBase64('\Drupal\user\Plugin\Block\UserLoginBlock::build');
|
||||
// This is based on the implementation in
|
||||
// \Drupal\Core\Form\FormBuilder::prepareForm(), but the user login block
|
||||
// requires different behavior for the destination query argument.
|
||||
$placeholder = 'form_action_p_4r8ITd22yaUvXM6SzwrSe9rnQWe48hz9k1Sxto3pBvE';
|
||||
|
||||
$form['#attached']['placeholders'][$placeholder] = [
|
||||
'#lazy_builder' => ['\Drupal\user\Plugin\Block\UserLoginBlock::renderPlaceholderFormAction', []],
|
||||
];
|
||||
$form['#action'] = $placeholder;
|
||||
|
||||
// Build action links.
|
||||
$items = [];
|
||||
if (\Drupal::config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY) {
|
||||
@@ -128,4 +143,20 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* #lazy_builder callback; renders a form action URL including destination.
|
||||
*
|
||||
* @return array
|
||||
* A renderable array representing the form action.
|
||||
*
|
||||
* @see \Drupal\Core\Form\FormBuilder::renderPlaceholderFormAction()
|
||||
*/
|
||||
public static function renderPlaceholderFormAction() {
|
||||
return [
|
||||
'#type' => 'markup',
|
||||
'#markup' => Url::fromRoute('<current>', [], ['query' => \Drupal::destination()->getAsArray(), 'external' => FALSE])->toString(),
|
||||
'#cache' => ['contexts' => ['url.path', 'url.query_args']],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Drupal\user\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
|
||||
@@ -82,21 +83,26 @@ class UserSelection extends DefaultSelection {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$selection_handler_settings = $this->configuration['handler_settings'];
|
||||
|
||||
// Merge in default values.
|
||||
$selection_handler_settings += [
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'filter' => [
|
||||
'type' => '_none',
|
||||
'role' => NULL,
|
||||
],
|
||||
'include_anonymous' => TRUE,
|
||||
];
|
||||
] + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$configuration = $this->getConfiguration();
|
||||
|
||||
$form['include_anonymous'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Include the anonymous user.'),
|
||||
'#default_value' => $selection_handler_settings['include_anonymous'],
|
||||
'#default_value' => $configuration['include_anonymous'],
|
||||
];
|
||||
|
||||
// Add user specific filter options.
|
||||
@@ -109,7 +115,7 @@ class UserSelection extends DefaultSelection {
|
||||
],
|
||||
'#ajax' => TRUE,
|
||||
'#limit_validation_errors' => [],
|
||||
'#default_value' => $selection_handler_settings['filter']['type'],
|
||||
'#default_value' => $configuration['filter']['type'],
|
||||
];
|
||||
|
||||
$form['filter']['settings'] = [
|
||||
@@ -118,18 +124,13 @@ class UserSelection extends DefaultSelection {
|
||||
'#process' => [['\Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem', 'formProcessMergeParent']],
|
||||
];
|
||||
|
||||
if ($selection_handler_settings['filter']['type'] == 'role') {
|
||||
// Merge in default values.
|
||||
$selection_handler_settings['filter'] += [
|
||||
'role' => NULL,
|
||||
];
|
||||
|
||||
if ($configuration['filter']['type'] == 'role') {
|
||||
$form['filter']['settings']['role'] = [
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => $this->t('Restrict to the selected roles'),
|
||||
'#required' => TRUE,
|
||||
'#options' => array_diff_key(user_role_names(TRUE), [RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID]),
|
||||
'#default_value' => $selection_handler_settings['filter']['role'],
|
||||
'#default_value' => $configuration['filter']['role'],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -143,11 +144,12 @@ class UserSelection extends DefaultSelection {
|
||||
*/
|
||||
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
|
||||
$query = parent::buildEntityQuery($match, $match_operator);
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
|
||||
$configuration = $this->getConfiguration();
|
||||
|
||||
// Filter out the Anonymous user if the selection handler is configured to
|
||||
// exclude it.
|
||||
if (isset($handler_settings['include_anonymous']) && !$handler_settings['include_anonymous']) {
|
||||
if (!$configuration['include_anonymous']) {
|
||||
$query->condition('uid', 0, '<>');
|
||||
}
|
||||
|
||||
@@ -157,8 +159,8 @@ class UserSelection extends DefaultSelection {
|
||||
}
|
||||
|
||||
// Filter by role.
|
||||
if (!empty($handler_settings['filter']['role'])) {
|
||||
$query->condition('roles', $handler_settings['filter']['role'], 'IN');
|
||||
if (!empty($configuration['filter']['role'])) {
|
||||
$query->condition('roles', $configuration['filter']['role'], 'IN');
|
||||
}
|
||||
|
||||
// Adding the permission check is sadly insufficient for users: core
|
||||
@@ -190,10 +192,10 @@ class UserSelection extends DefaultSelection {
|
||||
public function validateReferenceableNewEntities(array $entities) {
|
||||
$entities = parent::validateReferenceableNewEntities($entities);
|
||||
// Mirror the conditions checked in buildEntityQuery().
|
||||
if (!empty($this->configuration['handler_settings']['filter']['role'])) {
|
||||
$entities = array_filter($entities, function ($user) {
|
||||
if ($role = $this->getConfiguration()['filter']['role']) {
|
||||
$entities = array_filter($entities, function ($user) use ($role) {
|
||||
/** @var \Drupal\user\UserInterface $user */
|
||||
return !empty(array_intersect($user->getRoles(), $this->configuration['handler_settings']['filter']['role']));
|
||||
return !empty(array_intersect($user->getRoles(), $role));
|
||||
});
|
||||
}
|
||||
if (!$this->currentUser->hasPermission('administer users')) {
|
||||
@@ -209,9 +211,10 @@ class UserSelection extends DefaultSelection {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) {
|
||||
parent::entityQueryAlter($query);
|
||||
|
||||
// Bail out early if we do not need to match the Anonymous user.
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
if (isset($handler_settings['include_anonymous']) && !$handler_settings['include_anonymous']) {
|
||||
if (!$this->getConfiguration()['include_anonymous']) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -228,17 +231,17 @@ class UserSelection extends DefaultSelection {
|
||||
// Re-add the condition and a condition on uid = 0 so that we end up
|
||||
// with a query in the form:
|
||||
// WHERE (name LIKE :name) OR (:anonymous_name LIKE :name AND uid = 0)
|
||||
$or = db_or();
|
||||
$or = new Condition('OR');
|
||||
$or->condition($condition['field'], $condition['value'], $condition['operator']);
|
||||
// Sadly, the Database layer doesn't allow us to build a condition
|
||||
// in the form ':placeholder = :placeholder2', because the 'field'
|
||||
// part of a condition is always escaped.
|
||||
// As a (cheap) workaround, we separately build a condition with no
|
||||
// field, and concatenate the field and the condition separately.
|
||||
$value_part = db_and();
|
||||
$value_part = new Condition('AND');
|
||||
$value_part->condition('anonymous_name', $condition['value'], $condition['operator']);
|
||||
$value_part->compile($this->connection, $query);
|
||||
$or->condition(db_and()
|
||||
$or->condition((new Condition('AND'))
|
||||
->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + [':anonymous_name' => \Drupal::config('user.settings')->get('anonymous')])
|
||||
->condition('base_table.uid', 0)
|
||||
);
|
||||
|
||||
@@ -52,7 +52,7 @@ class UserSearch extends SearchPluginBase implements AccessibleInterface {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
static public function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$container->get('database'),
|
||||
$container->get('entity.manager'),
|
||||
@@ -162,13 +162,15 @@ class UserSearch extends SearchPluginBase implements AccessibleInterface {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHelp() {
|
||||
$help = ['list' => [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => [
|
||||
$this->t('User search looks for user names and partial user names. Example: mar would match usernames mar, delmar, and maryjane.'),
|
||||
$this->t('You can use * as a wildcard within your keyword. Example: m*r would match user names mar, delmar, and elementary.'),
|
||||
$help = [
|
||||
'list' => [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => [
|
||||
$this->t('User search looks for user names and partial user names. Example: mar would match usernames mar, delmar, and maryjane.'),
|
||||
$this->t('You can use * as a wildcard within your keyword. Example: m*r would match user names mar, delmar, and elementary.'),
|
||||
],
|
||||
],
|
||||
]];
|
||||
];
|
||||
|
||||
return $help;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use Drupal\migrate\Row;
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "profile_field",
|
||||
* source_provider = "profile"
|
||||
* source_module = "profile"
|
||||
* )
|
||||
*/
|
||||
class ProfileField extends DrupalSqlBase {
|
||||
|
||||
@@ -11,7 +11,8 @@ use Drupal\migrate\Plugin\migrate\source\DummyQueryTrait;
|
||||
* @todo Support default picture?
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "user_picture_instance"
|
||||
* id = "user_picture_instance",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class UserPictureInstance extends DrupalSqlBase {
|
||||
@@ -28,7 +29,8 @@ class UserPictureInstance extends DrupalSqlBase {
|
||||
'file_directory' => $this->variableGet('user_picture_path', 'pictures'),
|
||||
'max_filesize' => $this->variableGet('user_picture_file_size', '30') . 'KB',
|
||||
'max_resolution' => $this->variableGet('user_picture_dimensions', '85x85'),
|
||||
]]);
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,7 +10,7 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_profile_field_values",
|
||||
* source_provider = "profile"
|
||||
* source_module = "profile"
|
||||
* )
|
||||
*/
|
||||
class ProfileFieldValues extends DrupalSqlBase {
|
||||
|
||||
@@ -9,7 +9,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
* Drupal 6 role source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user_role"
|
||||
* id = "d6_user_role",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class Role extends DrupalSqlBase {
|
||||
|
||||
@@ -9,7 +9,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
* Drupal 6 user source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user"
|
||||
* id = "d6_user",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class User extends DrupalSqlBase {
|
||||
|
||||
@@ -10,7 +10,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
* @todo Support default picture?
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user_picture"
|
||||
* id = "d6_user_picture",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class UserPicture extends DrupalSqlBase {
|
||||
|
||||
@@ -9,7 +9,8 @@ use Drupal\migrate\Row;
|
||||
* Drupal 6 user picture source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_user_picture_file"
|
||||
* id = "d6_user_picture_file",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class UserPictureFile extends DrupalSqlBase {
|
||||
|
||||
@@ -9,7 +9,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
* Drupal 7 role source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_user_role"
|
||||
* id = "d7_user_role",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class Role extends DrupalSqlBase {
|
||||
|
||||
@@ -9,7 +9,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
|
||||
* Drupal 7 user source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_user"
|
||||
* id = "d7_user",
|
||||
* source_module = "user"
|
||||
* )
|
||||
*/
|
||||
class User extends FieldableEntity {
|
||||
|
||||
@@ -51,10 +51,10 @@ class Uid extends NumericArgument {
|
||||
* Override the behavior of title(). Get the name of the user.
|
||||
*
|
||||
* @return array
|
||||
* A list of usernames.
|
||||
* A list of usernames.
|
||||
*/
|
||||
public function titleQuery() {
|
||||
return array_map(function($account) {
|
||||
return array_map(function ($account) {
|
||||
return $account->label();
|
||||
}, $this->storage->loadMultiple($this->value));
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\user\Plugin\views\filter;
|
||||
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Plugin\views\filter\BooleanOperator;
|
||||
@@ -28,7 +29,7 @@ class Current extends BooleanOperator {
|
||||
$this->ensureMyTable();
|
||||
|
||||
$field = $this->tableAlias . '.' . $this->realField . ' ';
|
||||
$or = db_or();
|
||||
$or = new Condition('OR');
|
||||
|
||||
if (empty($this->value)) {
|
||||
$or->condition($field, '***CURRENT_USER***', '<>');
|
||||
|
||||
@@ -115,7 +115,8 @@ class Name extends InOperator {
|
||||
$this->valueOptions[$account->id()] = $account->label();
|
||||
}
|
||||
else {
|
||||
$this->valueOptions[$account->id()] = 'Anonymous'; // Intentionally NOT translated.
|
||||
// Intentionally NOT translated.
|
||||
$this->valueOptions[$account->id()] = 'Anonymous';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class PrivateTempStoreFactory {
|
||||
/**
|
||||
* The lock object used for this data.
|
||||
*
|
||||
* @var \Drupal\Core\Lock\LockBackendInterface $lockBackend
|
||||
* @var \Drupal\Core\Lock\LockBackendInterface
|
||||
*/
|
||||
protected $lockBackend;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ class SharedTempStoreFactory {
|
||||
/**
|
||||
* The lock object used for this data.
|
||||
*
|
||||
* @var \Drupal\Core\Lock\LockBackendInterface $lockBackend
|
||||
* @var \Drupal\Core\Lock\LockBackendInterface
|
||||
*/
|
||||
protected $lockBackend;
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ class RestRegisterUserTest extends RESTTestBase {
|
||||
* @param bool $include_password
|
||||
* Whether to include a password in the user values.
|
||||
*
|
||||
* @return string Serialized user values.
|
||||
* @return string
|
||||
* Serialized user values.
|
||||
*/
|
||||
protected function createSerializedUser($name, $include_password = TRUE) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\user\Tests;
|
||||
|
||||
use Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
@@ -77,10 +78,30 @@ class UserBlocksTest extends WebTestBase {
|
||||
|
||||
// Now, log out and repeat with a non-403 page.
|
||||
$this->drupalLogout();
|
||||
$this->drupalPostForm('filter/tips', $edit, t('Log in'));
|
||||
$this->drupalGet('filter/tips');
|
||||
$this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER));
|
||||
$this->drupalPostForm(NULL, $edit, t('Log in'));
|
||||
$this->assertNoText(t('User login'), 'Logged in.');
|
||||
$this->assertPattern('!<title.*?' . t('Compose tips') . '.*?</title>!', 'Still on the same page after login for allowed page');
|
||||
|
||||
// Log out again and repeat with a non-403 page including query arguments.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('filter/tips', ['query' => ['foo' => 'bar']]);
|
||||
$this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER));
|
||||
$this->drupalPostForm(NULL, $edit, t('Log in'));
|
||||
$this->assertNoText(t('User login'), 'Logged in.');
|
||||
$this->assertPattern('!<title.*?' . t('Compose tips') . '.*?</title>!', 'Still on the same page after login for allowed page');
|
||||
$this->assertTrue(strpos($this->getUrl(), '/filter/tips?foo=bar') !== FALSE, 'Correct query arguments are displayed after login');
|
||||
|
||||
// Repeat with different query arguments.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('filter/tips', ['query' => ['foo' => 'baz']]);
|
||||
$this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER));
|
||||
$this->drupalPostForm(NULL, $edit, t('Log in'));
|
||||
$this->assertNoText(t('User login'), 'Logged in.');
|
||||
$this->assertPattern('!<title.*?' . t('Compose tips') . '.*?</title>!', 'Still on the same page after login for allowed page');
|
||||
$this->assertTrue(strpos($this->getUrl(), '/filter/tips?foo=baz') !== FALSE, 'Correct query arguments are displayed after login');
|
||||
|
||||
// Check that the user login block is not vulnerable to information
|
||||
// disclosure to third party sites.
|
||||
$this->drupalLogout();
|
||||
|
||||
@@ -130,7 +130,7 @@ class UserPasswordResetTest extends PageCacheTagsTestBase {
|
||||
|
||||
// Verify that the password reset session has been destroyed.
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertText(t('Your current password is missing or incorrect; it\'s required to change the Password.'), 'Password needed to make profile changes.');
|
||||
$this->assertText(t("Your current password is missing or incorrect; it's required to change the Password."), 'Password needed to make profile changes.');
|
||||
|
||||
// Log out, and try to log in again using the same one-time link.
|
||||
$this->drupalLogout();
|
||||
@@ -144,7 +144,7 @@ class UserPasswordResetTest extends PageCacheTagsTestBase {
|
||||
$before = count($this->drupalGetMails(['id' => 'user_password_reset']));
|
||||
$edit = ['name' => $this->account->getEmail()];
|
||||
$this->drupalPostForm(NULL, $edit, t('Submit'));
|
||||
$this->assertTrue( count($this->drupalGetMails(['id' => 'user_password_reset'])) === $before + 1, 'Email sent when requesting password reset using email address.');
|
||||
$this->assertTrue(count($this->drupalGetMails(['id' => 'user_password_reset'])) === $before + 1, 'Email sent when requesting password reset using email address.');
|
||||
|
||||
// Visit the user edit page without pass-reset-token and make sure it does
|
||||
// not cause an error.
|
||||
|
||||
@@ -33,6 +33,12 @@ class UserPictureTest extends WebTestBase {
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// This test expects unused managed files to be marked temporary and then
|
||||
// cleaned up by file_cron().
|
||||
$this->config('file.settings')
|
||||
->set('make_unused_managed_files_temporary', TRUE)
|
||||
->save();
|
||||
|
||||
$this->webUser = $this->drupalCreateUser([
|
||||
'access content',
|
||||
'access comments',
|
||||
|
||||
@@ -254,7 +254,7 @@ class UserRegistrationTest extends WebTestBase {
|
||||
$new_user = reset($accounts);
|
||||
$this->assertEqual($new_user->getUsername(), $name, 'Username matches.');
|
||||
$this->assertEqual($new_user->getEmail(), $mail, 'Email address matches.');
|
||||
$this->assertTrue(($new_user->getCreatedTime() > REQUEST_TIME - 20 ), 'Correct creation time.');
|
||||
$this->assertTrue(($new_user->getCreatedTime() > REQUEST_TIME - 20), 'Correct creation time.');
|
||||
$this->assertEqual($new_user->isActive(), $config_user_settings->get('register') == USER_REGISTER_VISITORS ? 1 : 0, 'Correct status field.');
|
||||
$this->assertEqual($new_user->getTimezone(), $config_system_date->get('timezone.default'), 'Correct time zone field.');
|
||||
$this->assertEqual($new_user->langcode->value, \Drupal::languageManager()->getDefaultLanguage()->getId(), 'Correct language field.');
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\user\Tests;
|
||||
|
||||
use Drupal\Core\Test\AssertMailTrait;
|
||||
|
||||
/**
|
||||
* Helper function for logging in from reset password email.
|
||||
*/
|
||||
trait UserResetEmailTestTrait {
|
||||
|
||||
use AssertMailTrait {
|
||||
getMails as drupalGetMails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login from reset password email.
|
||||
*/
|
||||
protected function loginFromResetEmail() {
|
||||
$_emails = $this->drupalGetMails();
|
||||
$email = end($_emails);
|
||||
$urls = [];
|
||||
preg_match('#.+user/reset/.+#', $email['body'], $urls);
|
||||
$resetURL = $urls[0];
|
||||
$this->drupalGet($resetURL);
|
||||
$this->drupalPostForm(NULL, NULL, 'Log in');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -126,10 +126,10 @@ class AccessRoleTest extends AccessTestBase {
|
||||
$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
|
||||
// DisplayPluginBase::applyDisplayCacheabilityMetadata() 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->assertTrue(in_array('user.roles', $build['#cache']['contexts']));
|
||||
// $this->assertEqual([], $build['#cache']['tags']);
|
||||
$this->assertEqual(Cache::PERMANENT, $build['#cache']['max-age']);
|
||||
$this->assertEqual($result, '');
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\user\Tests\Views;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ class HandlerFilterUserNameTest extends ViewTestBase {
|
||||
}
|
||||
|
||||
// Pass in just valid user IDs in the entity_autocomplete target_id format.
|
||||
$options['query']['uid'] = array_map(function($account) {
|
||||
$options['query']['uid'] = array_map(function ($account) {
|
||||
return ['target_id' => $account->id()];
|
||||
}, $this->accounts);
|
||||
|
||||
|
||||
@@ -78,10 +78,9 @@ class UserData implements UserDataInterface {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($module, $uid, $name, $value) {
|
||||
$serialized = 0;
|
||||
if (!is_scalar($value)) {
|
||||
$serialized = (int) !is_scalar($value);
|
||||
if ($serialized) {
|
||||
$value = serialize($value);
|
||||
$serialized = 1;
|
||||
}
|
||||
$this->connection->merge('users_data')
|
||||
->keys([
|
||||
|
||||
Reference in New Issue
Block a user