Commit 0f704ad9 authored by alexpott's avatar alexpott

Issue #2068329 by peximo, plach, LinL, marcingy, Désiré, penyaskito, herom,...

Issue #2068329 by peximo, plach, LinL, marcingy, Désiré, penyaskito, herom, chx: Convert user SQL queries to the Entity Query API.
parent edb46e0c
......@@ -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\LanguageManagerInterface;
use Drupal\language\ConfigurableLanguageManagerInterface;
......@@ -28,6 +29,13 @@ abstract class AccountFormController extends ContentEntityFormController {
*/
protected $languageManager;
/**
* The entity query factory service.
*
* @var \Drupal\Core\Entity\Query\QueryFactory
*/
protected $entityQuery;
/**
* Constructs a new EntityFormController object.
*
......@@ -35,10 +43,13 @@ abstract class AccountFormController extends ContentEntityFormController {
* The entity manager.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
* @param \Drupal\Core\Entity\Query\QueryFactory
* The entity query factory.
*/
public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager) {
public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, QueryFactory $entity_query) {
parent::__construct($entity_manager);
$this->languageManager = $language_manager;
$this->entityQuery = $entity_query;
}
/**
......@@ -47,7 +58,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')
);
}
......@@ -304,13 +316,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) {
$this->setFormError('name', $form_state, $this->t('The name %name is already taken.', array('%name' => $form_state['values']['name'])));
......@@ -321,13 +332,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.
......
......@@ -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));
......
......@@ -8,14 +8,22 @@
namespace Drupal\user;
use Drupal\Core\Cache\Cache;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\Language\LanguageManager;
/**
* Form controller for the profile forms.
*/
class ProfileFormController extends AccountFormController {
/**
* {@inheritdoc}
*/
public function __construct(EntityManagerInterface $entity_manager, LanguageManager $language_manager, QueryFactory $entity_query) {
parent::__construct($entity_manager, $language_manager, $entity_query);
}
/**
* {@inheritdoc}
*/
......
......@@ -7,6 +7,9 @@
namespace Drupal\user;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\Language\LanguageManager;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
......@@ -14,6 +17,13 @@
*/
class RegisterFormController extends AccountFormController {
/**
* {@inheritdoc}
*/
public function __construct(EntityManagerInterface $entity_manager, LanguageManager $language_manager, QueryFactory $entity_query) {
parent::__construct($entity_manager, $language_manager, $entity_query);
}
/**
* Overrides Drupal\Core\Entity\EntityFormController::form().
*/
......
......@@ -10,6 +10,8 @@
use Drupal\Component\Utility\String;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Entity\Query\QueryFactory;
/**
* Defines a helper class to get user autocompletion results.
......@@ -30,6 +32,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.
*
......@@ -38,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;
}
/**
......@@ -66,9 +84,14 @@ public function getMatches($string, $include_anonymous = FALSE) {
$matches[] = array('value' => $anonymous_name, 'label' => String::checkPlain($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[] = array('value' => $account->name, 'label' => String::checkPlain($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[] = array('value' => $account->getUsername(), 'label' => String::checkPlain($account->getUsername()));
}
}
......
......@@ -112,12 +112,12 @@ public function save(EntityInterface $entity) {
/**
* {@inheritdoc}
*/
public function saveRoles(EntityInterface $user) {
public function saveRoles(UserInterface $account) {
$query = $this->database->insert('users_roles')->fields(array('uid', 'rid'));
foreach ($user->getRoles() as $rid) {
foreach ($account->getRoles() as $rid) {
if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
$query->values(array(
'uid' => $user->id(),
'uid' => $account->id(),
'rid' => $rid,
));
}
......@@ -129,7 +129,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;
}
......@@ -144,4 +144,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();
}
}
......@@ -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 $account);
/**
* 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);
}
......@@ -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')
......
......@@ -443,16 +443,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();
}
/**
......@@ -966,21 +964,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));
}
/**
......
......@@ -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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment