diff --git a/core/modules/user/lib/Drupal/user/AccountFormController.php b/core/modules/user/lib/Drupal/user/AccountFormController.php index fdb39ae..98be615 100644 --- a/core/modules/user/lib/Drupal/user/AccountFormController.php +++ b/core/modules/user/lib/Drupal/user/AccountFormController.php @@ -9,6 +9,7 @@ use Drupal\Core\Entity\ContentEntityFormController; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Entity\Query\QueryFactory; use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageManager; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -26,6 +27,13 @@ protected $languageManager; /** + * The entity query factory service. + * + * @var \Drupal\Core\Entity\Query\QueryFactory + */ + protected $entityQuery; + + /** * Constructs a new EntityFormController object. * * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager @@ -33,9 +41,10 @@ * @param \Drupal\Core\Language\LanguageManager $language_manager * The language manager. */ - public function __construct(EntityManagerInterface $entity_manager, LanguageManager $language_manager) { + public function __construct(EntityManagerInterface $entity_manager, LanguageManager $language_manager, QueryFactory $entity_query) { parent::__construct($entity_manager); $this->languageManager = $language_manager; + $this->entityQuery = $entity_query; } /** @@ -44,7 +53,8 @@ public function __construct(EntityManagerInterface $entity_manager, LanguageMana public static function create(ContainerInterface $container) { return new static( $container->get('entity.manager'), - $container->get('language_manager') + $container->get('language_manager'), + $container->get('entity.query') ); } @@ -301,13 +311,12 @@ public function validate(array $form, array &$form_state) { // Cast the user ID as an integer. It might have been set to NULL, which // could lead to unexpected results. else { - $name_taken = (bool) db_select('users') - ->fields('users', array('uid')) - ->condition('uid', (int) $account->id(), '<>') - ->condition('name', db_like($form_state['values']['name']), 'LIKE') - ->range(0, 1) - ->execute() - ->fetchField(); + $name_taken = (bool) $this->entityQuery->get('user') + ->condition('uid', (int) $account->id(), '<>') + ->condition('name', $form_state['values']['name']) + ->range(0, 1) + ->count() + ->execute(); if ($name_taken) { form_set_error('name', $this->t('The name %name is already taken.', array('%name' => $form_state['values']['name']))); @@ -318,13 +327,12 @@ public function validate(array $form, array &$form_state) { $mail = $form_state['values']['mail']; if (!empty($mail)) { - $mail_taken = (bool) db_select('users') - ->fields('users', array('uid')) - ->condition('uid', (int) $account->id(), '<>') - ->condition('mail', db_like($mail), 'LIKE') - ->range(0, 1) - ->execute() - ->fetchField(); + $mail_taken = (bool) $this->entityQuery->get('user') + ->condition('uid', (int) $account->id(), '<>') + ->condition('mail', $mail) + ->range(0, 1) + ->count() + ->execute(); if ($mail_taken) { // Format error message dependent on whether the user is logged in or not. diff --git a/core/modules/user/lib/Drupal/user/Plugin/Block/UserNewBlock.php b/core/modules/user/lib/Drupal/user/Plugin/Block/UserNewBlock.php index 30b83c8..4add297 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Block/UserNewBlock.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Block/UserNewBlock.php @@ -10,7 +10,10 @@ use Drupal\block\BlockBase; use Drupal\block\Annotation\Block; use Drupal\Core\Annotation\Translation; +use Drupal\Core\Entity\Query\QueryFactory; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Session\AccountInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides a "Who's new" block. @@ -21,7 +24,34 @@ * category = @Translation("Lists (Views)") * ) */ -class UserNewBlock extends BlockBase { +class UserNewBlock extends BlockBase implements ContainerFactoryPluginInterface { + + /** + * The entity query factory service. + * + * @var \Drupal\Core\Entity\Query\QueryFactory + */ + protected $entityQuery; + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity.query') + ); + } + + /** + * {@inheritdoc} + */ + public function __construct(array $configuration, $plugin_id, array $plugin_definition, QueryFactory $entity_query) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->entityQuery = $entity_query; + } /** * {@inheritdoc} @@ -67,7 +97,13 @@ public function blockSubmit($form, &$form_state) { */ public function build() { // Retrieve a list of new users who have accessed the site successfully. - $uids = db_query_range('SELECT uid FROM {users} WHERE status <> 0 AND access <> 0 ORDER BY created DESC', 0, $this->configuration['whois_new_count'])->fetchCol(); + $uids = $this->entityQuery->get('user') + ->condition('status', 0, '<>') + ->condition('access', 0, '<>') + ->sort('created', 'DESC') + ->range(0, $this->configuration['whois_new_count']) + ->execute(); + $build = array( '#theme' => 'item_list__user__new', '#items' => array(), diff --git a/core/modules/user/lib/Drupal/user/Plugin/Block/UserOnlineBlock.php b/core/modules/user/lib/Drupal/user/Plugin/Block/UserOnlineBlock.php index 9a647a5..7115f4d 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Block/UserOnlineBlock.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Block/UserOnlineBlock.php @@ -10,7 +10,10 @@ use Drupal\block\BlockBase; use Drupal\block\Annotation\Block; use Drupal\Core\Annotation\Translation; +use Drupal\Core\Entity\Query\QueryFactory; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Session\AccountInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides a "Who's online" block. @@ -24,7 +27,34 @@ * category = @Translation("Lists (Views)") * ) */ -class UserOnlineBlock extends BlockBase { +class UserOnlineBlock extends BlockBase implements ContainerFactoryPluginInterface { + + /** + * The entity query factory service. + * + * @var \Drupal\Core\Entity\Query\QueryFactory + */ + protected $entityQuery; + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity.query') + ); + } + + /** + * {@inheritdoc} + */ + public function __construct(array $configuration, $plugin_id, array $plugin_definition, QueryFactory $entity_query) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->entityQuery = $entity_query; + } /** * {@inheritdoc} @@ -84,7 +114,10 @@ public function build() { $interval = REQUEST_TIME - $this->configuration['seconds_online']; // Perform database queries to gather online user lists. - $authenticated_count = db_query("SELECT COUNT(uid) FROM {users} WHERE access >= :timestamp", array(':timestamp' => $interval))->fetchField(); + $authenticated_count = $this->entityQuery->get('user') + ->condition('access', $interval, '>=') + ->count() + ->execute(); $build = array( '#theme' => 'item_list__user__online', @@ -94,7 +127,13 @@ public function build() { // Display a list of currently online users. $max_users = $this->configuration['max_list_count']; if ($authenticated_count && $max_users) { - $uids = db_query_range('SELECT uid FROM {users} WHERE access >= :interval AND uid > 0 ORDER BY access DESC', 0, $max_users, array(':interval' => $interval))->fetchCol(); + $uids = $this->entityQuery->get('user') + ->condition('access', $interval, '>=') + ->condition('uid', 0, '>') + ->sort('access', 'DESC') + ->range(0, $max_users) + ->execute(); + foreach (user_load_multiple($uids) as $account) { $username = array( '#theme' => 'username', diff --git a/core/modules/user/lib/Drupal/user/Plugin/Validation/Constraint/UserUniqueValidator.php b/core/modules/user/lib/Drupal/user/Plugin/Validation/Constraint/UserUniqueValidator.php index 945223f..f169cae 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Validation/Constraint/UserUniqueValidator.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Validation/Constraint/UserUniqueValidator.php @@ -22,14 +22,13 @@ public function validate($value, Constraint $constraint) { $field = $this->context->getMetadata()->getTypedData()->getParent(); $uid = $field->getParent()->id(); - $value_taken = (bool) db_select('users') - ->fields('users', array('uid')) + $value_taken = (bool) \Drupal::entityQuery('user') // The UID could be NULL, so we cast it to 0 in that case. ->condition('uid', (int) $uid, '<>') - ->condition($field->getName(), db_like($value), 'LIKE') + ->condition($field->getName(), $value) ->range(0, 1) - ->execute() - ->fetchField(); + ->count() + ->execute(); if ($value_taken) { $this->context->addViolation($constraint->message, array("%value" => $value)); diff --git a/core/modules/user/lib/Drupal/user/ProfileFormController.php b/core/modules/user/lib/Drupal/user/ProfileFormController.php index 3c36981..282edca 100644 --- a/core/modules/user/lib/Drupal/user/ProfileFormController.php +++ b/core/modules/user/lib/Drupal/user/ProfileFormController.php @@ -8,6 +8,8 @@ namespace Drupal\user; use Drupal\Core\Cache\Cache; +use Drupal\Core\Entity\Query\QueryFactory; +use Drupal\Core\Language\LanguageManager; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -19,6 +21,13 @@ class ProfileFormController extends AccountFormController { /** * {@inheritdoc} */ + public function __construct(LanguageManager $language_manager, QueryFactory $entity_query) { + parent::__construct($language_manager, $entity_query); + } + + /** + * {@inheritdoc} + */ protected function actions(array $form, array &$form_state) { $element = parent::actions($form, $form_state); diff --git a/core/modules/user/lib/Drupal/user/RegisterFormController.php b/core/modules/user/lib/Drupal/user/RegisterFormController.php index 38612a2..73aa395 100644 --- a/core/modules/user/lib/Drupal/user/RegisterFormController.php +++ b/core/modules/user/lib/Drupal/user/RegisterFormController.php @@ -7,6 +7,9 @@ namespace Drupal\user; +use Drupal\Core\Entity\Query\QueryFactory; +use Drupal\Core\Language\LanguageManager; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; /** @@ -15,6 +18,13 @@ class RegisterFormController extends AccountFormController { /** + * {@inheritdoc} + */ + public function __construct(LanguageManager $language_manager, QueryFactory $entity_query) { + parent::__construct($language_manager, $entity_query); + } + + /** * Overrides Drupal\Core\Entity\EntityFormController::form(). */ public function form(array $form, array &$form_state) { diff --git a/core/modules/user/lib/Drupal/user/UserAutocomplete.php b/core/modules/user/lib/Drupal/user/UserAutocomplete.php index 4d36923..c0873db 100644 --- a/core/modules/user/lib/Drupal/user/UserAutocomplete.php +++ b/core/modules/user/lib/Drupal/user/UserAutocomplete.php @@ -9,6 +9,9 @@ use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Database\Connection; +use Drupal\Core\Entity\EntityManager; +use Drupal\Core\Entity\Query\QueryFactory; +use Drupal\Component\Utility\String; /** * Defines a helper class to get user autocompletion results. @@ -30,6 +33,20 @@ class UserAutocomplete { protected $configFactory; /** + * The entity query factory service. + * + * @var \Drupal\Core\Entity\Query\QueryFactory + */ + protected $entityQuery; + + /** + * The entity manager service. + * + * @var \Drupal\Core\Entity\EntityManager + */ + protected $entityManager; + + /** * Constructs a UserAutocomplete object. * * @param \Drupal\Core\Database\Connection $connection @@ -37,9 +54,11 @@ class UserAutocomplete { * @param \Drupal\Core\Config\ConfigFactory $config_factory * The config factory. */ - public function __construct(Connection $connection, ConfigFactory $config_factory) { + public function __construct(Connection $connection, ConfigFactory $config_factory, EntityManager $entity_manager, QueryFactory $entity_query) { $this->connection = $connection; $this->configFactory = $config_factory; + $this->entityQuery = $entity_query; + $this->entityManager = $entity_manager; } /** @@ -65,9 +84,15 @@ public function getMatches($string, $include_anonymous = FALSE) { $matches[$anonymous_name] = check_plain($anonymous_name); } } - $result = $this->connection->select('users')->fields('users', array('name'))->condition('name', db_like($string) . '%', 'LIKE')->range(0, 10)->execute(); - foreach ($result as $account) { - $matches[$account->name] = check_plain($account->name); + + $uids = $this->entityQuery->get('user') + ->condition('name', $string, 'STARTS_WITH') + ->range(0, 10) + ->execute(); + + $controller = $this->entityManager->getStorageController('user'); + foreach ($controller->loadMultiple($uids) as $account) { + $matches[$account->getUsername()] = String::checkPlain($account->getUsername()); } } diff --git a/core/modules/user/lib/Drupal/user/UserStorageController.php b/core/modules/user/lib/Drupal/user/UserStorageController.php index 48e8206..0d7ffe5 100644 --- a/core/modules/user/lib/Drupal/user/UserStorageController.php +++ b/core/modules/user/lib/Drupal/user/UserStorageController.php @@ -114,7 +114,7 @@ public function save(EntityInterface $entity) { /** * {@inheritdoc} */ - public function saveRoles(EntityInterface $user) { + public function saveRoles(UserInterface $user) { $query = $this->database->insert('users_roles')->fields(array('uid', 'rid')); foreach ($user->getRoles() as $rid) { if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { @@ -131,7 +131,7 @@ public function saveRoles(EntityInterface $user) { * {@inheritdoc} */ public function addRoles(array $users) { - $result = db_query('SELECT rid, uid FROM {users_roles} WHERE uid IN (:uids)', array(':uids' => array_keys($users))); + $result = $this->database->query('SELECT rid, uid FROM {users_roles} WHERE uid IN (:uids)', array(':uids' => array_keys($users))); foreach ($result as $record) { $users[$record->uid]->roles[] = $record->rid; } @@ -146,4 +146,14 @@ public function deleteUserRoles(array $uids) { ->execute(); } + /** + * {@inheritdoc} + */ + public function updateLastLoginTimestamp(UserInterface $account) { + $this->database->update('users') + ->fields(array('login' => $account->getLastLoginTime())) + ->condition('uid', $account->id()) + ->execute(); + } + } diff --git a/core/modules/user/lib/Drupal/user/UserStorageControllerInterface.php b/core/modules/user/lib/Drupal/user/UserStorageControllerInterface.php index 114a24c..ec4348d 100644 --- a/core/modules/user/lib/Drupal/user/UserStorageControllerInterface.php +++ b/core/modules/user/lib/Drupal/user/UserStorageControllerInterface.php @@ -25,9 +25,9 @@ public function addRoles(array $users); /** * Save the user's roles. * - * @param \Drupal\Core\Entity\EntityInterface $user + * @param \Drupal\user\UserInterface $account */ - public function saveRoles(EntityInterface $user); + public function saveRoles(UserInterface $user); /** * Remove the roles of a user. @@ -36,4 +36,10 @@ public function saveRoles(EntityInterface $user); */ public function deleteUserRoles(array $uids); + /** + * Update the last login timestamp of the user. + * + * @param \Drupal\user\UserInterface $account + */ + public function updateLastLoginTimestamp(UserInterface $account); } diff --git a/core/modules/user/user.api.php b/core/modules/user/user.api.php index 6533c0e..80209d8 100644 --- a/core/modules/user/user.api.php +++ b/core/modules/user/user.api.php @@ -118,22 +118,18 @@ function hook_user_cancel($edit, $account, $method) { case 'user_cancel_block_unpublish': // Unpublish nodes (current revisions). module_load_include('inc', 'node', 'node.admin'); - $nodes = db_select('node_field_data', 'n') - ->fields('n', array('nid')) - ->condition('uid', $account->id()) - ->execute() - ->fetchCol(); + $nodes = \Drupal::entityQuery('node') + ->condition('uid', $user->id()) + ->execute(); node_mass_update($nodes, array('status' => 0), NULL, TRUE); break; case 'user_cancel_reassign': // Anonymize nodes (current revisions). module_load_include('inc', 'node', 'node.admin'); - $nodes = db_select('node_field_data', 'n') - ->fields('n', array('nid')) - ->condition('uid', $account->id()) - ->execute() - ->fetchCol(); + $nodes = \Drupal::entityQuery('node') + ->condition('uid', $user->id()) + ->execute(); node_mass_update($nodes, array('uid' => 0), NULL, TRUE); // Anonymize old revisions. db_update('node_field_revision') diff --git a/core/modules/user/user.module b/core/modules/user/user.module index b55cee6..c68d005 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -464,16 +464,14 @@ function user_access($string, AccountInterface $account = NULL) { * @param $name * A string containing a name of the user. * - * @return - * Object with property 'name' (the user name), if the user is blocked; - * FALSE if the user is not blocked. + * @return bool + * TRUE if the user is blocked, FALSE otherwise. */ function user_is_blocked($name) { - return db_select('users') - ->fields('users', array('name')) - ->condition('name', db_like($name), 'LIKE') + return (bool) \Drupal::entityQuery('user') + ->condition('name', $name) ->condition('status', 0) - ->execute()->fetchObject(); + ->execute(); } /** @@ -1000,21 +998,20 @@ function user_authenticate($name, $password) { function user_login_finalize(UserInterface $account) { global $user; $user = $account; - watchdog('user', 'Session opened for %name.', array('%name' => $user->getUsername())); + watchdog('user', 'Session opened for %name.', array('%name' => $account->getUsername())); // Update the user table timestamp noting user has logged in. // This is also used to invalidate one-time login links. $account->setLastLoginTime(REQUEST_TIME); - db_update('users') - ->fields(array('login' => $user->getLastLoginTime())) - ->condition('uid', $user->id()) - ->execute(); + \Drupal::entityManager() + ->getStorageController('user') + ->updateLastLoginTimestamp($account); // Regenerate the session ID to prevent against session fixation attacks. // This is called before hook_user in case one of those functions fails // or incorrectly does a redirect which would leave the old session in place. drupal_session_regenerate(); - \Drupal::moduleHandler()->invokeAll('user_login', array($user)); + \Drupal::moduleHandler()->invokeAll('user_login', array($account)); } /** @@ -1792,12 +1789,12 @@ function user_node_load($nodes, $types) { $uids[$nid] = $node->getAuthorId(); } - // Fetch name and data for these users. - $user_names = db_query("SELECT uid, name FROM {users} WHERE uid IN (:uids)", array(':uids' => $uids))->fetchAllKeyed(); - - // Add these values back into the node objects. + // Add loaded user name values back into the node objects. + $users = \Drupal::entityManager() + ->getStorageController('user') + ->loadMultiple($uids); foreach ($uids as $nid => $uid) { - $nodes[$nid]->name = $user_names[$uid]; + $nodes[$nid]->name = $users[$uid]->getUsername(); } } diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml index 6fb7d47..c1cc9fb 100644 --- a/core/modules/user/user.services.yml +++ b/core/modules/user/user.services.yml @@ -20,7 +20,7 @@ services: arguments: ['@database'] user.autocomplete: class: Drupal\user\UserAutocomplete - arguments: ['@database', '@config.factory'] + arguments: ['@database', '@config.factory', '@entity.manager', '@entity.query'] user_maintenance_mode_subscriber: class: Drupal\user\EventSubscriber\MaintenanceModeSubscriber tags: