*/
protected $hasGeneratedStyles = false;
- /**
- * @var array Cache for mtime
- * @par Usage:
- * @code
- * array( [hash] => [mtime], [hash] => [mtime], ... )
- * @endcode
- */
- protected $modifiedTime = array();
-
/**
* @var array Place where readStyleFile() tracks file dependencies
* @par Usage:
$this->{$member} = $option;
break;
// Single strings
- case 'group':
case 'position':
+ $this->isPositionDefined = true;
+ case 'group':
case 'skipFunction':
$this->{$member} = (string)$option;
break;
}
/**
- * Get the last modified timestamp of this module.
+ * Helper method to gather file mtimes 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
* calculations on files relevant to the given language, skin and debug
* mode.
*
- * @param ResourceLoaderContext $context Context in which to calculate
- * the modified time
- * @return int UNIX timestamp
* @see ResourceLoaderModule::getFileDependencies
+ * @param ResourceLoaderContext $context
+ * @return array
*/
- public function getModifiedTime( ResourceLoaderContext $context ) {
- if ( isset( $this->modifiedTime[$context->getHash()] ) ) {
- return $this->modifiedTime[$context->getHash()];
- }
-
+ protected function getFileMtimes( ResourceLoaderContext $context ) {
$files = array();
// Flatten style files into $files
// entry point Less file we already know about.
$files = array_values( array_unique( $files ) );
- // If a module is nothing but a list of dependencies, we need to avoid
- // giving max() an empty array
- if ( count( $files ) === 0 ) {
- $this->modifiedTime[$context->getHash()] = 1;
- return $this->modifiedTime[$context->getHash()];
- }
-
- $filesMtime = max( array_map( array( __CLASS__, 'safeFilemtime' ), $files ) );
-
- $this->modifiedTime[$context->getHash()] = max(
- $filesMtime,
- $this->getMsgBlobMtime( $context->getLanguage() ),
- $this->getDefinitionMtime( $context )
- );
-
- return $this->modifiedTime[$context->getHash()];
+ // 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 );
}
/**
*/
public function getDefinitionSummary( ResourceLoaderContext $context ) {
$summary = parent::getDefinitionSummary( $context );
+
+ $options = array();
foreach ( array(
'scripts',
'debugScripts',
'group',
'position',
'skipFunction',
+ // FIXME: localBasePath includes the MediaWiki installation path and
+ // needlessly causes cache invalidation.
'localBasePath',
'remoteBasePath',
'debugRaw',
'raw',
) as $member ) {
- $summary[$member] = $this->{$member};
+ $options[$member] = $this->{$member};
};
+
+ $summary[] = array(
+ 'options' => $options,
+ 'fileMtimes' => $this->getFileMTimes( $context ),
+ 'msgBlobMtime' => $this->getMsgBlobMtime( $context->getLanguage() ),
+ );
return $summary;
}
- /* Protected Methods */
-
/**
* @param string|ResourceLoaderFilePath $path
* @return string