You are here

function trash_flag_flag_access_multiple in Trash Flag 7

Implements hook_flag_access_multiple().

Parameters

$flag: flag object

$nid_actions: Array $nid => 'flag'|'unflag'

$account: User account

Return value

array Array $nid => $access, (null or unset means "no opinion")

1 call to trash_flag_flag_access_multiple()
_trash_flag_flag_access in ./trash_flag.module
Future: Implements hook_flag_access().

File

./trash_flag.module, line 92

Code

function trash_flag_flag_access_multiple($flag, $nid_actions, $account) {
  $access = array();

  // Don't care for others.
  if ($flag->name != 'trash') {
    return $access;
  }
  $action_map = array(
    'flag' => 'trash',
    'unflag' => 'untrash',
  );

  // Global permisisons.
  $allowed_actions = array();
  foreach ($action_map as $action => $trash_action) {
    if (user_access("{$trash_action} any content")) {
      $allowed_actions[$action] = TRUE;
    }
  }
  foreach ($nid_actions as $nid => $action) {
    if (isset($allowed_actions[$action])) {
      $access[$nid] = TRUE;
      unset($nid_actions[$nid]);
    }
  }

  // That's all? Return it.
  if (empty($nid_actions)) {
    return $access;
  }

  // Type specific permisisons.
  // Get allowed nodetypes, then nids for that.
  $trash_any_types = $trash_own_types = array();
  foreach ($action_map as $action => $trash_action) {
    foreach (node_type_get_names() as $type => $_) {
      if (user_access("{$trash_action} any {$type} content", $account)) {
        $trash_any_types[] = $type;
      }
      elseif (user_access("{$trash_action} own {$type} content", $account)) {
        $trash_own_types[] = $type;
      }
    }
  }
  $fetched_nids = array();
  if ($trash_any_types || $trash_own_types) {
    $query = db_select('node', 'n')
      ->fields('n', array(
      'nid',
    ))
      ->condition('nid', array_keys($nid_actions), 'IN');
    if ($trash_any_types && $trash_own_types) {
      $or = db_or()
        ->condition('type', $trash_any_types)
        ->condition(db_and()
        ->condition('type', $trash_own_types)
        ->condition('uid', $account->uid));
      $query
        ->condition($or);
    }
    elseif ($trash_any_types) {
      $query
        ->condition('type', $trash_any_types);
    }
    else {
      $query
        ->condition('type', $trash_own_types);
      $query
        ->condition('uid', $account->uid);
    }
    $fetched_nids = $query
      ->execute()
      ->fetchCol();
  }
  foreach ($fetched_nids as $fetched_nid) {
    $access[$fetched_nid] = TRUE;
    unset($nid_actions[$fetched_nid]);
  }

  // That's all? Return it.
  if (empty($nid_actions)) {
    return $access;
  }

  // OG permissions. One after the other.
  foreach ($nid_actions as $nid => $action) {
    $trash_action = $action_map[$action];

    // @see og_user_access_entity().
    $node = entity_load_single('node', $nid);
    list(, , $bundle_name) = entity_extract_ids('node', $node);
    $is_group_content = og_is_group_content_type('node', $bundle_name);
    if ($is_group_content && ($groups = og_get_entity_groups('node', $node))) {
      foreach ($groups as $group_type => $gids) {
        foreach ($gids as $gid) {
          if (og_user_access($group_type, $gid, "{$trash_action} any content", $account) || og_user_access($group_type, $gid, "{$trash_action} any {$bundle_name} content", $account) || $account->uid == $node->uid && og_user_access_entity("{$trash_action} own {$bundle_name} content", 'node', $node, $account)) {
            $access[$nid] = TRUE;
          }
        }
      }
    }
  }
  return $access;
}