og_subgroups.module in Subgroups for Organic groups 7
Same filename and directory in other branches
Enable defining hierarchy of groups for organic groups.
File
og_subgroups.moduleView source
<?php
/**
* @file
* Enable defining hierarchy of groups for organic groups.
*/
/**
* Implementation of hook_ctools_plugin_directory().
*/
function og_subgroups_ctools_plugin_directory($module, $plugin) {
// Safety: go away if CTools is not at an appropriate version.
if (!module_invoke('ctools', 'api_version', OG_REQUIRED_CTOOLS_API)) {
return;
}
if ($module == 'ctools') {
return 'plugins/' . $plugin;
}
}
/**
* Check if a user has access permission in one of the ancestors groups
* and return the tree structure of the group hierarchy.
*
* @param $entity_groups
* Array of group id to check and start moving up in the hierarchy.
* @param $account
* Optional; The account to check
* @param $string
* Optional; The permission string, if empty return the full tree structure in
* $structure, otherwise stops when the permission is grant.
* @param $structure
* Optional; This is the array that you should send by refeference to get back
* all the tree structure of the given groups.
* Array contain 2 keys ['gid'] - group id, and ['level'] the depth of the
* parent.
* @param $level
* Optional; Level of tree to start counting from, normally there is no need
* to change this. Default to 0 being the entity given.
*
* @return
* TRUE if user has access grant with the given perm to one of the enstertors
* groups.
*/
function og_subgroups_get_reverse_hierarchy_tree_perm($entity_groups, $string = '', $account = NULL, &$structure = array(), &$graph = FALSE, $level = 0) {
// Check if user has the permission in a parent group.
foreach ($entity_groups as $gid) {
// Save the hierarchy structure.
$structure[$gid] = array();
$structure[$gid]['gid'] = $gid;
$structure[$gid]['level'] = $level;
// Build a graph with graph api
if (is_array($graph) && module_exists('graphapi')) {
$group = og_load($gid);
graphapi_set_node_title($graph, $gid, $group->label);
}
// Check access permission.
if ($string) {
if (og_user_access($gid, $string, $account, TRUE)) {
return TRUE;
}
}
}
// Get all groups that are content of user_groups (as an array of group ids).
$groups = og_load_multiple($entity_groups);
$parent_groups = array();
foreach ($groups as $group) {
// Load the entity associated with the group.
$entity = og_load_entity_from_group($group->gid);
// Get all groups that are associated with passed group.
$parents = og_get_entity_groups($group->entity_type, $entity);
$parent_groups += $parents;
// Build a graph path with graph api
if (is_array($graph) && module_exists('graphapi')) {
foreach ($parents as $parent) {
graphapi_set_node_title($graph, $parent, $parent);
graphapi_set_link_data($graph, $group->gid, $parent, array(
'color' => '#018FE2',
));
}
}
}
if ($parent_groups) {
// Recurssion call of the function.
return og_subgroups_get_reverse_hierarchy_tree_perm($parent_groups, $string, $account, $structure, $graph, ++$level);
}
else {
// Reached a dead end, return false.
return FALSE;
}
}
/**
* Implements hook_og_user_access_alter()
*/
function og_subgroups_og_user_access_alter(&$perm, $context) {
// Update the permission for a user that tries to access a sub group.
// This gives to any users his og group permission to all his subgroups,
// without the -need for him to be a member in the groups.
$perm[$context['string']] = og_subgroups_get_reverse_hierarchy_tree_perm(array(
$context['group']->gid,
), $context['string'], $context['account']);
}
/**
* Implements hook_node_access_records_alter().
*
* This alter is fired on node save, we want to add view permission to a user's
* subgroups (private groups), to do so we add the parent groups id to all
* groups.
*/
function og_subgroups_node_access_records_alter(&$grants, $node) {
// Relevant only for private groups.
if (module_exists('og_access')) {
// The group IDs, that in case access is granted, will be recorded.
$gids = array();
$private = FALSE;
$groups = array();
// Dealing with a node group that is private.
if (!empty($node->{OG_ACCESS_FIELD}[LANGUAGE_NONE][0]['value'])) {
$group = og_get_group('node', $node->nid);
if ($group) {
$groups[] = $group->gid;
$private = TRUE;
}
}
elseif (isset($node->{OG_CONTENT_ACCESS_FIELD}[LANGUAGE_NONE][0]['value'])) {
// If no groups with og realm are defined, this means it's a public group
// then do nothing, otherwise treat as a private group.
if ($node->{OG_CONTENT_ACCESS_FIELD}[LANGUAGE_NONE][0]['value'] == OG_CONTENT_ACCESS_PRIVATE || $node->{OG_CONTENT_ACCESS_FIELD}[LANGUAGE_NONE][0]['value'] == OG_CONTENT_ACCESS_DEFAULT && og_subgroups_grants_has_og_realm($grants)) {
$groups = og_get_entity_groups('node', $node);
$private = TRUE;
}
}
// If group is private, then grant permissions for parent groups.
if ($private) {
og_subgroups_get_reverse_hierarchy_tree_perm($groups, '', NULL, $gids);
// Check existing grant and remove from gids[], to avoid duplication.
foreach ($grants as $granted) {
if (isset($gids[$granted['gid']])) {
unset($gids[$granted['gid']]);
}
}
// Build the new access Grant array.
foreach ($gids as $gid) {
$grants[] = array(
'realm' => OG_ACCESS_AUTHENTICATED_REALM,
'gid' => $gid['gid'],
'grant_view' => 1,
'grant_update' => 0,
'grant_delete' => 0,
'priority' => 0,
);
}
}
}
}
/**
* Return TRUE if $grants contain an OG realm
*/
function og_subgroups_grants_has_og_realm($grants) {
foreach ($grants as $granted) {
if ($granted['realm'] == OG_ACCESS_AUTHENTICATED_REALM) {
return TRUE;
}
}
return FALSE;
}
/**
* Get hierarchy tree.
*
* @param $entity_type
* @param $etid
* @param $options
*/
function og_get_hierarchy($entity_type, $etid, $options = array(), &$tree = array(), $depth = 0) {
$options += array(
'direction' => 'up',
'type' => 'single',
'sanitize' => TRUE,
);
$wrapper = entity_metadata_wrapper($entity_type, $etid);
if ($depth == 0 && ($group = $wrapper->group
->value())) {
if ($options['type'] == 'single') {
$tree[$group->gid] = og_label($group->gid, $options['sanitize']);
}
else {
$tree[$depth][$group->gid] = og_label($group->gid, $options['sanitize']);
}
}
if ($options['direction'] == 'up' && $options['type'] == 'single') {
$group = FALSE;
// Get the first group associated with the entity.
if ($wrapper->og_membership
->get(0)
->value()) {
$group = $wrapper->og_membership
->get(0)->group
->value();
$tree[$group->gid] = og_label($group->gid, $options['sanitize']);
og_get_hierarchy($group->entity_type, $group->etid, $options, $tree, $depth + 1);
}
}
return $tree;
}
Functions
Name | Description |
---|---|
og_get_hierarchy | Get hierarchy tree. |
og_subgroups_ctools_plugin_directory | Implementation of hook_ctools_plugin_directory(). |
og_subgroups_get_reverse_hierarchy_tree_perm | Check if a user has access permission in one of the ancestors groups and return the tree structure of the group hierarchy. |
og_subgroups_grants_has_og_realm | Return TRUE if $grants contain an OG realm |
og_subgroups_node_access_records_alter | Implements hook_node_access_records_alter(). |
og_subgroups_og_user_access_alter | Implements hook_og_user_access_alter() |