X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fresourceloader%2FResourceLoaderModule.php;h=3dd7a4b0e2998d96c4e6ed804a58ee6794d1e0e2;hb=9435cd81b07f94a8283d23aff8835c9c734f05db;hp=80c82205502014c7e3399a1fcd039cc0f18cd555;hpb=f2244f61f447c3a6556169e3d177e64d2e496a40;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/resourceloader/ResourceLoaderModule.php b/includes/resourceloader/ResourceLoaderModule.php index 80c8220550..3dd7a4b0e2 100644 --- a/includes/resourceloader/ResourceLoaderModule.php +++ b/includes/resourceloader/ResourceLoaderModule.php @@ -67,10 +67,6 @@ abstract class ResourceLoaderModule { // In-object cache for module content protected $contents = array(); - // Whether the position returned by getPosition() is defined in the module configuration - // and not a default value - protected $isPositionDefined = false; - /** * @var Config */ @@ -291,19 +287,6 @@ abstract class ResourceLoaderModule { return 'bottom'; } - /** - * Whether the position returned by getPosition() is a default value or comes from the module - * definition. This method is meant to be short-lived, and is only useful until classes added - * via addModuleStyles with a default value define an explicit position. See getModuleStyles() - * in OutputPage for the related migration warning. - * - * @return bool - * @since 1.26 - */ - public function isPositionDefault() { - return !$this->isPositionDefined; - } - /** * Whether this module's JS expects to work without the client-side ResourceLoader module. * Returning true from this function will prevent mw.loader.state() call from being @@ -377,32 +360,33 @@ abstract class ResourceLoaderModule { * * These are only image files referenced by the module's stylesheet. * - * @param string $skin Skin name + * @param ResourceLoaderContext $context * @return array List of files */ - protected function getFileDependencies( $skin ) { - // Try in-object cache first - if ( isset( $this->fileDeps[$skin] ) ) { - return $this->fileDeps[$skin]; - } + protected function getFileDependencies( ResourceLoaderContext $context ) { + $vary = $context->getSkin() . '|' . $context->getLanguage(); - $dbr = wfGetDB( DB_SLAVE ); - $deps = $dbr->selectField( 'module_deps', - 'md_deps', - array( - 'md_module' => $this->getName(), - 'md_skin' => $skin, - ), - __METHOD__ - ); + // Try in-object cache first + if ( !isset( $this->fileDeps[$vary] ) ) { + $dbr = wfGetDB( DB_SLAVE ); + $deps = $dbr->selectField( 'module_deps', + 'md_deps', + array( + 'md_module' => $this->getName(), + 'md_skin' => $vary, + ), + __METHOD__ + ); - if ( !is_null( $deps ) ) { - $this->fileDeps[$skin] = (array)FormatJson::decode( $deps, true ); - } else { - $this->fileDeps[$skin] = array(); + if ( !is_null( $deps ) ) { + $this->fileDeps[$vary] = self::expandRelativePaths( + (array)FormatJson::decode( $deps, true ) + ); + } else { + $this->fileDeps[$vary] = array(); + } } - - return $this->fileDeps[$skin]; + return $this->fileDeps[$vary]; } /** @@ -414,27 +398,34 @@ abstract class ResourceLoaderModule { * @param string $skin Skin name * @param array $deps Array of file names */ - public function setFileDependencies( $skin, $deps ) { - $this->fileDeps[$skin] = $deps; + public function setFileDependencies( ResourceLoaderContext $context, $files ) { + $vary = $context->getSkin() . '|' . $context->getLanguage(); + $this->fileDeps[$vary] = $files; } /** * Set the files this module depends on indirectly for a given skin. * - * @since 1.26 - * @param string $skin Skin name + * @since 1.27 + * @param ResourceLoaderContext $context * @param array $localFileRefs List of files */ - protected function saveFileDependencies( $skin, $localFileRefs ) { + protected function saveFileDependencies( ResourceLoaderContext $context, $localFileRefs ) { + // Normalise array + $localFileRefs = array_values( array_unique( $localFileRefs ) ); + sort( $localFileRefs ); + try { // If the list has been modified since last time we cached it, update the cache - if ( $localFileRefs !== $this->getFileDependencies( $skin ) ) { + if ( $localFileRefs !== $this->getFileDependencies( $context ) ) { + $vary = $context->getSkin() . '|' . $context->getLanguage(); $dbw = wfGetDB( DB_MASTER ); $dbw->replace( 'module_deps', array( array( 'md_module', 'md_skin' ) ), array( 'md_module' => $this->getName(), - 'md_skin' => $skin, - 'md_deps' => FormatJson::encode( $localFileRefs ), + 'md_skin' => $vary, + // Use relative paths to avoid ghost entries when $IP changes (T111481) + 'md_deps' => FormatJson::encode( self::getRelativePaths( $localFileRefs ) ), ) ); } @@ -443,6 +434,37 @@ abstract class ResourceLoaderModule { } } + /** + * Make file paths relative to MediaWiki directory. + * + * This is used to make file paths safe for storing in a database without the paths + * becoming stale or incorrect when MediaWiki is moved or upgraded (T111481). + * + * @since 1.27 + * @param array $filePaths + * @return array + */ + public static function getRelativePaths( Array $filePaths ) { + global $IP; + return array_map( function ( $path ) use ( $IP ) { + return RelPath\getRelativePath( $path, $IP ); + }, $filePaths ); + } + + /** + * Expand directories relative to $IP. + * + * @since 1.27 + * @param array $filePaths + * @return array + */ + public static function expandRelativePaths( Array $filePaths ) { + global $IP; + return array_map( function ( $path ) use ( $IP ) { + return RelPath\joinPath( $IP, $path ); + }, $filePaths ); + } + /** * Get the last modification timestamp of the messages in this module for a given language. * @param string $lang Language code @@ -485,6 +507,17 @@ abstract class ResourceLoaderModule { $this->msgBlobMtime[$lang] = $mtime; } + /** + * Get module-specific LESS variables, if any. + * + * @since 1.27 + * @param ResourceLoaderContext $context + * @return array Module-specific LESS variables. + */ + protected function getLessVars( ResourceLoaderContext $context ) { + return array(); + } + /** * Get an array of this module's resources. Ready for serving to the web. * @@ -569,11 +602,11 @@ abstract class ResourceLoaderModule { foreach ( $style as $cssText ) { if ( is_string( $cssText ) ) { $stylePairs[$media][] = - $rl->filter( 'minify-css', $cssText ); + ResourceLoader::filter( 'minify-css', $cssText ); } } } elseif ( is_string( $style ) ) { - $stylePairs[$media] = $rl->filter( 'minify-css', $style ); + $stylePairs[$media] = ResourceLoader::filter( 'minify-css', $style ); } } } @@ -824,14 +857,13 @@ abstract class ResourceLoaderModule { protected function validateScriptFile( $fileName, $contents ) { if ( $this->getConfig()->get( 'ResourceLoaderValidateJS' ) ) { // Try for cache hit - // Use CACHE_ANYTHING since parsing JS is much slower than a DB query - $key = wfMemcKey( + $cache = ObjectCache::getLocalClusterInstance(); + $key = $cache->makeKey( 'resourceloader', 'jsparse', self::$parseCacheVersion, md5( $contents ) ); - $cache = wfGetCache( CACHE_ANYTHING ); $cacheEntry = $cache->get( $key ); if ( is_string( $cacheEntry ) ) { return $cacheEntry;