Issue #106721 by msonnabaum, lotyrin, erikwebb, catch, ezra-g, joelpittet, oleg.medvedev, jrglasgow, dawehner, bdragon: Optimize node access queries.

8.0.x
Nathaniel Catchpole 2014-03-05 09:41:12 +00:00
parent 486edae6c8
commit d1d797046f
1 changed files with 30 additions and 26 deletions

View File

@ -9,6 +9,7 @@ namespace Drupal\node;
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 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
$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 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
->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 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
$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 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
->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;
}
}