$labels['basic_submit']));
}
if (isset($form['advanced']['submit']) && !empty($labels['advanced_submit'])) {
$form['advanced']['submit']['#value'] = t('!search_config:advanced_submit', array('!search_config:advanced_submit' => $labels['advanced_submit']));
}
// Other form elements. Map into an array to iterate over each element.
$title_display = search_config_string_overrides('title_display');
$label_elements = array();
if (isset($form['basic'])) {
$label_elements['basic'] = &$form['basic']['keys'];
}
if (isset($form['advanced'])) {
$label_elements['advanced_fieldset'] = &$form['advanced'];
$label_elements['advanced_type'] = &$form['advanced']['type'];
$fkeywords = &$form['advanced']['keywords'];
$label_elements['advanced_any'] = &$fkeywords['or'];
$label_elements['advanced_phrase'] = &$fkeywords['phrase'];
$label_elements['advanced_none'] = &$fkeywords['negative'];
if (isset($form['advanced']['language'])) {
$label_elements['advanced_language'] = &$form['advanced']['language'];
}
}
foreach ($label_elements as $key => $element) {
if (empty($element)) {
continue;
}
if (!empty($fkeys['#default_value']) && !empty($labels[$key . '_with_keys'])) {
$label_elements[$key]['#title'] = t('!search_config:' . $key, array('!search_config:' . $key => $labels[$key . '_with_keys']));
}
elseif (!empty($labels[$key])) {
$label_elements[$key]['#title'] = t('!search_config:' . $key, array('!search_config:' . $key => $labels[$key]));
}
if (!empty($title_display[$key])) {
switch ($title_display[$key]) {
case 'description':
$label_elements[$key]['#description'] = $label_elements[$key]['#title'];
$label_elements[$key]['#title_display'] = 'invisible';
break;
case 'invisible':
$label_elements[$key]['#title_display'] = 'invisible';
break;
case 'default':
default:
}
}
}
}
/**
* This function implements the options to configure the default Drupal search
* form, including type filter, field visibility, form visibility, etc.
*/
function _search_config_advanced_form(&$form, $form_state) {
global $user, $search_config_node_results;
// Settings
$settings = search_config_node_settings();
$fs_phrase = $settings['fields']['containing_phrase'];
$fs_any = $settings['fields']['containing_any'];
$fs_none = $settings['fields']['containing_none'];
$fs_types = $settings['fields']['types'];
// Return the form for super admin unchanged
if ($user->uid == 1 && !empty($settings['restrictions']['admin_bypass'])) {
return $form;
}
// Form elements
$fkeys = &$form['basic']['keys'];
$fkeywords = &$form['advanced']['keywords'];
$ftype = &$form['advanced']['type'];
if (isset($form['advanced']['language'])) {
$fs_language = $settings['fields']['language'];
$form['advanced']['language']['#access'] = search_config_get_access($fs_language['remove'], $fs_language['roles']);
}
// Change the form fieldset.
switch ($settings['forms']['advanced_expand']) {
case 'remove':
$form['advanced']['#type'] = 'item';
$form['advanced']['#prefix'] = '
';
$form['advanced']['#suffix'] = '
';
unset($form['advanced']['#title']);
break;
case 'expand_always':
$form['advanced']['#collapsible'] = FALSE;
break;
case 'expand_if_empty':
$form['advanced']['#collapsed'] = !empty($search_config_node_results);
break;
case 'expand_on_first':
$form['advanced']['#collapsed'] = !empty($fkeys['#default_value']);
break;
case 'default':
default:
// Do nothing!
}
// Set form element access rights.
if ($settings['forms']['toggle_forms']) {
$form['basic']['#access'] = FALSE;
}
$fkeywords['phrase']['#access'] = search_config_get_access($fs_phrase['remove'], $fs_phrase['roles']);
$fkeywords['or']['#access'] = search_config_get_access($fs_any['remove'], $fs_any['roles']);
$fkeywords['negative']['#access'] = search_config_get_access($fs_none['remove'], $fs_none['roles']);
$ftype['#access'] = search_config_get_access($fs_types['remove'], $fs_types['roles']);
switch ($settings['forms']['remove_containing_wrapper']) {
case 'remove':
$fkeywords['phrase']['#access'] = FALSE;
$fkeywords['or']['#access'] = FALSE;
$fkeywords['negative']['#access'] = FALSE;
$fkeywords['#access'] = FALSE;
break;
case 'empty':
// Check the 3 fields and also if we are going to move the basic form here.
if (!($fkeywords['phrase']['#access'] || $fkeywords['or']['#access'] || $fkeywords['negative']['#access']
|| $settings['forms']['move_keyword_search'])) {
$fkeywords['#access'] = FALSE;
}
break;
case 'default':
default:
// Do nothing.
}
// Set the advanced forms values, (as best we can).
if ($settings['forms']['advanced_populate']) {
$basic_values = array();
$values = _parse_search_expression($fkeys['#default_value']);
$sections = _parse_search_expression($fkeys['#default_value']);
// Apply any negitive values.
if (count($sections['negative'])) {
foreach ($sections['negative'] as $index => $value) {
if (is_array($value)) {
$sections['negative'][$index] = implode(' OR ', $value);
}
}
if ($fkeywords['negative']['#access']) {
$fkeywords['negative']['#value'] = implode(' ', $sections['negative']);
}
else {
foreach ($sections['negative'] as $negative) {
$basic_values[] = '-' . $negative;
}
}
}
if (count($sections['positive'])) {
// Try and find an OR set.
$no_or = $fkeywords['or']['#access'];
$no_phrase = $fkeywords['phrase']['#access'];
foreach ($sections['positive'] as $index => $value) {
if (is_array($value)) {
if ($no_or) {
$fkeywords['or']['#value'] = implode(' ', $value);
$no_or = TRUE;
}
else {
$basic_values[] = implode(' OR ', $value);
}
}
else {
if (strpos($value, ' ')) {
if ($no_phrase) {
$fkeywords['phrase']['#value'] = $value;
$no_phrase = FALSE;
}
else {
$value = '"' . $value . '"';
$basic_values[] = $value;
}
}
else {
$basic_values[] = $value;
}
}
}
}
if (isset($sections['options']['type']) && $ftype['#access']) {
$types = explode(',', $sections['options']['type']);
$ftype['#default_value'] = drupal_map_assoc($types);
unset($sections['options']['type']);
}
// @todo: figure out how these work: 'language' & 'term'
foreach (array('language', 'term', 'type') as $key) {
if (isset($sections['options'][$key])) {
$basic_values[] = $key . ':' . $sections['options'][$key];
}
}
// Lose the values if we have no access
$access = empty($fkeys['#access']) ? 1 : $fkeys['#access'];
if ($access) {
$fkeys['#default_value'] = implode(' ', $basic_values);
}
}
if ($ftype['#access']) {
// Remove these ones from the display.
$base_types = array_filter($fs_types['filter']);
$access = user_access('search all content');
$allowed_types = array();
foreach (search_config_content_types() as $key => $type) {
if (in_array($key, $base_types) || !($access || user_access("search $key content"))) {
unset($ftype['#options'][$key]);
}
else {
$allowed_types [$key]= $key;
}
}
if (!empty($fs_types['groupings'])) {
// Parse the groupings for used types.
$selected_types = empty($ftype['#default_value']) ? array() : $ftype['#default_value'];
$grouping_selected_types = array();
$used_types = array();
foreach ($fs_types['groupings'] as $gtypes => $glabel) {
foreach (explode(',', $gtypes) as $gtype) {
if (isset($allowed_types[$gtype])) {
$used_types [$gtype] = $gtype;
}
}
}
// And again to set the values
$filtered_groupings = array();
foreach ($fs_types['groupings'] as $gtypes => $glabel) {
$filtered_gtypes = array();
foreach (explode(',', $gtypes) as $gtype) {
if (isset($allowed_types[$gtype])) {
$filtered_gtypes [$gtype] = $gtype;
}
elseif ($gtype == '') {
$filtered_gtypes += $allowed_types;
}
elseif ($gtype == '') {
$filtered_gtypes += array_diff_key($allowed_types, $used_types);
}
}
$is_selected = array_intersect_key($selected_types, $filtered_gtypes);
$gkey = implode(',', $filtered_gtypes);
// Potentially, filtering will cause key overlaps. Keep the first label.
if (!empty($gkey) && !isset($filtered_groupings[$gkey])) {
$filtered_groupings[$gkey] = $glabel;
if ($is_selected) {
$grouping_selected_types[$gkey] = $gkey;
}
}
}
$ftype['#options'] = $filtered_groupings;
$ftype['#default_value'] = $grouping_selected_types;
if (empty($ftype['#element_validate'])) {
$ftype['#element_validate'] = array();
}
$ftype['#element_validate'] = array('search_config_type_element_validate') + $ftype['#element_validate'];
}
}
// TODO - Categories et al
// This moves the keywords search element into the advanced form.
if ($settings['forms']['move_keyword_search']) {
$fkeys['#size'] = $fkeywords['or']['#size'];
$fkeywords = array('keys' => $fkeys) + $fkeywords;
unset($form['basic']['keys']);
$form['basic']['#access'] = FALSE;
}
return $form;
}
function search_config_type_element_validate($element, &$form_state) {
$types = array();
foreach ($element['#value'] as $opt_types) {
foreach (explode(',', $opt_types) as $type) {
$types[$type] = $type;
}
}
form_set_value($element, $types, $form_state);
}
/**
* Cloned from the search module to parse the query string.
*/
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);
}
// OR operator: instead of a single keyword, we store an array of all
// OR'd keywords.
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;
}
// AND operator: implied, so just ignore it.
elseif ($match[2] == 'AND' || $match[2] == 'and') {
continue;
}
// Plain keyword.
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;
}