summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/update/update.compare.inc61
-rw-r--r--modules/update/update.fetch.inc7
-rw-r--r--modules/update/update.module2
3 files changed, 67 insertions, 3 deletions
diff --git a/modules/update/update.compare.inc b/modules/update/update.compare.inc
index 30ae642fd..5c7c914f9 100644
--- a/modules/update/update.compare.inc
+++ b/modules/update/update.compare.inc
@@ -23,8 +23,15 @@
function update_get_projects() {
static $projects = array();
if (empty($projects)) {
- _update_process_info_list($projects, module_rebuild_cache(), 'module');
- _update_process_info_list($projects, system_theme_data(), 'theme');
+ // Retrieve the projects from cache, if present.
+ $projects = update_project_cache('update_project_projects');
+ if (empty($projects)) {
+ // Still empty, so we have to rebuild the cache.
+ _update_process_info_list($projects, module_rebuild_cache(), 'module');
+ _update_process_info_list($projects, system_theme_data(), 'theme');
+ // Set the projects array into the cache table.
+ cache_set('update_project_projects', $projects, 'cache_update', time() + 3600);
+ }
}
return $projects;
}
@@ -225,6 +232,13 @@ function update_process_project_info(&$projects) {
* @see update_process_project_info()
*/
function update_calculate_project_data($available) {
+ // Retrieve the projects from cache, if present.
+ $projects = update_project_cache('update_project_data');
+ // If $projects is empty, then the cache must be rebuilt.
+ // Otherwise, return the cached data and skip the rest of the function.
+ if (!empty($projects)) {
+ return $projects;
+ }
$projects = update_get_projects();
update_process_project_info($projects);
foreach ($projects as $project => $project_info) {
@@ -535,5 +549,48 @@ function update_calculate_project_data($available) {
// contrib module to provide fine-grained settings to ignore specific
// projects or releases).
drupal_alter('update_status', $projects);
+
+ // Set the projects array into the cache table.
+ cache_set('update_project_data', $projects, 'cache_update', time() + 3600);
+ return $projects;
+}
+
+/**
+ * Retrieve data from {cache_update} or empty the cache when necessary.
+ *
+ * Two very expensive arrays computed by this module are the list of all
+ * installed modules and themes (and .info data, project associations, etc),
+ * and the current status of the site relative to the currently available
+ * releases. These two arrays are cached in the {cache_update} table and used
+ * whenever possible. The cache is cleared whenever the administrator visits
+ * the status report, available updates report, or the module or theme
+ * administration pages, since we should always recompute the most current
+ * values on any of those pages.
+ *
+ * @param $cid
+ * The cache id of data to return from the cache. Valid options are
+ * 'update_project_data' and 'update_project_projects'.
+ *
+ * @return
+ * The cached value of the $projects array generated by
+ * update_calculate_project_data() or update_get_projects(), or an empty
+ * array when the cache is cleared.
+ */
+function update_project_cache($cid) {
+ $projects = array();
+
+ // In some cases, we must clear the cache. Rather than do so on a time
+ // basis, we check for specific paths.
+ $q = $_GET['q'];
+ $paths = array('admin/build/modules', 'admin/build/themes', 'admin/reports', 'admin/reports/updates', 'admin/reports/status', 'admin/reports/updates/check');
+ if (in_array($q, $paths)) {
+ cache_clear_all($cid, 'cache_update');
+ }
+ else {
+ $cache = cache_get($cid, 'cache_update');
+ if (!empty($cache->data) && $cache->expire > time()) {
+ $projects = $cache->data;
+ }
+ }
return $projects;
}
diff --git a/modules/update/update.fetch.inc b/modules/update/update.fetch.inc
index 4ecdbc235..ce4c836a8 100644
--- a/modules/update/update.fetch.inc
+++ b/modules/update/update.fetch.inc
@@ -26,6 +26,13 @@ function _update_refresh() {
global $base_url;
include_once './modules/update/update.compare.inc';
+ // Since we're fetching new available update data, we want to clear
+ // everything in our cache, to ensure we recompute the status. Note that
+ // this does not cause update_get_projects() to be recomputed twice in the
+ // same page load (e.g. when manually checking) since that function stashes
+ // its answer in a static array.
+ update_invalidate_cache();
+
$available = array();
$data = array();
$site_key = md5($base_url . drupal_get_private_key());
diff --git a/modules/update/update.module b/modules/update/update.module
index 8f624c5c9..204047e8c 100644
--- a/modules/update/update.module
+++ b/modules/update/update.module
@@ -379,7 +379,7 @@ function update_flush_caches() {
* Invalidates any cached data relating to update status.
*/
function update_invalidate_cache() {
- cache_clear_all('update_info', 'cache_update');
+ cache_clear_all('*', 'cache_update', TRUE);
}
/**