Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.423
diff -u -r1.423 taxonomy.module
--- modules/taxonomy/taxonomy.module	28 Jun 2008 19:51:02 -0000	1.423
+++ modules/taxonomy/taxonomy.module	9 Jul 2008 21:03:20 -0000
@@ -36,6 +36,35 @@
 }
 
 /**
+ * Implementation of hook_search_form.
+ */
+function taxonomy_search_form() {
+  // 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_search_keys.
+ */
+function taxonomy_search_keys() {
+  return array(
+    'category' => array('where' => "tn.cid = '%s'", 'join' => 'INNER JOIN {term_node} tn ON n.vid = tn.vid'),
+  );
+}
+
+
+/**
  * Implementation of hook_link().
  *
  * This hook is extended with $type = 'taxonomy terms' to allow themes to
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.967
diff -u -r1.967 node.module
--- modules/node/node.module	26 May 2008 17:12:55 -0000	1.967
+++ modules/node/node.module	9 Jul 2008 21:03:17 -0000
@@ -1250,35 +1250,20 @@
       $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('search_keys') 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) . ')';
+          if (isset($options['join'])) {
+            $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');
       }
 
       // Get the ranking expressions.
@@ -1370,6 +1355,31 @@
 }
 
 /**
+ * Implementation of hook_search_form.
+ */
+function node_search_form() {
+  // 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_search_keys.
+ */
+function node_search_keys() {
+  return array(
+    'type' => array('where' => "n.type = '%s'"),
+  );
+}
+
+/**
  * Implementation of hook_user().
  */
 function node_user($op, &$edit, &$user) {
@@ -1907,28 +1917,8 @@
       '#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('search_form');
+      
     $form['advanced']['submit'] = array(
       '#type' => 'submit',
       '#value' => t('Advanced search'),
@@ -1936,22 +1926,6 @@
       '#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';
   }
 }
@@ -1964,20 +1938,16 @@
   $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('search_keys') 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, $term, 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/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.218
diff -u -r1.218 locale.module
--- modules/locale/locale.module	1 Jul 2008 20:36:40 -0000	1.218
+++ modules/locale/locale.module	9 Jul 2008 21:03:11 -0000
@@ -598,3 +598,34 @@
     return $block;
   }
 }
+
+/**
+ * Implementation of hook_search_form.
+ */
+function locale_search_form() {
+  // 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_search_keys.
+ */
+function locale_search_keys() {
+  return array(
+    'language' => array('where' => "n.language = '%s'"),
+  );
+}
