You are here

function og_subgroups_node_access_records_alter in Subgroups for Organic groups 7.2

Same name and namespace in other branches
  1. 7 og_subgroups.module \og_subgroups_node_access_records_alter()

Implements hook_node_access_records_alter().

File

./og_subgroups.module, line 156
Provides users the ability to inherit permissions on subgroups.

Code

function og_subgroups_node_access_records_alter(&$grants, $node) {
  if (!empty($node->status) && module_exists('og_access') && (og_is_group_type('node', $node->type) || variable_get('og_subgroup_private_content', TRUE) && og_is_group_content_type('node', $node->type))) {

    // Since subgroups are technically group content, they inherit group access.
    // However, that access is only one level deep so we need to redo it.
    $all_parent = og_subgroups_parents_load('node', $node->nid, FALSE, TRUE, FALSE, TRUE);
    if (!empty($all_parent['node'])) {
      $gids = array();

      // Retrieve all parents that inherit.
      // NOTE that this may not include immediate parents.
      $parents_with_inheritance = og_subgroups_parents_load('node', $node->nid, TRUE, TRUE, FALSE, TRUE);

      // This is almost completely copied form og_access_node_access_records.
      // only difference is using $parents_with_inheritance vs og_get_entity_groups
      $wrapper = entity_metadata_wrapper('node', $node);
      $content_access = OG_CONTENT_ACCESS_DEFAULT;
      if (!empty($wrapper->{OG_ACCESS_FIELD}) && $wrapper->{OG_ACCESS_FIELD}
        ->value()) {
        $content_access = OG_CONTENT_ACCESS_PRIVATE;
      }
      else {
        if (!empty($wrapper->{OG_CONTENT_ACCESS_FIELD})) {
          $content_access = $wrapper->{OG_CONTENT_ACCESS_FIELD}
            ->value();
        }
      }
      switch ($content_access) {
        case OG_CONTENT_ACCESS_DEFAULT:
          if (!og_is_group_type('node', $node->type)) {

            // For content nodes, add back in the immediate parents regardless
            // of user inheritance.
            $immediate_parents = og_subgroups_parents_load('node', $node->nid, FALSE, FALSE);
            $parents_with_inheritance = array_merge_recursive($immediate_parents, $parents_with_inheritance);
          }
          if (!$parents_with_inheritance) {
            break;
          }
          $has_private = FALSE;
          foreach ($parents_with_inheritance as $group_type => $values) {
            $parents = entity_load($group_type, $values);
            foreach ($values as $gid) {
              $list_gids[$group_type][] = $gid;
              if ($has_private) {

                // We already know we have a private group, so we can avoid
                // re-checking it.
                continue;
              }
              if (og_subgroups_is_parent_private($group_type, $parents[$gid])) {
                $has_private = TRUE;
              }
            }
          }
          if ($has_private) {
            $gids = array_merge_recursive($gids, $list_gids);
          }
          break;
        case OG_CONTENT_ACCESS_PUBLIC:

          // Do nothing.
          break;
        case OG_CONTENT_ACCESS_PRIVATE:
          $gids['node'][] = $node->nid;
          if (!empty($wrapper->{OG_CONTENT_ACCESS_FIELD})) {

            // Group also has content-access field
            // Add back in the immediate parents regardless of user inheritance.
            $immediate_parents = og_subgroups_parents_load('node', $node->nid, FALSE, FALSE);
            $parents_with_inheritance = array_merge_recursive($immediate_parents, $parents_with_inheritance);
          }
          $gids = array_merge_recursive($gids, $parents_with_inheritance);
          break;
      }

      // Remove any OG_ACCESS_REALM . ':node' grants (which may contain parents
      // that don't inherit) and re-add ones based on new gids.
      $old_grants = $grants;
      foreach ($grants as $key => $grant) {
        if ($grant['realm'] == OG_ACCESS_REALM . ':node') {
          unset($grants[$key]);
        }
      }
      if (!empty($gids['node'])) {

        // Make sure the group has access to itself if it's been restricted.
        if (!in_array($gids['node'], $gids['node'])) {
          $gids['node'][] = $node->nid;
        }
        foreach (array_unique($gids['node']) as $gid) {
          $grants[] = array(
            'realm' => OG_ACCESS_REALM . ':node',
            'gid' => $gid,
            'grant_view' => 1,
            'grant_update' => 0,
            'grant_delete' => 0,
            'priority' => 0,
          );
        }
      }

      // Make sure the caches are cleared just to be sure.
      if ($old_grants != $grants) {
        og_subgroups_clear_caches_for_group('node', $node->nid);
      }
    }
  }
}