You are here

function module_grants_node_revision_access in Module Grants 6.3

Same name and namespace in other branches
  1. 6.4 module_grants.module \module_grants_node_revision_access()
  2. 6 module_grants.module \module_grants_node_revision_access()

Menu options dealing with revisions have their revision-specific permissions checked via user_access(), before being tested for the associated node-specific operation. Return a boolean indicating whether the current user has access to the requested revision AND node.

Note, unlike _node_revision_access(), it is ok to also call this function on nodes that have only a single revision. Also unlike _node_revision_access(), the function below makes sure not to cache access to a revision based on vid alone, as different revision operations may be requested by various modules in response to a single HTTP request (read: mouse-click).

Parameters

$revision_op: The requested revision operation, e.g. 'view revisions'.

$node: Node object for which revision access is requested.

Return value

TRUE when the current user has the requested access to the supplied revision

See also

node.module, _node_revision_access()

1 string reference to 'module_grants_node_revision_access'
module_grants_menu_alter in ./module_grants.module
Implementation of hook_menu_alter().

File

./module_grants.module, line 300
Module to apply access grants to pre-published content just as they are to published content and to make multiple content access modules work together in the expected way.

Code

function module_grants_node_revision_access($revision_op, $node) {
  static $access = array();
  if (!$node) {
    return FALSE;
  }
  $vid = $node->vid;
  if (isset($access["{$vid}:{$revision_op}"])) {
    return $access["{$vid}:{$revision_op}"];
  }
  if (!isset($node->num_revisions) || !isset($node->is_current)) {
    drupal_set_message('Node object data incomplete -- have you enabled the Node Tools submodule?', 'warning', FALSE);
  }

  // See if other modules have anything to say about this revision_op, i.e.
  // whether they implement hook_user_node_access($revision_op, $node).
  $or_modules = variable_get('module_grants_OR_modules', FALSE);
  $hook = 'user_node_access';
  foreach (module_implements($hook) as $module) {
    $result = module_invoke($module, $hook, $revision_op, $node);
    if (!is_null($result)) {
      if ($or_modules) {
        if ($result) {

          // OR permissions together: return as soon as one succeeds
          break;
        }
      }
      elseif (!$result) {

        // AND permissons together: return as soon as one fails
        break;
      }
    }
  }

  // If no module implements hook_user_node_access() for this revision_op,
  // then fall back to the equivalent of what _node_revision_access() does, i.e.
  // check user permission, followed by node access.
  $node_op = is_null($result) ? _module_grants_user_node_access($revision_op, $node) : $result;
  if ($node_op && $node_op != 'view' && $node_op != 'update' && $node_op != 'delete') {
    drupal_set_message($module . '_' . $hook . " returns illegal node operation 'node_op'", 'warning', FALSE);
  }
  $access["{$vid}:{$revision_op}"] = $node_op && module_grants_node_access($node_op, $node);
  return $access["{$vid}:{$revision_op}"];
}