? LICENSE.txt
Index: multisite_search.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/multisite_search/multisite_search.info,v
retrieving revision 1.1.4.2
diff -u -p -r1.1.4.2 multisite_search.info
--- multisite_search.info	11 Jun 2008 08:55:18 -0000	1.1.4.2
+++ multisite_search.info	12 Oct 2010 16:50:16 -0000
@@ -5,4 +5,10 @@ description = "Search across all web sit
 dependencies[] = search
 package = Multisite Search
 
-core = 6.x
\ No newline at end of file
+core = 6.x
+; Information added by drupal.org packaging script on 2008-06-11
+version = "6.x-1.1"
+core = "6.x"
+project = "multisite_search"
+datestamp = "1213176011"
+
Index: multisite_search.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/multisite_search/multisite_search.install,v
retrieving revision 1.1.4.3
diff -u -p -r1.1.4.3 multisite_search.install
--- multisite_search.install	13 Nov 2008 06:20:48 -0000	1.1.4.3
+++ multisite_search.install	12 Oct 2010 16:50:17 -0000
@@ -1,12 +1,7 @@
 <?php
-// $Id: multisite_search.install,v 1.1.4.3 2008/11/13 06:20:48 gloscon Exp $
+// $Id: multisite_search.install,v 1.1.4.2 2008/02/18 04:37:19 gloscon Exp $
 
 /**
- * @file
- * Drupal Multisite search installation.
- */
- 
-/**
  * Implementation of hook_install().
  */
 function multisite_search_install() {
@@ -17,59 +12,78 @@ function multisite_search_install() {
 /**
  * Implementation of hook_schema().
  */
-function multisite_search_schema() {  
+function multisite_search_schema(){  
   $schema['multisite_drupal_search_dataset'] = array(
     'fields' => array(
-      'sid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'type' => array('type' => 'varchar', 'default' => NULL, 'length' => 16),
-      'data' => array('type' => 'text', 'not null' => TRUE, 'size' => 'big'),
-      'subdmn_id' => array('type' => 'varchar', 'not null' => TRUE, 'length' => 255)
+      'sid'=>array('type'=>'int','unsigned'=>TRUE,'not null' => TRUE,'default'=>0),
+      'type'=>array('type'=>'varchar','default'=>NULL,'length'=>16),
+      'data'=>array('type'=>'text','not null' => TRUE,'size'=>'big'),
+      'subdmn_id'=>array('type'=>'varchar','not null' => TRUE,'length'=>255)
     ),
     'indexes' => array(
-       'sid_type' => array('sid', 'type', 'subdmn_id')
+       'sid_type' => array('sid','type','subdmn_id')
     ),
   );
+
   $schema['multisite_drupal_search_index'] = array(
     'fields' => array(
-      'word' => array('type' => 'varchar', 'not null' => TRUE, 'default' => '', 'length' => 50),
-      'sid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'type' => array('type' => 'varchar', 'default' => NULL, 'length' => 16),
-      'subdmn_id' => array('type' => 'varchar', 'not null' => TRUE, 'length' => 255),
-      'fromsid' => array('type' => 'int', 'unsigned' => TRUE , 'not null' => TRUE, 'default' => 0),
-      'fromtype' => array('type' => 'varchar', 'default' => NULL, 'length' => 16),
-      'fromsubdmn_id' => array('type' => 'varchar', 'not null' => TRUE, 'length' => 255),
-      'score' => array('type' => 'float', 'default' => NULL)
+      'word'=>array('type'=>'varchar','not null' => TRUE,'default'=>'','length'=>50),
+      'sid'=>array('type'=>'int','unsigned'=>TRUE,'not null' => TRUE,'default'=>0),
+      'type'=>array('type'=>'varchar','default'=>NULL,'length'=>16),
+      'subdmn_id'=>array('type'=>'varchar','not null' => TRUE,'length'=>255),
+      'fromsid'=>array('type'=>'int','unsigned'=>TRUE,'not null' => TRUE,'default'=>0),
+      'fromtype'=>array('type'=>'varchar','default'=>NULL,'length'=>16),
+      'fromsubdmn_id'=>array('type'=>'varchar','not null' => TRUE,'length'=>255),
+      'score'=>array('type'=>'float','default'=>NULL)
     ),
     'indexes' => array(
-      'sid_type' => array('sid', 'type', 'subdmn_id'),
-      'from_sid_type' => array('fromsid', 'fromtype', 'fromsubdmn_id'),
-      'word' => array('word')
+       'sid_type' => array('sid','type','subdmn_id'),
+       'from_sid_type' => array('fromsid','fromtype','fromsubdmn_id'),
+       'word' => array('word')
     ),
   );
+
   $schema['multisite_drupal_search_total'] = array(
     'fields' => array(
-      'word' => array('type' => 'varchar', 'not null' => TRUE, 'default' => '', 'length' => 50),
-      'count' => array('type' => 'float', 'default' => NULL)
+      'word'=>array('type'=>'varchar','not null' => TRUE,'default'=>'','length'=>50),
+      'count'=>array('type'=>'float','default'=>NULL)
     ),
-    'primary key' => array('word'),
+      'primary key' => array('word'),
   );
   // store multisite information 
   $schema['multisite_drupal_search_sites'] = array(
     'fields' => array(
-      'site_id' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'length' => 11),
-      'table_prefix' => array('type' => 'varchar', 'not null' => TRUE, 'length' => 225),
-      'site_url' => array('type' => 'varchar', 'not null' => TRUE, 'length' => 225)
+      'site_id'=>array('type'=>'serial','unsigned'=>TRUE,'not null'=>TRUE,'length'=>11),
+      'table_prefix'=>array('type'=>'varchar','not null'=>TRUE,'length'=>225),
+      'site_url'=>array('type'=>'varchar','not null'=>TRUE,'length'=>225)
     ),
-      'primary key' => array('site_id'),
+      'primary key'=>array('site_id'),
   );
+
   return $schema;
 }
 
+
+function multisite_search_update_6001() {
+  $items = array();
+  $items[] = update_sql("ALTER TABLE {multisite_drupal_search_sites} ADD db_connection varchar(32) NOT NULL");
+  $items[] = update_sql("ALTER TABLE {multisite_drupal_search_index} CHANGE subdmn_id subdmn_id INT NOT NULL");
+  $items[] = update_sql("ALTER TABLE {multisite_drupal_search_dataset} CHANGE subdmn_id subdmn_id INT NOT NULL");
+  return $items;
+}
+
+function multisite_search_update_6002() {
+  $items = array();
+  $items[] = update_sql("ALTER TABLE {multisite_drupal_search_index} ADD date INT NOT NULL");
+  return $items;
+}
+
 /**
  * Implementation of hook_uninstall().
  */
 function multisite_search_uninstall() {
   drupal_uninstall_schema('multisite_search');
+
   // Drop tables.
   db_query('DROP TABLE IF EXISTS multisite_drupal_search_dataset');
   db_query('DROP TABLE IF EXISTS multisite_drupal_search_index');
Index: multisite_search.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/multisite_search/multisite_search.module,v
retrieving revision 1.1.4.2
diff -u -p -r1.1.4.2 multisite_search.module
--- multisite_search.module	13 Nov 2008 06:20:49 -0000	1.1.4.2
+++ multisite_search.module	12 Oct 2010 16:50:18 -0000
@@ -1,5 +1,6 @@
 <?php
-// $Id: multisite_search.module,v 1.1.4.2 2008/11/13 06:20:49 gloscon Exp $
+
+// $Id: multisite_search.module,v 1.1.4.1 2008/02/15 08:58:17 gloscon Exp $
 
 /**
  * @file
@@ -7,122 +8,209 @@
  */
 
 /**
-* Implementation hook_help();
-*/
-
+ * Implementation hook_help();
+ */
 function multisite_search_help($path, $arg) {
-  global $user;
-  switch ($path) {
-    case 'admin/modules#description':
-      // This description is shown in the listing at admin/modules.
-      return t('Notify site admin when new node has been created.');
-  }
+    global $user;
+    switch ($path) {
+        case 'admin/modules#description':
+            // This description is shown in the listing at admin/modules.
+            return t('Notify site admin when new node has been created.');
+    }
 }
 
 function multisite_search_theme() {
-  return array(
-    'multisite_search_theme_form' => array(
-      'arguments' => array('form' => NULL),
-    ),
-    'multisite_search_block_form' => array(
-      'arguments' => array('form' => NULL),
-    ),
-  );
+
+    return array(
+        'multisite_search_theme_form' => array(
+            'arguments' => array('form' => NULL),
+        ),
+        'multisite_search_block_form' => array(
+            'arguments' => array('form' => NULL),
+        ),
+    );
 }
 
 function multisite_search_menu() {
-  $items = array();
-    $items['admin/mssearch'] = array(
-      'title' => 'Multisite Configuration',
-      'description' => 'Manage sub site\'s info',
-      'position' => 'left',
-      'weight' => -10,
-      'page callback' => 'add_multisite_for_mssearch',
-      'access callback' => 'user_access',
-      'access arguments' => array('administer site configuration'),
+    $items = array();
+
+    $items['admin/settings/mssearch'] = array(
+        'title' => 'Multisites',
+        'description' => 'Manage multi sites information',
+        'position' => 'left',
+        'page callback' => 'add_multisite_for_mssearch',
+        'access callback' => 'user_access',
+        'access arguments' => array('administer site configuration'),
+        'type' => MENU_DEFAULT_LOCAL_TASK,
+    );
+
+    $items['admin/settings/mssearch/general'] = array(
+        'title' => 'Multisite Sites',
+        'description' => 'Manage multi sites information',
+        'position' => 'left',
+        'weight' => -10,
+        'page callback' => 'add_multisite_for_mssearch',
+        'access callback' => 'user_access',
+        'access arguments' => array('administer site configuration'),
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 0,
+    );
+
+    $items['admin/settings/mssearch/settings'] = array(
+        'title' => 'Multisite Settings',
+        'description' => 'Manage MultiSite Search cron and order settings',
+        'position' => 'left',
+        'weight' => -10,
+        'page callback' => 'drupal_get_form',
+        'page arguments' => array('multisite_search_settings'),
+        'access callback' => 'user_access',
+        'access arguments' => array('administer site configuration'),
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 1,
+    );
+
+    return $items;
+}
+
+/**
+ * Form builder. MultiSite Search Settigns
+ *
+ * @ingroup forms
+ * @see system_settings_form()
+ */
+function multisite_search_settings() {
+
+    $form['multisite_search_cron_ttl'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Cron TTL'),
+        '#required' => TRUE,
+        '#description' => 'Define the limit in seconds of multisite re-indexing process, after NNN configured the multisite search will run a reindex',
+        '#default_value' => variable_get('multisite_search_cron_ttl', '3600')
+    );
+
+
+    $options = array('score' => "Order by Score", 'date' => "Order by Date");
+
+    $form['multisite_search_order'] = array(
+        '#type' => 'select', '#title' => t('Order type'),
+        '#default_value' => variable_get('multisite_search_order','score'), '#options' => $options,
+        '#description' => t('Results will be ordered by this criteria.')
     );
-  return $items;
+
+    return system_settings_form($form);
 }
 
 /**
  * Menu callback -- ask for confirmation of node deletion
  */
 function multisite_for_mssearch_delete_confirm(&$form_state, $siteid) {
-  $form['site_id'] = array('#type' => 'value', '#value' => $siteid);
-  return confirm_form($form, t('Are you sure you want to delete sub site id '. $siteid), $_GET['destination'] ? $_GET['destination'] : 'admin/mssearch', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
+    $form['site_id'] = array('#type' => 'value', '#value' => $siteid);
+
+    return confirm_form($form, t('Are you sure you want to delete sub site id ' . $siteid), $_GET['destination'] ? $_GET['destination'] : 'admin/mssearch', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
 }
 
 function multisite_for_mssearch_delete_confirm_submit($form, &$form_state) {
-  if ($form_state['values']['confirm']) {
-    multisite_for_mssearch_delete_site($form_state['values']['site_id']);
-  }
-  $form_state['redirect'] = 'admin/mssearch';
+
+    if ($form_state['values']['confirm']) {
+        multisite_for_mssearch_delete_site($form_state['values']['site_id']);
+    }
+    $form_state['redirect'] = 'admin/mssearch';
 }
 
-function multisite_for_mssearch_delete_site($site_id) { 
-  // site id is given 
-  // get details of this site ?? 
-  // delete all data related to this site from 3 search table ?? 
-  $subdmn_id = get_subdmn_id($site_id);
-  db_query("DELETE FROM multisite_drupal_search_sites WHERE site_id = %d", $site_id);
-  db_query("DELETE FROM multisite_drupal_search_dataset WHERE subdmn_id = '%s'", $subdmn_id);
-  db_query("DELETE FROM multisite_drupal_search_index WHERE subdmn_id = '%s'", $subdmn_id);
-  drupal_set_message(t("Sub-site deleted successfully."));
+function multisite_for_mssearch_delete_site($site_id) {
+    // site id is given
+    // get details of this site ??
+    // delete all data related to this site from 3 search table ??
+    $subdmn_id = get_subdmn_id($site_id);
+    db_query("DELETE FROM {multisite_drupal_search_sites} WHERE site_id = %d", $site_id);
+    db_query("DELETE FROM {multisite_drupal_search_dataset} WHERE subdmn_id = '%s'", $subdmn_id);
+    db_query("DELETE FROM {multisite_drupal_search_index} WHERE subdmn_id = '%s'", $subdmn_id);
+    drupal_set_message(t("Sub-site deleted successfully."));
+    drupal_goto('admin/settings/mssearch/general');
 }
 
 function get_subdmn_id($site_id) {
-  $object =  db_fetch_object(db_query("SELECT table_prefix FROM multisite_drupal_search_sites WHERE site_id=%d", $site_id));
-  return $object->table_prefix;
+    $object = db_fetch_object(db_query("SELECT table_prefix FROM {multisite_drupal_search_sites} WHERE site_id=%d", $site_id));
+    return $object->table_prefix;
 }
 
 function add_multisite_for_mssearch() {
-  if (arg(3)== 'delete') { 
-    return drupal_get_form('multisite_for_mssearch_delete_confirm', arg(2));
-  }
-  $output = "";
-  // show all existing sub-site 
-  $sql = db_query("SELECT * FROM multisite_drupal_search_sites ORDER BY site_id");
-  $total  = db_result(db_query("SELECT COUNT(*) FROM multisite_drupal_search_sites ORDER BY site_id"));
-  $header = array(t("Site id"), t("Table prefix"), t("Site URL"), t("Operations"));
-  $rows = array();
-  if ($total == 0) {
-    $rows[] = array('data' => array( array('data' => t('No site found'), 'colspan' => 4, 'align' => 'center')));
-  }
-  while ($res = db_fetch_array($sql)) {
-    $rows[] = array($res['site_id'], $res['table_prefix'], $res['site_url'], l("delete", 'admin/mssearch/'. $res['site_id'] .'/delete'));
-  }
-  $output .= theme('table', $header, $rows);
-  $output .= '<h2>'. t('Add New Sub-Site') .'</h2>';
-  $output .= drupal_get_form("add_multisite_for_mssearch_form");
-  return $output;
+
+    if (arg(4) == 'delete') {
+        return drupal_get_form('multisite_for_mssearch_delete_confirm', arg(3));
+    }
+
+    $output = "";
+    // show all existing sub-site
+
+    $sql = db_query("SELECT * FROM {multisite_drupal_search_sites} ORDER BY site_id");
+    $total = db_result(db_query("SELECT COUNT(*) FROM {multisite_drupal_search_sites} ORDER BY site_id"));
+
+    $header = array("Site id", "Table prefix", "Site URL", "DB Connection", "Operations");
+    $rows = array();
+
+    if ($total == 0) {
+        $rows[] = array('data' => array(array('data' => 'No site found', 'colspan' => 4, 'align' => 'center')));
+    }
+    while ($res = db_fetch_array($sql)) {
+        $rows[] = array($res['site_id'], $res['table_prefix'], $res['site_url'], $res['db_connection'], l("delete", 'admin/settings/mssearch/' . $res['site_id'] . '/delete'));
+    }
+
+    $output .= theme('table', $header, $rows);
+    $output .= "<br /><h2>Add New Site</h2>";
+    $output .= drupal_get_form("add_multisite_for_mssearch_form");
+
+    return $output;
 }
 
 function add_multisite_for_mssearch_form() {
-  $form = array();
-  $form['table_prefix'] = array(
-    '#title' => 'Enter sub-site table prefix',
-    '#type' => 'textfield',
-    '#size' => 15,
-    '#default_value' => '',
-    '#attributes' => array('title' => t('Enter the table prefix of subsite.')),
-  );
-  $form['site_url'] = array(
-    '#title' => 'Enter sub-site URL',
-    '#type' => 'textfield',
-    '#size' => 15,
-    '#required' => TRUE,
-    '#default_value' => '',
-    '#description' => 'eg: http://subdomainname.domainname.com',
-    '#attributes' => array('title' => t('Enter complete subsite URL')),
-  );
-  $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
-  return $form;
+
+    global $db_url;
+
+    if (is_array($db_url)) {
+        foreach ($db_url as $key => $db_string) {
+            $db_connections[$key] = $key;
+        }
+    } else {
+        $db_connections = array('default', 'default');
+    }
+    $form = array();
+
+    $form['site_url'] = array(
+        '#title' => 'Enter site URL',
+        '#type' => 'textfield',
+        '#size' => 45,
+        '#required' => TRUE,
+        '#default_value' => '',
+        '#description' => 'eg: http://subdomainname.domainname.com',
+        '#attributes' => array('title' => t('Enter complete subsite URL')),
+    );
+
+    $form['table_prefix'] = array(
+        '#title' => 'Enter site table prefix',
+        '#type' => 'textfield',
+        '#size' => 45,
+        '#default_value' => '',
+        '#attributes' => array('title' => t('Enter the table prefix of subsite.')),
+    );
+
+    $form['db_connection'] = array(
+        '#type' => 'select',
+        '#title' => t('Database connection'),
+        '#default_value' => 'default',
+        '#options' => $db_connections,
+        '#description' => t('Setting what DB connection must be used for this site. check db connection in your settings.php file.'),
+    );
+
+    $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
+
+    return $form;
 }
 
 function add_multisite_for_mssearch_form_submit($form, &$form_state) {
-  // save subsite 
-  db_query("INSERT INTO multisite_drupal_search_sites VALUES(NULL, '%s', '%s')", $form_state['values']['table_prefix'], $form_state['values']['site_url']); 
-  return;
+    // save subsite
+    db_query("INSERT INTO {multisite_drupal_search_sites} VALUES(NULL, '%s', '%s','%s')", $form_state['values']['table_prefix'], $form_state['values']['site_url'], $form_state['values']['db_connection']);
+    return;
 }
 
 /**
@@ -134,99 +222,101 @@ function add_multisite_for_mssearch_form
  * @return unknown
  */
 function multisite_search_block($op = 'list', $delta = 0, $edit = array()) {
-  // The $op parameter determines what piece of information is being requested.
-  switch ($op) {
-    case 'list':
-      $blocks[0]['info'] = t('Multisite search');
-      return $blocks;
-    case 'configure':
-      $form = array();
-      if ($delta == 0) {
-        // All we need to provide is a text field, Drupal will take care of
-        // the other block configuration options and the save button.
-      }
-      return $form;
-    case 'save':
-      // If $op is "save", we need to save settings from the configuration form.
-      // Since the first block is the only one that allows configuration, we
-      // need to check $delta to make sure we only save it.
-      if ($delta == 0) {
-        // Have Drupal save the string to the database.
-      }
-      return;
-    case 'view':
-    default:
-      // If $op is "view", then we need to generate the block for display
-      // purposes. The $delta parameter tells us which block is being requested.
-      if ($op == 'view' && user_access('search content')) { 
-        switch ($delta) {
-          case 0:
-            // The subject is displayed at the top of the block. Note that it
-            // should be passed through t() for translation.
-            $block['subject'] = t('');
-            // The content of the block is typically generated by calling a custom
-            // function.
-            $block['content'] = drupal_get_form('multisite_search_block_form');
-            break;
-        }
-      }
-      return $block;
-  }
-} 
+    // The $op parameter determines what piece of information is being requested.
+    switch ($op) {
+        case 'list':
+            $blocks[0]['info'] = t('Multisite search');
+            return $blocks;
+        case 'configure':
+            $form = array();
+            if ($delta == 0) {
+                // All we need to provide is a text field, Drupal will take care of
+                // the other block configuration options and the save button.
+            }
+            return $form;
+        case 'save':
+            // If $op is "save", we need to save settings from the configuration form.
+            // Since the first block is the only one that allows configuration, we
+            // need to check $delta to make sure we only save it.
+            if ($delta == 0) {
+                // Have Drupal save the string to the database.
+            }
+            return;
+        case 'view': default:
+            // If $op is "view", then we need to generate the block for display
+            // purposes. The $delta parameter tells us which block is being requested.
+            if ($op == 'view' && user_access('search content')) {
+                switch ($delta) {
+                    case 0:
+                        // The subject is displayed at the top of the block. Note that it
+                        // should be passed through t() for translation.
+                        $block['subject'] = t('');
+                        // The content of the block is typically generated by calling a custom
+                        // function.
+                        $block['content'] = drupal_get_form('multisite_search_block_form');
+                        break;
+                }
+            }
+            return $block;
+    }
+}
 
 /**
  * Process a block search form submission.
  */
 function multisite_search_box_form_submit($form, &$form_state) {
-  $form_id = $form['form_id']['#value'];
-  $form_state['redirect'] = 'search/multisite_search/'. trim($form_state['values'][$form_id .'_keys']);
+    $form_id = $form['form_id']['#value'];
+    $form_state['redirect'] = 'search/multisite_search/' . trim($form_state['values'][$form_id . '_keys']);
 }
 
 /**
  * Theme the theme search form.
  */
 function theme_multisite_search_theme_form($form) {
-  return '<div id="search" class="container-inline">'. drupal_render($form) .'</div>';
+    return '<div id="search" class="container-inline">' . drupal_render($form) . '</div>';
 }
 
 /**
  * Theme the block search form.
  */
 function theme_multisite_search_block_form($form) {
-  $fst = drupal_render($form['multisite_search_block_form_keys']);
-  $sec = drupal_render($form['submit']);
-  $out = '<div class="container-inline">'. $fst . $sec .'</div>';
-  return '<div>'. $out .'<div class="container-inline">'. drupal_render($form) .'</div></div>';
+
+    $fst = drupal_render($form['multisite_search_block_form_keys']);
+    $sec = drupal_render($form['submit']);
+    $out = '<div class="container-inline">' . $fst . $sec . '</div>';
+
+    return '<div>' . $out . '<div class="container-inline">' . drupal_render($form) . '</div></div>';
 }
 
 function multisite_search_forms() {
-  $forms['multisite_search_theme_form']= array(
-    'callback' => 'multisite_search_box',
-    'callback arguments' => array('multisite_search_theme_form'),
-  );
-  $forms['multisite_search_block_form']= array(
-    'callback' => 'multisite_search_box',
-    'callback arguments' => array('multisite_search_block_form'),
-  );
-  return $forms;
+    $forms['multisite_search_theme_form'] = array(
+        'callback' => 'multisite_search_box',
+        'callback arguments' => array('multisite_search_theme_form'),
+    );
+    $forms['multisite_search_block_form'] = array(
+        'callback' => 'multisite_search_box',
+        'callback arguments' => array('multisite_search_block_form'),
+    );
+    return $forms;
 }
 
 /**
  * Output a search form for the search block and the theme's search box.
  */
 function multisite_search_box(&$form_state, $form_id) {
-  // Use search_keys instead of keys to avoid ID conflicts with the search block.
-  $form[$form_id .'_keys'] = array(
-    '#title' => t('Search Multi-site'),
-    '#type' => 'textfield',
-    '#size' => 15,
-    '#default_value' => '',
-    '#attributes' => array('title' => t('Enter the terms you wish to search for.')),
-  );
-  $form['submit'] = array('#type' => 'submit', '#value' => t('Search'));
-  $form['#submit'][] = 'multisite_search_box_form_submit';
-  // Always go to the search page since the search form is not guaranteed to be on every page.
-  return $form;
+
+    // Use search_keys instead of keys to avoid ID conflicts with the search block.
+    $form[$form_id . '_keys'] = array(
+        '#title' => t('Search Multi-site'),
+        '#type' => 'textfield',
+        '#size' => 15,
+        '#default_value' => '',
+        '#attributes' => array('title' => t('Enter the terms you wish to search for.')),
+    );
+    $form['submit'] = array('#type' => 'submit', '#value' => t('Search'));
+    $form['#submit'][] = 'multisite_search_box_form_submit';
+    // Always go to the search page since the search form is not guaranteed to be on every page.
+    return $form;
 }
 
 // make a cron hook and update table taking all database tables and make prefix 
@@ -237,178 +327,318 @@ function multisite_search_box(&$form_sta
  * search_dirty).
  */
 function multisite_search_cron() {
-  // We register a shutdown function to ensure that search_total is always up
-  // to date.
-  // set this module weight to 10 
-  db_query("UPDATE {system} SET weight = 10 WHERE name = 'multisite_search'");
-  // Synchronise tables 
-  // delete all from all & insert new 
-  db_query('TRUNCATE TABLE multisite_drupal_search_dataset');
-  db_query('TRUNCATE TABLE multisite_drupal_search_index');
-  db_query('TRUNCATE TABLE multisite_drupal_search_total');
-  // get all sites 
-  // get prefix 
-  $res = db_query("SELECT * FROM multisite_drupal_search_sites ");
-  while ($result = db_fetch_array($res)) {
-    // get table prefix 
-    $tblpf = $result['table_prefix'];
-    // insert into search dataset 
-    $res1 = db_query("SELECT * FROM ". $tblpf ."search_dataset");
-    while ($result1 = db_fetch_array($res1)) { 
-      // insert into new multisite table 
-      db_query("INSERT INTO multisite_drupal_search_dataset (sid, type, data, subdmn_id) VALUES (%d, '%s', '%s', '%s')", $result1['sid'], $result1['type'], $result1['data'], $tblpf);
-    }
-    // insert into search index 
-    $res2 = db_query("SELECT * FROM ". $tblpf ."search_index");
-    while ($result2 = db_fetch_array($res2)) { 
-      // insert into new multisite table 
-      db_query("INSERT INTO multisite_drupal_search_index (word, sid, type, subdmn_id, fromsid, fromtype, fromsubdmn_id, score) VALUES ('%s', %d, '%s', '%s', '%s', %d, '%s', %f)", $result2['word'], $result2['sid'], $result2['type'], $tblpf, $result2['fromsid'], $result2['fromtype'], $tblpf, $result2['score']);
-    }
-    // ??????  how to proceed with this in a better way 
-    // insert into search total -- need to have done without cron job 
-    $res3 = db_query("SELECT DISTINCT (word) FROM multisite_drupal_search_index");
-    while ($result3 = db_fetch_array($res3)) { 
-      // for each word update search total
-      $word = $result3['word'];
-      $total = db_result(db_query("SELECT SUM(score) FROM multisite_drupal_search_index WHERE word = '%s'", $word));
-      // Apply Zipf's law to equalize the probability distribution
-      $total = log10(1 + 1/(max(1, $total)));
-      db_query("UPDATE multisite_drupal_search_total SET count = %f WHERE word = '%s'", $total, $word);
-      if (!db_affected_rows()) {
-        db_query("INSERT INTO multisite_drupal_search_total (word, count) VALUES ('%s', %f)", $word, $total);
-      }
+
+    //Fetch last execution
+    $msearch_last_cron_execution = variable_get('multisite_search_last_cron_execution', FALSE);
+
+    //Validate if we are in the umbral to maintain the index search
+    if ($msearch_last_cron_execution && time() < ( $msearch_last_cron_execution + variable_get('multisite_search_cron_ttl', '3600'))) {
+        return false;
+    } else {
+        variable_set('multisite_search_last_cron_execution', time());
     }
-  }
-}
 
-/**
-* Implementation of hook_search().
-*/
-function multisite_search_search($op = 'search', $keys = NULL) {
-  switch ($op) {  
-    case 'name':
-      return t('web site'); // Used on search tab. 
-    case 'reset':
-    return;
-    case 'search': 
-    // Search the index for the keywords that were entered.
-      // Build matching conditions
-      list($join1, $where1) = _db_rewrite_sql();
-      $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;
+    // We register a shutdown function to ensure that search_total is always up
+    // to date.
+    // set this module weight to 10
+    db_query("UPDATE {system} SET weight = 10 WHERE name = 'multisite_search'");
+
+    // Synchronise tables
+    // delete all from all & insert new
+    db_query('TRUNCATE TABLE {multisite_drupal_search_dataset}');
+    db_query('TRUNCATE TABLE {multisite_drupal_search_index}');
+    db_query('TRUNCATE TABLE {multisite_drupal_search_total}');
+
+    // get all sites
+    // get prefix
+
+    $res = db_query("SELECT * FROM {multisite_drupal_search_sites}");
+    while ($result = db_fetch_array($res)) {
+        // get table prefix
+        $tblpf = $result['table_prefix'];
+        $db_connection_name = $result['db_connection'];
+
+        if ($db_connection_name != 'default')
+            db_set_active($db_connection_name);
+        // insert into search dataset
+        $res1 = db_query("SELECT * FROM " . $tblpf . "search_dataset");
+        while ($result1 = db_fetch_array($res1)) {
+            // insert into new multisite table
+            if ($db_connection_name != 'default')
+                db_set_active ();
+            db_query("INSERT INTO {multisite_drupal_search_dataset} (sid, type, data, subdmn_id) VALUES (%d, '%s', '%s', '%s')", $result1['sid'], $result1['type'], $result1['data'], $result['site_id']);
         }
-        $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;
+
+        if ($db_connection_name != 'default')
+            db_set_active($db_connection_name);
+        // insert into search index
+        $res2 = db_query("SELECT si.*,n.changed as date FROM " . $tblpf . "search_index si," . $tblpf . "node n where n.nid=si.sid");
+        while ($result2 = db_fetch_array($res2)) {
+            // insert into new multisite table
+            if ($db_connection_name != 'default')
+                db_set_active ();
+            db_query("INSERT INTO {multisite_drupal_search_index} (word, sid, type, subdmn_id, fromsid, fromtype, fromsubdmn_id, score,date) VALUES ('%s', %d, '%s', '%s', '%s', %d, '%s', %f,%d)",
+                                                                   $result2['word'], $result2['sid'], $result2['type'], $result['site_id'], $result2['fromsid'], $result2['fromtype'], $tblpf, $result2['score'],$result2['date']);
         }
-        $conditions1 .= ' AND ('. implode(' OR ', $categories) .')';
-        $join1 .= ' INNER JOIN {term_node} tn ON n.nid = tn.nid';
-        $keys = search_query_insert($keys, 'category');
-      }
-      // Build ranking expression (we try to map each parameter to a
-      // uniform distribution in the range 0..1).
-      $ranking = array();
-      $arguments2 = array();
-      $join2 = '';
-      // Used to avoid joining on node_comment_statistics twice
-      $stats_join = FALSE;
-      $total = 0;
-      // 1. factor 
-      if ($weight = (int)variable_get('node_rank_relevance', 5)) {
-        // Average relevance values hover around 0.15
-        $ranking[] = '%d * i.relevance';
-        $arguments2[] = $weight;
-        $total += $weight;
-      }
-      // 2.factor 
-      if ($weight = (int)variable_get('node_rank_recent', 5)) {
-        // Exponential decay with half-life of 6 months, starting at last indexed node
-        $ranking[] = '%d * POW(2, (GREATEST(n.created, n.changed, c.last_comment_timestamp) - %d) * 6.43e-8)';
-        $arguments2[] = $weight;
-        $arguments2[] = (int)variable_get('node_cron_last', 0);
-        $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
-        $stats_join = TRUE;
-        $total += $weight;
-      }
-      // 3.factor 
-      if (module_exists('comment') && $weight = (int)variable_get('node_rank_comments', 5)) {
-        // Inverse law that maps the highest reply count on the site to 1 and 0 to 0.
-        $scale = variable_get('node_cron_comments_scale', 0.0);
-        $ranking[] = '%d * (2.0 - 2.0 / (1.0 + c.comment_count * %f))';
-        $arguments2[] = $weight;
-        $arguments2[] = $scale;
-        if (!$stats_join) {
-          $join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
+        // ??????  how to proceed with this in a better way
+        // insert into search total -- need to have done without cron job
+        if ($db_connection_name != 'default')
+            db_set_active ();
+        $res3 = db_query("SELECT DISTINCT (word) FROM {multisite_drupal_search_index}");
+        while ($result3 = db_fetch_array($res3)) {
+            // for each word update search total
+            $word = $result3['word'];
+            $total = db_result(db_query("SELECT SUM(score) FROM {multisite_drupal_search_index} WHERE word = '%s'", $word));
+            // Apply Zipf's law to equalize the probability distribution
+            $total = log10(1 + 1 / (max(1, $total)));
+            db_query("UPDATE {multisite_drupal_search_total} SET count = %f WHERE word = '%s'", $total, $word);
+            if (!db_affected_rows()) {
+                db_query("INSERT INTO {multisite_drupal_search_total} (word, count) VALUES ('%s', %f)", $word, $total);
+            }
         }
-        $total += $weight;
-      }
-      // 4.factor 
-      if (module_exists('statistics') && variable_get('statistics_count_content_views', 0) &&
-          $weight = (int)variable_get('node_rank_views', 5)) {
-        // Inverse law that maps the highest view count on the site to 1 and 0 to 0.
-        $scale = variable_get('node_cron_views_scale', 0.0);
-        $ranking[] = '%d * (2.0 - 2.0 / (1.0 + nc.totalcount * %f))';
-        $arguments2[] = $weight;
-        $arguments2[] = $scale;
-        $join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid';
-        $total += $weight;
-      }
-      $select2 = (count($ranking) ? implode(' + ', $ranking) : 'i.relevance') .' AS score';
-      // study things before this and is this needed assumption no 
-      // Do search simple no need other table 
-      $find = do_multisite_drupal_search($keys, 'node');  
-      // Load results
-      $results = array();
-      foreach ($find as $item) { 
-        // get site table prefix 
-        // load some other site node how ?? 
-        $tbl_prefix = $item->subdmn_id; 
-        // get this table prefix item site url 
-        $msite_sql = db_query("SELECT * FROM multisite_drupal_search_sites WHERE table_prefix='%s'", $tbl_prefix);
-        $msite_res = db_fetch_array($msite_sql);
-        $msite_url = $msite_res['site_url'];
-        global $db_prefix;
-        global $base_url;
-        global $user;
-        // Build the node body. 
-        $node = db_fetch_object(db_query("SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM ". $tbl_prefix ."node n INNER JOIN ". $tbl_prefix ."users u ON u.uid = n.uid INNER JOIN ". $tbl_prefix ."node_revisions r ON r.vid = n.vid WHERE n.nid=%d", $item->sid));
-        // Fetch comments for snippet 
-        // Fetch terms for snippet
-        $extra = array(); 
-        // assuming have to show only total comment 
-        $comments = db_result(db_query('SELECT comment_count FROM '. $tbl_prefix .'node_comment_statistics WHERE nid = %d', $node->nid));
-        $extra[] = format_plural($comments, '1 comment', '@count comments');
-        // attachment module ???
-        if (user_access('access user profiles')) { 
-          $tuname = "<a href='". $msite_url . url('user/'. $node->uid) ."'>". $node->name ."</a>";
+    }
+}
+
+/**
+ * Implementation of hook_search().
+ */
+function multisite_search_search($op = 'search', $keys = NULL) {
+
+    switch ($op) {
+        case 'name':
+            return t('Multi Site'); // Used on search tab.
+        case 'reset':
+            return;
+        case 'search':
+            // Search the index for the keywords that were entered.
+            // Build matching conditions
+            list($join1, $where1) = _db_rewrite_sql();
+            $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;
+                }
+                $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.nid = tn.nid';
+                $keys = search_query_insert($keys, 'category');
+            }
+
+            // Build ranking expression (we try to map each parameter to a
+            // uniform distribution in the range 0..1).
+            $ranking = array();
+            $arguments2 = array();
+            $join2 = '';
+            // Used to avoid joining on node_comment_statistics twice
+            $stats_join = FALSE;
+            $total = 0;
+
+            // 1. factor
+            if ($weight = (int) variable_get('node_rank_relevance', 5)) {
+                // Average relevance values hover around 0.15
+                $ranking[] = '%d * i.relevance';
+                $arguments2[] = $weight;
+                $total += $weight;
+            }
+
+            // 2.factor
+            if ($weight = (int) variable_get('node_rank_recent', 5)) {
+                // Exponential decay with half-life of 6 months, starting at last indexed node
+                $ranking[] = '%d * POW(2, (GREATEST(n.created, n.changed, c.last_comment_timestamp) - %d) * 6.43e-8)';
+                $arguments2[] = $weight;
+                $arguments2[] = (int) variable_get('node_cron_last', 0);
+                $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
+                $stats_join = TRUE;
+                $total += $weight;
+            }
+
+            // 3.factor
+            if (module_exists('comment') && $weight = (int) variable_get('node_rank_comments', 5)) {
+                // Inverse law that maps the highest reply count on the site to 1 and 0 to 0.
+                $scale = variable_get('node_cron_comments_scale', 0.0);
+                $ranking[] = '%d * (2.0 - 2.0 / (1.0 + c.comment_count * %f))';
+                $arguments2[] = $weight;
+                $arguments2[] = $scale;
+                if (!$stats_join) {
+                    $join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
+                }
+                $total += $weight;
+            }
+
+            // 4.factor
+            if (module_exists('statistics') && variable_get('statistics_count_content_views', 0) &&
+                    $weight = (int) variable_get('node_rank_views', 5)) {
+                // Inverse law that maps the highest view count on the site to 1 and 0 to 0.
+                $scale = variable_get('node_cron_views_scale', 0.0);
+                $ranking[] = '%d * (2.0 - 2.0 / (1.0 + nc.totalcount * %f))';
+                $arguments2[] = $weight;
+                $arguments2[] = $scale;
+                $join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid';
+                $total += $weight;
+            }
+            $select2 = (count($ranking) ? implode(' + ', $ranking) : 'i.relevance') . ' AS score';
+
+            // study things before this and is this needed assumption no
+            // Do search simple no need other table
+            //$find = do_multisite_drupal_search($keys, 'node');
+
+            $sort = variable_get('multisite_search_order', 'score');
+            $find = do_multisite_drupal_search($keys, 'node','', '1', array(), 'i.relevance AS score','',array(), "ORDER BY $sort DESC");
+            // Load results
+            $results = array();
+            foreach ($find as $item) {
+                // get site table prefix
+                // load some other site node how ??
+                $tbl_prefix = get_subdmn_id($item->subdmn_id);
+                // get this table prefix item site url
+                $msite_sql = db_query("SELECT * FROM {multisite_drupal_search_sites} WHERE site_id='%s'", $item->subdmn_id);
+                $msite_res = db_fetch_array($msite_sql);
+                $msite_url = $msite_res['site_url'];
+                $msite_db_connection = $msite_res['db_connection'];
+                $msite_table_prefix = $msite_res['table_prefix'];
+
+                global $db_prefix;
+                global $base_url;
+                global $user;
+
+                // Build the node body.
+                if ($msite_db_connection != 'default')
+                    db_set_active($msite_db_connection);
+
+                $node = db_fetch_object(db_query("SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.sticky, 
+                                                         r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid,
+                                                         u.name, u.picture, u.data
+                                                  FROM " . $tbl_prefix . "node n
+                                                  INNER JOIN " . $tbl_prefix . "users u ON u.uid = n.uid
+                                                  INNER JOIN " . $tbl_prefix . "node_revisions r ON r.vid = n.vid
+                                                  WHERE n.nid=%d", $item->sid));
+                
+                if ($msite_db_connection != 'default')
+                    db_set_active ();
+
+                // Fetch comments for snippet
+                // Fetch terms for snippet
+                $extra = array();
+                // assuming have to show only total comment
+                if ($msite_db_connection != 'default')
+                    db_set_active($msite_db_connection);
+
+                $comments = db_result(db_query('SELECT comment_count FROM ' . $tbl_prefix . 'node_comment_statistics WHERE nid = %d', $node->nid));
+
+                if ($msite_db_connection != 'default')
+                    db_set_active ();
+
+                $extra[] = format_plural($comments, '1 comment', '@count comments');
+
+                // attachment module ???
+                if (user_access('access user profiles')) {
+                    $tuname = "<a href='" . $msite_url . multisite_search_get_path_alias('user/' . $node->uid,'',$msite_table_prefix,$msite_db_connection) . "'>" . $node->name . "</a>";
+                } else {
+                    $tuname = $node->name;
+                } 
+
+                // check access permission and do accordingly
+                if(!empty($node)){
+                    if ($msite_db_connection == 'default') {
+                        $results[] = array('link' => '' . $msite_url . url('node/' . $item->sid),
+                            'type' => node_get_types('name', $node),
+                            'title' => $node->title,
+                            'user' => $tuname,
+                            'date' => $node->changed,
+                            'node' => $node,
+                            'extra' => $extra,
+                            'score' => $item->score / $total,
+                            'snippet' => search_excerpt($keys, $node->body));
+                    } else {
+                        $results[] = array('link' => '' . $msite_url . multisite_search_get_path_alias('node/' . $item->sid, '', $msite_table_prefix, $msite_db_connection),
+                            'type' => node_get_types('name', $node),
+                            'title' => $node->title,
+                            'user' => $tuname,
+                            'date' => $node->changed,
+                            'node' => $node,
+                            'extra' => $extra,
+                            'score' => $item->score / $total,
+                            'snippet' => search_excerpt($keys, $node->body));
+                    }
+                }
+            }
+            return $results;
+    }
+}
+
+function multisite_search_get_path_alias($path, $path_language = '', $prefix, $db_connection) {
+    $result = $path;
+    db_set_active($db_connection);
+    if ($alias = multisite_search_lookup_path('alias', $path, $path_language, $prefix,$db_connection)) {
+        $result = $alias;
+    } else {
+            $result = base_path() . $path;
+    }
+    db_set_active();
+    return $result;
+}
+
+function multisite_search_lookup_path($action, $path = '', $path_language = '', $prefix ='',$db_connection ='default') {
+    global $language;
+    // $map is an array with language keys, holding arrays of Drupal paths to alias relations
+    static $map = array(), $no_src = array(), $count;
+
+    $path_language = $path_language ? $path_language : $language->language;
+
+    // Use $count to avoid looking up paths in subsequent calls if there simply are no aliases
+    if (!isset($count)) {
+        $count = db_result(db_query('SELECT COUNT(pid) FROM ' . $prefix . 'url_alias'));
+    }
+
+    if ($action == 'wipe') {
+        $map = array();
+        $no_src = array();
+        $count = NULL;
+    } elseif ($count > 0 && $path != '') {
+        if ($action == 'alias') {
+            if (isset($map[$db_connection][$path_language][$path])) {
+                return $map[$db_connection][$path_language][$path];
+            }
+            // Get the most fitting result falling back with alias without language
+            //drupal_set_message(sprint_f("SELECT dst FROM " . $prefix . "url_alias WHERE src = '%s' AND language IN('%s', '') ORDER BY language DESC, pid DESC", $path, $path_language));
+            $alias = db_result(db_query("SELECT dst FROM " . $prefix . "url_alias WHERE src = '%s' AND language IN('%s', '') ORDER BY language DESC, pid DESC", $path, $path_language));
+            $map[$db_connection][$path_language][$path] = $alias;
+            return $alias;
         }
-        else {
-          $tuname = $node->name;
+        // Check $no_src for this $path in case we've already determined that there
+        // isn't a path that has this alias
+        elseif ($action == 'source' && !isset($no_src[$path_language][$path])) {
+            // Look for the value $path within the cached $map
+            $src = '';
+            if (!isset($map[$db_connection][$path_language]) || !($src = array_search($path, $map[$db_connection][$path_language]))) {
+                // Get the most fitting result falling back with alias without language
+                if ($src = db_result(db_query("SELECT src FROM " . $prefix . "url_alias WHERE dst = '%s' AND language IN('%s', '') ORDER BY language DESC, pid DESC", $path, $path_language))) {
+                    $map[$db_connection][$path_language][$src] = $path;
+                } else {
+                    // We can't record anything into $map because we do not have a valid
+                    // index and there is no need because we have not learned anything
+                    // about any Drupal path. Thus cache to $no_src.
+                    $no_src[$path_language][$path] = TRUE;
+                }
+            }
+            return $src;
         }
-        // check access permission and do accordingly 
-        $results[] = array(
-          'link' => ''. $msite_url . url('node/'. $item->sid),
-          'type' => node_get_types('name', $node),
-          'title' => $node->title,
-          'user' => $tuname,
-          'date' => $node->changed,
-          'node' => $node,
-          'extra' => $extra,
-          'score' => $item->score / $total,
-          'snippet' => search_excerpt($keys, $node->body));
-      }
-      return $results;
-  }
+    }
+
+    return FALSE;
 }
 
 /**
@@ -479,37 +709,42 @@ function multisite_search_search($op = '
  * @ingroup search
  */
 function do_multisite_drupal_search($keywords, $type, $join1 = '', $where1 = '1', $arguments1 = array(), $select2 = 'i.relevance AS score', $join2 = '', $arguments2 = array(), $sort_parameters = 'ORDER BY score DESC') {
-  $query = search_parse_query($keywords);
-  if ($query[2] == '') {
-    form_set_error('keys', t('You must include at least one positive keyword with @count characters or more.', array('@count' => variable_get('minimum_word_size', 3))));
-  }
-  if ($query === NULL || $query[0] == '' || $query[2] == '') {
-    return array();
-  }
-  // First pass: select all possible matching sids, doing a simple index-based OR matching on the keywords.
-  // 'matches' is used to reject those items that cannot possibly match the query.
-  $conditions = $where1 .' AND ('. $query[2] .") AND i.type = '%s'";
-  $arguments = array_merge($arguments1, $query[3], array($type, $query[4]));
-  $result = db_query_temporary("SELECT i.type, i.sid, i.subdmn_id, SUM(i.score * t.count) AS relevance, COUNT(*) AS matches FROM multisite_drupal_search_index i INNER JOIN multisite_drupal_search_total t ON i.word = t.word $join1 WHERE $conditions GROUP BY i.subdmn_id, i.type, i.sid HAVING COUNT(*) >= %d", $arguments, 'temp_search_sids');
-  // Calculate maximum relevance, to normalize it
-  $normalize = db_result(db_query('SELECT MAX(relevance) FROM temp_search_sids'));
-  if (!$normalize) {
-    return array();
-  }
-  $select2 = str_replace('i.relevance', '('. (1.0 / $normalize) .' * i.relevance)', $select2);
-  // Second pass: only keep items that match the complicated keywords conditions (phrase search, negative keywords, ...)
-  $conditions = '('. $query[0] .')';
-  $arguments = array_merge($arguments2, $query[1]);
-  $result = db_query_temporary("SELECT i.type, i.sid, i.subdmn_id, $select2 FROM temp_search_sids i INNER JOIN multisite_drupal_search_dataset d ON i.sid = d.sid AND i.type = d.type AND i.subdmn_id = d.subdmn_id $join2 WHERE $conditions $sort_parameters", $arguments, 'temp_search_results');
-  if (($count = db_result(db_query('SELECT COUNT(*) FROM temp_search_results'))) == 0) {
-    return array();
-  }
-  $count_query = "SELECT $count";
-  // Do actual search query
-  $result = pager_query("SELECT * FROM temp_search_results", 10, 0, $count_query);
-  $results = array();
-  while ($item = db_fetch_object($result)) {
-    $results[] = $item;
-  }
-  return $results;
+    $query = search_parse_query($keywords);
+
+    if ($query[2] == '') {
+        form_set_error('keys', t('You must include at least one positive keyword with @count characters or more.', array('@count' => variable_get('minimum_word_size', 3))));
+    }
+    if ($query === NULL || $query[0] == '' || $query[2] == '') {
+        return array();
+    }
+
+    // First pass: select all possible matching sids, doing a simple index-based OR matching on the keywords.
+    // 'matches' is used to reject those items that cannot possibly match the query.
+    $conditions = $where1 . ' AND (' . $query[2] . ") AND i.type = '%s'";
+    $arguments = array_merge($arguments1, $query[3], array($type, $query[4]));
+    $result = db_query_temporary("SELECT i.type, i.sid, i.subdmn_id, SUM(i.score * t.count) AS relevance, COUNT(*) AS matches , i.date FROM {multisite_drupal_search_index} i INNER JOIN {multisite_drupal_search_total} t ON i.word = t.word $join1 WHERE $conditions GROUP BY i.subdmn_id, i.type, i.sid HAVING COUNT(*) >= %d", $arguments, 'temp_search_sids');
+
+    // Calculate maximum relevance, to normalize it
+    $normalize = db_result(db_query('SELECT MAX(relevance) FROM temp_search_sids'));
+    if (!$normalize) {
+        return array();
+    }
+    $select2 = str_replace('i.relevance', '(' . (1.0 / $normalize) . ' * i.relevance)', $select2);
+
+    // Second pass: only keep items that match the complicated keywords conditions (phrase search, negative keywords, ...)
+    $conditions = '(' . $query[0] . ')';
+    $arguments = array_merge($arguments2, $query[1]);
+    $result = db_query_temporary("SELECT i.type, i.sid, i.subdmn_id, $select2 FROM temp_search_sids i INNER JOIN {multisite_drupal_search_dataset} d ON i.sid = d.sid AND i.type = d.type AND i.subdmn_id = d.subdmn_id $join2 WHERE $conditions $sort_parameters", $arguments, 'temp_search_results');
+    if (($count = db_result(db_query('SELECT COUNT(*) FROM temp_search_results'))) == 0) {
+        return array();
+    }
+    $count_query = "SELECT $count";
+
+    // Do actual search query
+    $result = pager_query("SELECT * FROM temp_search_results", 10, 0, $count_query);
+    $results = array();
+    while ($item = db_fetch_object($result)) {
+        $results[] = $item;
+    }
+    return $results;
 }
