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'] );
202 $params[
'physicalHeight'] = File::scaleHeight( $srcWidth, $srcHeight,
$wgSVGMaxSize );
205 $srcWidth = $image->getWidth( $params[
'page'] );
206 $srcHeight = $image->getHeight( $params[
'page'] );
207 $params[
'physicalWidth'] = File::scaleHeight( $srcHeight, $srcWidth,
$wgSVGMaxSize );
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...
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