25use Wikimedia\ScopedCallback;
40 'originalwidth' =>
'ImageWidth',
41 'originalheight' =>
'ImageLength',
42 'description' =>
'ImageDescription',
43 'title' =>
'ObjectName',
49 wfDebug(
"\$wgSVGConverter is invalid, disabling SVG rendering.\n" );
70 # @todo Detect animated SVGs
71 $metadata =
$file->getMetadata();
74 if ( isset( $metadata[
'animated'] ) ) {
75 return $metadata[
'animated'];
95 $metadata =
$file->getMetadata();
99 if ( isset( $metadata[
'translations'] ) ) {
100 foreach ( $metadata[
'translations'] as
$lang => $langType ) {
102 $langList[] = strtolower(
$lang );
107 return array_unique( $langList );
126 foreach ( $svgLanguages as $svgLang ) {
127 if ( strcasecmp( $svgLang, $userPreferredLanguage ) === 0 ) {
130 $trimmedSvgLang = $svgLang;
131 while ( strpos( $trimmedSvgLang,
'-' ) !==
false ) {
132 $trimmedSvgLang = substr( $trimmedSvgLang, 0, strrpos( $trimmedSvgLang,
'-' ) );
133 if ( strcasecmp( $trimmedSvgLang, $userPreferredLanguage ) === 0 ) {
148 return $params[
'lang'] ?? $params[
'targetlang'] ??
'en';
176 if ( parent::normaliseParams( $image, $params ) ) {
196 # Don't make an image bigger than wgMaxSVGSize on the smaller side
197 if ( $params[
'physicalWidth'] <= $params[
'physicalHeight'] ) {
199 $srcWidth = $image->getWidth( $params[
'page'] );
200 $srcHeight = $image->getHeight( $params[
'page'] );
205 $srcWidth = $image->getWidth( $params[
'page'] );
206 $srcHeight = $image->getHeight( $params[
'page'] );
212 if ( isset( $params[
'targetlang'] ) && !$image->getMatchedLanguage( $params[
'targetlang'] ) ) {
213 unset( $params[
'targetlang'] );
227 function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
231 $clientWidth = $params[
'width'];
232 $clientHeight = $params[
'height'];
233 $physicalWidth = $params[
'physicalWidth'];
234 $physicalHeight = $params[
'physicalHeight'];
237 if ( $flags & self::TRANSFORM_LATER ) {
242 if ( isset( $metadata[
'error'] ) ) {
243 $err =
wfMessage(
'svg-long-error', $metadata[
'error'][
'message'] );
250 wfMessage(
'thumbnail_dest_directory' ) );
253 $srcPath = $image->getLocalRefPath();
254 if ( $srcPath ===
false ) {
256 sprintf(
'Thumbnail failed on %s: could not get local copy of "%s"',
260 $params[
'width'], $params[
'height'],
269 $lnPath =
"$tmpDir/" . basename( $srcPath );
270 $ok = mkdir( $tmpDir, 0771 );
273 sprintf(
'Thumbnail failed on %s: could not create temporary directory %s',
276 $params[
'width'], $params[
'height'],
277 wfMessage(
'thumbnail-temp-create' )->text()
280 $ok = symlink( $srcPath, $lnPath );
282 $cleaner =
new ScopedCallback(
function () use ( $tmpDir, $lnPath ) {
283 Wikimedia\suppressWarnings();
286 Wikimedia\restoreWarnings();
290 sprintf(
'Thumbnail failed on %s: could not link %s to %s',
293 $params[
'width'], $params[
'height'],
298 $status = $this->
rasterize( $lnPath, $dstPath, $physicalWidth, $physicalHeight,
$lang );
299 if ( $status ===
true ) {
317 public function rasterize( $srcPath, $dstPath, $width, $height,
$lang =
false ) {
325 if ( !is_callable( $func ) ) {
328 $err = $func( $srcPath,
335 $retval = (bool)$err;
339 [
'$path/',
'$width',
'$height',
'$input',
'$output' ],
343 Shell::escape( $srcPath ),
344 Shell::escape( $dstPath ) ],
349 if (
$lang !==
false ) {
350 $env[
'LANG'] =
$lang;
353 wfDebug( __METHOD__ .
": $cmd\n" );
358 if ( $retval != 0 || $removed ) {
367 $im =
new Imagick( $srcPath );
368 $im->setImageFormat(
'png' );
369 $im->setBackgroundColor(
'transparent' );
370 $im->setImageDepth( 8 );
372 if ( !$im->thumbnailImage( intval( $width ), intval( $height ),
false ) ) {
373 return 'Could not resize image';
375 if ( !$im->writeImage( $dstPath ) ) {
376 return "Could not write to $dstPath";
387 if ( $metadata ===
false &&
$file instanceof
File ) {
388 $metadata =
$file->getMetadata();
392 if ( isset( $metadata[
'width'] ) && isset( $metadata[
'height'] ) ) {
393 return [ $metadata[
'width'], $metadata[
'height'],
'SVG',
394 "width=\"{$metadata['width']}\" height=\"{$metadata['height']}\"" ];
396 return [ 0, 0,
'SVG',
"width=\"0\" height=\"0\"" ];
401 return [
'png',
'image/png' ];
417 if ( isset( $metadata[
'error'] ) ) {
418 return wfMessage(
'svg-long-error', $metadata[
'error'][
'message'] )->text();
424 $msg =
wfMessage(
'svg-long-desc-animated' );
429 $msg->numParams(
$file->getWidth(),
$file->getHeight() )->params( $size );
431 return $msg->parse();
444 $metadata += $svgReader->getMetadata();
445 }
catch ( Exception $e ) {
447 $metadata[
'error'] = [
448 'message' => $e->getMessage(),
449 'code' => $e->getCode()
451 wfDebug( __METHOD__ .
': ' . $e->getMessage() .
"\n" );
458 Wikimedia\suppressWarnings();
460 Wikimedia\restoreWarnings();
461 if ( isset( $unser[
'version'] ) && $unser[
'version'] == self::SVG_METADATA_VERSION ) {
474 if ( $meta ===
false ) {
477 if ( !isset( $meta[
'originalWidth'] ) ) {
486 $fields = [
'objectname',
'imagedescription' ];
501 $metadata =
$file->getMetadata();
506 if ( !$metadata || isset( $metadata[
'error'] ) ) {
519 foreach ( $metadata as $name => $value ) {
520 $tag = strtolower( $name );
521 if ( isset( self::$metaConversion[$tag] ) ) {
522 $tag = strtolower( self::$metaConversion[$tag] );
529 in_array( $tag, $visibleFields ) ?
'visible' :
'collapsed',
536 return $showMeta ? $result :
false;
545 if ( in_array( $name, [
'width',
'height' ] ) ) {
547 return ( $value > 0 );
548 } elseif ( $name ==
'lang' ) {
550 if ( $value ===
'' || !Language::isValidCode( $value ) ) {
568 if ( $code !==
'en' ) {
569 $lang =
'lang' . strtolower( $code ) .
'-';
571 if ( !isset( $params[
'width'] ) ) {
575 return "$lang{$params['width']}px";
580 if ( preg_match(
'/^lang([a-z]+(?:-[a-z]+)*)-(\d+)px$/i', $str, $m ) ) {
581 return [
'width' => array_pop( $m ),
'lang' => $m[1] ];
582 } elseif ( preg_match(
'/^(\d+)px$/', $str, $m ) ) {
583 return [
'width' => $m[1],
'lang' =>
'en' ];
590 return [
'img_lang' =>
'lang',
'img_width' =>
'width' ];
598 $scriptParams = [
'width' => $params[
'width'] ];
599 if ( isset( $params[
'lang'] ) ) {
600 $scriptParams[
'lang'] = $params[
'lang'];
603 return $scriptParams;
607 $metadata =
$file->getMetadata();
612 if ( !$metadata || isset( $metadata[
'error'] ) ) {
616 foreach ( $metadata as $name => $value ) {
617 $tag = strtolower( $name );
618 if ( $tag ===
'originalwidth' || $tag ===
'originalheight' ) {
623 if ( isset( self::$metaConversion[$tag] ) ) {
624 $tag = self::$metaConversion[$tag];
625 $stdMetadata[$tag] = $value;
unserialize( $serialized)
$wgSVGConverter
Pick a converter defined in $wgSVGConverters.
$wgSVGMaxSize
Don't scale a SVG larger than this.
$wgSVGConverterPath
If not in the executable PATH, specify the SVG converter path.
$wgSVGConverters
Scalable Vector Graphics (SVG) may be uploaded as images.
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfTempDir()
Tries to get the system directory for temporary files.
wfRandomString( $length=32)
Get a random string containing a number of pseudo-random hex characters.
wfHostname()
Get host name of the current machine, for use in error reporting.
wfShellExecWithStderr( $cmd, &$retval=null, $environ=[], $limits=[])
Execute a shell command, returning both stdout and stderr.
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
wfMkdirParents( $dir, $mode=null, $caller=null)
Make directory, and make all parent directories if they don't exist.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Implements some public methods and some protected utility functions which are required by multiple ch...
static scaleHeight( $srcWidth, $srcHeight, $dstWidth)
Calculate the height of a thumbnail using the source and destination width.
Media handler abstract base class for images.
validateParam( $name, $value)
isVectorized( $file)
The material is vectorized and thus scaling is lossless.
normaliseParams( $image, &$params)
formatMetadata( $file, $context=false)
parseParamString( $str)
Parse a param string made with makeParamString back into an array.
getMetadata( $file, $filename)
mustRender( $file)
True if handled types cannot be displayed directly in a browser but can be rendered.
getScriptParams( $params)
makeParamString( $params)
getCommonMetaArray(File $file)
Get an array of standard (FormatMetadata type) metadata values.
unpackMetadata( $metadata)
static array $metaConversion
A list of metadata tags that can be converted to the commonly used exif tags.
doTransform( $image, $dstPath, $dstUrl, $params, $flags=0)
getImageSize( $file, $path, $metadata=false)
getLanguageFromParams(array $params)
Determines render language from image parameters.
getAvailableLanguages(File $file)
Which languages (systemLanguage attribute) is supported.
getLongDesc( $file)
Subtitle for the image.
normaliseParamsInternal( $image, $params)
Code taken out of normaliseParams() for testability.
getMetadataType( $image)
Get a string describing the type of metadata, for display purposes.
getThumbType( $ext, $mime, $params=null)
Get the thumbnail extension and MIME type for a given source MIME type.
getDefaultRenderLanguage(File $file)
What language to render file in if none selected.
rasterize( $srcPath, $dstPath, $width, $height, $lang=false)
Transform an SVG file to PNG This function can be called outside of thumbnail contexts.
isEnabled()
False if the handler is disabled for all files.
canAnimateThumbnail( $file)
We do not support making animated svg thumbnails.
visibleMetadataFields()
Get a list of metadata items which should be displayed when the metadata table is collapsed.
static rasterizeImagickExt( $srcPath, $dstPath, $width, $height)
getMatchedLanguage( $userPreferredLanguage, array $svgLanguages)
SVG's systemLanguage matching rules state: 'The systemLanguage attribute ... [e]valuates to "true" if...
const SVG_METADATA_VERSION
isMetadataValid( $image, $metadata)
Check if the metadata string is valid for this handler.
getParamMap()
Get an associative array mapping magic word IDs to parameter names.
Media transform output for images.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
if(!is_readable( $file)) $ext
if(!isset( $args[0])) $lang