You are here

public function SearchApiViewsHandlerFilterFulltext::query in Search API 7

Add this filter to the query.

Overrides SearchApiViewsHandlerFilter::query

File

contrib/search_api_views/includes/handler_filter_fulltext.inc, line 160
Contains SearchApiViewsHandlerFilterFulltext.

Class

SearchApiViewsHandlerFilterFulltext
Views filter handler class for handling fulltext fields.

Code

public function query() {
  while (is_array($this->value)) {
    $this->value = $this->value ? reset($this->value) : '';
  }

  // Catch empty strings entered by the user, but not "0".
  if ($this->value === '') {
    return;
  }
  $fields = $this->options['fields'];
  $available_fields = array_keys($this
    ->getFulltextFields());
  $fields = $fields ? array_intersect($fields, $available_fields) : $available_fields;

  // If something already specifically set different fields, we silently fall
  // back to mere filtering.
  $filter = $this->options['mode'] == 'filter';
  if (!$filter) {
    $old = $this->query
      ->getFields();
    $filter = $old && (array_diff($old, $fields) || array_diff($fields, $old));
  }
  if ($filter) {
    $filter = $this->query
      ->createFilter('OR');
    $op = $this->operator === 'NOT' ? '<>' : '=';
    foreach ($fields as $field) {
      $filter
        ->condition($field, $this->value, $op);
    }
    $this->query
      ->filter($filter);
    return;
  }

  // If the operator was set to OR or NOT, set OR as the conjunction. (It is
  // also set for NOT since otherwise it would be "not all of these words".)
  if ($this->operator != 'AND') {
    $this->query
      ->setOption('conjunction', 'OR');
  }
  try {
    $this->query
      ->fields($fields);
  } catch (SearchApiException $e) {
    $this->query
      ->abort($e
      ->getMessage());
    return;
  }
  $old = $this->query
    ->getKeys();
  $old_original = $this->query
    ->getOriginalKeys();
  $this->query
    ->keys($this->value);
  if ($this->operator == 'NOT') {
    $keys =& $this->query
      ->getKeys();
    if (is_array($keys)) {
      $keys['#negation'] = TRUE;
    }
    else {

      // We can't know how negation is expressed in the server's syntax.
    }
  }

  // If there were fulltext keys set, we take care to combine them in a
  // meaningful way (especially with negated keys).
  if ($old) {
    $keys =& $this->query
      ->getKeys();

    // Array-valued keys are combined.
    if (is_array($keys)) {

      // If the old keys weren't parsed into an array, we instead have to
      // combine the original keys.
      if (is_scalar($old)) {
        $keys = "({$old}) ({$this->value})";
      }
      else {

        // If the conjunction or negation settings aren't the same, we have to
        // nest both old and new keys array.
        if (!empty($keys['#negation']) != !empty($old['#negation']) || $keys['#conjunction'] != $old['#conjunction']) {
          $keys = array(
            '#conjunction' => 'AND',
            $old,
            $keys,
          );
        }
        else {
          foreach (element_children($old) as $i) {
            $keys[] = $old[$i];
          }
        }
      }
    }
    elseif (is_scalar($old_original)) {
      $combined_keys = "({$old_original}) ({$keys})";
      $this->query
        ->keys($combined_keys);
      $keys = $combined_keys;
    }
  }
}