diff --git a/modules/node.module b/modules/node.module index bdce5ebea327aeac23282c4e9a3f980d045e6786..092523f1b30a5cb4a8af0eb2a9e321e646b6f775 100644 --- a/modules/node.module +++ b/modules/node.module @@ -731,94 +731,6 @@ function node_search($op = 'search', $keys = null) { 'snippet' => search_excerpt($keys, $node->body)); } return $results; - - case 'form': - $form = array(); - - // Keyword boxes - $form['advanced'] = array( - '#type' => 'fieldset', - '#title' => t('Advanced search'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - '#attributes' => array('class' => 'search-advanced'), - ); - $form['advanced']['keywords'] = array( - '#prefix' => '<div class="criterion">', - '#suffix' => '</div>', - ); - $form['advanced']['keywords']['or'] = array( - '#type' => 'textfield', - '#title' => t('Containing any of the words'), - '#size' => 30, - '#maxlength' => 255, - ); - $form['advanced']['keywords']['phrase'] = array( - '#type' => 'textfield', - '#title' => t('Containing the phrase'), - '#size' => 30, - '#maxlength' => 255, - ); - $form['advanced']['keywords']['negative'] = array( - '#type' => 'textfield', - '#title' => t('Containing none of the words'), - '#size' => 30, - '#maxlength' => 255, - ); - - // Taxonomy box - if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) { - $form['advanced']['category'] = array( - '#type' => 'select', - '#title' => t('Only in the category(s)'), - '#prefix' => '<div class="criterion">', - '#size' => 10, - '#suffix' => '</div>', - '#options' => $taxonomy, - '#multiple' => TRUE, - ); - } - - // Node types - $types = node_get_types(); - $form['advanced']['type'] = array( - '#type' => 'checkboxes', - '#title' => t('Only of the type(s)'), - '#prefix' => '<div class="criterion">', - '#suffix' => '</div>', - '#options' => $types, - ); - $form['advanced']['submit'] = array( - '#type' => 'submit', - '#value' => t('Advanced search'), - '#prefix' => '<div class="action">', - '#suffix' => '</div><br clear="all" />', - ); - return $form; - - case 'post': - // Insert extra restrictions into the search keywords string. - $edit = &$_POST['edit']; - if (isset($edit['type']) && is_array($edit['type'])) { - $keys = search_query_insert($keys, 'type', implode(',', array_keys($edit['type']))); - } - if (isset($edit['category']) && is_array($edit['category'])) { - $keys = search_query_insert($keys, 'category', implode(',', $edit['category'])); - } - if ($edit['or'] != '') { - if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' '. $edit['or'], $matches)) { - $keys = $keys .' '. implode(' OR ', $matches[1]); - } - } - if ($edit['negative'] != '') { - if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' '. $edit['negative'], $matches)) { - $keys = $keys .' -'. implode(' -', $matches[1]); - } - } - if ($edit['phrase'] != '') { - $keys .= ' "'. str_replace('"', ' ', $edit['phrase']) .'"'; - } - return trim($keys); } } @@ -2163,14 +2075,126 @@ function node_update_index() { } } +/** + * Implementation of hook_form_alter(). + */ function node_form_alter($form_id, &$form) { + // Node publishing options if (isset($form['type']) && $form['type']['#value'] .'_node_settings' == $form_id) { - $form['workflow']['node_options_'. $form['type']['#value']] = array( - '#type' => 'checkboxes', '#title' => t('Default options'), '#default_value' => variable_get('node_options_'. $form['type']['#value'], array('status', 'promote')), - '#options' => array('status' => t('Published'), 'moderate' => t('In moderation queue'), 'promote' => t('Promoted to front page'), 'sticky' => t('Sticky at top of lists'), 'revision' => t('Create new revision')), + $form['workflow']['node_options_'. $form['type']['#value']] = array('#type' => 'checkboxes', + '#title' => t('Default options'), + '#default_value' => variable_get('node_options_'. $form['type']['#value'], array('status', 'promote')), + '#options' => array( + 'status' => t('Published'), + 'moderate' => t('In moderation queue'), + 'promote' => t('Promoted to front page'), + 'sticky' => t('Sticky at top of lists'), + 'revision' => t('Create new revision'), + ), '#description' => t('Users with the <em>administer nodes</em> permission will be able to override these options.'), ); } + + // Advanced node search form + elseif ($form_id == 'search_form' && arg(1) == 'node') { + // Keyword boxes: + $form['advanced'] = array( + '#type' => 'fieldset', + '#title' => t('Advanced search'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#attributes' => array('class' => 'search-advanced'), + ); + $form['advanced']['keywords'] = array( + '#prefix' => '<div class="criterion">', + '#suffix' => '</div>', + ); + $form['advanced']['keywords']['or'] = array( + '#type' => 'textfield', + '#title' => t('Containing any of the words'), + '#size' => 30, + '#maxlength' => 255, + ); + $form['advanced']['keywords']['phrase'] = array( + '#type' => 'textfield', + '#title' => t('Containing the phrase'), + '#size' => 30, + '#maxlength' => 255, + ); + $form['advanced']['keywords']['negative'] = array( + '#type' => 'textfield', + '#title' => t('Containing none of the words'), + '#size' => 30, + '#maxlength' => 255, + ); + + // Taxonomy box: + if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) { + $form['advanced']['category'] = array( + '#type' => 'select', + '#title' => t('Only in the category(s)'), + '#prefix' => '<div class="criterion">', + '#size' => 10, + '#suffix' => '</div>', + '#options' => $taxonomy, + '#multiple' => TRUE, + ); + } + + // Node types: + $types = node_get_types(); + $form['advanced']['type'] = array( + '#type' => 'checkboxes', + '#title' => t('Only of the type(s)'), + '#prefix' => '<div class="criterion">', + '#suffix' => '</div>', + '#options' => $types, + ); + $form['advanced']['submit'] = array( + '#type' => 'submit', + '#value' => t('Advanced search'), + '#prefix' => '<div class="action">', + '#suffix' => '</div><br clear="all" />', + ); + + $form['#validate']['node_search_validate'] = array(); + } +} + +/** + * Form API callback for the search form. Registered in node_form_alter(). + */ +function node_search_validate($form_id, $form_values) { + // Initialise using any existing basic search keywords. + $keys = $form_values['processed_keys']['#ref']; + + // Insert extra restrictions into the search keywords string. + if (isset($form_values['type']) && is_array($form_values['type'])) { + // Retrieve selected types - Forms API sets the value of unselected checkboxes to 0. + $form_values['type'] = array_filter($form_values['type']); + if (count($form_values['type'])) { + $keys = search_query_insert($keys, 'type', implode(',', array_keys($form_values['type']))); + } + } + if (isset($form_values['category']) && is_array($form_values['category'])) { + $keys = search_query_insert($keys, 'category', implode(',', $form_values['category'])); + } + if ($form_values['or'] != '') { + if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' '. $form_values['or'], $matches)) { + $keys .= ' '. implode(' OR ', $matches[1]); + } + } + if ($form_values['negative'] != '') { + if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' '. $form_values['negative'], $matches)) { + $keys .= ' -'. implode(' -', $matches[1]); + } + } + if ($form_values['phrase'] != '') { + $keys .= ' "'. str_replace('"', ' ', $form_values['phrase']) .'"'; + } + if (!empty($keys)) { + $form_values['processed_keys']['#ref'] = trim($keys); + } } /** diff --git a/modules/node/node.module b/modules/node/node.module index bdce5ebea327aeac23282c4e9a3f980d045e6786..092523f1b30a5cb4a8af0eb2a9e321e646b6f775 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -731,94 +731,6 @@ function node_search($op = 'search', $keys = null) { 'snippet' => search_excerpt($keys, $node->body)); } return $results; - - case 'form': - $form = array(); - - // Keyword boxes - $form['advanced'] = array( - '#type' => 'fieldset', - '#title' => t('Advanced search'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - '#attributes' => array('class' => 'search-advanced'), - ); - $form['advanced']['keywords'] = array( - '#prefix' => '<div class="criterion">', - '#suffix' => '</div>', - ); - $form['advanced']['keywords']['or'] = array( - '#type' => 'textfield', - '#title' => t('Containing any of the words'), - '#size' => 30, - '#maxlength' => 255, - ); - $form['advanced']['keywords']['phrase'] = array( - '#type' => 'textfield', - '#title' => t('Containing the phrase'), - '#size' => 30, - '#maxlength' => 255, - ); - $form['advanced']['keywords']['negative'] = array( - '#type' => 'textfield', - '#title' => t('Containing none of the words'), - '#size' => 30, - '#maxlength' => 255, - ); - - // Taxonomy box - if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) { - $form['advanced']['category'] = array( - '#type' => 'select', - '#title' => t('Only in the category(s)'), - '#prefix' => '<div class="criterion">', - '#size' => 10, - '#suffix' => '</div>', - '#options' => $taxonomy, - '#multiple' => TRUE, - ); - } - - // Node types - $types = node_get_types(); - $form['advanced']['type'] = array( - '#type' => 'checkboxes', - '#title' => t('Only of the type(s)'), - '#prefix' => '<div class="criterion">', - '#suffix' => '</div>', - '#options' => $types, - ); - $form['advanced']['submit'] = array( - '#type' => 'submit', - '#value' => t('Advanced search'), - '#prefix' => '<div class="action">', - '#suffix' => '</div><br clear="all" />', - ); - return $form; - - case 'post': - // Insert extra restrictions into the search keywords string. - $edit = &$_POST['edit']; - if (isset($edit['type']) && is_array($edit['type'])) { - $keys = search_query_insert($keys, 'type', implode(',', array_keys($edit['type']))); - } - if (isset($edit['category']) && is_array($edit['category'])) { - $keys = search_query_insert($keys, 'category', implode(',', $edit['category'])); - } - if ($edit['or'] != '') { - if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' '. $edit['or'], $matches)) { - $keys = $keys .' '. implode(' OR ', $matches[1]); - } - } - if ($edit['negative'] != '') { - if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' '. $edit['negative'], $matches)) { - $keys = $keys .' -'. implode(' -', $matches[1]); - } - } - if ($edit['phrase'] != '') { - $keys .= ' "'. str_replace('"', ' ', $edit['phrase']) .'"'; - } - return trim($keys); } } @@ -2163,14 +2075,126 @@ function node_update_index() { } } +/** + * Implementation of hook_form_alter(). + */ function node_form_alter($form_id, &$form) { + // Node publishing options if (isset($form['type']) && $form['type']['#value'] .'_node_settings' == $form_id) { - $form['workflow']['node_options_'. $form['type']['#value']] = array( - '#type' => 'checkboxes', '#title' => t('Default options'), '#default_value' => variable_get('node_options_'. $form['type']['#value'], array('status', 'promote')), - '#options' => array('status' => t('Published'), 'moderate' => t('In moderation queue'), 'promote' => t('Promoted to front page'), 'sticky' => t('Sticky at top of lists'), 'revision' => t('Create new revision')), + $form['workflow']['node_options_'. $form['type']['#value']] = array('#type' => 'checkboxes', + '#title' => t('Default options'), + '#default_value' => variable_get('node_options_'. $form['type']['#value'], array('status', 'promote')), + '#options' => array( + 'status' => t('Published'), + 'moderate' => t('In moderation queue'), + 'promote' => t('Promoted to front page'), + 'sticky' => t('Sticky at top of lists'), + 'revision' => t('Create new revision'), + ), '#description' => t('Users with the <em>administer nodes</em> permission will be able to override these options.'), ); } + + // Advanced node search form + elseif ($form_id == 'search_form' && arg(1) == 'node') { + // Keyword boxes: + $form['advanced'] = array( + '#type' => 'fieldset', + '#title' => t('Advanced search'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#attributes' => array('class' => 'search-advanced'), + ); + $form['advanced']['keywords'] = array( + '#prefix' => '<div class="criterion">', + '#suffix' => '</div>', + ); + $form['advanced']['keywords']['or'] = array( + '#type' => 'textfield', + '#title' => t('Containing any of the words'), + '#size' => 30, + '#maxlength' => 255, + ); + $form['advanced']['keywords']['phrase'] = array( + '#type' => 'textfield', + '#title' => t('Containing the phrase'), + '#size' => 30, + '#maxlength' => 255, + ); + $form['advanced']['keywords']['negative'] = array( + '#type' => 'textfield', + '#title' => t('Containing none of the words'), + '#size' => 30, + '#maxlength' => 255, + ); + + // Taxonomy box: + if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) { + $form['advanced']['category'] = array( + '#type' => 'select', + '#title' => t('Only in the category(s)'), + '#prefix' => '<div class="criterion">', + '#size' => 10, + '#suffix' => '</div>', + '#options' => $taxonomy, + '#multiple' => TRUE, + ); + } + + // Node types: + $types = node_get_types(); + $form['advanced']['type'] = array( + '#type' => 'checkboxes', + '#title' => t('Only of the type(s)'), + '#prefix' => '<div class="criterion">', + '#suffix' => '</div>', + '#options' => $types, + ); + $form['advanced']['submit'] = array( + '#type' => 'submit', + '#value' => t('Advanced search'), + '#prefix' => '<div class="action">', + '#suffix' => '</div><br clear="all" />', + ); + + $form['#validate']['node_search_validate'] = array(); + } +} + +/** + * Form API callback for the search form. Registered in node_form_alter(). + */ +function node_search_validate($form_id, $form_values) { + // Initialise using any existing basic search keywords. + $keys = $form_values['processed_keys']['#ref']; + + // Insert extra restrictions into the search keywords string. + if (isset($form_values['type']) && is_array($form_values['type'])) { + // Retrieve selected types - Forms API sets the value of unselected checkboxes to 0. + $form_values['type'] = array_filter($form_values['type']); + if (count($form_values['type'])) { + $keys = search_query_insert($keys, 'type', implode(',', array_keys($form_values['type']))); + } + } + if (isset($form_values['category']) && is_array($form_values['category'])) { + $keys = search_query_insert($keys, 'category', implode(',', $form_values['category'])); + } + if ($form_values['or'] != '') { + if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' '. $form_values['or'], $matches)) { + $keys .= ' '. implode(' OR ', $matches[1]); + } + } + if ($form_values['negative'] != '') { + if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' '. $form_values['negative'], $matches)) { + $keys .= ' -'. implode(' -', $matches[1]); + } + } + if ($form_values['phrase'] != '') { + $keys .= ' "'. str_replace('"', ' ', $form_values['phrase']) .'"'; + } + if (!empty($keys)) { + $form_values['processed_keys']['#ref'] = trim($keys); + } } /** diff --git a/modules/search.module b/modules/search.module index 9353e1028e7db62b0ecd57353bd620b0f4930eb9..e2999c42d930f1dfd43e8874d82625b547078ba6 100644 --- a/modules/search.module +++ b/modules/search.module @@ -890,30 +890,19 @@ function search_view() { // Search form submits with POST but redirects to GET. This way we can keep // the search query URL clean as a whistle: // search/type/keyword+keyword - if (isset($_POST['edit']['keys'])) { + if (!isset($_POST['edit']['keys'])) { if ($type == '') { - $type = 'node'; + // Note: search/node can not be a default tab because it would take on the + // path of its parent (search). It would prevent remembering keywords when + // switching tabs. This is why we drupal_goto to it from the parent instead. + drupal_goto('search/node'); } - $keys = module_invoke($type, 'search', 'post', $_POST['edit']['keys']); - drupal_goto('search/'. $type .'/'. (is_null($keys) ? $_POST['edit']['keys'] : $keys)); - } - else if ($type == '') { - // Note: search/node can not be a default tab because it would take on the - // path of its parent (search). It would prevent remembering keywords when - // switching tabs. This is why we drupal_goto to it from the parent instead. - drupal_goto('search/node'); - } - $keys = search_get_keys(); - if (user_access('search content')) { + $keys = search_get_keys(); // Only perform search if there is non-whitespace search term: if (trim($keys)) { // Log the search keys: - watchdog('search', - t('Search: %keys (%type).', array('%keys' => theme('placeholder', $keys), '%type' => module_invoke($type, 'search', 'name'))), - WATCHDOG_NOTICE, - l(t('results'), 'search/'. $type .'/'. $keys) - ); + watchdog('search', t('Search: %keys (%type).', array('%keys' => theme('placeholder', $keys), '%type' => module_invoke($type, 'search', 'name'))), WATCHDOG_NOTICE, l(t('results'), 'search/'. $type .'/'. $keys)); // Collect the search results: $results = search_data($keys, $type); @@ -925,21 +914,15 @@ function search_view() { $results = theme('box', t('Your search yielded no results'), search_help('search#noresults')); } } - else if (isset($_POST['edit'])) { - form_set_error('keys', t('Please enter some keywords.')); - } // Construct the search form. - // Note, we do this last because of the form_set_error() above. $output = search_form(NULL, $keys, $type); - $output .= $results; return $output; } - else { - drupal_access_denied(); - } + + return search_form(NULL, $keys, $type); } /** @@ -985,7 +968,7 @@ function search_view() { * @return * An HTML string containing the search form. */ -function search_form($action = '', $keys = '', $type = null, $prompt = null) { +function search_form($action = '', $keys = '', $type = NULL, $prompt = NULL) { if (!$action) { $action = url('search/'. $type); @@ -994,18 +977,51 @@ function search_form($action = '', $keys = '', $type = null, $prompt = null) { $prompt = t('Enter your keywords'); } - $form = array('#action' => $action, '#attributes' => array('class' => 'search-form'), '#redirect' => FALSE); + $form = array( + '#action' => $action, + '#attributes' => array('class' => 'search-form'), + '#redirect' => FALSE, + ); + $form['module'] = array('#type' => 'value', '#value' => $type); $form['basic'] = array('#type' => 'item', '#title' => $prompt); - $form['basic']['inline'] = array('#type' => 'markup', '#prefix' => '<div class="container-inline">', '#suffix' => '</div>'); - $form['basic']['inline']['keys'] = array('#type' => 'textfield', '#title' => '', '#default_value' => $keys, '#size' => $prompt ? 40 : 20, '#maxlength' => 255); + $form['basic']['inline'] = array('#prefix' => '<div class="container-inline">', '#suffix' => '</div>'); + $form['basic']['inline']['keys'] = array( + '#type' => 'textfield', + '#title' => '', + '#default_value' => $keys, + '#size' => $prompt ? 40 : 20, + '#maxlength' => 255, + ); + // processed_keys is used to coordinate keyword passing between other forms that hook into the basic search form. + $form['basic']['inline']['processed_keys'] = array('#type' => 'value', '#value' => array()); $form['basic']['inline']['submit'] = array('#type' => 'submit', '#value' => t('Search')); - $form_module = module_invoke($type, 'search', 'form', $keys); - if (isset($form_module) && is_array($form_module)) { - $form = array_merge($form, $form_module); + return drupal_get_form('search_form', $form); +} + +/** + * As the search form collates keys from other modules hooked in via hook_form_alter, the validation + * takes place in _submit. search_form_validate() is used solely to set the #ref property for the basic + * search form. + */ +function search_form_validate($form_id, $form_values) { + $form_values['processed_keys']['#ref'] = trim($form_values['keys']); +} + +/** + * Process a search form submission. Uses a forms API #ref to accept processed search keys + * from forms that hook into the default search form. + */ +function search_form_submit($form_id, $form_values) { + $keys = $form_values['processed_keys']['#ref']; + if (trim($keys) == '') { + form_set_error('keys', t('Please enter some keywords.')); + // Fall through to the drupal_goto() call. + $keys = ''; } - return drupal_get_form('search_form', $form); + $type = $form_values['module'] ? $form_values['module'] : 'node'; + drupal_goto('search/'. $type .'/'. $keys); } /** diff --git a/modules/search/search.module b/modules/search/search.module index 9353e1028e7db62b0ecd57353bd620b0f4930eb9..e2999c42d930f1dfd43e8874d82625b547078ba6 100644 --- a/modules/search/search.module +++ b/modules/search/search.module @@ -890,30 +890,19 @@ function search_view() { // Search form submits with POST but redirects to GET. This way we can keep // the search query URL clean as a whistle: // search/type/keyword+keyword - if (isset($_POST['edit']['keys'])) { + if (!isset($_POST['edit']['keys'])) { if ($type == '') { - $type = 'node'; + // Note: search/node can not be a default tab because it would take on the + // path of its parent (search). It would prevent remembering keywords when + // switching tabs. This is why we drupal_goto to it from the parent instead. + drupal_goto('search/node'); } - $keys = module_invoke($type, 'search', 'post', $_POST['edit']['keys']); - drupal_goto('search/'. $type .'/'. (is_null($keys) ? $_POST['edit']['keys'] : $keys)); - } - else if ($type == '') { - // Note: search/node can not be a default tab because it would take on the - // path of its parent (search). It would prevent remembering keywords when - // switching tabs. This is why we drupal_goto to it from the parent instead. - drupal_goto('search/node'); - } - $keys = search_get_keys(); - if (user_access('search content')) { + $keys = search_get_keys(); // Only perform search if there is non-whitespace search term: if (trim($keys)) { // Log the search keys: - watchdog('search', - t('Search: %keys (%type).', array('%keys' => theme('placeholder', $keys), '%type' => module_invoke($type, 'search', 'name'))), - WATCHDOG_NOTICE, - l(t('results'), 'search/'. $type .'/'. $keys) - ); + watchdog('search', t('Search: %keys (%type).', array('%keys' => theme('placeholder', $keys), '%type' => module_invoke($type, 'search', 'name'))), WATCHDOG_NOTICE, l(t('results'), 'search/'. $type .'/'. $keys)); // Collect the search results: $results = search_data($keys, $type); @@ -925,21 +914,15 @@ function search_view() { $results = theme('box', t('Your search yielded no results'), search_help('search#noresults')); } } - else if (isset($_POST['edit'])) { - form_set_error('keys', t('Please enter some keywords.')); - } // Construct the search form. - // Note, we do this last because of the form_set_error() above. $output = search_form(NULL, $keys, $type); - $output .= $results; return $output; } - else { - drupal_access_denied(); - } + + return search_form(NULL, $keys, $type); } /** @@ -985,7 +968,7 @@ function search_view() { * @return * An HTML string containing the search form. */ -function search_form($action = '', $keys = '', $type = null, $prompt = null) { +function search_form($action = '', $keys = '', $type = NULL, $prompt = NULL) { if (!$action) { $action = url('search/'. $type); @@ -994,18 +977,51 @@ function search_form($action = '', $keys = '', $type = null, $prompt = null) { $prompt = t('Enter your keywords'); } - $form = array('#action' => $action, '#attributes' => array('class' => 'search-form'), '#redirect' => FALSE); + $form = array( + '#action' => $action, + '#attributes' => array('class' => 'search-form'), + '#redirect' => FALSE, + ); + $form['module'] = array('#type' => 'value', '#value' => $type); $form['basic'] = array('#type' => 'item', '#title' => $prompt); - $form['basic']['inline'] = array('#type' => 'markup', '#prefix' => '<div class="container-inline">', '#suffix' => '</div>'); - $form['basic']['inline']['keys'] = array('#type' => 'textfield', '#title' => '', '#default_value' => $keys, '#size' => $prompt ? 40 : 20, '#maxlength' => 255); + $form['basic']['inline'] = array('#prefix' => '<div class="container-inline">', '#suffix' => '</div>'); + $form['basic']['inline']['keys'] = array( + '#type' => 'textfield', + '#title' => '', + '#default_value' => $keys, + '#size' => $prompt ? 40 : 20, + '#maxlength' => 255, + ); + // processed_keys is used to coordinate keyword passing between other forms that hook into the basic search form. + $form['basic']['inline']['processed_keys'] = array('#type' => 'value', '#value' => array()); $form['basic']['inline']['submit'] = array('#type' => 'submit', '#value' => t('Search')); - $form_module = module_invoke($type, 'search', 'form', $keys); - if (isset($form_module) && is_array($form_module)) { - $form = array_merge($form, $form_module); + return drupal_get_form('search_form', $form); +} + +/** + * As the search form collates keys from other modules hooked in via hook_form_alter, the validation + * takes place in _submit. search_form_validate() is used solely to set the #ref property for the basic + * search form. + */ +function search_form_validate($form_id, $form_values) { + $form_values['processed_keys']['#ref'] = trim($form_values['keys']); +} + +/** + * Process a search form submission. Uses a forms API #ref to accept processed search keys + * from forms that hook into the default search form. + */ +function search_form_submit($form_id, $form_values) { + $keys = $form_values['processed_keys']['#ref']; + if (trim($keys) == '') { + form_set_error('keys', t('Please enter some keywords.')); + // Fall through to the drupal_goto() call. + $keys = ''; } - return drupal_get_form('search_form', $form); + $type = $form_values['module'] ? $form_values['module'] : 'node'; + drupal_goto('search/'. $type .'/'. $keys); } /**