cvs diff: Diffing modules/update Index: modules/update/update.manager.inc =================================================================== RCS file: /Users/wright/drupal/local_repo/drupal/modules/update/update.manager.inc,v retrieving revision 1.27 diff -u -p -r1.27 update.manager.inc --- modules/update/update.manager.inc 1 Dec 2010 00:23:36 -0000 1.27 +++ modules/update/update.manager.inc 1 Dec 2010 05:16:35 -0000 @@ -557,11 +557,16 @@ function update_manager_install_form_sub // Unfortunately, we can only use the directory name for this. :( $project = drupal_substr($files[0], 0, -1); - try { - update_manager_archive_verify($project, $local_cache, $directory); - } - catch (Exception $e) { - form_set_error($field, $e->getMessage()); + $archive_errors = update_manager_archive_verify($project, $local_cache, $directory); + if (!empty($archive_errors)) { + form_set_error($field, array_shift($archive_errors)); + // @todo: Fix me in D8: We need a way to set multiple errors on the same + // form element and have all of them appear! + if (!empty($archive_errors)) { + foreach ($archive_errors as $key => $message) { + drupal_set_message($message, 'error'); + } + } return; } @@ -682,15 +687,13 @@ function update_manager_archive_extract( * @param string $directory * The directory that the archive was extracted into. * - * @return void - * @throws Exception on failure. + * @return array + * An array of error messages to display if the archive was invalid. If + * there are no errors, it will be an empty array. * */ function update_manager_archive_verify($project, $archive_file, $directory) { - $failures = module_invoke_all('verify_update_archive', $project, $archive_file, $directory); - if (!empty($failures)) { - throw new Exception(t('Unable to extract %file', array('%file' => $archive_file))); - } + return module_invoke_all('verify_update_archive', $project, $archive_file, $directory); } /** @@ -770,11 +773,11 @@ function update_manager_batch_project_ge } // Verify it. - try { - update_manager_archive_verify($project, $local_cache, $extract_directory); - } - catch (Exception $e) { - $context['results']['errors'][$project] = $e->getMessage(); + $archive_errors = update_manager_archive_verify($project, $local_cache, $extract_directory); + if (!empty($archive_errors)) { + foreach ($archive_errors as $key => $message) { + $context['results']['errors']["$project-$key"] = $message; + } return; } Index: modules/update/update.module =================================================================== RCS file: /Users/wright/drupal/local_repo/drupal/modules/update/update.module,v retrieving revision 1.70 diff -u -p -r1.70 update.module --- modules/update/update.module 6 Oct 2010 13:36:30 -0000 1.70 +++ modules/update/update.module 1 Dec 2010 06:34:05 -0000 @@ -641,6 +641,76 @@ function theme_update_last_check($variab } /** + * Implements hook_verify_update_archive(). + * + * First, we ensure that the archive isn't a copy of Drupal core, which the + * Update manager does not yet support. @see http://drupal.org/node/606592 + * + * Then, we make sure that every module or theme included in the archive has a + * .info file, and that the .info file claims the code is compatible with + * Drupal 7. + * + * @see drupal_system_listing() + * @see _system_rebuild_modules() + */ +function update_verify_update_archive($project, $archive_file, $directory) { + // Make sure this isn't a tarball of Drupal core. + if ( + file_exists("$directory/$project/index.php") + && file_exists("$directory/$project/update.php") + && file_exists("$directory/$project/includes/bootstrap.inc") + && file_exists("$directory/$project/modules/node/node.module") + && file_exists("$directory/$project/modules/system/system.module") + ) { + return array( + 'no-core' => t('Automatic updating of Drupal core is not supported. See the upgrade guide for information on how to update Drupal core manually.', array('@upgrade-guide' => 'http://drupal.org/upgrade')), + ); + } + + $failures = array(); + + $missing_info = array(); + $files = file_scan_directory("$directory/$project", '/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', array('key' => 'name', 'min_depth' => 0)); + foreach ($files as $key => $file) { + // If it has no info file, set an error. + $info_file = dirname($file->uri) . '/' . $file->name . '.info'; + if (!file_exists($info_file)) { + $missing_info[] = $file->filename; + } + } + if (!empty($missing_info)) { + $failures['no info file'] = format_plural( + count($missing_info), + '%archive_file contains %names which is missing an info file.', + '%archive_file contains the following modules which are missing info files: %names', + array('%archive_file' => basename($archive_file), '%names' => implode(', ', $missing_info)) + ); + } + + $incompatible = array(); + $files = file_scan_directory("$directory/$project", '/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info/', array('key' => 'name', 'min_depth' => 0)); + foreach ($files as $key => $file) { + // Get the .info file for the module or theme this file belongs to. + $info = drupal_parse_info_file($file->uri); + + // If the module or theme is incompatible with Drupal core, set an error. + if (empty($info['core']) || $info['core'] != DRUPAL_CORE_COMPATIBILITY) { + $incompatible[] = $info['name']; + } + } + + if (!empty($incompatible)) { + $failures['incompatible'] = format_plural( + count($incompatible), + '%archive_file contains a version of %names that is not compatible with Drupal !version.', + '%archive_file contains versions of modules or themes that are not compatible with Drupal !version: %names', + array('!version' => DRUPAL_CORE_COMPATIBILITY, '%archive_file' => basename($archive_file), '%names' => implode(', ', $incompatible)) + ); + } + return $failures; +} + +/** * @defgroup update_status_cache Private update status cache system * @{ * cvs diff: Diffing modules/update/tests