You are here

function module_grants_node_access in Module Grants 6

Same name and namespace in other branches
  1. 6.4 module_grants.module \module_grants_node_access()
  2. 6.3 module_grants.module \module_grants_node_access()
  3. 7 module_grants.module \module_grants_node_access()

Similar to node_access() in node.module but ANDs rather than ORs grants together on a per module base to create more natural behaviour. Also makes sure that published and unpublished content are treated in the same way, i.e. that grants are checked in either case.

Parameters

$op: One of 'view', 'update' or 'delete'. 'create' isn't used.

$node: The node for which the supplied operation is checked

$account: user object, use NULL or omit for current user

Return value

FALSE if the supplied operation isn't permitted on the node

2 calls to module_grants_node_access()
get_nodes in ./module_grants.module
Retrieve a list of nodes or revisions accessible to the logged-in user via the supplied operation.
module_grants_node_revision_access in ./module_grants.module
Menu options dealing with revisions have their revision-specific permission checked before being tested for the associated node-specific operation. Return a boolean indicating whether the current user has the requested permission AND access to the…
1 string reference to 'module_grants_node_access'
module_grants_menu_alter in ./module_grants.module
Implementation of hook_menu_alter().

File

./module_grants.module, line 141
Module to enable access control for unpublished content. Also makes sure that modules that operate on access grants behave in the expected way when enabled together.

Code

function module_grants_node_access($op, $node, $account = NULL) {
  global $user;
  if (!$node) {
    return FALSE;
  }

  // If the node is in a restricted format, disallow editing.
  if ($op == 'update' && !filter_access($node->format)) {
    return FALSE;
  }

  // If no user object is supplied, the access check is for the current user.
  if (empty($account)) {
    $account = $user;
  }
  if (user_access('administer nodes', $account)) {
    return TRUE;
  }
  if (!user_access('access content', $account)) {
    return FALSE;
  }
  $module = node_get_types('module', $node);
  if ($module == 'node') {
    $module = 'node_content';
  }
  $access = module_invoke($module, 'access', $op, $node, $account);
  if (!is_null($access)) {

    //drupal_set_message("'$op' access=$access by $module: '$node->title'", 'warning');
    return $access;
  }

  // If the module neither allows nor denies access, then find grants
  // amongst modules that implement hook_node_grants()
  $all_grants = grants_by_module($op, $account);
  $base_sql = "SELECT COUNT(*) FROM {node_access} WHERE (nid=0 OR nid=%d) AND ((gid=0 AND realm='all')";
  if (count($all_grants) == 0) {

    // no module implements hook_node_grants()
    $sql = "{$base_sql}) AND grant_{$op} >=1";
    $result = db_result(db_query($sql, $node->nid));
  }
  foreach ($all_grants as $module => $module_grants) {
    $sql = "{$base_sql} OR ({$module_grants})) AND grant_{$op} >=1";

    // Effectively AND module_grants together by breaking loop as soon as one fails
    // A single SQL statement may be slightly quicker but won't tells us
    // which of the modules denied access. This is useful debug feedback.
    $result = db_result(db_query($sql, $node->nid));

    //drupal_set_message("'$op' access=$result by $module-grants: '$node->title'", 'warning');
    if ($result == 0) {
      break;
    }
  }
  return $result;
}