resourceloader: Add version to ResourceLoaderImage urls for long-cache
[lhc/web/wiklou.git] / includes / resourceloader / ResourceLoaderImage.php
index 7829b71..3878205 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 /**
- * Class encapsulating an image used in a ResourceLoaderImageModule.
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -25,6 +23,7 @@ use MediaWiki\Shell\Shell;
 /**
  * Class encapsulating an image used in a ResourceLoaderImageModule.
  *
+ * @ingroup ResourceLoader
  * @since 1.25
  */
 class ResourceLoaderImage {
@@ -56,8 +55,9 @@ class ResourceLoaderImage {
        private $extension;
 
        /**
-        * @param string $name Image name
-        * @param string $module Module name
+        * @param string $name Self-name of the image as known to ResourceLoaderImageModule.
+        * @param string $module Self-name of the module containing this image.
+        *  Used to find the image in the registry e.g. through a load.php url.
         * @param string|array $descriptor Path to image file, or array structure containing paths
         * @param string $basePath Directory to which paths in descriptor refer
         * @param array $variants
@@ -95,9 +95,9 @@ class ResourceLoaderImage {
 
                // Ensure that all files have common extension.
                $extensions = [];
-               $descriptor = (array)$this->descriptor;
+               $descriptor = is_array( $this->descriptor ) ? $this->descriptor : [ $this->descriptor ];
                array_walk_recursive( $descriptor, function ( $path ) use ( &$extensions ) {
-                       $extensions[] = pathinfo( $path, PATHINFO_EXTENSION );
+                       $extensions[] = pathinfo( $this->getLocalPath( $path ), PATHINFO_EXTENSION );
                } );
                $extensions = array_unique( $extensions );
                if ( count( $extensions ) !== 1 ) {
@@ -150,31 +150,43 @@ class ResourceLoaderImage {
         */
        public function getPath( ResourceLoaderContext $context ) {
                $desc = $this->descriptor;
-               if ( is_string( $desc ) ) {
-                       return $this->basePath . '/' . $desc;
+               if ( !is_array( $desc ) ) {
+                       return $this->getLocalPath( $desc );
                }
                if ( isset( $desc['lang'] ) ) {
                        $contextLang = $context->getLanguage();
                        if ( isset( $desc['lang'][$contextLang] ) ) {
-                               return $this->basePath . '/' . $desc['lang'][$contextLang];
+                               return $this->getLocalPath( $desc['lang'][$contextLang] );
                        }
                        $fallbacks = Language::getFallbacksFor( $contextLang, Language::STRICT_FALLBACKS );
                        foreach ( $fallbacks as $lang ) {
                                if ( isset( $desc['lang'][$lang] ) ) {
-                                       return $this->basePath . '/' . $desc['lang'][$lang];
+                                       return $this->getLocalPath( $desc['lang'][$lang] );
                                }
                        }
                }
                if ( isset( $desc[$context->getDirection()] ) ) {
-                       return $this->basePath . '/' . $desc[$context->getDirection()];
+                       return $this->getLocalPath( $desc[$context->getDirection()] );
                }
                if ( isset( $desc['default'] ) ) {
-                       return $this->basePath . '/' . $desc['default'];
+                       return $this->getLocalPath( $desc['default'] );
                } else {
                        throw new MWException( 'No matching path found' );
                }
        }
 
+       /**
+        * @param string|ResourceLoaderFilePath $path
+        * @return string
+        */
+       protected function getLocalPath( $path ) {
+               if ( $path instanceof ResourceLoaderFilePath ) {
+                       return $path->getLocalPath();
+               }
+
+               return "{$this->basePath}/$path";
+       }
+
        /**
         * Get the extension of the image.
         *
@@ -206,7 +218,7 @@ class ResourceLoaderImage {
         * @param string $script URL to load.php
         * @param string|null $variant Variant to get the URL for
         * @param string $format Format to get the URL for, 'original' or 'rasterized'
-        * @return string
+        * @return string URL
         */
        public function getUrl( ResourceLoaderContext $context, $script, $variant, $format ) {
                $query = [
@@ -220,7 +232,8 @@ class ResourceLoaderImage {
                }
                // The following parameters are at the end to keep the original order of the parameters.
                $query['skin'] = $context->getSkin();
-               $query['version'] = $context->getVersion();
+               $rl = $context->getResourceLoader();
+               $query['version'] = $rl->makeVersionQuery( $context, [ $this->getModule() ] );
 
                return wfAppendQuery( $script, $query );
        }
@@ -325,6 +338,7 @@ class ResourceLoaderImage {
                // Reattach all direct children of the `<svg>` root node to the `<g>` wrapper
                while ( $root->firstChild ) {
                        $node = $root->firstChild;
+                       // @phan-suppress-next-line PhanUndeclaredProperty False positive
                        if ( !$titleNode && $node->nodeType === XML_ELEMENT_NODE && $node->tagName === 'title' ) {
                                // Remember the first encountered `<title>` node
                                $titleNode = $node;
@@ -425,7 +439,8 @@ class ResourceLoaderImage {
 
                        file_put_contents( $tempFilenameSvg, $svg );
 
-                       $metadata = SVGMetadataExtractor::getMetadata( $tempFilenameSvg );
+                       $svgReader = new SVGReader( $tempFilenameSvg );
+                       $metadata = $svgReader->getMetadata();
                        if ( !isset( $metadata['width'] ) || !isset( $metadata['height'] ) ) {
                                unlink( $tempFilenameSvg );
                                return false;