8.2.x node.api.php hook_node_grants(\Drupal\Core\Session\AccountInterface $account, $op)
8.0.x node.api.php hook_node_grants(\Drupal\Core\Session\AccountInterface $account, $op)
8.1.x node.api.php hook_node_grants(\Drupal\Core\Session\AccountInterface $account, $op)
4.6.x core.php hook_node_grants($user, $op)
4.7.x core.php hook_node_grants($user, $op)
5.x core.php hook_node_grants($account, $op)
6.x core.php hook_node_grants($account, $op)
7.x node.api.php hook_node_grants($account, $op)

Inform the node access system what permissions the user has.

This hook is for implementation by node access modules. In this hook, the module grants a user different "grant IDs" within one or more "realms". In hook_node_access_records(), the realms and grant IDs are associated with permission to view, edit, and delete individual nodes.

The realms and grant IDs can be arbitrarily defined by your node access module; it is common to use role IDs as grant IDs, but that is not required. Your module could instead maintain its own list of users, where each list has an ID. In that case, the return value of this hook would be an array of the list IDs that this user is a member of.

A node access module may implement as many realms as necessary to properly define the access privileges for the nodes. Note that the system makes no distinction between published and unpublished nodes. It is the module's responsibility to provide appropriate realms to limit access to unpublished content.

Node access records are stored in the {node_access} table and define which grants are required to access a node. There is a special case for the view operation -- a record with node ID 0 corresponds to a "view all" grant for the realm and grant ID of that record. If there are no node access modules enabled, the core node module adds a node ID 0 record for realm 'all'. Node access modules can also grant "view all" permission on their custom realms; for example, a module could create a record in {node_access} with:

$record = array(
  'nid' => 0,
  'gid' => 888,
  'realm' => 'example_realm',
  'grant_view' => 1,
  'grant_update' => 0,
  'grant_delete' => 0,
);
drupal_write_record('node_access', $record);

And then in its hook_node_grants() implementation, it would need to return:

if ($op == 'view') {
  $grants['example_realm'] = array(888);
}

If you decide to do this, be aware that the node_access_rebuild() function will erase any node ID 0 entry when it is called, so you will need to make sure to restore your {node_access} record after node_access_rebuild() is called.

Parameters

$account: The user object whose grants are requested.

$op: The node operation to be performed, such as 'view', 'update', or 'delete'.

Return value

An array whose keys are "realms" of grants, and whose values are arrays of the grant IDs within this realm that this user is being granted.

For a detailed example, see node_access_example.module.

See also

node_access_view_all_nodes()

node_access_rebuild()

Related topics

2 functions implement hook_node_grants()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

node_access_test_node_grants in modules/node/tests/node_access_test.module
Implements hook_node_grants().
node_test_node_grants in modules/node/tests/node_test.module
Implements hook_node_grants().
11 invocations of hook_node_grants()
block_form_system_performance_settings_alter in modules/block/block.module
Implements hook_form_FORM_ID_alter().
module_disable in includes/module.inc
Disables a given set of modules.
node_access in modules/node/node.module
Determines whether the current user may perform the operation on the node.
node_access_grants in modules/node/node.module
Fetches an array of permission IDs granted to the given user ID.
node_access_rebuild in modules/node/node.module
Rebuilds the node access database.

... See full list

File

modules/node/node.api.php, line 197
Hooks provided by the Node module.

Code

function hook_node_grants($account, $op) {
  if (user_access('access private content', $account)) {
    $grants['example'] = array(1);
  }
  $grants['example_author'] = array($account->uid);
  return $grants;
}

Comments

The documentation states:

The realms and grant IDs can be arbitrarily defined by your node access module; it is common to use role IDs as grant IDs, but that is not required.

Please note that he grant id must be an integer though.

In the hook_node_access_records already defines whether a grant defines view, delete or update rights. To me it seems unnecessary to provide 2 places to distinguish between operations. I think it would be better if users either have a grant or not, not depending on the type of operation.

When would it be necessary to use this $op at all?

i also don't understand the need for $op

Why is $node not an argument here? I am trying to hid snippets and search results using hook_node_grants() but I can only use $account and $op to do the filtering. This seems to just be mirroring the permissioning system.

I believe the idea is to use this in conjunction with hook_node_access_records(), which will deliver the node right to your front door, with a bow tie. A grant would be *somewhat* similar to a programmatically created instance "role", that can contain one or many users. This hook essentially defined those "roles" (grants id), and then hook_node_access_records() tells them, on a node-by-node basis, what that grant id has access to.

It should be noted that by implementing hook_node_grants you render all block caching useless. From the block.module file:

// Block caching is not compatible with node access modules.

Hi all, how are the priorities of the grants managed? If an entity has node_access data for only 2 realms, do we need to provide the values for all the realms in the hook_node_grants?
Also, can we give an array of grant ids from which to choose, or can node_grants only return one gid per realm?