public function Search::query

Same name in this branch

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 FilterPluginBase::query

File

drupal/core/modules/search/lib/Drupal/search/Plugin/views/filter/Search.php, line 118
Definition of Drupal\search\Plugin\views\filter\Search.

Class

Search
Field handler to provide simple renderer that allows linking to a node.

Namespace

Drupal\search\Plugin\views\filter

Code

public function query() {

  // Since attachment views don't validate the exposed input, parse the search
  // expression if required.
  if (!$this->parsed) {
    $this
      ->query_parse_search_expression($this->value);
  }
  $required = FALSE;
  if (!isset($this->search_query)) {
    $required = TRUE;
  }
  else {
    $words = $this->search_query
      ->words();
    if (empty($words)) {
      $required = TRUE;
    }
  }
  if ($required) {
    if ($this->operator == 'required') {
      $this->query
        ->add_where($this->options['group'], 'FALSE');
    }
  }
  else {
    $search_index = $this
      ->ensureMyTable();
    $search_condition = db_and();

    // Create a new join to relate the 'serach_total' table to our current 'search_index' table.
    $definition = array(
      'table' => 'search_total',
      'field' => 'word',
      'left_table' => $search_index,
      'left_field' => 'word',
    );
    $join = drupal_container()
      ->get('plugin.manager.views.join')
      ->createInstance('standard', $definition);
    $search_total = $this->query
      ->add_relationship('search_total', $join, $search_index);
    $this->search_score = $this->query
      ->add_field('', "SUM({$search_index}.score * {$search_total}.count)", 'score', array(
      'aggregate' => TRUE,
    ));
    if (empty($this->query->relationships[$this->relationship])) {
      $base_table = $this->view->storage
        ->get('base_table');
    }
    else {
      $base_table = $this->query->relationships[$this->relationship]['base'];
    }
    $search_condition
      ->condition("{$search_index}.type", $base_table);
    if (!$this->search_query
      ->simple()) {
      $search_dataset = $this->query
        ->add_table('search_dataset');
      $conditions = $this->search_query
        ->conditions();
      $condition_conditions =& $conditions
        ->conditions();
      foreach ($condition_conditions as $key => &$condition) {

        // Take sure we just look at real conditions.
        if (is_numeric($key)) {

          // Replace the conditions with the table alias of views.
          $this->search_query
            ->condition_replace_string('d.', "{$search_dataset}.", $condition);
        }
      }
      $search_conditions =& $search_condition
        ->conditions();
      $search_conditions = array_merge($search_conditions, $condition_conditions);
    }
    else {

      // Stores each condition, so and/or on the filter level will still work.
      $or = db_or();
      foreach ($words as $word) {
        $or
          ->condition("{$search_index}.word", $word);
      }
      $search_condition
        ->condition($or);
    }
    $this->query
      ->add_where($this->options['group'], $search_condition);
    $this->query
      ->add_groupby("{$search_index}.sid");
    $matches = $this->search_query
      ->matches();
    $placeholder = $this
      ->placeholder();
    $this->query
      ->add_having_expression($this->options['group'], "COUNT(*) >= {$placeholder}", array(
      $placeholder => $matches,
    ));
  }

  // Set to NULL to prevent PDO exception when views object is cached.
  $this->search_query = NULL;
}