'Custom Search', 'description' => 'Customize the default search, change labels, default texts, ordering, and display content types and taxonomy selectors.', 'page callback' => 'drupal_get_form', 'page arguments' => array('custom_search_admin'), 'access arguments' => array('administer custom search'), 'file' => 'custom_search.admin.inc', ); $items['admin/settings/custom_search/settings'] = array( 'title' => 'Settings', 'description' => 'Change the labels, the default texts and the ordering of elements.', 'access arguments' => array('administer custom search'), 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => 0, ); $items['admin/settings/custom_search/content'] = array( 'title' => 'Content', 'description' => 'Select the content types to present as search options in the search block.', 'page arguments' => array('custom_search_content_admin'), 'access arguments' => array('administer custom search'), 'file' => 'custom_search.admin.inc', 'type' => MENU_LOCAL_TASK, 'weight' => 1, ); $items['admin/settings/custom_search/results'] = array( 'title' => 'Results page', 'description' => 'Customize the search results page.', 'page arguments' => array('custom_search_results_admin'), 'access arguments' => array('administer custom search'), 'file' => 'custom_search.admin.inc', 'type' => MENU_LOCAL_TASK, 'weight' => 4, ); return $items; } /** * Implementation of hook_perm(). */ function custom_search_perm() { return array('administer custom search', 'use custom search'); } /** * Implementation of hook_form_alter(). */ function custom_search_form_alter(&$form, $form_state, $form_id) { if (user_access('use custom search')) { switch ($form_id) { case 'search_form': // Apply Custom Search settings to the advanced search form. if (!variable_get('custom_search_advanced_or_display', TRUE)) unset($form['advanced']['keywords']['or']); if (!variable_get('custom_search_advanced_phrase_display', TRUE)) unset($form['advanced']['keywords']['phrase']); if (!variable_get('custom_search_advanced_negative_display', TRUE)) unset($form['advanced']['keywords']['negative']); $names = array_keys(node_get_types('names')); foreach ($names as $name) { if (!variable_get('custom_search_advanced_type_' . $name . '_display', TRUE)) unset($form['advanced']['type']['#options'][$name]); } if (!count($form['advanced']['type']['#options'])) unset($form['advanced']['type']); if (!variable_get('custom_search_results_search', TRUE)) { // If basic search is hidded, original search terms are imported into advanced search. $original_keys = $form['basic']['inline']['keys']['#default_value']; $temp_keys = explode(' ', $original_keys); foreach ($temp_keys as $value) { if (drupal_substr($value, 0, 5) != 'type:' && drupal_substr($value, 0, 9) != 'category:') $keys[] = $value; } $form['advanced']['keywords']['or']['#default_value'] = implode(' ', $keys); if (!isset($GLOBALS['nb_results']) || (isset($GLOBALS['nb_results']) && !$GLOBALS['nb_results'])) $form['advanced']['#collapsed'] = FALSE; $form['basic']['#prefix'] = '
'; $form['basic']['#suffix'] = '
'; } if (!variable_get('custom_search_results_advanced_search', TRUE)) unset($form['advanced']); break; case 'search_theme_form': case 'search_block_form': case 'custom_search_blocks_form': $delta = ($form_id == 'custom_search_blocks_form') ? 'blocks_' . $form['delta']['#value'] . '_' : ''; // Search box. $form[$form_id]['#default_value'] = variable_get('custom_search_text', ''); $form[$form_id]['#weight'] = variable_get('custom_search_' . $delta . 'search_box_weight', 0); $form[$form_id]['#attributes']['class'] .= ' custom-search-default-value custom-search-box'; // Default text. $form['default_text'] = array( '#type' => 'hidden', '#default_value' => variable_get('custom_search_text', ''), '#attributes' => array('class' => 'default-text'), ); // CSS $path = drupal_get_path('module', 'custom_search'); drupal_add_css($path . '/custom_search.css', 'module'); if ($form_id != 'custom_search_blocks_form') { // Title. $form[$form_id]['#title'] = variable_get('custom_search_label', CUSTOM_SEARCH_LABEL_DEFAULT); if (!variable_get('custom_search_label_visibility', TRUE)) $form[$form_id]['#post_render'] = array('_custom_search_hide_label'); // Criterion if (variable_get('custom_search_criteria_or_display', FALSE)) { $form['custom_search_criteria_or'] = array( '#type' => 'textfield', '#title' => variable_get('custom_search_criteria_or_label', CUSTOM_SEARCH_CRITERIA_OR_LABEL_DEFAULT), '#size' => 15, '#maxlength' => 255, '#weight' => variable_get('custom_search_criteria_or_weight', 6), ); } if (variable_get('custom_search_criteria_phrase_display', FALSE)) { $form['custom_search_criteria_phrase'] = array( '#type' => 'textfield', '#title' => variable_get('custom_search_criteria_phrase_label', CUSTOM_SEARCH_CRITERIA_PHRASE_LABEL_DEFAULT), '#size' => 15, '#maxlength' => 255, '#weight' => variable_get('custom_search_criteria_phrase_weight', 7), ); } if (variable_get('custom_search_criteria_negative_display', FALSE)) { $form['custom_search_criteria_negative'] = array( '#type' => 'textfield', '#title' => variable_get('custom_search_criteria_negative_label', CUSTOM_SEARCH_CRITERIA_NEGATIVE_LABEL_DEFAULT), '#size' => 15, '#maxlength' => 255, '#weight' => variable_get('custom_search_criteria_negative_weight', 8), ); } } // Content type & other searches. // Content types. $toptions = array(); $types = array_keys(array_filter(variable_get('custom_search_' . $delta . 'node_types', array()))); if (count($types)) { $names = node_get_types('names'); if (count($types) > 1) $toptions['c-all'] = variable_get('custom_search_' . $delta . 'type_selector_all', CUSTOM_SEARCH_ALL_TEXT_DEFAULT); foreach ($types as $type) { $toptions['c-' . $type] = $names[$type]; } } $options = array(); // Other searches. $others = array_keys(array_filter(variable_get('custom_search_' . $delta . 'other', array()))); // If content types and other searches are combined, make an optgroup. if (count($others) && count($toptions) && variable_get('custom_search_' . $delta . 'type_selector', 'select') == 'select') { $content = module_invoke('node', 'search', 'name'); $options[$content] = $toptions; } else { $options = $toptions; } foreach (module_implements('search') as $module) { if ($module != 'node' && $name = module_invoke($module, 'search', 'name')) { if (in_array($module, $others)) $options['o-' . $module] = $name; } } if (count($options)) { $selector_type = variable_get('custom_search_' . $delta . 'type_selector', 'select'); if ($selector_type == 'selectmultiple') { $selector_type = 'select'; $multiple = TRUE; } else $multiple = FALSE; $form['custom_search_types'] = array( '#type' => $selector_type, '#multiple' => $multiple, '#title' => variable_get('custom_search_' . $delta . 'type_selector_label', CUSTOM_SEARCH_TYPE_SELECTOR_LABEL_DEFAULT), '#options' => $options, '#default_value' => ((variable_get('custom_search_' . $delta . 'type_selector', 'select') == 'checkboxes') ? array('c-all') : 'c-all'), '#attributes' => array('class' => 'custom-search-selector custom-search-types'), '#weight' => variable_get('custom_search_' . $delta . 'content_types_weight', 1), '#validated' => TRUE, ); // If there's only one type, hide the selector if (count($others) + count($types) == 1) { $form['custom_search_types']['#type'] = 'hidden'; $default_value = array_keys(array_slice($options, count($options)-1)); $form['custom_search_types']['#default_value'] = $default_value[0]; } if (!variable_get('custom_search_' . $delta . 'type_selector_label_visibility', TRUE)) $form['custom_search_types']['#post_render'] = array('_custom_search_hide_label'); } // Custom paths if (variable_get('custom_search_' . $delta . 'paths', '') != '') { $options = array(); $lines = explode("\n", variable_get('custom_search_' . $delta . 'paths', '')); foreach ($lines as $line) { $temp = explode('|', $line); $options[$temp[0]] = $temp[1]; } if (count($options) == 1) { $form['custom_search_paths'] = array( '#type' => 'hidden', '#default_value' => $temp[0], ); } else { $form['custom_search_paths'] = array( '#type' => 'select', '#options' => $options, '#weight' => variable_get('custom_search_' . $delta . 'paths', 9), ); } } // Submit button. $form['submit']['#value'] = variable_get('custom_search_submit_text', CUSTOM_SEARCH_SUBMIT_TEXT_DEFAULT); if (variable_get('custom_search_image_path', '') != '') { $form['submit']['#type'] = 'image_button'; $form['submit']['#src'] = variable_get('custom_search_image_path', ''); $form['submit']['#name'] = 'op'; $form['submit']['#attributes'] = array('alt' => variable_get('custom_search_submit_text', CUSTOM_SEARCH_SUBMIT_TEXT_DEFAULT)); $form['submit']['#attributes'] = array('class' => 'custom-search-button'); } elseif ($form['submit']['#value'] == '') $form['submit']['#attributes'] = array('style' => 'display:none;'); $form['submit']['#weight'] = variable_get('custom_search_' . $delta . 'submit_button_weight', 3); // Form attributes $form['#attributes']['target'] = variable_get('custom_search_target', '_self'); $form['#attributes']['class'] = 'search-form'; $form['#submit'][] = 'custom_search_submit'; $form['form_token']['#default_value'] = drupal_get_token($form_id); break; } } } /** * Alter the search to respect the search modes selected. */ function custom_search_submit($form, &$form_state) { $delta = (isset($form_state['values']['delta'])) ? 'blocks_' . $form_state['values']['delta'] . '_' : '' ; $type = 'node'; $keys = $form_state['values'][$form_state['values']['form_id']]; $types = $form_state['values']['custom_search_types']; if (!is_array($types)) $types = array($types); $types = array_map('_custom_search_filter_keys', array_filter($types)); if (module_exists('taxonomy')) { $terms = array(); $vocabularies = taxonomy_get_vocabularies(); foreach ($vocabularies as $voc) { $vterms = $form_state['values']['custom_search_vocabulary_' . $voc->vid]; if (!is_array($vterms)) $vterms = array($vterms); $terms = array_merge($terms, $vterms); } $terms = array_map('_custom_search_filter_keys', array_values(array_filter($terms))); // if one or more -Any- is selected, delete them while (($index = array_search('all', $terms)) !== FALSE) array_splice($terms, $index, 1); } $search_types = module_implements('search'); $values = array_values($types); // temp transform of the array to have numerical index for the next test if (in_array($values[0], $search_types)) { $type = $values[0]; } else { if (trim($form_state['values']['custom_search_criteria_or']) != '') $keys .= ' ' . str_replace(' ', ' OR ', trim($form_state['values']['custom_search_criteria_or'])); if (trim($form_state['values']['custom_search_criteria_negative']) != '') $keys .= ' -' . str_replace(' ', ' -', trim($form_state['values']['custom_search_criteria_negative'])); if (trim($form_state['values']['custom_search_criteria_phrase']) != '') $keys .= ' "' . trim($form_state['values']['custom_search_criteria_phrase']) . '"'; if (count($types)) { // If a content type is selected, and it's not -Any-, search for that type. if (!in_array('all', $types)) $keys = search_query_insert($keys, 'type', implode(',', $types)); // If -Any- is selected and -Any- is set to restrict the search, grab the content types. elseif (variable_get('custom_search_' . $delta . 'any_restricts', FALSE)) { $restricted_types = array_keys(array_filter(variable_get('custom_search_' . $delta . 'node_types', array()))); $keys = search_query_insert($keys, 'type', implode(',', $restricted_types)); } } if (module_exists('taxonomy') && count($terms)) { $keys = search_query_insert($keys, 'category', implode(',', $terms)); } } if (module_exists('apachesolr_search')) $type = 'apachesolr_search'; elseif (module_exists('google_appliance')) $type = variable_get('google_appliance_default_search_path', 'google-appliance'); elseif (module_exists('luceneapi_node') && variable_get('luceneapi:default_search', 0)) $type = variable_get('luceneapi:default_search', 0); if (isset($form_state['values']['custom_search_paths']) && $form_state['values']['custom_search_paths'] != '') { $form_state['redirect'] = str_replace('[key]', $keys, $form_state['values']['custom_search_paths']); } else $form_state['redirect'] = 'search/' . $type . '/' . $keys; } /* * Presents links to filter the search results. */ function custom_search_preprocess_search_results(&$variables) { $GLOBALS['nb_results'] = count($variables['results']); // save # of results for collapsing advanced search $position = variable_get('custom_search_filter', 'disabled'); if (user_access('use custom search') && $position != 'disabled') { // Get search words (minus type:node_type) $keys = search_get_keys(); if (strpos($keys, 'type:') !== FALSE) { $keys = drupal_substr($keys, 0, strpos($keys, 'type:')-1); } // Get Custom Search authorised types $searchable_node_types = variable_get('custom_search_node_types', array()); $searchable_node_types = array_keys(array_filter($searchable_node_types, 'custom_search_filter_array')); if (!count($searchable_node_types)) $searchable_node_types = array_keys(node_get_types('names')); $node_types = db_query("SELECT type, name FROM {node_type} WHERE type IN (" . db_placeholders($searchable_node_types, 'varchar') . ")", $searchable_node_types); // Build menu $items = array(); $items[] = l(variable_get('custom_search_type_selector_all', CUSTOM_SEARCH_ALL_TEXT_DEFAULT), 'search/node/' . $keys); while ($node_type = db_fetch_array($node_types)) { $items[] = l($node_type['name'], 'search/node/' . $keys .' type:' . $node_type['type']); } $title = variable_get('custom_search_filter_label', CUSTOM_SEARCH_FILTER_LABEL_DEFAULT); if ($position == 'above' && count($items) > 2) $variables['search_results'] = '
' . theme('item_list', $items, $title) . '
' . $variables['search_results']; elseif (count($items) > 2) $variables['search_results'] .= '
' . theme('item_list', $items, $title) . '
'; } } /* * Customisation of the results info. */ function custom_search_preprocess_search_result(&$variables) { $infos = array(); foreach ($variables['info_split'] as $key => $info) { if (variable_get('custom_search_results_info_' . $key, TRUE)) array_push($infos, $info); } $variables['info'] = implode(' - ', $infos); } /** * Implementation of hook_init(). */ function custom_search_init() { if (user_access('use custom search')) { drupal_add_js(drupal_get_path('module', 'custom_search') . '/custom_search.js'); } } /** * Implementation of hook_theme(). */ function custom_search_theme() { if (user_access('use custom search')) { return array( 'custom_search_javascript' => array('arguments' => array()), 'custom_search_sort_form' => array('arguments' => array('form' => NULL)), ); } else return array(); } /** * Content admin form. */ function custom_search_content_admin_form($delta = '') { if ($delta != '') $delta = 'blocks_' . $delta . '_'; $form['custom_search_' . $delta . 'node_types'] = array( '#type' => 'checkboxes', '#title' => t('Content types'), '#default_value' => variable_get('custom_search_' . $delta . 'node_types', array()), '#options' => node_get_types('names'), ); // Other searches. $options = array(); foreach (module_implements('search') as $module) { if ($module != 'node' && $name = module_invoke($module, 'search', 'name')) { $options[$module] = $name; } } if (count($options)) { $form['custom_search_' . $delta . 'other'] = array( '#type' => 'checkboxes', '#title' => t('Other searches'), '#default_value' => variable_get('custom_search_' . $delta . 'other', array()), '#options' => $options, ); } $form['custom_search_' . $delta . 'type_selector'] = array( '#type' => 'select', '#title' => t('Selector type'), '#options' => array( 'select' => t('Drop-down list'), 'selectmultiple' => t('Drop-down list with multiple choices'), 'radios' => t('Radio buttons'), 'checkboxes' => t('Checkboxes'), ), '#description' => t('Choose which selector type to use. Note: content types and other searches cannot be combined in a single search.'), '#default_value' => variable_get('custom_search_' . $delta . 'type_selector', 'select'), ); $form['custom_search_' . $delta . 'type_selector_label_visibility'] = array( '#type' => 'checkbox', '#title' => t('Display label'), '#default_value' => variable_get('custom_search_' . $delta . 'type_selector_label_visibility', TRUE), ); $form['custom_search_' . $delta . 'type_selector_label'] = array( '#type' => 'textfield', '#title' => t('Label text'), '#default_value' => variable_get('custom_search_' . $delta . 'type_selector_label', CUSTOM_SEARCH_TYPE_SELECTOR_LABEL_DEFAULT), '#description' => t('Enter the label text for the selector. The default value is "!default".', array('!default' => CUSTOM_SEARCH_TYPE_SELECTOR_LABEL_DEFAULT)), ); $form['custom_search_' . $delta . 'type_selector_all'] = array( '#type' => 'textfield', '#title' => t('-Any content type- text'), '#default_value' => variable_get('custom_search_' . $delta . 'type_selector_all', CUSTOM_SEARCH_ALL_TEXT_DEFAULT), '#required' => TRUE, '#description' => t('Enter the text for "any content type" choice. The default value is "!default".', array('!default' => CUSTOM_SEARCH_ALL_TEXT_DEFAULT)), ); $form['custom_search_' . $delta . 'any_restricts'] = array( '#type' => 'checkbox', '#title' => t('Choosing -Any- restricts the search to the selected content types.'), '#default_value' => variable_get('custom_search_' . $delta . 'any_restricts', FALSE), '#description' => t('If not checked, choosing -Any- will search in all content types.'), ); return $form; } /** * Custom paths admin form. */ function custom_search_custom_paths_admin_form($delta = '') { if ($delta != '') $delta = 'blocks_' . $delta . '_'; $form['custom_search_' . $delta . 'paths'] = array( '#type' => 'textarea', '#title' => t('Custom search paths'), '#default_value' => variable_get('custom_search_' . $delta . 'paths', ''), '#description' => t('If you want to use a custom search paths, enter them here in the form path|label, one per line. The [key] token will be replaced by what is entered in the search box. Ie: mysearch/[key]|My custom search label. If only one path is specified, the selector will be hidden.'), ); return $form; } /** * Filter the types. */ function _custom_search_filter_keys($val) { return drupal_substr($val, 2); } /** * Remove the label by adding a class. */ function _custom_search_hide_label($content, $elements) { if (strpos($content, '