View source
<?php
define('OG_ACCESS_REALM', 'og_access');
define('OG_ACCESS_FIELD', 'group_access');
define('OG_CONTENT_ACCESS_FIELD', 'group_content_access');
define('OG_CONTENT_ACCESS_DEFAULT', 0);
define('OG_CONTENT_ACCESS_PUBLIC', 1);
define('OG_CONTENT_ACCESS_PRIVATE', 2);
define('OG_ACCESS_PRIVACY_CHANGE_BATCH_PROCESSING', 'og_access_privacy_change_batch_processing');
function og_access_node_grants($account, $op) {
if ($op != 'view') {
return;
}
if ($groups = og_get_entity_groups('user', $account)) {
foreach ($groups as $group_type => $gids) {
foreach ($gids as $gid) {
$realm = OG_ACCESS_REALM . ':' . $group_type;
$grants[$realm][] = $gid;
}
}
}
return !empty($grants) ? $grants : array();
}
function og_access_node_access_records($node) {
if (empty($node->status)) {
return array();
}
$gids = array();
$wrapper = entity_metadata_wrapper('node', $node);
if (!empty($wrapper->{OG_CONTENT_ACCESS_FIELD}) && $wrapper->{OG_CONTENT_ACCESS_FIELD}
->value() == OG_CONTENT_ACCESS_DEFAULT) {
_og_access_verify_access_field_existence($node);
}
if (!empty($wrapper->{OG_ACCESS_FIELD}) && $wrapper->{OG_ACCESS_FIELD}
->value() && og_is_group('node', $node)) {
$gids['node'][] = $node->nid;
}
$content_access = !empty($wrapper->{OG_CONTENT_ACCESS_FIELD}) ? $wrapper->{OG_CONTENT_ACCESS_FIELD}
->value() : OG_CONTENT_ACCESS_DEFAULT;
switch ($content_access) {
case OG_CONTENT_ACCESS_DEFAULT:
if (!($entity_groups = og_get_entity_groups('node', $node))) {
break;
}
$has_private = FALSE;
foreach ($entity_groups as $group_type => $values) {
entity_load($group_type, $values);
foreach ($values as $gid) {
$list_gids[$group_type][] = $gid;
if ($has_private) {
continue;
}
$group_wrapper = entity_metadata_wrapper($group_type, $gid);
if (!empty($group_wrapper->{OG_ACCESS_FIELD}) && $group_wrapper->{OG_ACCESS_FIELD}
->value()) {
$has_private = TRUE;
}
}
}
if ($has_private) {
$gids = array_merge_recursive($gids, $list_gids);
}
break;
case OG_CONTENT_ACCESS_PUBLIC:
break;
case OG_CONTENT_ACCESS_PRIVATE:
$gids = array_merge_recursive($gids, og_get_entity_groups('node', $node));
break;
}
foreach ($gids as $group_type => $values) {
foreach ($values as $gid) {
$grants[] = array(
'realm' => OG_ACCESS_REALM . ':' . $group_type,
'gid' => $gid,
'grant_view' => 1,
'grant_update' => 0,
'grant_delete' => 0,
'priority' => 0,
);
}
}
return !empty($grants) ? $grants : array();
}
function og_access_og_fields_info() {
$allowed_values = array(
0 => 'Public - accessible to all site users',
1 => 'Private - accessible only to group members',
);
$items[OG_ACCESS_FIELD] = array(
'type' => array(
'group',
),
'description' => t('Determine access to the group.'),
'entity' => array(
'node',
),
'field' => array(
'field_name' => OG_ACCESS_FIELD,
'no_ui' => TRUE,
'type' => 'list_boolean',
'cardinality' => 1,
'settings' => array(
'allowed_values' => $allowed_values,
'allowed_values_function' => '',
),
),
'instance' => array(
'label' => t('Group visibility'),
'required' => TRUE,
'default_value' => array(
0 => array(
'value' => 0,
),
),
'widget_type' => 'options_select',
'view modes' => array(
'full' => array(
'label' => 'above',
'type' => 'options_onoff',
),
'teaser' => array(
'label' => 'above',
'type' => 'options_onoff',
),
),
),
);
$allowed_values = array(
0 => 'Use group defaults',
1 => 'Public - accessible to all site users',
2 => 'Private - accessible only to group members',
);
$items[OG_CONTENT_ACCESS_FIELD] = array(
'type' => array(
'group content',
),
'description' => t('Determine access to the group content, which may override the group settings.'),
'entity' => array(
'node',
),
'field' => array(
'field_name' => OG_CONTENT_ACCESS_FIELD,
'no_ui' => TRUE,
'type' => 'list_integer',
'cardinality' => 1,
'settings' => array(
'allowed_values' => $allowed_values,
'allowed_values_function' => '',
),
),
'instance' => array(
'label' => t('Group content visibility'),
'required' => TRUE,
'default_value' => array(
0 => array(
'value' => 0,
),
),
'widget_type' => 'options_select',
'view modes' => array(
'full' => array(
'label' => 'above',
'type' => 'list_default',
),
'teaser' => array(
'label' => 'above',
'type' => 'list_default',
),
),
),
);
return $items;
}
function _og_access_verify_access_field_existence($node) {
$fields_names = og_get_group_audience_fields('node', $node->type);
$groups_bundles = og_get_all_group_bundle();
foreach (array_keys($fields_names) as $field_name) {
$field_info = field_info_field($field_name);
$target_type = $field_info['settings']['target_type'];
foreach (array_keys($groups_bundles[$target_type]) as $bundle) {
$instances = field_info_instances($target_type, $bundle);
if (empty($instances[OG_ACCESS_FIELD])) {
$params = array(
'!nid' => $node->nid,
'%entity_type' => $target_type,
'%bundle' => $bundle,
);
throw new OgException(format_string('Cannot set visibility of node ID !nid as the %entity_type group of type %bundle does not have the "Group visibility" field attached to it.', $params));
}
}
}
}
function og_access_og_access_invoke_node_access_acquire_grants($context) {
$wrapper = entity_metadata_wrapper($context['entity_type'], $context['entity']);
if (!isset($wrapper->{OG_ACCESS_FIELD})) {
return;
}
$original_wrapper = entity_metadata_wrapper($context['entity_type'], $context['entity']->original);
$og_access = $wrapper->{OG_ACCESS_FIELD}
->value();
$original_og_access = $original_wrapper->{OG_ACCESS_FIELD}
->value();
return $og_access !== $original_og_access;
}
function og_access_check_node_access_grants_is_needed($entity, $entity_type) {
if (!variable_get(OG_ACCESS_PRIVACY_CHANGE_BATCH_PROCESSING, TRUE)) {
return FALSE;
}
if (!og_is_group($entity_type, $entity)) {
return FALSE;
}
$context = array(
'entity' => $entity,
'entity_type' => $entity_type,
);
$result = module_invoke_all('og_access_invoke_node_access_acquire_grants', $context);
drupal_alter('og_access_invoke_node_access_acquire_grants', $result, $context);
return in_array(TRUE, $result);
}
function og_access_entity_update($entity, $entity_type) {
if (!og_access_check_node_access_grants_is_needed($entity, $entity_type)) {
return;
}
og_access_handle_group_privacy_change($entity_type, $entity);
}
function og_access_handle_group_privacy_change($entity_type, $entity) {
list($id) = entity_extract_ids($entity_type, $entity);
$batch = array(
'title' => t('Handle group privacy change'),
'operations' => array(
array(
'og_access_invoke_node_access_acquire_grants',
array(
$entity_type,
$id,
),
),
),
);
batch_set($batch);
}
function og_access_invoke_node_access_acquire_grants($group_type, $group_id, &$context) {
if (empty($context['sandbox'])) {
$query = new EntityFieldQuery();
$total = $query
->entityCondition('entity_type', 'og_membership')
->propertyCondition('group_type', $group_type, '=')
->propertyCondition('entity_type', 'node', '=')
->propertyCondition('gid', $group_id, '=')
->count()
->execute();
$context['sandbox']['progress'] = 0;
$context['sandbox']['last_id'] = 0;
$context['sandbox']['total'] = $total;
}
$limit = 50;
$query = new EntityFieldQuery();
$result = $query
->entityCondition('entity_type', 'og_membership')
->propertyCondition('group_type', $group_type, '=')
->propertyCondition('entity_type', 'node', '=')
->range(0, $limit)
->propertyCondition('etid', $context['sandbox']['last_id'], '>')
->propertyCondition('gid', $group_id, '=')
->propertyOrderBy('etid', 'ASC')
->execute();
if (!isset($result['og_membership'])) {
$context['finished'] = 1;
return;
}
foreach (entity_load('og_membership', array_keys($result['og_membership'])) as $og_membership) {
$node = node_load($og_membership->etid);
node_access_acquire_grants($node);
$context['sandbox']['progress']++;
$context['sandbox']['last_id'] = $node->nid;
}
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['total'];
}
function og_access_form_og_ui_admin_settings_alter(&$form, &$form_state) {
$form[OG_ACCESS_PRIVACY_CHANGE_BATCH_PROCESSING] = array(
'#type' => 'checkbox',
'#title' => t('Update group content privacy'),
'#description' => t('Upon group privacy change, create batch operation to update group content.'),
'#default_value' => variable_get(OG_ACCESS_PRIVACY_CHANGE_BATCH_PROCESSING, TRUE),
);
}