function _parse_search_expression in Search configuration 8
Same name and namespace in other branches
- 7 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 325
Code
function _parse_search_expression($expression) {
$sections = [
'negative' => [],
'positive' => [],
'options' => [],
];
// Pull out known option selectors
foreach ([
'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 ? [
$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 = [
$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;
}