Index: twitter.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/twitter/twitter.inc,v
retrieving revision 1.3.2.12
diff -u -r1.3.2.12 twitter.inc
--- twitter.inc	2 Jul 2009 13:26:21 -0000	1.3.2.12
+++ twitter.inc	1 Oct 2009 17:19:51 -0000
@@ -111,6 +111,52 @@
 
 
 /**
+ * Fetch the search results for a Twitter.com search.
+ *
+ * @param $search_term
+ *   The term to search for. Can be a hash tag.
+ * @param $filter_since
+ *   A boolean indicating that Twitter should only return statuses that have not
+ *   been locally cached. This incurs an extra database hit, to retrieve the date
+ *   of the most recent locally cached twitter message for the screen name.
+ * @param $cache
+ *   A boolean indicating whether the statuses should be cached in the local
+ *   site's database after they're retrieved.
+ * @return
+ *   An array of Twitter statuses.
+ */
+function twitter_fetch_search($search_term, $filter_since = FALSE, $cache = TRUE) {
+
+  // TODO: filter_since needs work when not searching for user posts
+  if ($filter_since) {
+    $sql  = "SELECT t.created_at FROM {twitter} t ORDER BY t.created_at DESC";
+    $since = db_result(db_query($sql));
+  }
+
+  // TODO: Open up to other search APIs, if other Twitter search APIs exist
+  $url = "http://search.twitter.com/search.json?q=" . urlencode($search_term);
+  if (!empty($since)) {
+    $url .= '&since='. urlencode($since);
+  }
+
+  $results = drupal_http_request($url, array(), 'GET');
+
+  if (_twitter_request_failure($results)) {
+    return array();
+  }
+  else {
+    $results = _twitter_convert_json_to_array($results->data);
+    if ($cache) {
+      foreach($results as $status) {
+        twitter_cache_status($status);
+      }
+    }
+    return $results;
+  }
+}
+
+
+/**
  * Post a message to a Twitter.com account.
  *
  * @param $screen_name
@@ -524,6 +570,40 @@
   return $result;
 }
 
+/**
+ * Internal JSON munging code
+ */
+
+function _twitter_convert_json_to_array($data) {
+  $results = array();
+  $jsonObj = json_decode($data);
+  if (!empty($jsonObj->results)) {
+    foreach($jsonObj->results as $status) {
+      $results[] = array(
+        'twitter_id' => $status->id,
+        'screen_name' => $status->from_user,
+        'created_at' => $status->created_at,
+        'created_time' => strtotime($status->created_at),
+        'text' => $status->text,
+        'source' => $status->source,
+      );
+      
+      // If the screen name isn't already cached, save a partial user object with the tweet.
+      if (!db_result(db_query("SELECT * from {twitter} WHERE screen_name = '%s' LIMIT 1", $status->from_user))) {
+        $account = array(
+          'twitter_uid' => $status->from_user_id,
+          'screen_name' => $status->from_user,
+          'profile_image_url' => $status->profile_image_url,
+          'protected' => FALSE,
+          'last_refresh' => strtotime($status->created_at),
+        );
+        twitter_cache_account($account);
+      }
+    }
+  }
+  return $results;
+}
+
 function _twitter_account_fields($user, $account = array()) {
   $form['uid'] = array(
     '#type' => 'value',
Index: twitter.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/twitter/twitter.module,v
retrieving revision 1.3.2.14
diff -u -r1.3.2.14 twitter.module
--- twitter.module	2 Jul 2009 14:54:18 -0000	1.3.2.14
+++ twitter.module	1 Oct 2009 17:19:52 -0000
@@ -197,6 +197,11 @@
     }
     twitter_touch_account($account['screen_name']);
   }
+  
+  $search = variable_get('twitter_global_search', NULL);
+  if (!empty($search)) {
+    twitter_fetch_search($search);
+  }
 
   // Nuke old statuses.
   if ($age = variable_get('twitter_expire', 0)) {
Index: twitter.pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/twitter/twitter.pages.inc,v
retrieving revision 1.2.2.8
diff -u -r1.2.2.8 twitter.pages.inc
--- twitter.pages.inc	2 Jul 2009 13:23:44 -0000	1.2.2.8
+++ twitter.pages.inc	1 Oct 2009 17:19:52 -0000
@@ -25,6 +25,18 @@
     '#description' => t("If your Twitter account is protected, or you wish to post to Twitter from Drupal, you must enter the Twitter account's password."),
     '#default_value' => variable_get('twitter_global_password', NULL),
   );
+  
+  $form['global_search'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Search / Hash tags'),
+  );
+
+  $form['global_search']['twitter_global_search'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Terms/Tags'),
+    '#default_value' => variable_get('twitter_global_search', NULL),
+    '#description' => t('Search phrase to aggregate. See the <a href="http://search.twitter.com/operators">Twitter Search Operators</a> page for options. (Usually separate terms with "OR" i.e. "#drupal OR #twitter")'),
+  );
 
   $form['import'] = array(
     '#type' => 'fieldset',
