custom_search.module in Custom Search 6
Same filename and directory in other branches
Bring customizations to the default search box
Adds node types and taxonomy options to the search form
File
custom_search.moduleView source
<?php
/**
* @file
* Bring customizations to the default search box
*
* Adds node types and taxonomy options to the search form
*/
define('CUSTOM_SEARCH_LABEL_DEFAULT', t('Search this site'));
define('CUSTOM_SEARCH_SUBMIT_TEXT_DEFAULT', t('Search'));
define('CUSTOM_SEARCH_TYPE_SELECTOR_LABEL_DEFAULT', t('Search for'));
define('CUSTOM_SEARCH_MAX_LENGTH_DEFAULT', 128);
define('CUSTOM_SEARCH_SIZE_DEFAULT', 15);
define('CUSTOM_SEARCH_ALL_TEXT_DEFAULT', t('-Any-'));
define('CUSTOM_SEARCH_CRITERIA_OR_LABEL_DEFAULT', t('Containing any of the words'));
define('CUSTOM_SEARCH_CRITERIA_PHRASE_LABEL_DEFAULT', t('Containing the phrase'));
define('CUSTOM_SEARCH_CRITERIA_NEGATIVE_LABEL_DEFAULT', t('Containing none of the words'));
define('CUSTOM_SEARCH_FILTER_LABEL_DEFAULT', t('Filter the results'));
define('CUSTOM_SEARCH_PATHS_SELECTOR_LABEL_DEFAULT', t('Customize your search'));
define('CUSTOM_SEARCH_PATHS_TERMS_SEPARATOR_DEFAULT', '+');
/**
* Includes
*/
module_load_include('inc', 'custom_search', 'includes/forms');
module_load_include('inc', 'custom_search', 'includes/apachesolr_search');
module_load_include('inc', 'custom_search', 'includes/google_appliance');
module_load_include('inc', 'custom_search', 'includes/luceneapi_node');
/**
* Implementation of hook_menu().
*/
function custom_search_menu() {
$items['admin/settings/custom_search'] = array(
'title' => '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_menu_alter().
* (needed for compatibility with Search Ranking)
*/
function custom_search_menu_alter(&$callbacks) {
// Panels integration
if ($callbacks['search/node/%menu_tail']['page callback'] == 'page_manager_search_page') {
return;
}
$callbacks['search/node/%menu_tail']['page callback'] = 'search_view';
$callbacks['search/node/%menu_tail']['file'] = 'search.pages.inc';
$callbacks['search/node/%menu_tail']['file path'] = drupal_get_path('module', 'search');
}
/**
* 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) {
// Filter the form_id value to identify all the custom blocks
$form_id_processed = $form_id;
$delta = '';
for ($a = 1; $a <= variable_get('custom_search_blocks_number', 1); $a++) {
if ($form_id == 'custom_search_blocks_form_' . $a) {
$form_id_processed = 'custom_search_blocks_form';
$delta = 'blocks_' . $a . '_';
}
}
switch ($form_id_processed) {
case 'search_form':
if (isset($form['advanced'])) {
// Criteria
if (!variable_get('custom_search_advanced_or_display', TRUE)) {
$form['advanced']['keywords']['or']['#type'] = 'hidden';
}
if (!variable_get('custom_search_advanced_phrase_display', TRUE)) {
$form['advanced']['keywords']['phrase']['#type'] = 'hidden';
}
if (!variable_get('custom_search_advanced_negative_display', TRUE)) {
$form['advanced']['keywords']['negative']['#type'] = 'hidden';
}
// Taxonomy
if (module_exists('taxonomy')) {
$vocabularies = taxonomy_get_vocabularies();
foreach ($vocabularies as $voc) {
if (!variable_get('custom_search_advanced_voc' . $voc->vid . '_display', TRUE)) {
unset($form['advanced']['category']['#options'][$voc->name]);
}
}
if (!count($form['advanced']['category']['#options'])) {
unset($form['advanced']['category']['#type']);
}
}
// Content Types
$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']['#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['custom_search_nb_results']) || isset($GLOBALS['custom_search_nb_results']) && !$GLOBALS['custom_search_nb_results']) {
$form['advanced']['#collapsed'] = FALSE;
}
$form['basic']['#prefix'] = '<div class="element-invisible">';
$form['basic']['#suffix'] = '</div>';
}
$form['advanced']['#collapsible'] = variable_get('custom_search_results_advanced_search_collapsible', TRUE);
$form['advanced']['#collapsed'] = variable_get('custom_search_results_advanced_search_collapsed', TRUE);
if (!variable_get('custom_search_results_advanced_search', TRUE)) {
$form['advanced']['#type'] = 'hidden';
}
}
break;
case 'search_theme_form':
case 'search_block_form':
case 'custom_search_blocks_form':
if (user_access('use custom search')) {
// Title.
$form[$form_id]['#title'] = variable_get('custom_search_' . $delta . 'label', CUSTOM_SEARCH_LABEL_DEFAULT);
if (!variable_get('custom_search_' . $delta . 'label_visibility', TRUE)) {
$form[$form_id]['#post_render'] = array(
'_custom_search_hide_label',
);
}
// Search box.
$form[$form_id]['#default_value'] = variable_get('custom_search_' . $delta . 'text', '');
$form[$form_id]['#weight'] = variable_get('custom_search_' . $delta . 'search_box_weight', 0);
if (!isset($form[$form_id]['#attributes']['class'])) {
$form[$form_id]['#attributes']['class'] = '';
}
$form[$form_id]['#attributes']['class'] .= ' custom-search-default-value custom-search-box';
$form[$form_id]['#size'] = variable_get('custom_search_' . $delta . 'size', CUSTOM_SEARCH_SIZE_DEFAULT);
$form[$form_id]['#maxlength'] = variable_get('custom_search_' . $delta . 'max_length', CUSTOM_SEARCH_MAX_LENGTH_DEFAULT);
// Default text.
$form['default_text'] = array(
'#type' => 'hidden',
'#default_value' => variable_get('custom_search_' . $delta . 'text', ''),
'#attributes' => array(
'class' => 'default-text',
),
);
// CSS
drupal_add_css(drupal_get_path('module', 'custom_search') . '/custom_search.css', 'module');
// Criterion
$criteria = array(
'or' => 6,
'phrase' => 7,
'negative' => 8,
);
foreach ($criteria as $c => $w) {
if (variable_get('custom_search_' . $delta . 'criteria_' . $c . '_display', FALSE)) {
$form['custom_search_criteria_' . $c] = array(
'#type' => 'textfield',
'#title' => variable_get('custom_search_' . $delta . 'criteria_' . $c . '_label', constant('CUSTOM_SEARCH_CRITERIA_' . strtoupper($c) . '_LABEL_DEFAULT')),
'#size' => 15,
'#maxlength' => 255,
'#weight' => variable_get('custom_search_' . $delta . 'criteria_' . $c . '_weight', $w),
);
}
}
// 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 || variable_get('custom_search_' . $delta . 'any_force', FALSE)) {
$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' => $selector_type != 'radios' && $selector_type != 'checkboxes' ? array(
'class' => 'custom-search-selector custom-search-types',
) : array(),
'#prefix' => $selector_type == 'radios' || $selector_type == 'checkboxes' ? '<div class="custom-search-selector custom-search-types">' : '',
'#suffix' => $selector_type == 'radios' || $selector_type == 'checkboxes' ? '</div>' : '',
'#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 && !variable_get('custom_search_' . $delta . 'any_force', FALSE)) {
$form['custom_search_types']['#type'] = 'hidden';
$form['custom_search_types']['#default_value'] = key(array_slice($options, count($options) - 1));
}
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]] = count($temp) >= 2 ? t($temp[1]) : '';
}
if (count($options) == 1) {
$form['custom_search_paths'] = array(
'#type' => 'hidden',
'#default_value' => key($options),
);
}
else {
$form['custom_search_paths'] = array(
'#type' => variable_get('custom_search_' . $delta . 'paths_selector', 'select'),
'#title' => variable_get('custom_search_' . $delta . 'paths_selector_label', CUSTOM_SEARCH_PATHS_SELECTOR_LABEL_DEFAULT),
'#options' => $options,
'#default_value' => key($options),
'#weight' => variable_get('custom_search_' . $delta . 'custom_paths_weight', 9),
);
if (!variable_get('custom_search_' . $delta . 'paths_selector_label_visibility', TRUE)) {
$form['custom_search_paths']['#post_render'] = array(
'_custom_search_hide_label',
);
}
}
}
// Submit button.
$form['submit']['#value'] = variable_get('custom_search_' . $delta . 'submit_text', CUSTOM_SEARCH_SUBMIT_TEXT_DEFAULT);
if (variable_get('custom_search_' . $delta . 'image_path', '') != '') {
$form['submit']['#type'] = 'image_button';
$form['submit']['#src'] = variable_get('custom_search_' . $delta . 'image_path', '');
$form['submit']['#name'] = 'op';
$form['submit']['#attributes'] = array(
'alt' => variable_get('custom_search_' . $delta . 'submit_text', CUSTOM_SEARCH_SUBMIT_TEXT_DEFAULT),
'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);
// Popup
$form['popup'] = array(
'#type' => 'fieldset',
'#weight' => 1 + variable_get('custom_search_' . $delta . 'search_box_weight', 0),
'#attributes' => array(
'class' => 'custom_search-popup',
),
);
if (!empty($form['custom_search_types']) && variable_get('custom_search_' . $delta . 'content_types_region', 'block') == 'popup') {
$form['popup']['custom_search_types'] = $form['custom_search_types'];
unset($form['custom_search_types']);
}
if (!empty($form['custom_search_paths']) && variable_get('custom_search_' . $delta . 'custom_paths_region', 'block') == 'popup') {
$form['popup']['custom_search_paths'] = $form['custom_search_paths'];
unset($form['custom_search_paths']);
}
foreach ($criteria as $c => $w) {
if (variable_get('custom_search_' . $delta . 'criteria_' . $c . '_display', FALSE) && variable_get('custom_search_' . $delta . 'criteria_' . $c . '_region', 'block') == 'popup') {
$form['popup']['custom_search_criteria_' . $c] = $form['custom_search_criteria_' . $c];
unset($form['custom_search_criteria_' . $c]);
}
}
// Form attributes
$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'] . '_' : '';
variable_set('custom_search_delta', $delta);
// save for later use (exclusion & refresh)
$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');
if (in_array(current($types), $search_types)) {
$type = current($types);
}
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']) . '"';
}
$original_keywords = $keys;
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));
}
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));
}
}
// Integrates other search modules
if (module_exists('apachesolr_search') && variable_get('apachesolr_search_make_default', 0)) {
$search_path = _custom_search_apachesolr_search(array(
'keywords' => $original_keywords,
'types' => $types,
'terms' => !empty($terms) ? $terms : array(),
));
}
elseif (module_exists('google_appliance')) {
$search_path = _custom_search_google_appliance_search(array(
'keys' => $keys,
));
}
elseif (module_exists('luceneapi_node') && variable_get('luceneapi:default_search', 0)) {
$search_path = _custom_search_lucenapi_search(array(
'keywords' => $original_keywords,
'types' => $types,
'terms' => !empty($terms) ? $terms : array(),
));
}
else {
$search_path = array(
'path' => 'search/' . $type . '/' . $keys,
'query' => '',
);
}
// Build a custom path if needed
if (isset($form_state['values']['custom_search_paths']) && $form_state['values']['custom_search_paths'] != '') {
$custom_path = str_replace('[key]', $form_state['values'][$form_state['values']['form_id']], $form_state['values']['custom_search_paths']);
if (strpos($form_state['values']['custom_search_paths'], '[terms]') !== FALSE) {
$custom_path = str_replace('[terms]', count($terms) ? implode($form_state['values']['custom_search_paths_terms_separator'], $terms) : '', $custom_path);
}
$form_state['redirect'] = $custom_path;
// check for external path. If not, add base path
if (drupal_substr($custom_path, 0, 4) != 'http') {
$form_state['redirect'] = url($form_state['redirect'], array(
'absolute' => TRUE,
));
}
}
else {
$form_state['redirect'] = url($search_path['path'], array(
'query' => $search_path['query'],
'absolute' => TRUE,
));
}
}
/*
* Rewrite the sql query to exclude content types
*/
function custom_search_db_rewrite_sql($query, $primary_table, $primary_field, $args) {
if ($query == '' && $primary_table == 'n' && ($primary_field = 'nid' && empty($args))) {
$excluded_types = array_filter(variable_get('custom_search_' . variable_get('custom_search_delta', '') . 'node_types_excluded', array()));
if (!empty($excluded_types)) {
$where = " n.type NOT IN ('" . join("','", $excluded_types) . "') ";
return array(
'where' => $where,
);
}
}
}
/**
* Implementation of hook_init().
*/
function custom_search_init() {
if (user_access('use custom search')) {
drupal_add_js(drupal_get_path('module', 'custom_search') . '/js/custom_search.js');
drupal_add_js(array(
'custom_search' => array(
'form_target' => variable_get('custom_search_target', '_self'),
'solr' => module_exists('apachesolr_search') && variable_get('apachesolr_search_make_default', 0) ? 1 : 0,
),
), 'setting');
}
}
/**
* Implementation of hook_theme().
*/
function custom_search_theme() {
$path = drupal_get_path('module', 'custom_search') . '/theme';
$custom_search_theme_array = array(
'custom_search_javascript' => array(
'arguments' => array(),
),
'custom_search_sort_form' => array(
'path' => $path,
'template' => 'custom_search-sort-form',
'arguments' => array(
'form' => NULL,
),
),
'search_results' => array(
'arguments' => array(
'results' => NULL,
'type' => NULL,
),
'path' => $path,
'file' => 'custom_search.pages.inc',
'template' => 'custom_search-results',
),
'search_result' => array(
'arguments' => array(
'result' => NULL,
'type' => NULL,
),
'path' => $path,
'file' => 'custom_search.pages.inc',
'template' => 'custom_search-result',
),
);
// Panels integration
$search_results_page_callback = menu_get_item('search/node/%menu_tail');
if ($search_results_page_callback['page_callback'] == 'page_manager_search_page') {
unset($custom_search_theme_array['search_results'], $custom_search_theme_array['search_result']);
}
return $custom_search_theme_array;
}
/**
* Filter the types.
*/
function _custom_search_filter_keys($val) {
return strlen($val) > 2 && $val[1] == '-' ? drupal_substr($val, 2) : $val;
}
/**
* Remove the label by adding a class.
*/
function _custom_search_hide_label($content, $elements) {
if (strpos($content, '<label class') !== FALSE) {
$content = str_replace('<label class="', '<label class="element-invisible ', $content);
}
else {
$content = str_replace('<label', '<label class="element-invisible"', $content);
}
return $content;
}
/**
* Function used to filter node_type array to only filter those that are configured in Custom Search Form
*/
function custom_search_filter_array($value = FALSE) {
return $value !== 0;
}
Functions
Name | Description |
---|---|
custom_search_db_rewrite_sql | |
custom_search_filter_array | Function used to filter node_type array to only filter those that are configured in Custom Search Form |
custom_search_form_alter | Implementation of hook_form_alter(). |
custom_search_init | Implementation of hook_init(). |
custom_search_menu | Implementation of hook_menu(). |
custom_search_menu_alter | Implementation of hook_menu_alter(). (needed for compatibility with Search Ranking) |
custom_search_perm | Implementation of hook_perm(). |
custom_search_submit | Alter the search to respect the search modes selected. |
custom_search_theme | Implementation of hook_theme(). |
_custom_search_filter_keys | Filter the types. |
_custom_search_hide_label | Remove the label by adding a class. |