diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 4bd7862..91d27e8 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -1044,7 +1044,7 @@ function node_query_node_access_alter(AlterableInterface $query) { return; } - $tables = &$query->getTables(); + $tables = $query->getTables(); $base_table = $query->getMetaData('base_table'); // If the base table is not given, default to node if present. if (!$base_table) { diff --git a/core/modules/node/src/NodeGrantDatabaseStorage.php b/core/modules/node/src/NodeGrantDatabaseStorage.php index 63c5148..276b6f8 100644 --- a/core/modules/node/src/NodeGrantDatabaseStorage.php +++ b/core/modules/node/src/NodeGrantDatabaseStorage.php @@ -152,15 +152,27 @@ public function checkAll(AccountInterface $account) { /** * {@inheritdoc} */ - public function alterQuery($query, array &$tables, $op, AccountInterface $account, $base_table) { + public function alterQuery($query, array $tables, $op, AccountInterface $account, $base_table) { if (!$langcode = $query->getMetaData('langcode')) { $langcode = FALSE; } + // $tables_ref should effectively be the same as $tables, except it is a + // reference to the original copy of the data, within the $query object. + // Edits made to $tables_ref are retained within the $query object. + // $tables_ref would not be necessary if the version of $tables in + // the alterQuery arguments was passed by reference -- but that + // would technically be an API change. + $tables_ref = &$query->getTables(); + // Find all instances of the base table being joined -- could appear // more than once in the query, and could be aliased. Join each one to // the node_access table. $grants = node_access_grants($op, $account); + + // The main loop is using $tables instead of $tables_ref -- if for any + // reason the two arrays differ, technically this function has been + // told to operate on the entries listed in $tables. foreach ($tables as $nalias => $tableinfo) { $table = $tableinfo['table']; if (!($table instanceof SelectInterface) && $table == $base_table) { @@ -195,23 +207,25 @@ public function alterQuery($query, array &$tables, $op, AccountInterface $accoun // Now handle entities. $subquery->where("$nalias.$field = na.nid"); - if (empty($tableinfo['join type'])) { + if (empty($tableinfo['join type']) || empty($tables_ref[$nalias]['join type'])) { $query->exists($subquery); } else { // If it's a join, add the node access check to the join condition. + // This requires altering the table information -- and therefore has + // to use $tables_ref instead of $tables. $join_cond = $query ->andConditionGroup() ->exists($subquery); // Add the existing join conditions into the Condition object. - if ($tables[$nalias]['condition'] instanceof ConditionInterface) { - $join_cond->condition($tables[$nalias]['condition']); + if ($tables_ref[$nalias]['condition'] instanceof ConditionInterface) { + $join_cond->condition($tables_ref[$nalias]['condition']); } else { - $join_cond->where($tables[$nalias]['condition'], $tables[$nalias]['arguments']); - $tables[$nalias]['arguments'] = array(); + $join_cond->where($tables_ref[$nalias]['condition'], $tables_ref[$nalias]['arguments']); + $tables_ref[$nalias]['arguments'] = array(); } - $tables[$nalias]['condition'] = $join_cond; + $tables_ref[$nalias]['condition'] = $join_cond; } } } diff --git a/core/modules/node/src/NodeGrantDatabaseStorageInterface.php b/core/modules/node/src/NodeGrantDatabaseStorageInterface.php index 3cf8b7c..c59f941 100644 --- a/core/modules/node/src/NodeGrantDatabaseStorageInterface.php +++ b/core/modules/node/src/NodeGrantDatabaseStorageInterface.php @@ -50,7 +50,7 @@ public function checkAll(AccountInterface $account); * @return int * Status of the access check. */ - public function alterQuery($query, array &$tables, $op, AccountInterface $account, $base_table); + public function alterQuery($query, array $tables, $op, AccountInterface $account, $base_table); /** * Writes a list of grants to the database, deleting previously saved ones.