You are here

public function SearchApiQuery::build in Search API 8

Builds the necessary info to execute the query.

Parameters

view $view: The view which is executed.

Overrides QueryPluginBase::build

1 call to SearchApiQuery::build()
SearchApiQuery::query in src/Plugin/views/query/SearchApiQuery.php
Generate a query and a countquery from all of the information supplied to the object.

File

src/Plugin/views/query/SearchApiQuery.php, line 460

Class

SearchApiQuery
Defines a Views query class for searching on Search API indexes.

Namespace

Drupal\search_api\Plugin\views\query

Code

public function build(ViewExecutable $view) {
  $this->view = $view;

  // Initialize the pager and let it modify the query to add limits. This has
  // to be done even for aborted queries since it might otherwise lead to a
  // fatal error when Views tries to access $view->pager.
  $view
    ->initPager();
  $view->pager
    ->query();

  // If the query was aborted by some plugin (or, possibly, hook), we don't
  // need to do anything else here. Adding conditions or other options to an
  // aborted query doesn't make sense.
  if ($this
    ->shouldAbort()) {
    return;
  }

  // Setup the nested filter structure for this query.
  if (!empty($this->where)) {

    // If the different groups are combined with the OR operator, we have to
    // add a new OR filter to the query to which the filters for the groups
    // will be added.
    if ($this->groupOperator === 'OR') {
      $base = $this->query
        ->createConditionGroup('OR');
      $this->query
        ->addConditionGroup($base);
    }
    else {
      $base = $this->query;
    }

    // Add a nested filter for each filter group, with its set conjunction.
    foreach ($this->where as $group_id => $group) {
      if (!empty($group['conditions']) || !empty($group['condition_groups'])) {
        $group += [
          'type' => 'AND',
        ];

        // For filters without a group, we want to always add them directly to
        // the query.
        $conditions = $group_id === '' ? $this->query : $this->query
          ->createConditionGroup($group['type']);
        if (!empty($group['conditions'])) {
          foreach ($group['conditions'] as $condition) {
            list($field, $value, $operator) = $condition;
            $conditions
              ->addCondition($field, $value, $operator);
          }
        }
        if (!empty($group['condition_groups'])) {
          foreach ($group['condition_groups'] as $nested_conditions) {
            $conditions
              ->addConditionGroup($nested_conditions);
          }
        }

        // If no group was given, the filters were already set on the query.
        if ($group_id !== '') {
          $base
            ->addConditionGroup($conditions);
        }
      }
    }
  }

  // Add the "search_api_bypass_access" option to the query, if desired.
  if (!empty($this->options['bypass_access'])) {
    $this->query
      ->setOption('search_api_bypass_access', TRUE);
  }

  // If the View and the Panel conspire to provide an overridden path then
  // pass that through as the base path.
  if (($path = $this->view
    ->getPath()) && strpos(Url::fromRoute('<current>')
    ->toString(), $path) !== 0) {
    $this->query
      ->setOption('search_api_base_path', $path);
  }

  // Save query information for Views UI.
  $view->build_info['query'] = (string) $this->query;

  // Add the fields to be retrieved to the query, as information for the
  // backend.
  $this->query
    ->setOption('search_api_retrieved_field_values', array_values($this->retrievedFieldValues));
}