Commit d1d79704 authored by catch's avatar catch

Issue #106721 by msonnabaum, lotyrin, erikwebb, catch, ezra-g, joelpittet,...

Issue #106721 by msonnabaum, lotyrin, erikwebb, catch, ezra-g, joelpittet, oleg.medvedev, jrglasgow, dawehner, bdragon: Optimize node access queries.
parent 486edae6
......@@ -9,6 +9,7 @@
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
......@@ -79,14 +80,7 @@ public function access(NodeInterface $node, $operation, $langcode, AccountInterf
$query->condition($nids);
$query->range(0, 1);
$grants = $query->orConditionGroup();
foreach (node_access_grants($operation, $account) as $realm => $gids) {
foreach ($gids as $gid) {
$grants->condition(db_and()
->condition('gid', $gid)
->condition('realm', $realm));
}
}
$grants = static::buildGrantsQueryCondition(node_access_grants($operation, $account));
if (count($grants) > 0) {
$query->condition($grants);
......@@ -105,15 +99,8 @@ public function checkAll(AccountInterface $account) {
->condition('nid', 0)
->condition('grant_view', 1, '>=');
$grants = db_or();
foreach (node_access_grants('view', $account) as $realm => $gids) {
foreach ($gids as $gid) {
$grants->condition(db_and()
->condition('gid', $gid)
->condition('realm', $realm)
);
}
}
$grants = static::buildGrantsQueryCondition(node_access_grants('view', $account));
if (count($grants) > 0 ) {
$query->condition($grants);
}
......@@ -139,17 +126,9 @@ public function alterQuery($query, array $tables, $op, AccountInterface $account
$subquery = $this->database->select('node_access', 'na')
->fields('na', array('nid'));
$grant_conditions = db_or();
// If any grant exists for the specified user, then user has access to the
// node for the specified operation.
foreach ($grants as $realm => $gids) {
foreach ($gids as $gid) {
$grant_conditions->condition(db_and()
->condition('na.gid', $gid)
->condition('na.realm', $realm)
);
}
}
$grant_conditions = static::buildGrantsQueryCondition($grants);
// Attach conditions to the subquery for nodes.
if (count($grant_conditions->conditions())) {
......@@ -264,4 +243,29 @@ public function deleteNodeRecords(array $nids) {
->execute();
}
/**
* Creates a query condition from an array of node access grants.
*
* @param array $node_access_grants
* An array of grants, as returned by node_access_grants().
* @return \Drupal\Core\Database\Query\Condition
* A condition object to be passed to $query->condition().
*
* @see node_access_grants()
*/
static function buildGrantsQueryCondition(array $node_access_grants) {
$grants = new Condition("OR");
foreach ($node_access_grants as $realm => $gids) {
if (!empty($gids)) {
$and = new Condition('AND');
$grants->condition($and
->condition('gid', $gids, 'IN')
->condition('realm', $realm)
);
}
}
return $grants;
}
}
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