diff -u b/includes/bootstrap.inc b/includes/bootstrap.inc
--- b/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -835,9 +835,9 @@
function drupal_get_filename($type, $name, $filename = NULL) {
// The location of files will not change during the request, so do not use
// drupal_static().
- // The $files static variable will hold the locations of all requested files,
- // and any file that gets added during the request will have been checked
- // with a file_exists() at some point.
+ // The $files static variable will hold the locations of all requested files.
+ // We can be sure that any file listed in this static variable actually
+ // exists as all additions have gone through a file_exists() check.
static $files = array();
// Profiles are a special case: they have a fixed location and naming.
@@ -854,14 +854,15 @@
$files[$type][$name] = $filename;
}
elseif (isset($files[$type][$name])) {
- // This item had already been found earlier in the request, either in this
- // same function or by the static cache having been primed elsewhere, such
- // as in system_list(). Do nothing.
+ // This item had already been found earlier in the request, either through
+ // priming of the static cache (i.e. in system_list()), through a lookup
+ // in the {system} table, or through a file scan (cached or not).
+ // Do nothing.
}
else {
$system_filepaths = &drupal_static('system_filepaths');
if (!isset($system_filepaths[$type][$name])) {
- // Look for the file name listed in the {system} table.
+ // Look for the filename listed in the {system} table.
// Verify that we have an active database connection, before querying
// the database. This is required because this function is called both
// before we have a database connection (i.e. during installation) and
@@ -886,8 +887,8 @@
// hide the error completely.
}
}
- // Fallback to searching the filesystem if the database could not find the
- // file or the filename returned by the database is not found.
+ // Fall back to searching the filesystem if the database could not find the
+ // file or the file does not exist at the path returned by the database.
if (!isset($files[$type][$name])) {
$files[$type][$name] = _drupal_get_filename_fallback($type, $name);
}
@@ -895,9 +896,9 @@
if (isset($files[$type][$name])) {
// We found a file.
- // Clean up the item from the file scan cache, in case the item had been
- // marked as missing or moved.
$file_scans = &drupal_static('_drupal_get_filename_fallback');
+ // If this file had previously been marked as missing or moved, clean up
+ // the entry from the file scan cache.
if (isset($file_scans[$type][$name])) {
$file_scans[$type][$name] = NULL;
$file_scans['#write_cache'] = TRUE;
@@ -909,9 +910,10 @@
/**
* Helper function for drupal_get_filename().
*
- * This triggers a file scan, caching any missing or moved files. If an item
- * had been marked as missing or moved in a previous file scan, no new file
- * scans will be performed.
+ * This function looks for the requested file by triggering a file scan,
+ * caching the new location if the file has moved and caching the miss
+ * if the file is missing. If a file had been marked as missing or moved
+ * in a previous file scan, no new file scan will be performed.
*
* @param string $type
* The type of the item (theme, theme_engine, module, profile).
@@ -924,25 +926,27 @@
function _drupal_get_filename_fallback($type, $name) {
// This static variable will hold all missing and moved files, in order
// to prevent unnecessary file scans. It is an associative array with as
- // keys the file type and name, and as value the boolean FALSE if the
- // module is missing, or a string with location found in a file scan if
- // the module has moved from the location listed in the {system} table.
+ // keys the type and name of the item, and as value:
+ // - the boolean FALSE if the item is missing
+ // - a string with location found in a file scan if the module/theme has moved
+ // from the location listed in the {system} table.
$file_scans = &drupal_static('_drupal_get_filename_fallback');
if (!isset($file_scans)) {
$file_scans = array();
}
- // Get the missing and moved files from persistent cache, if available.
+ // Get the list of files marked as missing and moved during earlier file scans
+ // from the persistent cache, if available.
if (!isset($file_scans['#cache_merge_done'])) {
try {
if (function_exists('cache_get')) {
$cache = cache_get('_drupal_get_filename_fallback', 'cache_bootstrap');
if (!empty($cache->data)) {
- // Merge the changes already done in the current request
- // (including the setting of missing records to NULL) into the
- // values saved in persistent cache.
+ // Merge the changes to the file scan cache done in the current
+ // request (including the setting of previously set records to NULL)
+ // with the values that had been stored in the persistent cache.
$file_scans = drupal_array_merge_deep($cache->data, $file_scans);
- // Set a flag so we know that we've already done a merge with
- // the values in persistent cache.
+ // Set a flag so we remember that we've done a merge with the values
+ // stored in the persistent cache.
$file_scans['#cache_merge_done'] = TRUE;
}
}
@@ -952,7 +956,7 @@
}
}
- // Check whether this file had previously moved from its location in the
+ // Check whether this file had previously moved from the path listed in the
// {system} table.
if (isset($file_scans[$type][$name]) && is_string($file_scans[$type][$name]) && file_exists($file_scans[$type][$name])) {
// We found the file at the cached location.
@@ -964,15 +968,15 @@
$filename_from_file_scan = _drupal_get_filename_perform_file_scan($type, $name);
}
if (isset($filename_from_file_scan)) {
- // Check whether the current file was listed as being in another
+ // Check whether the file we found was listed as being in another
// location in the {system} table.
$system_filepaths = &drupal_static('system_filepaths');
if (isset($system_filepaths[$type][$name]) && $system_filepaths[$type][$name] != $filename_from_file_scan) {
- // This file has moved. Cache its new location into the missing and
- // moved files list.
+ // This file has moved. Store its new location in the file scan
+ // cache.
$file_scans[$type][$name] = $filename_from_file_scan[$type][$name];
- // Make sure our change to the missing and moved files list will be
- // written to persistent cache.
+ // Make sure our change to the file scan cache will be written to
+ // the persistent cache.
$file_scans['#write_cache'] = TRUE;
trigger_error(format_string('The following %type has moved on the file system: %name. In order to fix this, clear caches or put the file back in its original location. For more information, see the documentation page.', array('%type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING);
}
@@ -980,9 +984,9 @@
}
else {
trigger_error(format_string('The following %type is missing from the file system: %name. In order to fix this, put the file back in its original location or uninstall the module. For more information, see the documentation page.', array('%type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING);
- // Make sure our change to the missing files list will be written to
- // persistent cache.
- if (!isset($file_scans[$type][$name])) {
+ // Make sure our change to the file scan cache will be written to
+ // the persistent cache.
+ if (!(isset($file_scans[$type][$name]) && $file_scans[$type][$name] === FALSE)) {
$file_scans['#write_cache'] = TRUE;
}
// Mark the file as missing.
@@ -1022,7 +1026,7 @@
// Check if we had already scanned this directory/extension combination.
if (!isset($dirs[$dir][$extension])) {
// Log that we have now scanned this directory/extension combination
- // into a static variable to prevent unnecessary scans.
+ // into a static variable so as to prevent unnecessary file scans.
$dirs[$dir][$extension] = TRUE;
if (!function_exists('drupal_system_listing')) {
require_once DRUPAL_ROOT . '/includes/common.inc';
@@ -1046,17 +1050,21 @@
}
/**
- * Writes the missing and moved files to persistent cache.
+ * Writes the file scan cache to the persistent cache.
+ *
+ * This cache stores all files marked as missing or moved after a file scan
+ * to prevent unnecessary file scans in subsequent requests. This cache is
+ * cleared in system_list_reset() (i.e. after a module/theme rebuild).
*/
function drupal_file_scan_write_cache() {
- // Only write to cache if we are fully bootstrapped.
+ // Only write to the persistent cache if we are fully bootstrapped.
if (drupal_get_bootstrap_phase() != DRUPAL_BOOTSTRAP_FULL) {
return;
}
$file_scans = &drupal_static('_drupal_get_filename_fallback');
if (isset($file_scans['#write_cache'])) {
// Merge the newly found out missing and moved file data with
- // the previously existing data, if we hadn't done so yet.
+ // the previously existing data, if we had not done so yet.
if (!isset($file_scans['#cache_merge_done'])) {
$cache = cache_get('_drupal_get_filename_fallback', 'cache_bootstrap');
if (isset($cache->data)) {
@@ -1064,6 +1072,7 @@
}
}
$file_scans['#write_cache'] = NULL;
+ $file_scans['#cache_merge_done'] = NULL;
cache_set('_drupal_get_filename_fallback', $file_scans, 'cache_bootstrap');
}
}