function acb_node_grants_alter in Access Control Bridge 8
Same name and namespace in other branches
- 7 acb.module \acb_node_grants_alter()
Implements hook_node_grants_alter().
Let Drupal know of the current user's grants. We're using the _alter function because we need existing grants to calculate ours.
File
- ./
acb.module, line 132 - Drupal hooks and functions for the acb module.
Code
function acb_node_grants_alter(&$grants, AccountInterface $account, $op) {
// Split all grants into their respective controlling modules and prepare the array for the recursive cascader.
$split_grants = [];
// ACL requires special care. The responsible module can only be determined by using the database.
if (\Drupal::moduleHandler()
->moduleExists('acl')) {
$acl = db_select('acl')
->fields('acl', [
'acl_id',
'module',
])
->execute()
->fetchAllAssoc('acl_id');
}
// For our ACB grants, we need the 'Edit any domain content' and 'Delete any domain content' permissions to be enabled to
// enable other modules to control it effectively (due to the AND-logic we're implementing).
// Add them to the user grants if not already present if Domain Access is active.
// Additionally, fork $grants so we don't add them permanently to the referenced grants array.
$acb_grants = $grants;
if (\Drupal::moduleHandler()
->moduleExists('domain_access') && ($op == 'update' || $op == 'delete')) {
$user = User::load($account
->id());
$domains = \Drupal::service('domain_access.manager')
->getAccessValues($user);
if (!empty($domains)) {
foreach ($domains as $id) {
if (abs($id) > 0) {
$value = $id > 0 ? $id : 0;
if (!isset($acb_grants['domain_id']) || !in_array($value, $acb_grants['domain_id'])) {
$acb_grants['domain_id'][] = $value;
}
}
}
}
}
foreach (acb_get_modules() as $module) {
// ACL requires special care. Extract the ACL ids for the current module.
if (\Drupal::moduleHandler()
->moduleExists('acl')) {
$entry_storage = [];
foreach ($acl as $key => $entry) {
if (acb_is_module_realm($entry->module, $module) === TRUE) {
$entry_storage[$key] = $entry;
}
}
$acl_current = array_keys($entry_storage);
}
foreach ($acb_grants as $realm => $gids) {
// ACL requires special care. Filter out any ACL entries that were not set by the current module.
if ($realm == 'acl') {
$gids = array_intersect($gids, $acl_current);
}
// If this realm is originating from the current module (or if ACL has entries), then add the gids.
if (acb_is_module_realm($realm, $module) === TRUE || $realm == 'acl' && !empty($gids)) {
// Eventually prepare the module's subarray for pushing.
if (empty($split_grants[$module])) {
$split_grants[$module] = [];
}
foreach ($gids as $gid) {
array_push($split_grants[$module], [
'realm' => $realm,
'gid' => $gid,
]);
}
}
}
}
// We keep the existing grants and merge ACB's to support the case where only one module controls the node.
// Filter out any modules that didn't set grants.
$grants = array_merge($grants, _acb_cascade_grants(array_filter($split_grants)));
}