You are here

function _search_api_query_add_node_access in Search API 7

Adds a node access filter to a search query, if applicable.

Parameters

object $account: The user object, who searches.

SearchApiQueryInterface $query: The query to which a node access filter should be added, if applicable.

string $type: (optional) The type of search – either "node" or "comment". Defaults to "node".

Throws

SearchApiException If not all necessary fields are indexed on the index.

1 call to _search_api_query_add_node_access()
search_api_search_api_query_alter in ./search_api.module
Implements hook_search_api_query_alter().

File

./search_api.module, line 2257
Provides a flexible framework for implementing search services.

Code

function _search_api_query_add_node_access($account, SearchApiQueryInterface $query, $type = 'node') {

  // Don't do anything if the user can access all content.
  if (user_access('bypass node access', $account)) {
    return;
  }
  $is_comment = $type == 'comment';

  // Check whether the necessary fields are indexed.
  $fields = $query
    ->getIndex()->options['fields'];
  $required = array(
    'search_api_access_node',
    'status',
  );
  if (!$is_comment) {
    $required[] = 'author';
  }
  foreach ($required as $field) {
    if (empty($fields[$field])) {
      $vars['@field'] = $field;
      $vars['@index'] = $query
        ->getIndex()->name;
      throw new SearchApiException(t('Required field @field not indexed on index @index. Could not perform access checks.', $vars));
    }
  }

  // If the user cannot access content/comments at all, return no results.
  if (!user_access('access content', $account) || $is_comment && !user_access('access comments', $account)) {

    // Simple hack for returning no results.
    $query
      ->condition('status', 0);
    $query
      ->condition('status', 1);
    watchdog('search_api', 'User @name tried to execute a search, but cannot access content.', array(
      '@name' => theme('username', array(
        'account' => $account,
      )),
    ), WATCHDOG_NOTICE);
    return;
  }

  // Filter by the "published" status.
  $published = $is_comment ? COMMENT_PUBLISHED : NODE_PUBLISHED;
  if (!$is_comment && user_access('view own unpublished content')) {
    $filter = $query
      ->createFilter('OR');
    $filter
      ->condition('status', $published);
    $filter
      ->condition('author', $account->uid);
    $query
      ->filter($filter);
  }
  else {
    $query
      ->condition('status', $published);
  }

  // Filter by node access grants.
  $filter = $query
    ->createFilter('OR');
  $grants = node_access_grants('view', $account);
  foreach ($grants as $realm => $gids) {
    foreach ($gids as $gid) {
      $filter
        ->condition('search_api_access_node', "node_access_{$realm}:{$gid}");
    }
  }
  $filter
    ->condition('search_api_access_node', 'node_access__all');
  $query
    ->filter($filter);
}