function oa_user_access_nids in Open Atrium Core 7.2
Determine whether a user has a given privilege for groups.
This modules the logic of og_user_access but for multiple node groups. IMPORTANT, any changes to og_user_access reflect here.
We cannot offer any speed improvements if og_user_access_alter is implemented as it requires a entity_load.
Parameters
$group_type: This will fall through to og_user_access access if not 'node'
$nids: Array of node nids that are groups.
$string: String can be a string or array of strings (which diverges from og_user_access) of permissions to check. If an array is passed, it'll be TRUE for that group if user has ANY of the permissions.
Return value
An array of nids to access.
4 calls to oa_user_access_nids()
- oa_og_subgroups_check_access in includes/
oa_core.util.inc - Check access for this group's parents.
- oa_user_access in includes/
oa_core.util.inc - Replacement for og_user_access.
- OgSubspacesSelectionHandler::buildEntityFieldQuery in plugins/
entityreference/ selection/ OgSubspacesSelectionHandler.class.php - Build an EntityFieldQuery to get referencable entities.
- OgSubspacesSelectionHandler::getGidsForCreate in plugins/
entityreference/ selection/ OgSubspacesSelectionHandler.class.php - Get group IDs from URL or OG-context, with access to create group-content.
1 string reference to 'oa_user_access_nids'
File
- includes/
oa_core.util.inc, line 1555 - Code for Utility functions for OpenAtrium spaces
Code
function oa_user_access_nids($group_type, $nids, $string, $account = NULL, $skip_alter = FALSE, $ignore_admin = FALSE) {
global $user;
$strings = is_array($string) ? $string : array(
$string,
);
$access =& drupal_static(__FUNCTION__, array());
if (empty($account)) {
$account = $user;
}
$nids = drupal_map_assoc($nids);
// Administer group permission. We don't cache it cause ignore_admin can change.
if ($account->uid == 1 || !$ignore_admin && user_access('administer group', $account)) {
$return = array();
foreach ($nids as $nid) {
$return[$nid] = TRUE;
}
return $return;
}
// We don't handle not-nodes (cause hard to look up owner), the alter hook
// (it needs full node_load).
$alter = module_implements('og_user_access_alter');
foreach (array(
'og_subgroups',
'og_ui',
) as $remove) {
$pos = array_search($remove, $alter);
if ($pos !== FALSE) {
unset($alter[$pos]);
}
}
// We cannot replicate unknown alters or unsubscribe logic, so fallback.
// @see og_ui_og_user_access_alter().
if ($group_type != 'node' || !$skip_alter && $alter || in_array('unsubscribe', $strings)) {
foreach ($nids as $nid) {
foreach ($strings as $string) {
if (!isset($access[$account->uid][$string][$nid])) {
$access[$account->uid][$string][$nid] = og_user_access($group_type, $nid, $string, $account, $skip_alter, $ignore_admin);
}
}
}
}
$lookup = array();
$all_lookup = array();
// Find what nodes/permissions still need to be looked up.
foreach ($strings as $string) {
if (!empty($access[$account->uid][$string])) {
$lookup[$string] = array_diff_key($nids, $access[$account->uid][$string]);
}
else {
$lookup[$string] = $nids;
}
if (!$lookup[$string]) {
unset($lookup[$string]);
}
}
foreach ($lookup as $string => $nids_array) {
$all_lookup += $nids_array;
}
// Group manager has all privileges (if variable is TRUE).
if ($all_lookup && !empty($account->uid) && variable_get('og_group_manager_full_access', TRUE)) {
$authored = db_query('SELECT nid FROM {node} WHERE nid in (:nids) AND uid = :uid', array(
':nids' => $all_lookup,
':uid' => $account->uid,
))
->fetchCol();
foreach ($authored as $nid) {
foreach ($strings as $string) {
$access[$account->uid][$string][$nid] = TRUE;
unset($lookup[$string][$nid]);
unset($all_lookup[$nid]);
}
}
}
if ($all_lookup && !empty($account->uid)) {
// Add administer group as first permission checked (as most likely).
if (!$ignore_admin) {
array_unshift($strings, 'administer group');
}
/**
* The query needed is quite complex for regular oa access.
*
* The rid in og_users_roles can either be associated with no group if
* the roles have not been overriden or with the group if they have.
*
* The rid can either be associated with the user or the 'member' role
* which is added automatically.
*
* Below is a sample query.
* @code
* SELECT om.gid, orp.permission
* FROM og_role_permission orp
* INNER JOIN og_role oro ON oro.rid = orp.rid
* INNER JOIN og_membership om ON om.group_type = 'node' AND oro.group_type = 'node' AND om.entity_type='user'
* INNER JOIN node n ON n.nid = om.gid
* INNER JOIN field_data_og_roles_permissions fdp on fdp.entity_type = 'node' AND fdp.entity_id = om.gid
* LEFT JOIN og_users_roles our ON our.rid = oro.rid AND our.uid = om.etid AND our.group_type = "node" AND our.gid = om.gid
* WHERE om.etid = 159
* AND (oro.gid = om.gid OR (fdp.og_roles_permissions_value = 0 and oro.gid = 0 AND oro.group_bundle = n.type))
* AND (our.uid = 159 OR oro.name = 'member')
* AND om.state = 1 AND om.gid IN (139);
* @endcode
*
* @todo BUNDLE DAMMIT
*/
$query = db_select('og_role_permission', 'orp');
$query
->innerJoin('og_role', 'oro', 'oro.rid = orp.rid');
$query
->innerJoin('og_membership', 'om', "om.group_type = 'node' AND oro.group_type = 'node' AND om.entity_type='user'");
$query
->innerJoin('node', 'n', "n.nid = om.gid");
$query
->innerJoin('field_data_og_roles_permissions', 'fdp', "fdp.entity_type = 'node' AND fdp.entity_id = om.gid");
$query
->leftJoin('og_users_roles', 'our', "our.rid = oro.rid AND our.uid = om.etid AND our.group_type = 'node' AND our.gid = om.gid");
$query
->fields('om', array(
'gid',
));
$query
->fields('orp', array(
'permission',
));
$query
->condition('om.etid', $account->uid);
$and = db_and()
->condition('fdp.og_roles_permissions_value', 0)
->condition('oro.gid', 0)
->where('n.type = oro.group_bundle');
$or = db_or()
->where('oro.gid = om.gid')
->condition($and);
$query
->condition($or);
$or = db_or()
->condition('our.uid', $account->uid)
->condition('oro.name', 'member');
$query
->condition($or);
$query
->condition('orp.permission', $strings);
$query
->condition('state', OG_STATE_ACTIVE);
$query
->condition('om.gid', $all_lookup);
$result = $query
->execute();
$rows = $result
->fetchAll();
foreach ($rows as $row) {
$access[$account->uid][$row->permission][$row->gid] = TRUE;
unset($lookup[$row->permission][$row->gid]);
}
}
// Check parent access.
// This needs further optomization.
if ($lookup && !$skip_alter && in_array('og_subgroups', module_implements('og_user_access_alter'))) {
$user_groups = og_subgroup_user_groups_load($account, FALSE);
foreach ($lookup as $string => $nids_array) {
foreach ($nids_array as $nid) {
if (oa_og_subgroups_check_access($string, $group_type, $nid, $user_groups, TRUE)) {
$access[$account->uid][$string][$nid] = TRUE;
unset($lookup[$string][$nid]);
}
}
}
}
// Any extra NID is no access.
foreach ($lookup as $string => $nids_array) {
foreach ($nids_array as $nid) {
// This should not be set, but just in case only set to false if not.
if (!isset($access[$account->uid][$string][$nid])) {
$access[$account->uid][$string][$nid] = FALSE;
}
}
}
// Figure out if user has any access.
$return = array();
$remaining_nids = $nids;
do {
$string = array_shift($strings);
if (!empty($access[$account->uid][$string])) {
$return += array_filter(array_intersect_key($access[$account->uid][$string], $remaining_nids));
}
$remaining_nids = array_diff_key($nids, $return);
} while ($remaining_nids && $strings);
// If no strings left, there are no access.
if ($remaining_nids) {
foreach ($remaining_nids as $nid) {
$return[$nid] = FALSE;
}
}
// Need to return array as combination of strings.
return $return;
}