}
/**
- * Helper method to gather file mtimes for getDefinitionSummary.
+ * Helper method to gather file hashes for getDefinitionSummary.
*
- * Last modified timestamps are calculated from the highest last modified
- * timestamp of this module's constituent files as well as the files it
- * depends on. This function is context-sensitive, only performing
- * calculations on files relevant to the given language, skin and debug
- * mode.
+ * This function is context-sensitive, only computing hashes of files relevant to the
+ * given language, skin, etc.
*
* @see ResourceLoaderModule::getFileDependencies
* @param ResourceLoaderContext $context
* @return array
*/
- protected function getFileMtimes( ResourceLoaderContext $context ) {
+ protected function getFileHashes( ResourceLoaderContext $context ) {
$files = array();
// Flatten style files into $files
// entry point Less file we already know about.
$files = array_values( array_unique( $files ) );
- // Don't max() because older files are significant.
- // While the associated file names are significant, that is already taken care of by the
- // definition summary. Avoid creating an array keyed by file path here because those are
- // absolute file paths. Including that would needlessly cause global cache invalidation
- // when the MediaWiki installation path changes (which is quite common in cases like
- // Wikimedia where the installation path reflects the MediaWiki branch name).
- return array_map( array( __CLASS__, 'safeFilemtime' ), $files );
+ // Don't include keys or file paths here, only the hashes. Including that would needlessly
+ // cause global cache invalidation when files move or if e.g. the MediaWiki path changes.
+ // Any significant ordering is already detected by the definition summary.
+ return array_map( array( __CLASS__, 'safeFileHash' ), $files );
}
/**
$options = array();
foreach ( array(
+ // T104950: Do not include localBasePath! That path may vary over time and needlessly
+ // invalidate cache. If the path changes in a way that makes relative file paths point
+ // to something else, getFileHashes() will incorporate that already.
'scripts',
'debugScripts',
'loaderScripts',
'group',
'position',
'skipFunction',
- // FIXME: localBasePath includes the MediaWiki installation path and
- // needlessly causes cache invalidation.
- 'localBasePath',
'remoteBasePath',
'debugRaw',
'raw',
$summary[] = array(
'options' => $options,
- 'fileMtimes' => $this->getFileMTimes( $context ),
+ 'fileHashes' => $this->getFileHashes( $context ),
'msgBlobMtime' => $this->getMsgBlobMtime( $context->getLanguage() ),
);
return $summary;
}
/**
- * Safe version of filemtime(), which doesn't throw a PHP warning if the file doesn't exist
- * but returns 1 instead.
- * @param string $filename File name
+ * Safe version of filemtime(), which doesn't throw a PHP warning if the file doesn't exist.
+ * Defaults to 1.
+ *
+ * @param string $filePath File path
* @return int UNIX timestamp
*/
- protected static function safeFilemtime( $filename ) {
+ protected static function safeFilemtime( $filePath ) {
MediaWiki\suppressWarnings();
- $mtime = filemtime( $filename ) ?: 1;
+ $mtime = filemtime( $filePath ) ?: 1;
MediaWiki\restoreWarnings();
-
return $mtime;
}
+
+ /**
+ * Safe version of sha1_file(), which doesn't throw a PHP warning if the file doesn't exist.
+ * Defaults to empty string.
+ *
+ * @param string $filePath File path
+ * @return string Hash
+ */
+ protected static function safeFileHash( $filePath ) {
+ MediaWiki\suppressWarnings();
+ $hash = sha1_file( $filename ) ?: '';
+ MediaWiki\restoreWarnings();
+ return $hash;
+ }
}