You are here

function workbench_access_handler_filter_access::query in Workbench Access 7

Add this filter to the query.

Due to the nature of fapi, the value and the operator have an unintended level of indirection. You will find them in $this->operator and $this->value respectively.

Overrides views_handler_filter_in_operator::query

File

includes/workbench_access_handler_filter_access.inc, line 77
Views integration for Workbench.

Class

workbench_access_handler_filter_access
@file Views integration for Workbench.

Code

function query() {
  global $user;
  static $node_types;

  // If workbench_access is not configured, do nothing.
  $active = workbench_access_get_active_tree();
  $access_table = $active['access_scheme']['field_table'];
  $tree = $active['tree'];
  if (empty($tree)) {
    return;
  }

  // Check the user's access.
  $account = $user;

  // Not a clone, but that's ok, since we need this data on $user.
  // Load workbench_access user data onto the account object.
  if (!isset($account->workbench_access)) {
    workbench_access_user_load_data($account);
  }

  // Get node types that do not use workbench_access for access control.
  $node_types = array();
  foreach (node_type_get_names() as $type => $name) {
    if (!variable_get('workbench_access_node_type_' . $type, TRUE)) {
      $node_types[$type] = $type;
    }
  }

  // Here we start altering the query. All of our alters should be their own
  // where group.
  // If the user has no workbench_access rights, and all node types use
  // workbench_access, force the query to return nothing.
  if (empty($account->workbench_access) && empty($node_types)) {
    $table = $this->view->base_table;
    $group = $this->query
      ->set_where_group('OR');
    $this->query
      ->add_where($group, "{$table}.nid", -1, '=');
    return;
  }

  // If there is no selection, use the user's own access tree.
  if (empty($this->value[0]) || $this->value[0] == -5) {
    workbench_access_build_tree($tree, array_keys($account->workbench_access));
    $group = $this->query
      ->set_where_group('OR');
    $node_type_filter = TRUE;
  }
  else {
    workbench_access_build_tree($tree, array_keys($this->value[0]));
    $group = $this->query
      ->set_where_group('AND');
    $node_type_filter = FALSE;
  }

  // Build the workbench_access where clause.
  if (!empty($tree)) {

    // Since we allow multi-select, this has to be a subquery.
    $ids = array_keys($tree);
    $table = $active['access_scheme']['field_table'];
    $subquery = db_select($table, $table);
    $subquery
      ->addField($table, 'nid');
    $subquery
      ->distinct();
    $subquery
      ->condition($table . '.' . $active['access_scheme']['query_field'], $ids, 'IN');
    $subquery
      ->condition($table . '.access_scheme', $active['access_scheme']['access_scheme']);
    $where_table = !empty($this->relationship) ? $this->relationship : $this->query->base_table;
    $this->query
      ->add_where($group, "{$where_table}.nid", $subquery, 'IN');
  }

  // If not all node types use workbench access for permissions, add them here.
  if (!empty($node_types)) {
    $table = $this->query->base_table;

    // Ensure that we have a proper table when using a relationship from a non-node base table.
    // @TODO: There may be cleaner ways to do this lookup.
    if (isset($this->view->relationship['vid'])) {
      $table = $this->view->relationship['vid']->alias;
    }
    elseif (isset($this->view->relationship['nid'])) {
      $table = $this->view->relationship['nid']->alias;
    }

    // If no filter is active, then we allow node types not under access control.
    if ($node_type_filter) {
      $this->query
        ->add_where($group, "{$table}.type", $node_types, 'IN');
    }
    else {
      $this->query
        ->add_where($group, "{$table}.type", $node_types, 'NOT IN');
    }
  }
}