You are here

protected function SearchApiSolrService::flattenKeys in Search API Solr 7

Flatten a keys array into a single search string.

Parameters

array $keys: The keys array to flatten, formatted as specified by SearchApiQueryInterface::getKeys().

Return value

string A Solr query string representing the same keys.

3 calls to SearchApiSolrService::flattenKeys()
SearchApiSolrService::getAutocompleteSuggestions in includes/service.inc
SearchApiSolrService::search in includes/service.inc
Executes a search on the server represented by this object.
SearchApiSolrService::searchMultiple in includes/service.inc
Implements SearchApiMultiServiceInterface::searchMultiple().

File

includes/service.inc, line 1782

Class

SearchApiSolrService
Search service class using Solr server.

Code

protected function flattenKeys(array $keys) {
  $k = array();
  $or = $keys['#conjunction'] == 'OR';
  $neg = !empty($keys['#negation']);
  foreach (element_children($keys) as $i) {
    $key = $keys[$i];
    if (!$key) {
      continue;
    }
    if (is_array($key)) {
      $subkeys = $this
        ->flattenKeys($key);
      if ($subkeys) {
        $nested_expressions = TRUE;

        // If this is a negated OR expression, we can't just use nested keys
        // as-is, but have to put them into parantheses.
        if ($or && $neg) {
          $subkeys = "({$subkeys})";
        }
        $k[] = $subkeys;
      }
    }
    else {
      $key = trim($key);
      $key = call_user_func(array(
        $this
          ->getConnectionClass(),
        'phrase',
      ), $key);
      $k[] = $key;
    }
  }
  if (!$k) {
    return '';
  }

  // Formatting the keys into a Solr query can be a bit complex. The following
  // code will produce filters that look like this:
  //
  // #conjunction | #negation | return value
  // ----------------------------------------------------------------
  // AND          | FALSE     | A B C
  // AND          | TRUE      | -(A AND B AND C)
  // OR           | FALSE     | ((A) OR (B) OR (C))
  // OR           | TRUE      | -A -B -C
  // If there was just a single, unnested key, we can ignore all this.
  if (count($k) == 1 && empty($nested_expressions)) {
    $k = reset($k);
    return $neg ? "*:* AND -{$k}" : $k;
  }
  if ($or) {
    if ($neg) {
      return '*:* AND -' . implode(' AND -', $k);
    }
    return '((' . implode(') OR (', $k) . '))';
  }
  $k = implode(' AND ', $k);
  return $neg ? "*:* AND -({$k})" : $k;
}