diff -Naur modules/search/search.module modules/search/search.module --- modules/search/search.module 2007-07-26 15:16:48.000000000 -0400 +++ modules/search/search.module 2007-11-04 19:49:55.000000000 -0500 @@ -272,6 +272,8 @@ // When re-indexing, keep link references db_query("DELETE FROM {search_index} WHERE sid = %d AND type = '%s'". ($reindex ? " AND fromsid = 0" : ''), $sid, $type); } + // Cached search results may no longer be valid. + cache_clear_all(NULL, 'cache_search'); } /** @@ -304,6 +306,34 @@ foreach (module_list() as $module) { module_invoke($module, 'update_index'); } + + // Don't allow search result caching if any node access modules such as organic + // groups have placed viewing restrictions on any nodes. Even if you have had + // organic groups enabled and have since disabled it, search caching will + // be prevented. If you find yourself in this position, you can restore the + // original un-restricted state of node_access like this: + // TRUNCATE node_access; + // INSERT INTO node_access VALUES (0,0,'all',1,0,0); + $r1 = db_result(db_query("SELECT count(*) FROM {node_access}")); + $r2 = db_result(db_query("SELECT count(*) FROM {node_access} WHERE grant_view = 1")); + if (($r1 == 1) && ($r2 == 1)) { + // Recalculate the list of popular search terms + $tops = array(); + $result = db_query("SELECT location, count(*) AS count FROM {watchdog} WHERE type = 'search' GROUP BY location HAVING count(*) > 2"); + while ($row = db_fetch_object($result)) { + $tops[] = strtolower($row->location); + } + // Since we just potentially indexed new or updated content, clear the cache. + cache_clear_all(NULL, 'cache_search'); + + // Set the search_cache_queries to the new top queries. + cache_set('search_cache_queries', 'cache_search', serialize($tops)); + } + else { + // No guarantee that the cache complies with node access restrictions, so + // wipe it. + cache_clear_all(NULL, 'cache_search'); + } } /** @@ -890,6 +920,7 @@ * Menu callback; presents the search form and/or search results. */ function search_view() { + global $base_root, $user; $type = arg(1); // Search form submits with POST but redirects to GET. This way we can keep @@ -909,8 +940,29 @@ // Log the search keys: watchdog('search', t('%keys (@type).', array('%keys' => $keys, '@type' => module_invoke($type, 'search', 'name'))), WATCHDOG_NOTICE, l(t('results'), 'search/'. $type .'/'. $keys)); - // Collect the search results: - $results = search_data($keys, $type); + // Look to the cache to see if this is a popular (thus cached) query + $request_uri = strtolower($base_root . request_uri()); + $results = NULL; + // Only cache results if the user is not an admin, is authenticated, has + // exactly one role, and the query is in the popular search queries array. + if ($cachable = ($user->uid > 1 && count($user->roles) === 1 && in_array('authenticated user', $user->roles))) { + $queries_cache = cache_get('search_cache_queries', 'cache_search'); + } + if ($cachable && $queries_cache) { + $search_cache_queries = unserialize($queries_cache->data); + if (in_array($request_uri, $search_cache_queries)) { + if ($search_cache = cache_get($request_uri, 'cache_search')) { + $results = $search_cache->data; + } + } + } + if (empty($results)) { + // Collect the search results: + $results = search_data($keys, $type); + if ($cachable) { + cache_set($request_uri, 'cache_search', $results); + } + } if ($results) { $results = theme('box', t('Search results'), $results);