Skip to content

Instantly share code, notes, and snippets.

@aklump
Last active January 19, 2018 23:36
Show Gist options
  • Save aklump/19e30bb9e46a97d59669 to your computer and use it in GitHub Desktop.
Save aklump/19e30bb9e46a97d59669 to your computer and use it in GitHub Desktop.
Drupal 7 node access per entity using a field dropdown, callback functions and the node access API.
<?php
/**
* Shows how to create a field that controls node access in Drupal 7 based
* on callback functions using the node access API and a field select list;
* so that content managers can easily control per-entity access control
* using a simply dropdown.
*
* 1. Create a custom module and insert the following 3 functions.
* 2. Create a List(text) field called field_access with widget select and
* attach it to the entity where you want to control access.
* 3. The values of of field_access should be a list of function|Option, e.g.,
*
* TRUE|Public
* user_is_logged_in|Auth. User
*
* 4. Each function will receive the same arguments as hook_node_grants:
* $account and $op
*
* 5. The function should return TRUE if access should be granted to user.
* 6. Rebuild access permission if needed: admin/reports/status/rebuild
*/
/**
* Implements hook_node_grants().
*/
function module_name_node_grants($account, $op) {
$grants = array();
foreach (_module_name_get_functions_gids() as $callback => $gid) {
if ($callback($account, $op)) {
$grants['functions'][] = $gid;
}
}
return $grants;
}
/**
* Returns a map of functions to gids.
*
* @return array
* In this format function => gid.
*/
function _module_name_get_functions_gids() {
static $gids;
if (!isset($gids)) {
$info = field_info_field('field_access');
$gids = array_keys($info['settings']['allowed_values']);
$gids = array_filter($gids, function($callback) {
return function_exists($callback);
});
$gids = array_combine($gids, range(1, count($gids)));
}
return $gids;
}
/**
* Implements hook_node_access_records().
*/
function module_name_node_access_records($node) {
if (empty($node->field_access['und'][0]['value'])) {
return;
}
$function = &$node->field_access['und'][0]['value'];
$function = $function === 'TRUE' ? TRUE : $function;
$function = $function === 'FALSE' ? FALSE : $function;
if ($function === TRUE) {
return;
}
//first you need to negate published access in the realm all by setting
//everything to FALSE
$grants[] = array(
'realm' => 'all',
'gid' => 0,
'grant_view' => 0,
'grant_update' => 0,
'grant_delete' => 0,
'priority' => $priority,
);
$gids = _module_name_get_functions_gids();
if (is_string($function) && isset($gids[$function])) {
$grants[] = array(
'realm' => 'functions',
'gid' => $gids[$function],
'grant_view' => 1,
'grant_update' => 0,
'grant_delete' => 0,
'priority' => $priority,
);
}
return $grants;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment