cvs diff: Diffing modules/update Index: modules/update/update.compare.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/update/update.compare.inc,v retrieving revision 1.2 diff -u -p -u -p -r1.2 update.compare.inc --- modules/update/update.compare.inc 10 Jan 2008 14:14:54 -0000 1.2 +++ modules/update/update.compare.inc 12 Jan 2008 17:41:25 -0000 @@ -49,19 +49,28 @@ function _update_process_info_list(&$pro $file->info['project'] = update_get_project_name($file); } - if (!isset($projects[$file->info['project']])) { + // If we don't already know it, grab the modification time on the .info + // file itself. + if (!isset($file->info['_info_file_ctime'])) { + $info_filename = dirname($file->filename) .'/'. $file->name .'.info'; + $file->info['_info_file_ctime'] = filectime($info_filename); + } + + $project_name = $file->info['project']; + if (!isset($projects[$project_name])) { // Only process this if we haven't done this project, since a single // project can have multiple modules or themes. - $projects[$file->info['project']] = array( - 'name' => $file->info['project'], + $projects[$project_name] = array( + 'name' => $project_name, 'info' => $file->info, 'datestamp' => isset($file->info['datestamp']) ? $file->info['datestamp'] : 0, 'includes' => array($file->name => $file->info['name']), - 'project_type' => $file->info['project'] == 'drupal' ? 'core' : $project_type, + 'project_type' => $project_name == 'drupal' ? 'core' : $project_type, ); } else { - $projects[$file->info['project']]['includes'][$file->name] = $file->info['name']; + $projects[$project_name]['includes'][$file->name] = $file->info['name']; + $projects[$project_name]['info']['_info_file_ctime'] = max($projects[$project_name]['info']['_info_file_ctime'], $file->info['_info_file_ctime']); } } } Index: modules/update/update.module =================================================================== RCS file: /cvs/drupal/drupal/modules/update/update.module,v retrieving revision 1.10 diff -u -p -u -p -r1.10 update.module --- modules/update/update.module 10 Jan 2008 14:14:54 -0000 1.10 +++ modules/update/update.module 12 Jan 2008 17:41:26 -0000 @@ -320,17 +320,44 @@ function _update_no_data() { * Internal helper to try to get the update information from the cache * if possible, and to refresh the cache when necessary. * + * In addition to checking the cache lifetime, this function also ensures that + * there are no .info files for enabled modules or themes that have a newer + * modification timestamp than the last time we checked for available update + * data. If any .info file was modified, it almost certainly means a new + * version of something was installed. Without fresh available update data, + * the logic in update_calculate_project_data() will be wrong and produce + * confusing, bogus results. + * * @param $refresh * Boolean to indicate if this method should refresh the cache automatically * if there's no data. + * + * @see update_refresh() + * @see update_get_projects() */ function update_get_available($refresh = FALSE) { + include_once './modules/update/update.compare.inc'; $available = array(); - if (($cache = cache_get('update_info', 'cache_update')) + + // First, make sure that none of the .info files have a modification time + // newer than the last time we checked for available updates. + $needs_refresh = FALSE; + $last_check = variable_get('update_last_check', 0); + $projects = update_get_projects(); + foreach ($projects as $key => $project) { + if ($project['info']['_info_file_ctime'] > $last_check) { + $needs_refresh = TRUE; + break; + } + } + if (!$needs_refresh && ($cache = cache_get('update_info', 'cache_update')) && $cache->expire > time()) { $available = $cache->data; } - elseif ($refresh) { + elseif ($needs_refresh || $refresh) { + // If we need to refresh due to a newer .info file, ignore the argument + // and force the refresh (e.g., even for update_requirements()) to prevent + // bogus results. $available = update_refresh(); } return $available;