diff -u b/includes/bootstrap.inc b/includes/bootstrap.inc --- b/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -837,13 +837,13 @@ // drupal_static(). static $files = array(), $dirs = array(); - // We use drupal static for the bad records so we can test it. - // Drupal static fast pattern is used as this function may be called often. + // We use drupal_static() for the missing records so we can test it. + // drupal_static_fast() is used as this function may be called often. static $drupal_static_fast; if (!isset($drupal_static_fast)) { - $drupal_static_fast['bad'] = &drupal_static(__FUNCTION__ . ':bad'); + $drupal_static_fast['missing'] = &drupal_static('drupal_get_filename:missing'); } - $bad = &$drupal_static_fast['bad']; + $missing = &$drupal_static_fast['missing']; // Profiles are a special case: they have a fixed location and naming. if ($type == 'profile') { @@ -895,17 +895,15 @@ } // See if we have a cached list of files missing from the file system. - if (is_null($bad)) { - $cache = cache_get('drupal_get_filename:bad'); + if (!isset($missing)) { + $missing = array(); + $cache = cache_get('drupal_get_filename:missing'); if (!empty($cache->data)) { - $bad = $cache->data; - } - else { - $bad = array(); + $missing = $cache->data; } } - if (!isset($dirs[$dir][$extension]) && !isset($bad[$type][$name])) { + if (!isset($dirs[$dir][$extension]) && !isset($missing[$type][$name])) { $dirs[$dir][$extension] = TRUE; if (!function_exists('drupal_system_listing')) { require_once DRUPAL_ROOT . '/includes/common.inc'; @@ -925,15 +923,15 @@ if (isset($files[$type][$name])) { return $files[$type][$name]; } - elseif (!isset($bad[$type][$name])) { - // Add the missing file to a temporary cache and throw a watchdog alert. - $bad[$type][$name] = TRUE; - cache_set('drupal_get_filename:bad', $bad, 'cache', CACHE_TEMPORARY); - - // We don't have the watchdog table in the tests. - if (db_table_exists('watchdog')) { - watchdog('system', 'The following @type is missing from the file system: @name.', array('@type' => $type, '@name' => $name), WATCHDOG_ALERT); + else { + if (!isset($missing[$type][$name])) { + // Add the missing file to a temporary cache and throw an alert. This cache + // will be cleared on cron runs as well as when visiting the module and + // theme list pages. + $missing[$type][$name] = TRUE; + cache_set('drupal_get_filename:missing', $missing, 'cache', REQUEST_TIME + 24 * 60 * 60); } + trigger_error(t('The following @type is missing from the file system: @name.', array('@type' => $type, '@name' => $name)), E_USER_WARNING); } } diff -u b/modules/simpletest/tests/bootstrap.test b/modules/simpletest/tests/bootstrap.test --- b/modules/simpletest/tests/bootstrap.test +++ b/modules/simpletest/tests/bootstrap.test @@ -379,18 +379,6 @@ // automatically check there for 'script' files, just as it does for (e.g.) // 'module' files in modules. $this->assertIdentical(drupal_get_filename('script', 'test'), 'scripts/test.script', t('Retrieve test script location.')); - - // Generate a non-existing module name. - $non_existing_module = uniqid("", TRUE); - - // Searching for an item that does not exist returns NULL. - $this->assertNull(drupal_get_filename('module', $non_existing_module), 'Searching for an item that does not exist returns NULL.'); - - // Get the bad records static from drupal_get_filename. - $bad = &drupal_static('drupal_get_filename:bad'); - - // Searching for an item that does not exist creates a static record in drupal_get_filename. - $this->assertTrue($bad['module'][$non_existing_module], 'Searching for an item that does not exist creates a static record in drupal_get_filename.'); } } @@ -422,6 +410,35 @@ // automatically check there for 'script' files, just as it does for (e.g.) // 'module' files in modules. $this->assertIdentical(drupal_get_filename('script', 'test'), 'scripts/test.script', t('Retrieve test script location.')); + + // Generate a non-existing module name. + $non_existing_module = uniqid("", TRUE); + + // We save that the error handler is triggered by drupal_get_filename(). + // This variable is inherited in the error handler with 'use'. + $get_filename_test_triggered_error = FALSE; + + // Searching for an item that does not exist returns NULL. + // Set a custom error handler so we can ignore the file not found error. + set_error_handler(function($error_level, $message, $filename, $line, $context) use (&$get_filename_test_triggered_error) { + // Skip error handling if this is a "file not found" error. + if (strstr($message, 'is missing from the file system:')) { + $get_filename_test_triggered_error = TRUE; + return; + } + _drupal_error_handler($error_level, $message, $filename, $line, $context); + }); + + $this->assertNull(drupal_get_filename('module', $non_existing_module), 'Searching for an item that does not exist returns NULL.'); + $this->assertTrue($get_filename_test_triggered_error, 'Searching for an item that does not exist triggers an error.'); + // Restore the original error handler. + restore_error_handler(); + + // Get the bad records static from drupal_get_filename. + $missing = &drupal_static('drupal_get_filename:missing'); + + // Searching for an item that does not exist creates a static record in drupal_get_filename. + $this->assertTrue($missing['module'][$non_existing_module], 'Searching for an item that does not exist creates a static record in drupal_get_filename.'); } } only in patch2: unchanged: --- a/includes/update.inc +++ b/includes/update.inc @@ -795,6 +795,12 @@ function update_fix_d7_requirements() { function update_fix_d7_install_profile() { $profile = drupal_get_profile(); + // Default profile has been renamed to Standard in D7. + if ($profile == 'default') { + $profile = 'standard'; + variable_set('install_profile', $profile); + } + $results = db_select('system', 's') ->fields('s', array('name', 'schema_version')) ->condition('name', $profile) only in patch2: unchanged: --- a/modules/simpletest/simpletest.module +++ b/modules/simpletest/simpletest.module @@ -370,11 +370,27 @@ function simpletest_test_get_all() { // If this test class requires a non-existing module, skip it. if (!empty($info['dependencies'])) { + + // Searching for an item that does not exist triggers an PHP error. + // Set a custom error handler so we can ignore the file not found error. + set_error_handler(function($error_level, $message, $filename, $line, $context) { + // Skip error handling if this is a "file not found" error. + if (strstr($message, 'is missing from the file system:')) { + return; + } + _drupal_error_handler($error_level, $message, $filename, $line, $context); + }); + foreach ($info['dependencies'] as $module) { if (!drupal_get_filename('module', $module)) { + // Restore the original error handler. + restore_error_handler(); continue 2; } } + + // Restore the original error handler. + restore_error_handler(); } $groups[$info['group']][$class] = $info; only in patch2: unchanged: --- a/modules/system/system.admin.inc +++ b/modules/system/system.admin.inc @@ -134,6 +134,10 @@ function system_settings_overview() { * Menu callback; displays a listing of all themes. */ function system_themes_page() { + // Clean up the bootstrap "missing files" cache when listing themes. + drupal_static_reset('drupal_get_filename:missing'); + cache_clear_all('drupal_get_filename:missing', 'cache'); + // Get current list of themes. $themes = system_rebuild_theme_data(); uasort($themes, 'system_sort_modules_by_info_name'); @@ -788,6 +792,10 @@ function _system_is_incompatible(&$incompatible, $files, $file) { * @see system_modules_submit() */ function system_modules($form, $form_state = array()) { + // Clean up the bootstrap "missing modules" cache when listing modules. + drupal_static_reset('drupal_get_filename:missing'); + cache_clear_all('drupal_get_filename:missing', 'cache'); + // Get current list of modules. $files = system_rebuild_module_data();