diff -u b/includes/bootstrap.inc b/includes/bootstrap.inc --- b/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -837,14 +837,6 @@ // drupal_static(). static $files = array(), $dirs = array(); - // 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['missing'] = &drupal_static('drupal_get_filename:missing'); - } - $missing = &$drupal_static_fast['missing']; - // Profiles are a special case: they have a fixed location and naming. if ($type == 'profile') { $profile_filename = "profiles/$name/$name.profile"; @@ -881,6 +873,9 @@ // Fallback to searching the filesystem if the database could not find the // file or the file returned by the database is not found. if (!isset($files[$type][$name])) { + // We use drupal_static() for the missing records so we can test it. + $missing = &drupal_static('drupal_get_filename:missing'); + // We have a consistent directory naming: modules, themes... $dir = $type . 's'; if ($type == 'theme_engine') { @@ -897,9 +892,16 @@ // See if we have a cached list of files missing from the file system. if (!isset($missing)) { $missing = array(); - $cache = cache_get('drupal_get_filename:missing'); - if (!empty($cache->data)) { - $missing = $cache->data; + try { + if (function_exists('cache_get')) { + $cache = cache_get('drupal_get_filename:missing'); + if (!empty($cache->data)) { + $missing = $cache->data; + } + } + } + catch (Exception $e) { + // Hide the error. } } @@ -929,9 +931,16 @@ // 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); + try { + if (function_exists('cache_set')) { + cache_set('drupal_get_filename:missing', $missing, 'cache'); + } + } + catch (Exception $e) { + // Hide the error. + } } - trigger_error(t('The following @type is missing from the file system: @name. For more information, see the documentation page.', array('@type' => $type, '@name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING); + trigger_error(format_string('The following @type is missing from the file system: @name. For more information, see the documentation page.', array('@type' => $type, '@name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), 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 @@ -382,6 +382,11 @@ } /** + * @var bool + */ + protected $getFilenameTestTriggeredError = FALSE; + + /** * Test that drupal_get_filename() works correctly when the file is not found in the database. */ function testDrupalGetFilename() { @@ -412,7 +417,7 @@ $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); + $non_existing_module = $this->randomName(); // We save that the error handler is triggered by drupal_get_filename(). // This variable is inherited in the error handler with 'use'. @@ -420,17 +425,9 @@ // 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); - }); - + set_error_handler(array($this, 'fileNotFoundErrorHandler')); $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.'); + $this->assertTrue($this->getFilenameTestTriggeredError, 'Searching for an item that does not exist triggers an error.'); // Restore the original error handler. restore_error_handler(); @@ -442,4 +439,13 @@ $this->assertTrue($missing['module'][$non_existing_module], 'Searching for an item that does not exist creates a static record in drupal_get_filename().'); } + + public function fileNotFoundErrorHandler($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:')) { + $this->getFilenameTestTriggeredError = TRUE; + return; + } + _drupal_error_handler($error_level, $message, $filename, $line, $context); + } } reverted: --- b/modules/system/system.admin.inc +++ a/modules/system/system.admin.inc @@ -134,10 +134,6 @@ * 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'); @@ -792,10 +788,6 @@ * @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(); only in patch2: unchanged: --- a/modules/system/system.module +++ b/modules/system/system.module @@ -2365,6 +2365,10 @@ function system_get_info($type, $name = NULL) { * An associative array of module information. */ function _system_rebuild_module_data() { + // Clean up the bootstrap "missing files" cache when rebuilding theme data. + drupal_static_reset('drupal_get_filename:missing'); + cache_clear_all('drupal_get_filename:missing', 'cache'); + // Find modules $modules = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0); @@ -2501,6 +2505,10 @@ function _system_update_bootstrap_status() { * An associative array of themes information. */ function _system_rebuild_theme_data() { + // Clean up the bootstrap "missing files" cache when rebuilding theme data. + drupal_static_reset('drupal_get_filename:missing'); + cache_clear_all('drupal_get_filename:missing', 'cache'); + // Find themes $themes = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info$/', 'themes'); // Allow modules to add further themes.