Index: modules/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.217
diff -u -u -p -r1.217 locale.module
--- modules/locale/locale.module	23 Apr 2008 20:01:52 -0000	1.217
+++ modules/locale/locale.module	9 May 2008 23:18:36 -0000
@@ -598,3 +598,34 @@ function locale_block($op = 'list', $del
     return $block;
   }
 }
+
+/**
+ * Implementation of hook_searchform.
+ */
+function locale_searchform() {
+  // Languages:
+  $language_options = array();
+  foreach (language_list('language') as $key => $object) {
+    $language_options[$key] = $object->name;
+  }
+  if (count($language_options) > 1) {
+    $form['language'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Languages'),
+      '#prefix' => '<div class="criterion">',
+      '#suffix' => '</div>',
+      '#options' => $language_options,
+      '#weight' => 5,
+    );
+    return $form;
+  }
+}
+
+/**
+ * Implementation of hook_searchkeys.
+ */
+function locale_searchkeys() {
+  return array(
+    'language' => array('where' => "n.language = '%s'"),
+  );
+}
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.961
diff -u -u -p -r1.961 node.module
--- modules/node/node.module	6 May 2008 12:18:48 -0000	1.961
+++ modules/node/node.module	9 May 2008 23:18:36 -0000
@@ -1197,35 +1197,18 @@ function node_search($op = 'search', $ke
       $arguments1 = array();
       $conditions1 = 'n.status = 1';
 
-      if ($type = search_query_extract($keys, 'type')) {
-        $types = array();
-        foreach (explode(',', $type) as $t) {
-          $types[] = "n.type = '%s'";
-          $arguments1[] = $t;
+      // Extract the keywords from the query and add sql to the clauses.
+      foreach (module_invoke_all('searchkeys') as $term => $options) {
+        if ($type = search_query_extract($keys, $term)) {
+          $types = array();
+          foreach (explode(',', $type) as $t) {
+            $types[] = $options['where'];
+            $arguments1[] = $t;
+          }
+          $conditions1 .= ' AND (' . implode(' OR ', $types) . ')';
+          $joins .= $options['join'];
+          $keys = search_query_insert($keys, $term);
         }
-        $conditions1 .= ' AND (' . implode(' OR ', $types) . ')';
-        $keys = search_query_insert($keys, 'type');
-      }
-
-      if ($category = search_query_extract($keys, 'category')) {
-        $categories = array();
-        foreach (explode(',', $category) as $c) {
-          $categories[] = "tn.tid = %d";
-          $arguments1[] = $c;
-        }
-        $conditions1 .= ' AND (' . implode(' OR ', $categories) . ')';
-        $join1 .= ' INNER JOIN {term_node} tn ON n.vid = tn.vid';
-        $keys = search_query_insert($keys, 'category');
-      }
-
-      if ($languages = search_query_extract($keys, 'language')) {
-        $categories = array();
-        foreach (explode(',', $languages) as $l) {
-          $categories[] = "n.language = '%s'";
-          $arguments1[] = $l;
-        }
-        $conditions1 .= ' AND (' . implode(' OR ', $categories) . ')';
-        $keys = search_query_insert($keys, 'language');
       }
 
       // Build ranking expression (we try to map each parameter to a
@@ -1309,6 +1292,31 @@ function node_search($op = 'search', $ke
 }
 
 /**
+ * Implementation of hook_searchform.
+ */
+function node_searchform() {
+  // Node types:
+  $types = array_map('check_plain', node_get_types('names'));
+  $form['type'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Only of the type(s)'),
+    '#prefix' => '<div class="criterion">',
+    '#suffix' => '</div>',
+    '#options' => $types,
+  );
+  return $form;
+}
+
+/**
+ * Implementation of hook_searchkeys.
+ */
+function node_searchkeys() {
+  return array(
+    'type' => array('where' => "n.type = '%s'"),
+  );
+}
+
+/**
  * Implementation of hook_user().
  */
 function node_user($op, &$edit, &$user) {
@@ -1846,28 +1854,8 @@ function node_form_alter(&$form, $form_s
       '#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 = array_map('check_plain', node_get_types('names'));
-    $form['advanced']['type'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Only of the type(s)'),
-      '#prefix' => '<div class="criterion">',
-      '#suffix' => '</div>',
-      '#options' => $types,
-    );
+    $form['advanced'] += module_invoke_all('searchform');
+      
     $form['advanced']['submit'] = array(
       '#type' => 'submit',
       '#value' => t('Advanced search'),
@@ -1875,22 +1863,6 @@ function node_form_alter(&$form, $form_s
       '#suffix' => '</div>',
     );
 
-    // Languages:
-    $language_options = array();
-    foreach (language_list('language') as $key => $object) {
-      $language_options[$key] = $object->name;
-    }
-    if (count($language_options) > 1) {
-      $form['advanced']['language'] = array(
-        '#type' => 'checkboxes',
-        '#title' => t('Languages'),
-        '#prefix' => '<div class="criterion">',
-        '#suffix' => '</div>',
-        '#options' => $language_options,
-      );
-    }
-
-
     $form['#validate'][] = 'node_search_validate';
   }
 }
@@ -1903,20 +1875,16 @@ function node_search_validate($form, &$f
   $keys = $form_state['values']['processed_keys'];
 
   // Insert extra restrictions into the search keywords string.
-  if (isset($form_state['values']['type']) && is_array($form_state['values']['type'])) {
-    // Retrieve selected types - Forms API sets the value of unselected checkboxes to 0.
-    $form_state['values']['type'] = array_filter($form_state['values']['type']);
-    if (count($form_state['values']['type'])) {
-      $keys = search_query_insert($keys, 'type', implode(',', array_keys($form_state['values']['type'])));
+  foreach (module_invoke_all('searchkeys') as $term => $options) {
+    if (isset($form_state['values'][$term]) && is_array($form_state['values'][$term])) {
+      // Retrieve selected types - Forms API sets the value of unselected checkboxes to 0.
+      $form_state['values'][$term] = array_filter($form_state['values'][$term]);
+      if (count($form_state['values'][$term])) {
+        $keys = search_query_insert($keys, 'type', implode(',', array_keys($form_state['values'][$term])));
+      }
     }
   }
 
-  if (isset($form_state['values']['category']) && is_array($form_state['values']['category'])) {
-    $keys = search_query_insert($keys, 'category', implode(',', $form_state['values']['category']));
-  }
-  if (isset($form_state['values']['language']) && is_array($form_state['values']['language'])) {
-    $keys = search_query_insert($keys, 'language', implode(',', array_filter($form_state['values']['language'])));
-  }
   if ($form_state['values']['or'] != '') {
     if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' ' . $form_state['values']['or'], $matches)) {
       $keys .= ' ' . implode(' OR ', $matches[1]);
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.420
diff -u -u -p -r1.420 taxonomy.module
--- modules/taxonomy/taxonomy.module	6 May 2008 12:18:51 -0000	1.420
+++ modules/taxonomy/taxonomy.module	9 May 2008 23:18:42 -0000
@@ -1311,3 +1311,32 @@ function taxonomy_hook_info() {
     ),
   );
 }
+
+/**
+ * Implementation of hook_searchform.
+ */
+function taxonomy_searchform() {
+  // Taxonomy box:
+  if ($taxonomy = taxonomy_form_all(1)) {
+    $form['category'] = array(
+      '#type' => 'select',
+      '#title' => t('Only in the category(s)'),
+      '#prefix' => '<div class="criterion">',
+      '#size' => 10,
+      '#suffix' => '</div>',
+      '#options' => $taxonomy,
+      '#multiple' => TRUE,
+    );
+    return $form;
+  }
+}
+
+/**
+ * Implementation of hook_searchformkeys.
+ */
+function taxonomy_searchkeys() {
+  return array(
+    'category' => array('where' => "tn.cid = '%s'", 'join' => ' INNER JOIN {term_node} tn ON n.vid = tn.vid'),
+  );
+}
+
