function _acb_cascade_grants in Access Control Bridge 8
Same name and namespace in other branches
- 7 acb.module \_acb_cascade_grants()
The beating heart of this module. Receives split-sorted grants and converts it into cascaded grants to be used by this module. Workhorse for both hook_node_grants_alter() and hook_node_access_records_alter().
Parameters
array $grants: The recursive grants array.
bool $access_records: (optional) Boolean indicating if we should cascade access records (TRUE) or not user grants (FALSE)
array $output: (optional) The final output array used for recursing.
array $realm: (optional) The realm storage array used for recursing.
bool $view: (optional) The grant_view value used for recursing.
bool $update: (optional) The grant_update value used for recursing.
bool $delete: (optional) The grant_delete value used for recursing.
Return value
array The output grants array.
2 calls to _acb_cascade_grants()
- acb_node_access_records_alter in ./
acb.module - Implements hook_node_access_records_alter().
- acb_node_grants_alter in ./
acb.module - Implements hook_node_grants_alter().
File
- ./
acb.module, line 249 - Drupal hooks and functions for the acb module.
Code
function _acb_cascade_grants($grants, $access_records = FALSE, &$output = [], $realm = [], $view = 1, $update = 1, $delete = 1) {
// Let's make any possible cross-combination respecting the given element order of $grants.
if (count($grants)) {
// This nesting level has available combinations left.
foreach (reset($grants) as $grant) {
// Assemble new pieces for the realm.
$realm_storage = $realm;
$realm_storage[] = $grant['realm'] . '+' . $grant['gid'];
// Try to go one level deeper.
$grants_storage = array_slice($grants, 1);
// The recursive function is called differently for node access records and user grants.
if ($access_records) {
// We can use simple math to cascade each node access record grant value:
// multiplication ensures that zeros (deny) are retained throughout cascading
// while a one (allow) is only possible if all cascaded grants allow access.
_acb_cascade_grants($grants_storage, $access_records, $output, $realm_storage, $view * $grant['grant_view'], $update * $grant['grant_update'], $delete * $grant['grant_delete']);
}
else {
// For the user grants we call the recursive function twice: once using the updated realm and once pretending the realm wouldn't exist.
_acb_cascade_grants($grants_storage, $access_records, $output, $realm);
_acb_cascade_grants($grants_storage, $access_records, $output, $realm_storage);
}
}
}
// Create a record for this combination if:
// - in case of access records: there are no remaining nesting levels
// - in case of user grants: always!
if (!count($grants) || !$access_records) {
// Prepend 'acb' to comply to best practice of prefixing realms with the name of their responsible module.
$final_realm = 'acb&' . implode('&', $realm);
// Finished combination; save it.
// Exclude empty access record grants as they are useless and only take up memory.
if ($access_records && ($view || $update || $delete)) {
// Node access record.
$output[$final_realm] = [
'realm' => $final_realm,
'gid' => 0,
'grant_view' => (int) $view,
'grant_update' => (int) $update,
'grant_delete' => (int) $delete,
'priority' => 100,
];
}
elseif (!$access_records) {
// User grant.
if (!empty($realm)) {
$output[$final_realm] = [
0,
];
}
}
}
return $output;
}