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'); } }