diff --git a/helpers/entity.group.inc b/helpers/entity.group.inc index fa41f10..e1b3149 100644 --- a/helpers/entity.group.inc +++ b/helpers/entity.group.inc @@ -78,6 +78,36 @@ function group_load_by_member($uid, $type = NULL) { } /** + * Get Group entities id's for a provided outsider account. + * + * @param int $uid + * The id of the user entity. + * @param string $group_type + * Optionally provide a group type to filter group ids. + * + * @return array + * An array of group entities ID for the provided outsider account. + * Otherwise an empty array. + */ +function group_get_gids_by_outsider($uid, $group_type = '') { + $query = db_select('groups', 'g') + ->fields('g', array('gid')); + + if ($group_type) { + $query->condition('g.type', $group_type); + } + $query->leftJoin('group_membership', 'gm', 'g.gid = gm.gid'); + $query->condition(db_or() + ->isNull('gm.uid') + ->condition('gm.uid', $uid, '<>') + ) + ->groupBy('g.gid') + ->orderBy('g.gid', 'ASC'); + + return $query->execute()->fetchCol(); +} + +/** * Save a group. */ function group_save($group) { diff --git a/implementations/group.node.inc b/implementations/group.node.inc index 1d53eba..9b76962 100644 --- a/implementations/group.node.inc +++ b/implementations/group.node.inc @@ -111,104 +111,109 @@ function group_node_access($node, $op, $account) { * @see group_node_access_records(). */ function group_node_grants($account, $op) { - $grants = array(); + static $cache = array(); - // If the user can bypass group access, he only needs the master grant. - if (user_access('bypass group access', $account)) { - return array('group:bypass' => array(GROUP_BYPASS_GRANT_ID)); - } + if (!isset($cache[$account->uid][$op])) { + $grants = array(); + $cache[$account->uid][$op] =& $grants; - // Gather the machine names of all node types. - $node_types = array_keys(node_type_get_types()); + // If the user can bypass group access, he only needs the master grant. + if (user_access('bypass group access', $account)) { + return array('group:bypass' => array(GROUP_BYPASS_GRANT_ID)); + } - // Gather all groups the user is a member of. - $member_groups = group_load_by_member($account->uid); + // Gather the machine names of all node types. + $node_types = array_keys(node_type_get_types()); - // Provide grants for groups the user is an outsider to. - foreach (group_types() as $type => $group_type) { - $outsider_groups = group_load_by_type($type); - $outsider_gids = array_diff_key($outsider_groups, $member_groups); + // Provide grants for groups the user is an outsider to. + foreach (group_types() as $type => $group_type) { + // Gather all groups of this group type the user is an outsider of. + $outsider_gids = group_get_gids_by_outsider($account->uid, $group_type->name); + if ($outsider_gids) { - if ($outsider_gids) { - // If the user is an admin, he requires no further specific grants. - if (in_array('administer group', $group_type->outsider_permissions)) { - foreach ($outsider_gids as $gid) { - $grants['group:administer'][] = $gid; + // If the user is an admin, he requires no further specific grants. + if (in_array('administer group', $group_type->outsider_permissions)) { + foreach ($outsider_gids as $gid) { + $grants['group:administer'][] = $gid; + } + continue; + } + + foreach ($node_types as $node_type) { + // Shorten variable name for readability's sake. + $permissions = $group_type->outsider_permissions; + + // Allow the user to view content of this type. + if ($op == 'view' && in_array("view $node_type", $permissions)) { + foreach ($outsider_gids as $gid) { + $grants["group:$node_type:view"][] = $gid; + } + } + // Allow the user to edit any content of this type. + elseif ($op == 'update' && in_array("edit any $node_type", $permissions)) { + foreach ($outsider_gids as $gid) { + $grants["group:$node_type:update"][] = $gid; + } + } + // Allow the user to delete any content of this type. + elseif ($op == 'delete' && in_array("delete any $node_type", $permissions)) { + foreach ($outsider_gids as $gid) { + $grants["group:$node_type:delete"][] = $gid; + } + } + // Allow the user to edit own content of this type. + elseif ($op == 'update' && in_array("edit own $node_type", $permissions)) { + foreach ($outsider_gids as $gid) { + $grants["group:$gid:$node_type:update"][] = $account->uid; + } + } + // Allow the user to delete own content of this type. + elseif ($op == 'delete' && in_array("delete own $node_type", $permissions)) { + foreach ($outsider_gids as $gid) { + $grants["group:$gid:$node_type:delete"][] = $account->uid; + } + } } + } + } + + // Gather all groups the user is a member of. + $member_groups = group_load_by_member($account->uid); + + // Provide grants for groups the user is a member of. + foreach ($member_groups as $group) { + // If the user is an admin, he requires no further specific grants. + if (group_access('administer group', $group, $account)) { + $grants['group:administer'][] = $group->gid; continue; } foreach ($node_types as $node_type) { - // Shorten variable name for readability's sake. - $permissions = $group_type->outsider_permissions; - // Allow the user to view content of this type. - if ($op == 'view' && in_array("view $node_type", $permissions)) { - foreach ($outsider_gids as $gid) { - $grants["group:$node_type:view"][] = $gid; - } + if ($op == 'view' && group_access("view $node_type", $group, $account)) { + $grants["group:$node_type:view"][] = $group->gid; } // Allow the user to edit any content of this type. - elseif ($op == 'update' && in_array("edit any $node_type", $permissions)) { - foreach ($outsider_gids as $gid) { - $grants["group:$node_type:update"][] = $gid; - } + elseif ($op == 'update' && group_access("edit any $node_type", $group, $account)) { + $grants["group:$node_type:update"][] = $group->gid; } // Allow the user to delete any content of this type. - elseif ($op == 'delete' && in_array("delete any $node_type", $permissions)) { - foreach ($outsider_gids as $gid) { - $grants["group:$node_type:delete"][] = $gid; - } + elseif ($op == 'delete' && group_access("delete any $node_type", $group, $account)) { + $grants["group:$node_type:delete"][] = $group->gid; } // Allow the user to edit own content of this type. - elseif ($op == 'update' && in_array("edit own $node_type", $permissions)) { - foreach ($outsider_gids as $gid) { - $grants["group:$gid:$node_type:update"][] = $account->uid; - } + elseif ($op == 'update' && group_access("edit own $node_type", $group, $account)) { + $grants["group:$group->gid:$node_type:update"][] = $account->uid; } // Allow the user to delete own content of this type. - elseif ($op == 'delete' && in_array("delete own $node_type", $permissions)) { - foreach ($outsider_gids as $gid) { - $grants["group:$gid:$node_type:delete"][] = $account->uid; - } + elseif ($op == 'delete' && group_access("delete own $node_type", $group, $account)) { + $grants["group:$group->gid:$node_type:delete"][] = $account->uid; } } } } - // Provide grants for groups the user is a member of. - foreach ($member_groups as $group) { - // If the user is an admin, he requires no further specific grants. - if (group_access('administer group', $group, $account)) { - $grants['group:administer'][] = $group->gid; - continue; - } - - foreach ($node_types as $node_type) { - // Allow the user to view content of this type. - if ($op == 'view' && group_access("view $node_type", $group, $account)) { - $grants["group:$node_type:view"][] = $group->gid; - } - // Allow the user to edit any content of this type. - elseif ($op == 'update' && group_access("edit any $node_type", $group, $account)) { - $grants["group:$node_type:update"][] = $group->gid; - } - // Allow the user to delete any content of this type. - elseif ($op == 'delete' && group_access("delete any $node_type", $group, $account)) { - $grants["group:$node_type:delete"][] = $group->gid; - } - // Allow the user to edit own content of this type. - elseif ($op == 'update' && group_access("edit own $node_type", $group, $account)) { - $grants["group:$group->gid:$node_type:update"][] = $account->uid; - } - // Allow the user to delete own content of this type. - elseif ($op == 'delete' && group_access("delete own $node_type", $group, $account)) { - $grants["group:$group->gid:$node_type:delete"][] = $account->uid; - } - } - } - - return $grants; + return $cache[$account->uid][$op]; } /**