Merge "mediawiki.util: Don't hardcode selectors in updateTooltipAccessKeys if possible"
[lhc/web/wiklou.git] / includes / media / SVG.php
index d6f8483..ce7fcbb 100644 (file)
 class SvgHandler extends ImageHandler {
        const SVG_METADATA_VERSION = 2;
 
-       /**
-        * A list of metadata tags that can be converted
-        * to the commonly used exif tags. This allows messages
-        * to be reused, and consistent tag names for {{#formatmetadata:..}}
+       /** @var array A list of metadata tags that can be converted
+        *  to the commonly used exif tags. This allows messages
+        *  to be reused, and consistent tag names for {{#formatmetadata:..}}
         */
        private static $metaConversion = array(
                'originalwidth' => 'ImageWidth',
@@ -45,6 +44,7 @@ class SvgHandler extends ImageHandler {
                global $wgSVGConverters, $wgSVGConverter;
                if ( !isset( $wgSVGConverters[$wgSVGConverter] ) ) {
                        wfDebug( "\$wgSVGConverter is invalid, disabling SVG rendering.\n" );
+
                        return false;
                } else {
                        return true;
@@ -60,11 +60,11 @@ class SvgHandler extends ImageHandler {
        }
 
        /**
-        * @param $file File
+        * @param File $file
         * @return bool
         */
        function isAnimatedImage( $file ) {
-               # TODO: detect animated SVGs
+               # @todo Detect animated SVGs
                $metadata = $file->getMetadata();
                if ( $metadata ) {
                        $metadata = $this->unpackMetadata( $metadata );
@@ -72,9 +72,47 @@ class SvgHandler extends ImageHandler {
                                return $metadata['animated'];
                        }
                }
+
                return false;
        }
 
+       /**
+        * Which languages (systemLanguage attribute) is supported.
+        *
+        * @note This list is not guaranteed to be exhaustive.
+        * To avoid OOM errors, we only look at first bit of a file.
+        * Thus all languages on this list are present in the file,
+        * but its possible for the file to have a language not on
+        * this list.
+        *
+        * @param File $file
+        * @return Array of language codes, or empty if no language switching supported.
+        */
+       public function getAvailableLanguages( File $file ) {
+               $metadata = $file->getMetadata();
+               $langList = array();
+               if ( $metadata ) {
+                       $metadata = $this->unpackMetadata( $metadata );
+                       if ( isset( $metadata['translations'] ) ) {
+                               foreach ( $metadata['translations'] as $lang => $langType ) {
+                                       if ( $langType === SvgReader::LANG_FULL_MATCH ) {
+                                               $langList[] = $lang;
+                                       }
+                               }
+                       }
+               }
+               return $langList;
+       }
+
+       /**
+        * What language to render file in if none selected.
+        *
+        * @return String language code.
+        */
+       public function getDefaultRenderLanguage( File $file ) {
+               return 'en';
+       }
+
        /**
         * We do not support making animated svg thumbnails
         */
@@ -83,8 +121,8 @@ class SvgHandler extends ImageHandler {
        }
 
        /**
-        * @param $image File
-        * @param  $params
+        * @param File $image
+        * @param array $params
         * @return bool
         */
        function normaliseParams( $image, &$params ) {
@@ -108,14 +146,15 @@ class SvgHandler extends ImageHandler {
                                $params['physicalHeight'] = $wgSVGMaxSize;
                        }
                }
+
                return true;
        }
 
        /**
-        * @param $image File
-        * @param  $dstPath
-        * @param  $dstUrl
-        * @param  $params
+        * @param File $image
+        * @param string $dstPath
+        * @param string $dstUrl
+        * @param array $params
         * @param int $flags
         * @return bool|MediaTransformError|ThumbnailImage|TransformParameterError
         */
@@ -127,7 +166,7 @@ class SvgHandler extends ImageHandler {
                $clientHeight = $params['height'];
                $physicalWidth = $params['physicalWidth'];
                $physicalHeight = $params['physicalHeight'];
-               $lang = isset( $params['lang'] ) ? $params['lang'] : 'en';
+               $lang = isset( $params['lang'] ) ? $params['lang'] : $this->getDefaultRenderLanguage( $image );
 
                if ( $flags & self::TRANSFORM_LATER ) {
                        return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
@@ -136,6 +175,7 @@ class SvgHandler extends ImageHandler {
                $metadata = $this->unpackMetadata( $image->getMetadata() );
                if ( isset( $metadata['error'] ) ) { // sanity check
                        $err = wfMessage( 'svg-long-error', $metadata['error']['message'] )->text();
+
                        return new MediaTransformError( 'thumbnail_error', $clientWidth, $clientHeight, $err );
                }
 
@@ -160,7 +200,7 @@ class SvgHandler extends ImageHandler {
         * @param string $dstPath
         * @param string $width
         * @param string $height
-        * @param string $lang Language code of the language to render the SVG in
+        * @param bool|string $lang Language code of the language to render the SVG in
         * @throws MWException
         * @return bool|MediaTransformError
         */
@@ -204,10 +244,10 @@ class SvgHandler extends ImageHandler {
                }
                $removed = $this->removeBadFile( $dstPath, $retval );
                if ( $retval != 0 || $removed ) {
-                       wfDebugLog( 'thumbnail', sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"',
-                                       wfHostname(), $retval, trim( $err ), $cmd ) );
+                       $this->logErrorForExternalProcess( $retval, $err, $cmd );
                        return new MediaTransformError( 'thumbnail_error', $width, $height, $err );
                }
+
                return true;
        }
 
@@ -226,9 +266,9 @@ class SvgHandler extends ImageHandler {
        }
 
        /**
-        * @param $file File
-        * @param  $path
-        * @param bool $metadata
+        * @param File $file
+        * @param string $path Unused
+        * @param bool|array $metadata
         * @return array
         */
        function getImageSize( $file, $path, $metadata = false ) {
@@ -239,7 +279,7 @@ class SvgHandler extends ImageHandler {
 
                if ( isset( $metadata['width'] ) && isset( $metadata['height'] ) ) {
                        return array( $metadata['width'], $metadata['height'], 'SVG',
-                                       "width=\"{$metadata['width']}\" height=\"{$metadata['height']}\"" );
+                               "width=\"{$metadata['width']}\" height=\"{$metadata['height']}\"" );
                } else { // error
                        return array( 0, 0, 'SVG', "width=\"0\" height=\"0\"" );
                }
@@ -255,7 +295,7 @@ class SvgHandler extends ImageHandler {
         * a "nominal" resolution, and not a fixed one,
         * as well as so animation can be denoted.
         *
-        * @param $file File
+        * @param File $file
         * @return string
         */
        function getLongDesc( $file ) {
@@ -279,6 +319,11 @@ class SvgHandler extends ImageHandler {
                return $msg->parse();
        }
 
+       /**
+        * @param File $file
+        * @param string $filename
+        * @return string Serialised metadata
+        */
        function getMetadata( $file, $filename ) {
                $metadata = array( 'version' => self::SVG_METADATA_VERSION );
                try {
@@ -291,6 +336,7 @@ class SvgHandler extends ImageHandler {
                        );
                        wfDebug( __METHOD__ . ': ' . $e->getMessage() . "\n" );
                }
+
                return serialize( $metadata );
        }
 
@@ -318,16 +364,18 @@ class SvgHandler extends ImageHandler {
                        // Old but compatible
                        return self::METADATA_COMPATIBLE;
                }
+
                return self::METADATA_GOOD;
        }
 
-       function visibleMetadataFields() {
+       protected function visibleMetadataFields() {
                $fields = array( 'objectname', 'imagedescription' );
+
                return $fields;
        }
 
        /**
-        * @param $file File
+        * @param File $file
         * @return array|bool
         */
        function formatMetadata( $file ) {
@@ -344,7 +392,7 @@ class SvgHandler extends ImageHandler {
                        return false;
                }
 
-               /* TODO: add a formatter
+               /* @todo Add a formatter
                $format = new FormatSVG( $metadata );
                $formatted = $format->getFormattedData();
                */
@@ -369,12 +417,13 @@ class SvgHandler extends ImageHandler {
                                $value
                        );
                }
+
                return $showMeta ? $result : false;
        }
 
        /**
         * @param string $name Parameter name
-        * @param $string $value Parameter value
+        * @param mixed $value Parameter value
         * @return bool Validity
         */
        function validateParam( $name, $value ) {
@@ -383,12 +432,15 @@ class SvgHandler extends ImageHandler {
                        return ( $value > 0 );
                } elseif ( $name == 'lang' ) {
                        // Validate $code
-                       if ( !Language::isValidBuiltinCode( $value ) ) {
+                       if ( $value === '' || !Language::isValidBuiltinCode( $value ) ) {
                                wfDebug( "Invalid user language code\n" );
+
                                return false;
                        }
+
                        return true;
                }
+
                // Only lang, width and height are acceptable keys
                return false;
        }
@@ -406,6 +458,7 @@ class SvgHandler extends ImageHandler {
                if ( !isset( $params['width'] ) ) {
                        return false;
                }
+
                return "$lang{$params['width']}px";
        }
 
@@ -425,14 +478,16 @@ class SvgHandler extends ImageHandler {
        }
 
        /**
-        * @param $params
+        * @param array $params
         * @return array
         */
        function getScriptParams( $params ) {
-               return array(
-                       'width' => $params['width'],
-                       'lang' => $params['lang'],
-               );
+               $scriptParams = array( 'width' => $params['width'] );
+               if ( isset( $params['lang'] ) ) {
+                       $scriptParams['lang'] = $params['lang'];
+               }
+
+               return $scriptParams;
        }
 
        public function getCommonMetaArray( File $file ) {
@@ -457,6 +512,7 @@ class SvgHandler extends ImageHandler {
                                $stdMetadata[$tag] = $value;
                        }
                }
+
                return $stdMetadata;
        }
 }