function gnode_node_grants in Group 7
Implements hook_node_grants().
See also
File
- modules/
gnode/ gnode.node_access.inc, line 16 - Hooks and functions used in compliance mode.
Code
function gnode_node_grants($account, $op) {
// Provide the master grant for users who can bypass group access.
if (user_access('bypass group access')) {
return array(
'gnode_bypass' => array(
GNODE_MASTER_GRANT_ID,
),
);
}
// Initialize a grant array for members and one for anonymous/outsider users.
$grants_m = $grants_ao = array();
// Gather the machine names of all node types.
$node_types = array_keys(node_type_get_types());
// If the user could not bypass group access, we need to check their access
// for every single group. Because loading every group would incur a massive
// performance hit, we only load those groups the user is a member of.
foreach (GroupMembership::getByActiveStatus($account->uid) as $group_membership) {
// Add the groups the user is a member of to use later on.
$member_gids[] = $gid = $group_membership->gid;
// See whether the user has all permissions for this group.
$group_administrator = $group_membership
->hasPermission('administer group');
foreach ($node_types as $node_type) {
switch ($op) {
case 'view':
// Allow the user to view published content of this type.
if ($group_administrator || $group_membership
->hasPermission("view {$node_type} node")) {
$grants_m["gnode:{$node_type}"][] = $gid;
}
// Allow the user to view unpublished content of this type.
if ($group_administrator || $group_membership
->hasPermission("view unpublished {$node_type} node")) {
$grants_m["gnode_unpublished:{$node_type}"][] = $gid;
}
break;
case 'update':
case 'delete':
// If you can act on any node, there's no need for the author grant.
if ($group_administrator || $group_membership
->hasPermission("{$op} any {$node_type} node")) {
$grants_m["gnode:{$node_type}"][] = $gid;
}
elseif ($group_membership
->hasPermission("{$op} own {$node_type} node")) {
$grants_m["gnode_author:{$account->uid}:{$node_type}"][] = $gid;
}
break;
}
}
}
// All other groups have the benefit of sharing the same permission set among
// all anonymous or authenticated users per group type. We can therefore know
// the user's permissions for all groups of the same type they aren't part of.
$query = db_select('groups', 'g')
->fields('g', array(
'gid',
'type',
));
if (!empty($member_gids)) {
$query
->condition('gid', $member_gids, 'NOT IN');
}
foreach ($query
->execute() as $record) {
$gids_per_group_type[$record->type][] = $record->gid;
}
foreach (group_types() as $name => $group_type) {
// If we could not retrieve any group IDs, skip to the next group type.
if (empty($gids_per_group_type[$name])) {
continue;
}
// Get the IDs of all the groups the user is not part of for the group type.
$gids = $gids_per_group_type[$name];
// Grab the anonymous or outsider permissions for the group type depending
// on the user's account status (anonymous or authenticated).
$permissions = $account->uid == 0 ? $group_type->anonymous_permissions : $group_type->outsider_permissions;
// See whether the user has all permissions for this group type.
$group_administrator = in_array('administer group', $permissions, TRUE);
foreach ($node_types as $node_type) {
switch ($op) {
case 'view':
// Allow the user to view published content of this type.
if ($group_administrator || in_array("view {$node_type} node", $permissions, TRUE)) {
$grants_ao["gnode:{$node_type}"][] = $gids;
}
// Allow the user to view unpublished content of this type.
if ($group_administrator || in_array("view unpublished {$node_type} node", $permissions, TRUE)) {
$grants_ao["gnode_unpublished:{$node_type}"][] = $gids;
}
break;
case 'update':
case 'delete':
// If you can act on any node, there's no need for the author grant.
if ($group_administrator || in_array("{$op} any {$node_type} node", $permissions, TRUE)) {
$grants_ao["gnode:{$node_type}"][] = $gids;
}
elseif (in_array("{$op} own {$node_type} node", $permissions, TRUE)) {
$grants_ao["gnode_author:{$account->uid}:{$node_type}"][] = $gids;
}
break;
}
}
}
// The code above populated the anonymous/outsider grants by adding the group
// IDs per group type. We need to combine this into one big list of group IDs
// per entry in the $grants_ao array.
foreach ($grants_ao as $key => $grants_per_group_type) {
$grants_ao[$key] = array_reduce($grants_per_group_type, 'array_merge', array());
}
// Recursively merge the member grants with the anonymous/outsider grants.
return array_merge_recursive($grants_m, $grants_ao);
}