| Versions | |
|---|---|
| 7 | _node_query_node_access_alter($query, $base_table, $type) |
Helper for node access functions.
$query The query to add conditions to.
$base_table The table holding node ids.
$type Either 'node' or 'entity' depending on what sort of query it is. See node_query_node_access_alter() and node_query_entity_field_access_alter() for more.
drupal/
<?php
function _node_query_node_access_alter($query, $base_table, $type) {
global $user;
// Read meta-data from query, if provided.
if (!$account = $query->getMetaData('account')) {
$account = $user;
}
if (!$op = $query->getMetaData('op')) {
$op = 'view';
}
// If $account can bypass node access, or there are no node access modules,
// or the operation is 'view' and the $acount has a global view grant (i.e.,
// a view grant for node ID 0), we don't need to alter the query.
if (user_access('bypass node access', $account)) {
return;
}
if (!count(module_implements('node_grants'))) {
return;
}
if ($op == 'view' && node_access_view_all_nodes($account)) {
return;
}
// Prevent duplicate records.
$query->distinct();
// Find all instances of the {node} table being joined -- could appear
// more than once in the query, and could be aliased. Join each one to
// the node_access table.
$tables = $query->getTables();
$grants = node_access_grants($op, $account);
if ($type == 'entity') {
// The original query looked something like:
// @code
// SELECT nid FROM sometable s
// INNER JOIN node_access na ON na.nid = s.nid
// WHERE ($node_access_conditions)
// @endcode
//
// Our query will look like:
// @code
// SELECT entity_type, entity_id
// FROM field_data_something s
// LEFT JOIN node_access na ON s.entity_id = na.nid
// WHERE (entity_type = 'node' AND $node_access_conditions) OR (entity_type <> 'node')
// @endcode
//
// So instead of directly adding to the query object, we need to collect
// in a separate db_and() object and then at the end add it to the query.
$entity_conditions = db_and();
}
foreach ($tables as $nalias => $tableinfo) {
$table = $tableinfo['table'];
if (!($table instanceof SelectQueryInterface) && $table == $base_table) {
// The node_access table has the access grants for any given node so JOIN
// it to the table containing the nid which can be either the node
// table or a field value table.
if ($type == 'node') {
$access_alias = $query->join('node_access', 'na', '%alias.nid = ' . $nalias . '.nid');
}
else {
$access_alias = $query->leftJoin('node_access', 'na', '%alias.nid = ' . $nalias . '.entity_id');
$base_alias = $nalias;
}
$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($access_alias . '.gid', $gid)
->condition($access_alias . '.realm', $realm)
);
}
}
$count = count($grant_conditions->conditions());
if ($type == 'node') {
if ($count) {
$query->condition($grant_conditions);
}
$query->condition($access_alias . '.grant_' . $op, 1, '>=');
}
else {
if ($count) {
$entity_conditions->condition($grant_conditions);
}
$entity_conditions->condition($access_alias . '.grant_' . $op, 1, '>=');
}
}
}
if ($type == 'entity' && count($entity_conditions->conditions())) {
// All the node access conditions are only for field values belonging to
// nodes.
$entity_conditions->condition("$base_alias.entity_type", 'node');
$or = db_or();
$or->condition($entity_conditions);
// If the field value belongs to a non-node entity type then this function
// does not do anything with it.
$or->condition("$base_alias.entity_type", 'node', '<>');
// Add the compiled set of rules to the query.
$query->condition($or);
}
}
?>