You are here

function _parse_search_expression in Search configuration 7

Same name and namespace in other branches
  1. 8 search_config.node.inc \_parse_search_expression()

Cloned from the search module to parse the query string.

1 call to _parse_search_expression()
_search_config_advanced_form in ./search_config.node.inc
This function implements the options to configure the default Drupal search form, including type filter, field visibility, form visibility, etc.

File

./search_config.node.inc, line 319
Provides the search form alter functionality for search config.

Code

function _parse_search_expression($expression) {
  $sections = array(
    'negative' => array(),
    'positive' => array(),
    'options' => array(),
  );

  // Pull out known option selectors
  foreach (array(
    'type',
    'language',
    'term',
  ) as $option) {
    if (preg_match('/(^| )' . $option . ':([^ ]*)( |$)/i', $expression, $matches)) {
      $sections['options'][$option] = $matches[2];
      $expression = str_replace($matches[0], ' ', $expression);
    }
  }

  // Matchs words optionally prefixed by a dash. A word in this case is
  // something between two spaces, optionally quoted.
  preg_match_all('/ (-?)("[^"]+"|[^" ]+)/i', ' ' . $expression, $keywords, PREG_SET_ORDER);
  if (!empty($keywords)) {

    // Classify tokens.
    $or = FALSE;
    foreach ($keywords as $match) {
      $phrase = FALSE;

      // Strip off phrase quotes.
      if ($match[2][0] == '"') {
        $match[2] = substr($match[2], 1, -1);
        $phrase = TRUE;
      }

      // Simplify keyword according to indexing rules and external
      // preprocessors. Use same process as during search indexing, so it
      // will match search index.
      $words = search_simplify($match[2]);

      // Re-explode in case simplification added more words, except when
      // matching a phrase.
      $words = $phrase ? array(
        $words,
      ) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY);

      // Negative matches.
      if ($match[1] == '-') {
        $sections['negative'] = array_merge($sections['negative'], $words);
      }
      elseif ($match[2] == 'OR' && count($sections['positive'])) {
        $last = array_pop($sections['positive']);

        // Starting a new OR?
        if (!is_array($last)) {
          $last = array(
            $last,
          );
        }
        $sections['positive'][] = $last;
        $or = TRUE;
        continue;
      }
      elseif ($match[2] == 'AND' || $match[2] == 'and') {
        continue;
      }
      else {
        if ($or) {

          // Add to last element (which is an array).
          $sections['positive'][count($sections['positive']) - 1] = array_merge($sections['positive'][count($sections['positive']) - 1], $words);
        }
        else {
          $sections['positive'] = array_merge($sections['positive'], $words);
        }
      }
      $or = FALSE;
    }
  }
  return $sections;
}