);
}
+ $renderLangOptions = $this->displayImg->getAvailableLanguages();
+ if ( count( $renderLangOptions ) >= 1 ) {
+ $currentLanguage = $renderLang;
+ $defaultLang = $this->displayImg->getDefaultRenderLanguage();
+ if ( is_null( $currentLanguage ) ) {
+ $currentLanguage = $defaultLang;
+ }
+ $out->addHtml( $this->doRenderLangOpt( $renderLangOptions, $currentLanguage, $defaultLang ) );
+ }
+
// Add cannot animate thumbnail warning
if ( !$this->displayImg->canAnimateThumbIfAppropriate() ) {
// Include the extension so wiki admins can
? $wgImageLimits[$option]
: array( 800, 600 ); // if nothing is set, fallback to a hardcoded default
}
+
+ /**
+ * Output a drop-down box for language options for the file
+ *
+ * @param Array $langChoices Array of string language codes
+ * @param String $curLang Language code file is being viewed in.
+ * @param String $defaultLang Language code that image is rendered in by default
+ * @return String HTML to insert underneath image.
+ */
+ protected function doRenderLangOpt( array $langChoices, $curLang, $defaultLang ) {
+ global $wgScript;
+ sort( $langChoices );
+ $curLang = wfBCP47( $curLang );
+ $defaultLang = wfBCP47( $defaultLang );
+ $opts = '';
+ $haveCurrentLang = false;
+ $haveDefaultLang = false;
+
+ // We make a list of all the language choices in the file.
+ // Additionally if the default language to render this file
+ // is not included as being in this file (for example, in svgs
+ // usually the fallback content is the english content) also
+ // include a choice for that. Last of all, if we're viewing
+ // the file in a language not on the list, add it as a choice.
+ foreach ( $langChoices as $lang ) {
+ $code = wfBCP47( $lang );
+ $name = Language::fetchLanguageName( $code, $this->getContext()->getLanguage()->getCode() );
+ if ( $name !== '' ) {
+ $display = wfMessage( 'img-lang-opt', $code, $name )->text();
+ } else {
+ $display = $code;
+ }
+ $opts .= "\n" . XML::Option( $display, $code, $curLang === $code );
+ if ( $curLang === $code ) {
+ $haveCurrentLang = true;
+ }
+ if ( $defaultLang === $code ) {
+ $haveDefaultLang = true;
+ }
+ }
+ if ( !$haveDefaultLang ) {
+ // Its hard to know if the content is really in the default language, or
+ // if its just unmarked content that could be in any language.
+ $opts = XML::Option( wfMessage( 'img-lang-default' )->text(), '', $defaultLang === $curLang ) . $opts;
+ }
+ if ( !$haveCurrentLang && $defaultLang !== $curLang ) {
+ $name = Language::fetchLanguageName( $curLang, $this->getContext()->getLanguage()->getCode() );
+ if ( $name !== '' ) {
+ $display = wfMessage( 'img-lang-opt', $curLang, $name )->text();
+ } else {
+ $display = $curLang;
+ }
+ $opts = XML::Option( $display, $curLang, true ) . $opts;
+ }
+
+ $select = Html::rawElement( 'select', array( 'id' => 'mw-imglangselector', 'name' => 'lang' ), $opts );
+ $submit = Xml::submitButton( wfMessage( 'img-lang-go' )->text() );
+
+ $formContents = wfMessage( 'img-lang-info' )->rawParams( $select, $submit )->parse()
+ . Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() );
+
+ $langSelectLine = Html::rawElement( 'div', array( 'id' => 'mw-imglangselector-line' ),
+ Html::rawElement( 'form', array( 'action' => $wgScript ), $formContents )
+ );
+ return $langSelectLine;
+ }
}
/**
}
}
+ /**
+ * Gives a (possibly empty) list of languages to render
+ * the file in.
+ *
+ * If the file doesn't have translations, or if the file
+ * format does not support that sort of thing, returns
+ * an empty array.
+ *
+ * @return Array
+ * @since 1.23
+ */
+ public function getAvailableLanguages() {
+ $handler = $this->getHandler();
+ if ( $handler ) {
+ return $handler->getAvailableLanguages( $this );
+ } else {
+ return array();
+ }
+ }
+
+ /**
+ * In files that support multiple language, what is the default language
+ * to use if none specified.
+ *
+ * @return String lang code, or null if filetype doesn't support multiple languages.
+ * @since 1.23
+ */
+ public function getDefaultRenderLanguage() {
+ $handler = $this->getHandler();
+ if ( $handler ) {
+ return $handler->getDefaultRenderLanguage( $this );
+ } else {
+ return null;
+ }
+ }
+
/**
* Will the thumbnail be animated if one would expect it to be.
*
*/
class BmpHandler extends BitmapHandler {
/**
- * @param $file
+ * @param File $file
* @return bool
*/
function mustRender( $file ) {
/**
* Render files as PNG
*
- * @param $text
- * @param $mime
- * @param $params
+ * @param string $text
+ * @param string $mime
+ * @param array $params
* @return array
*/
function getThumbType( $text, $mime, $params = null ) {
* Get width and height from the bmp header.
*
* @param $image
- * @param $filename
+ * @param string $filename
* @return array
*/
function getImageSize( $image, $filename ) {
*/
class BitmapHandler extends ImageHandler {
/**
- * @param $image File
+ * @param File $image
* @param array $params Transform parameters. Entries with the keys 'width'
* and 'height' are the respective screen width and height, while the keys
* 'physicalWidth' and 'physicalHeight' indicate the thumbnail dimensions.
}
/**
- * @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 MediaTransformError|ThumbnailImage|TransformParameterError
*/
switch ( $scaler ) {
case 'hookaborted':
# Handled by the hook above
+ /** @var MediaTransformOutput $mto */
$err = $mto->isError() ? $mto : false;
break;
case 'im':
* Returns which scaler type should be used. Creates parent directories
* for $dstPath and returns 'client' on error
*
- * @return string client,im,custom,gd
+ * @param string $dstPath
+ * @param bool $checkDstPath
+ * @return string One of client, im, custom, gd, imext
*/
protected static function getScalerType( $dstPath, $checkDstPath = true ) {
global $wgUseImageResize, $wgUseImageMagick, $wgCustomConvertCommand;
* Get a ThumbnailImage that respresents an image that will be scaled
* client side
*
- * @param $image File File associated with this thumbnail
+ * @param File $image File associated with this thumbnail
* @param array $scalerParams Array with scaler params
* @return ThumbnailImage
*
- * @todo fixme: no rotation support
+ * @todo FIXME: No rotation support
*/
protected function getClientScalingThumbnailImage( $image, $scalerParams ) {
$params = array(
/**
* Transform an image using ImageMagick
*
- * @param $image File File associated with this thumbnail
+ * @param File $image File associated with this thumbnail
* @param array $params Array with scaler params
*
* @return MediaTransformError Error object if error occurred, false (=no error) otherwise
/**
* Transform an image using the Imagick PHP extension
*
- * @param $image File File associated with this thumbnail
+ * @param File $image File associated with this thumbnail
* @param array $params Array with scaler params
*
* @return MediaTransformError Error object if error occurred, false (=no error) otherwise
/**
* Transform an image using a custom command
*
- * @param $image File File associated with this thumbnail
+ * @param File $image File associated with this thumbnail
* @param array $params Array with scaler params
*
* @return MediaTransformError Error object if error occurred, false (=no error) otherwise
return false; # No error
}
- /**
- * Log an error that occurred in an external process
- *
- * @param $retval int
- * @param $err int
- * @param $cmd string
- */
- protected function logErrorForExternalProcess( $retval, $err, $cmd ) {
- wfDebugLog( 'thumbnail',
- sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"',
- wfHostname(), $retval, trim( $err ), $cmd ) );
- }
-
/**
* Get a MediaTransformError with error 'thumbnail_error'
*
/**
* Transform an image using the built in GD library
*
- * @param $image File File associated with this thumbnail
+ * @param File $image File associated with this thumbnail
* @param array $params Array with scaler params
*
* @return MediaTransformError Error object if error occurred, false (=no error) otherwise
/**
* Escape a string for ImageMagick's property input (e.g. -set -comment)
* See InterpretImageProperties() in magick/property.c
- * @return mixed|string
+ * @param string $s
+ * @return string
*/
function escapeMagickProperty( $s ) {
// Double the backslashes
/**
* Escape a string for ImageMagick's output filename. See
* InterpretImageFilename() in magick/image.c.
+ * @param string $path The file path
+ * @param bool|string $scene The scene specification, or false if there is none
* @return string
*/
function escapeMagickOutput( $path, $scene = false ) {
* Retrieve the version of the installed ImageMagick
* You can use PHPs version_compare() to use this value
* Value is cached for one hour.
- * @return String representing the IM version.
+ * @return string Representing the IM version.
*/
protected function getMagickVersion() {
global $wgMemc;
}
/**
- * @param $file File
+ * @param File $file
* @param array $params Rotate parameters.
- * 'rotation' clockwise rotation in degrees, allowed are multiples of 90
+ * 'rotation' clockwise rotation in degrees, allowed are multiples of 90
* @since 1.21
* @return bool
*/
wfDebug( __METHOD__ . ": running ImageMagick: $cmd\n" );
wfProfileIn( 'convert' );
$retval = 0;
+ // @todo FIXME: Undefined variable %env
$err = wfShellExecWithStderr( $cmd, $retval, $env );
wfProfileOut( 'convert' );
if ( $retval !== 0 ) {
* Rerurns whether the file needs to be rendered. Returns true if the
* file requires rotation and we are able to rotate it.
*
- * @param $file File
+ * @param File $file
* @return bool
*/
public function mustRender( $file ) {
* This sort of acts as an intermediary between MediaHandler::getMetadata
* and the various metadata extractors.
*
- * @todo other image formats.
+ * @todo Other image formats.
* @ingroup Media
*/
class BitmapMetadataHandler {
+ /** @var array */
private $metadata = array();
+ /** @var array Metadata priority */
private $metaPriority = array(
20 => array( 'other' ),
40 => array( 'native' ),
120 => array( 'exif' ),
);
+ /** @var string */
private $iptcType = 'iptc-no-hash';
/**
*
* Parameters are passed to the Exif class.
*
- * @param $filename string
- * @param $byteOrder string
+ * @param string $filename
+ * @param string $byteOrder
*/
function getExif( $filename, $byteOrder ) {
global $wgShowEXIF;
* doesn't have a priority, it will be silently discarded.
*
* @param array $metaArray array of metadata values
- * @param string $type type. defaults to other. if two things have the same type they're merged
+ * @param string $type Type. defaults to other. if two things have the same type they're merged
*/
function addMetadata( $metaArray, $type = 'other' ) {
if ( isset( $this->metadata[$type] ) ) {
*
* This function is generally called by the media handlers' getMetadata()
*
- * @return Array metadata array
+ * @return array Metadata array
*/
function getMetadataArray() {
// this seems a bit ugly... This is all so its merged in right order
/** Main entry point for jpeg's.
*
* @param string $filename filename (with full path)
- * @return array metadata result array.
+ * @return array Metadata result array.
* @throws MWException on invalid file.
*/
static function Jpeg( $filename ) {
* merge the png various tEXt chunks to that
* are interesting, but for now it only does XMP
*
- * @param string $filename full path to file
- * @return Array Array for storage in img_metadata.
+ * @param string $filename Full path to file
+ * @return array Array for storage in img_metadata.
*/
public static function PNG( $filename ) {
$showXMP = function_exists( 'xml_parser_create_ns' );
* XMP and image comment.
*
* @param string $filename full path to file
- * @return Array metadata array
+ * @return array Metadata array
*/
public static function GIF( $filename ) {
* but needs some further processing because PHP's exif support
* is stupid...)
*
- * @todo Add XMP support, so this function actually makes
- * sense to put here.
+ * @todo Add XMP support, so this function actually makes sense to put here.
*
* The various exceptions this throws are caught later.
- * @param $filename String
+ * @param string $filename
* @throws MWException
- * @return Array The metadata.
+ * @return array The metadata.
*/
public static function Tiff( $filename ) {
if ( file_exists( $filename ) ) {
* Little Endian or Big Endian. Needed for exif stuff.
*
* @param string $filename The filename
- * @return String 'BE' or 'LE' or false
+ * @return string 'BE' or 'LE' or false
*/
static function getTiffByteOrder( $filename ) {
$fh = fopen( $filename, 'rb' );
}
/**
- * @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 ThumbnailImage|TransformParameterError
*/
}
/**
- * @param $file
+ * @param File $file
* @return bool
*/
function mustRender( $file ) {
}
/**
- * @param $file
+ * @param File $file
* @return bool
*/
function isMultiPage( $file ) {
}
/**
- * @param $name
- * @param $value
+ * @param string $name
+ * @param mixed $value
* @return bool
*/
function validateParam( $name, $value ) {
}
/**
- * @param $params
+ * @param array $params
* @return bool|string
*/
function makeParamString( $params ) {
}
/**
- * @param $str
+ * @param string $str
* @return array|bool
*/
function parseParamString( $str ) {
}
/**
- * @param $params
+ * @param array $params
* @return array
*/
function getScriptParams( $params ) {
}
/**
- * @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 MediaTransformError|ThumbnailImage|TransformParameterError
*/
$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 );
} else {
$params = array(
/**
* Cache an instance of DjVuImage in an Image object, return that instance
*
+ * @param File $image
+ * @param string $path
* @return DjVuImage
*/
function getDjVuImage( $image, $path ) {
/**
* Cache a document tree for the DjVu XML metadata
- * @param $image File
- * @param $gettext Boolean: DOCUMENT (Default: false)
- * @return bool
+ * @param File $image
+ * @param bool $gettext DOCUMENT (Default: false)
+ * @return bool|SimpleXMLElement
*/
function getMetaTree( $image, $gettext = false ) {
- if ( isset( $image->dejaMetaTree ) ) {
+ if ( $gettext && isset( $image->djvuTextTree ) ) {
+ return $image->djvuTextTree;
+ }
+ if ( !$gettext && isset( $image->dejaMetaTree ) ) {
return $image->dejaMetaTree;
}
$image->djvuTextTree = false;
$tree = new SimpleXMLElement( $metadata );
if ( $tree->getName() == 'mw-djvu' ) {
+ /** @var SimpleXMLElement $b */
foreach ( $tree->children() as $b ) {
if ( $b->getName() == 'DjVuTxt' ) {
+ // @todo File::djvuTextTree and File::dejaMetaTree are declared
+ // dynamically. Add a public File::$data to facilitate this?
$image->djvuTextTree = $b;
} elseif ( $b->getName() == 'DjVuXML' ) {
$image->dejaMetaTree = $b;
}
}
+ /**
+ * @param File $image
+ * @param string $path
+ * @return bool|array False on failure
+ */
function getImageSize( $image, $path ) {
return $this->getDjVuImage( $image, $path )->getImageSize();
}
}
}
+ /**
+ * @param File $image
+ * @param int $page Page number to get information for
+ * @return bool|string Page text or false when no text found.
+ */
function getPageText( $image, $page ) {
$tree = $this->getMetaTree( $image, true );
if ( !$tree ) {
* @ingroup Media
*/
class DjVuImage {
+ /**
+ * @const DJVUTXT_MEMORY_LIMIT Memory limit for the DjVu description software
+ */
+ const DJVUTXT_MEMORY_LIMIT = 300000;
+
/**
* Constructor
*
$this->mFilename = $filename;
}
- /**
- * @const DJVUTXT_MEMORY_LIMIT Memory limit for the DjVu description software
- */
- const DJVUTXT_MEMORY_LIMIT = 300000;
-
/**
* Check if the given file is indeed a valid DjVu image file
* @return bool
// @todo FIXME: Would be good to replace this extract() call with
// something that explicitly initializes local variables.
extract( unpack( 'a4magic/a4chunk/NchunkLength', $header ) );
+ /** @var string $chunk
+ * @var string $chunkLength */
echo "$chunk $chunkLength\n";
$this->dumpForm( $file, $chunkLength, 1 );
fclose( $file );
// @todo FIXME: Would be good to replace this extract() call with
// something that explicitly initializes local variables.
extract( unpack( 'a4chunk/NchunkLength', $chunkHeader ) );
+ /** @var string $chunk
+ * @var string $chunkLength */
echo str_repeat( ' ', $indent * 4 ) . "$chunk $chunkLength\n";
if ( $chunk == 'FORM' ) {
// something that explicitly initializes local variables.
extract( unpack( 'a4magic/a4form/NformLength/a4subtype', $header ) );
+ /** @var string $magic
+ * @var string $subtype
+ * @var string $formLength
+ * @var string $formType */
if ( $magic != 'AT&T' ) {
wfDebug( __METHOD__ . ": not a DjVu file\n" );
} elseif ( $subtype == 'DJVU' ) {
// something that explicitly initializes local variables.
extract( unpack( 'a4chunk/Nlength', $header ) );
+ /** @var string $chunk
+ * @var string $length */
return array( $chunk, $length );
}
}
# Newer files have rotation info in byte 10, but we don't use it yet.
+ /** @var string $width
+ * @var string $height
+ * @var string $major
+ * @var string $minor
+ * @var string $resolution
+ * @var string $length
+ * @var string $gamma */
return array(
'width' => $width,
'height' => $height,
/**
* Hack to temporarily work around djvutoxml bug
- * @return bool|string
+ * @param $dump
+ * @return string
*/
function convertDumpToXML( $dump ) {
if ( strval( $dump ) == '' ) {
/** A fake value for things we don't want or don't support. */
const IGNORE = -1;
- //@{
- /* @var array
- * @private
+ /** @var array Exif tags grouped by category, the tagname itself is the key
+ * and the type is the value, in the case of more than one possible value
+ * type they are separated by commas.
*/
+ private $mExifTags;
- /**
- * Exif tags grouped by category, the tagname itself is the key and the type
- * is the value, in the case of more than one possible value type they are
- * separated by commas.
- */
- var $mExifTags;
-
- /**
- * The raw Exif data returned by exif_read_data()
- */
- var $mRawExifData;
+ /** @var array The raw Exif data returned by exif_read_data() */
+ private $mRawExifData;
- /**
- * A Filtered version of $mRawExifData that has been pruned of invalid
- * tags and tags that contain content they shouldn't contain according
- * to the Exif specification
+ /** @var array A Filtered version of $mRawExifData that has been pruned
+ * of invalid tags and tags that contain content they shouldn't contain
+ * according to the Exif specification
*/
- var $mFilteredExifData;
+ private $mFilteredExifData;
- /**
- * Filtered and formatted Exif data, see FormatMetadata::getFormattedData()
- */
- var $mFormattedExifData;
+ /** @var array Filtered and formatted Exif data, see FormatMetadata::getFormattedData() */
+ private $mFormattedExifData;
- //@}
+ /** @var string The file being processed */
+ private $file;
- //@{
- /* @var string
- * @private
- */
+ /** @var string The basename of the file being processed */
+ private $basename;
- /**
- * The file being processed
- */
- var $file;
+ /** @var string The private log to log to, e.g. 'exif' */
+ private $log = false;
- /**
- * The basename of the file being processed
- */
- var $basename;
-
- /**
- * The private log to log to, e.g. 'exif'
- */
- var $log = false;
-
- /**
- * The byte order of the file. Needed because php's
- * extension doesn't fully process some obscure props.
+ /** @var string The byte order of the file. Needed because php's extension
+ * doesn't fully process some obscure props.
*/
private $byteOrder;
- //@}
-
/**
* Constructor
*
- * @param string $file filename.
+ * @param string $file Filename.
* @param string $byteOrder Type of byte ordering either 'BE' (Big Endian)
* or 'LE' (Little Endian). Default ''.
* @throws MWException
* @todo FIXME: The following are broke:
- * SubjectArea. Need to test the more obscure tags.
- *
- * DigitalZoomRatio = 0/0 is rejected. need to determine if that's valid.
- * possibly should treat 0/0 = 0. need to read exif spec on that.
+ * SubjectArea. Need to test the more obscure tags.
+ * DigitalZoomRatio = 0/0 is rejected. need to determine if that's valid.
+ * Possibly should treat 0/0 = 0. need to read exif spec on that.
*/
function __construct( $file, $byteOrder = '' ) {
/**
# Exif IFD Attribute Information (p30-31)
'EXIF' => array(
- # TODO: NOTE: Nonexistence of this field is taken to mean nonconformance
+ # @todo NOTE: Nonexistence of this field is taken to mean nonconformance
# to the Exif 2.1 AND 2.2 standards
'ExifVersion' => Exif::UNDEFINED, # Exif version
'FlashPixVersion' => Exif::UNDEFINED, # Supported Flashpix version #p32
* Convert an Exif::UNDEFINED from a raw binary string
* to its value. This is sometimes needed depending on
* the type of UNDEFINED field
- * @param string $prop name of property
+ * @param string $prop Name of property
*/
private function exifPropToOrd( $prop ) {
if ( isset( $this->mFilteredExifData[$prop] ) ) {
/**
* Convert gps in exif form to a single floating point number
* for example 10 degress 20`40`` S -> -10.34444
- * @param string $prop a gps coordinate exif tag name (like GPSLongitude)
+ * @param string $prop A GPS coordinate exif tag name (like GPSLongitude)
*/
private function exifGPStoNumber( $prop ) {
$loc =& $this->mFilteredExifData[$prop];
/**#@+
* Validates if a tag value is of the type it should be according to the Exif spec
*
- * @private
- *
- * @param $in Mixed: the input value to check
+ * @param mixed $in The input value to check
* @return bool
*/
private function isByte( $in ) {
}
/**
- * @param $in
+ * @param mixed $in The input value to check
* @return bool
*/
private function isASCII( $in ) {
}
/**
- * @param $in
+ * @param mixed $in The input value to check
* @return bool
*/
private function isShort( $in ) {
}
/**
- * @param $in
+ * @param mixed $in The input value to check
* @return bool
*/
private function isLong( $in ) {
}
/**
- * @param $in
+ * @param mixed $in The input value to check
* @return bool
*/
private function isRational( $in ) {
}
/**
- * @param $in
+ * @param mixed $in The input value to check
* @return bool
*/
private function isUndefined( $in ) {
}
/**
- * @param $in
+ * @param mixed $in The input value to check
* @return bool
*/
private function isSlong( $in ) {
}
/**
- * @param $in
+ * @param mixed $in The input value to check
* @return bool
*/
private function isSrational( $in ) {
/**
* Validates if a tag has a legal value according to the Exif spec
*
- * @private
* @param string $section section where tag is located.
* @param string $tag the tag to check.
- * @param $val Mixed: the value of the tag.
- * @param $recursive Boolean: true if called recursively for array types.
+ * @param mixed $val The value of the tag.
+ * @param bool $recursive True if called recursively for array types.
* @return bool
*/
private function validate( $section, $tag, $val, $recursive = false ) {
/**
* Convenience function for debugging output
*
- * @private
- *
- * @param $in Mixed:
- * @param $fname String:
- * @param $action Mixed: , default NULL.
+ * @param mixed $in Arrays will be processed with print_r().
+ * @param string $fname Function name to log.
+ * @param string|bool|null $action Default null.
*/
private function debug( $in, $fname, $action = null ) {
if ( !$this->log ) {
/**
* Convenience function for debugging output
*
- * @private
- *
* @param string $fname the name of the function calling this function
- * @param $io Boolean: Specify whether we're beginning or ending
+ * @param bool $io Specify whether we're beginning or ending
*/
private function debugFile( $fname, $io ) {
if ( !$this->log ) {
return $metadata;
}
+ /**
+ * @param $image
+ * @param array $metadata
+ * @return bool|int
+ */
function isMetadataValid( $image, $metadata ) {
global $wgShowEXIF;
if ( !$wgShowEXIF ) {
}
/**
- * @param $image File
+ * @param File $image
* @return array|bool
*/
function formatMetadata( $image ) {
*
* @param string $data
* @return int 0, 90, 180 or 270
- * @todo FIXME orientation can include flipping as well; see if this is an
- * issue!
+ * @todo FIXME: Orientation can include flipping as well; see if this is an issue!
*/
protected function getRotationForExif( $data ) {
if ( !$data ) {
class FormatMetadata extends ContextSource {
/**
* Only output a single language for multi-language fields
- * @var boolean
+ * @var bool
* @since 1.23
*/
protected $singleLang = false;
/**
* Trigger only outputting single language for multilanguage fields
*
- * @param Boolean $val
+ * @param bool $val
* @since 1.23
*/
public function setSingleLanguage( $val ) {
* This is the usual entry point for this class.
*
* @param array $tags the Exif data to format ( as returned by
- * Exif::getFilteredData() or BitmapMetadataHandler )
- * @param IContextSource $context Context to use (optional)
+ * Exif::getFilteredData() or BitmapMetadataHandler )
+ * @param bool|IContextSource $context Context to use (optional)
* @return array
*/
public static function getFormattedData( $tags, $context = false ) {
* formats Exif (and other metadata) values into human readable form.
*
* @param array $tags the Exif data to format ( as returned by
- * Exif::getFilteredData() or BitmapMetadataHandler )
+ * Exif::getFilteredData() or BitmapMetadataHandler )
* @return array
* @since 1.23
*/
/**
* Flatten an array, using the content language for any messages.
*
- * @param array $vals array of values
+ * @param array $vals Array of values
* @param string $type Type of array (either lang, ul, ol).
- * lang = language assoc array with keys being the lang code
- * ul = unordered list, ol = ordered list
- * type can also come from the '_type' member of $vals.
- * @param $noHtml Boolean If to avoid returning anything resembling
- * html. (Ugly hack for backwards compatibility with old mediawiki).
- * @param IContextSource $context
+ * lang = language assoc array with keys being the lang code
+ * ul = unordered list, ol = ordered list
+ * type can also come from the '_type' member of $vals.
+ * @param bool $noHtml If to avoid returning anything resembling HTML.
+ * (Ugly hack for backwards compatibility with old MediaWiki).
+ * @param bool|IContextSource $context
* @return String single value (in wiki-syntax).
* @since 1.23
*/
*
* @param array $vals array of values
* @param string $type Type of array (either lang, ul, ol).
- * lang = language assoc array with keys being the lang code
- * ul = unordered list, ol = ordered list
- * type can also come from the '_type' member of $vals.
- * @param $noHtml Boolean If to avoid returning anything resembling
- * html. (Ugly hack for backwards compatibility with old mediawiki).
- * @param IContextSource $context
- * @return String single value (in wiki-syntax).
+ * lang = language assoc array with keys being the lang code
+ * ul = unordered list, ol = ordered list
+ * type can also come from the '_type' member of $vals.
+ * @param bool $noHtml If to avoid returning anything resembling HTML.
+ * (Ugly hack for backwards compatibility with old MediaWiki).
+ * @param bool|IContextSource $context
+ * @return string Single value (in wiki-syntax).
*/
public static function flattenArray( $vals, $type = 'ul', $noHtml = false, $context = false ) {
$obj = new FormatMetadata;
* lang = language assoc array with keys being the lang code
* ul = unordered list, ol = ordered list
* type can also come from the '_type' member of $vals.
- * @param $noHtml Boolean If to avoid returning anything resembling
- * html. (Ugly hack for backwards compatibility with old mediawiki).
+ * @param $noHtml Boolean If to avoid returning anything resembling HTML.
+ * (Ugly hack for backwards compatibility with old mediawiki).
* @return String single value (in wiki-syntax).
* @since 1.23
*/
*
* @param string $value value (this is not escaped)
* @param string $lang lang code of item or false
- * @param $default Boolean if it is default value.
- * @param $noHtml Boolean If to avoid html (for back-compat)
+ * @param bool $default If it is default value.
+ * @param bool $noHtml If to avoid html (for back-compat)
* @throws MWException
- * @return string language item (Note: despite how this looks,
- * this is treated as wikitext not html).
+ * @return string Language item (Note: despite how this looks, this is
+ * treated as wikitext, not as HTML).
*/
private function langItem( $value, $lang, $default = false, $noHtml = false ) {
if ( $lang === false && $default === false ) {
/**
* Convenience function for getFormattedData()
*
- * @private
- *
- * @param string $tag the tag name to pass on
- * @param string $val the value of the tag
- * @param string $arg an argument to pass ($1)
- * @param string $arg2 a 2nd argument to pass ($2)
+ * @param string $tag The tag name to pass on
+ * @param string $val The value of the tag
+ * @param string $arg An argument to pass ($1)
+ * @param string $arg2 A 2nd argument to pass ($2)
* @return string The text content of "exif-$tag-$val" message in lower case
*/
private function exifMsg( $tag, $val, $arg = null, $arg2 = null ) {
* Format a number, convert numbers from fractions into floating point
* numbers, joins arrays of numbers with commas.
*
- * @param $num Mixed: the value to format
- * @param $round float|int|bool digits to round to or false.
+ * @param mixed $num The value to format
+ * @param float|int|bool $round Digits to round to or false.
* @return mixed A floating point number or whatever we were fed
*/
private function formatNum( $num, $round = false ) {
/**
* Format a rational number, reducing fractions
*
- * @private
- *
- * @param $num Mixed: the value to format
+ * @param mixed $num The value to format
* @return mixed A floating point number or whatever we were fed
*/
private function formatFraction( $num ) {
/**
* Calculate the greatest common divisor of two integers.
*
- * @param $a Integer: Numerator
- * @param $b Integer: Denominator
+ * @param int $a Numerator
+ * @param int $b Denominator
* @return int
* @private
*/
* Format a coordinate value, convert numbers from floating point
* into degree minute second representation.
*
- * @param int $coord degrees, minutes and seconds
- * @param string $type latitude or longitude (for if its a NWS or E)
+ * @param int $coord Degrees, minutes and seconds
+ * @param string $type Latitude or longitude (for if its a NWS or E)
* @return mixed A floating point number or whatever we were fed
*/
private function formatCoords( $coord, $type ) {
/**
* Format the contact info field into a single value.
*
- * @param array $vals array with fields of the ContactInfo
- * struct defined in the IPTC4XMP spec. Or potentially
- * an array with one element that is a free form text
- * value from the older iptc iim 1:118 prop.
- *
* This function might be called from
* JpegHandler::convertMetadataVersion which is why it is
* public.
*
- * @return String of html-ish looking wikitext
+ * @param array $vals Array with fields of the ContactInfo
+ * struct defined in the IPTC4XMP spec. Or potentially
+ * an array with one element that is a free form text
+ * value from the older iptc iim 1:118 prop.
+ * @return string HTML-ish looking wikitext
* @since 1.23 no longer static
*/
public function collapseContactInfo( $vals ) {
private $meta;
/**
- * @param $meta array
+ * @param array $meta
*/
function __construct( $meta ) {
wfDeprecated( __METHOD__, '1.18' );
}
/**
- * @param $image File
+ * @param File $image
* @return array|bool
*/
function formatMetadata( $image ) {
}
/**
- * @param $image File
- * @todo unittests
+ * @todo Add unit tests
+ *
+ * @param File$image
* @return bool
*/
function getImageArea( $image ) {
}
/**
- * @param $image File
+ * @param File $image
* @return bool
*/
function isAnimatedImage( $image ) {
}
/**
- * @param $image File
+ * @param File $image
* @return string
*/
function getLongDesc( $image ) {
/**
* @throws Exception
- * @param $filename string
+ * @param string $filename
* @return array
*/
static function getMetadata( $filename ) {
}
/**
- * @param $fh
- * @param $bpp
+ * @param resource $fh
+ * @param int $bpp
* @return void
*/
static function readGCT( $fh, $bpp ) {
}
/**
- * @param $data
+ * @param string $data
* @throws Exception
* @return int
*/
}
/**
- * @param $fh
+ * @param resource $fh
* @throws Exception
*/
static function skipBlock( $fh ) {
* saying how long the sub-block is, followed by the sub-block.
* The entire block is terminated by a sub-block of length
* 0.
- * @param $fh FileHandle
- * @param $includeLengths Boolean Include the length bytes of the
+ * @param resource $fh File handle
+ * @param bool $includeLengths Include the length bytes of the
* sub-blocks in the returned value. Normally this is false,
* except XMP is weird and does a hack where you need to keep
* these length bytes.
* @see http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf
*
* @param string $rawData app13 block from jpeg containing iptc/iim data
- * @return Array iptc metadata array
+ * @return array IPTC metadata array
*/
static function parse( $rawData ) {
$parsed = iptcparse( $rawData );
* @todo Potentially this should also capture the timezone offset.
* @param array $date The date tag
* @param array $time The time tag
- * @param $c
- * @return String Date in exif format.
+ * @param string $c The charset
+ * @return string Date in EXIF format.
*/
private static function timeHelper( $date, $time, $c ) {
if ( count( $date ) === 1 ) {
/**
* Helper function of a helper function to convert charset for iptc values.
- * @param $data Mixed String or Array: The iptc string
+ * @param string|array $data The IPTC string
* @param string $charset The charset
*
* @return string
*/
abstract class ImageHandler extends MediaHandler {
/**
- * @param $file File
+ * @param File $file
* @return bool
*/
function canRender( $file ) {
}
/**
- * @param $image File
- * @param $params
+ * @param File $image
+ * @param array $params
* @return bool
*/
function normaliseParams( $image, &$params ) {
/**
* Validate thumbnail parameters and fill in the correct height
*
- * @param $width Integer: specified width (input/output)
- * @param $height Integer: height (output only)
- * @param $srcWidth Integer: width of the source image
- * @param $srcHeight Integer: height of the source image
- * @param $mimeType
+ * @param int $width Specified width (input/output)
+ * @param int $height Height (output only)
+ * @param int $srcWidth Width of the source image
+ * @param int $srcHeight Height of the source image
+ * @param string $mimeType Unused
* @return bool False to indicate that an error should be returned to the user.
*/
function validateThumbParams( &$width, &$height, $srcWidth, $srcHeight, $mimeType ) {
}
/**
- * @param $image File
- * @param $script
- * @param $params
- * @return bool|ThumbnailImage
+ * @param File $image
+ * @param string $script
+ * @param array $params
+ * @return bool|MediaTransformOutput
*/
function getScriptedTransform( $image, $script, $params ) {
if ( !$this->normaliseParams( $image, $params ) ) {
}
/**
- * @param $file File
+ * @param File $file
* @return string
*/
function getShortDesc( $file ) {
}
/**
- * @param $file File
+ * @param File $file
* @return string
*/
function getLongDesc( $file ) {
}
/**
- * @param $file File
+ * @param File $file
* @return string
*/
function getDimensionsString( $file ) {
}
/**
- * @param $file File
+ * @param File $file
* @param array $params Rotate parameters.
* 'rotation' clockwise rotation in degrees, allowed are multiples of 90
* @since 1.21
wfDebug( __METHOD__ . ": running jpgtran: $cmd\n" );
wfProfileIn( 'jpegtran' );
$retval = 0;
+ // @todo FIXME Undefined variable $env
$err = wfShellExecWithStderr( $cmd, $retval, $env );
wfProfileOut( 'jpegtran' );
if ( $retval !== 0 ) {
* and those can't extract xmp on files containing both exif and xmp data
*
* @param string $filename name of jpeg file
- * @return Array of interesting segments.
+ * @return array of interesting segments.
* @throws MWException if given invalid file.
*/
static function segmentSplitter( $filename ) {
/**
* Helper function for jpegSegmentSplitter
- * @param &$fh FileHandle for jpeg file
+ * @param resource &$fh File handle for JPEG file
* @throws MWException
- * @return string data content of segment.
+ * @return string Data content of segment.
*/
private static function jpegExtractMarker( &$fh ) {
$size = wfUnpack( "nint", fread( $fh, 2 ), 2 );
*
* @param string $app13 photoshop psir app13 block from jpg.
* @throws MWException (It gets caught next level up though)
- * @return String if the iptc hash is good or not.
+ * @return string If the iptc hash is good or not. One of 'iptc-no-hash',
+ * 'iptc-good-hash', 'iptc-bad-hash'.
*/
public static function doPSIR( $app13 ) {
if ( !$app13 ) {
const METADATA_GOOD = true;
const METADATA_BAD = false;
const METADATA_COMPATIBLE = 2; // for old but backwards compatible.
+ /**
+ * Max length of error logged by logErrorForExternalProcess()
+ */
+ const MAX_ERR_LOG_SIZE = 65535;
/** @var MediaHandler[] Instance cache with array of MediaHandler */
protected static $handlers = array();
* Get a MediaHandler for a given MIME type from the instance cache
*
* @param string $type
- *
* @return MediaHandler
*/
static function getHandler( $type ) {
* If you return false, the parser will do something quiet and forgiving.
*
* @param string $name
- * @param $value
+ * @param mixed $value
*/
abstract function validateParam( $name, $value );
* Changes the parameter array as necessary, ready for transformation.
* Should be idempotent.
* Returns false if the parameters are unacceptable and the transform should fail
- * @param $image
- * @param $params
+ * @param File $image
+ * @param array $params
*/
abstract function normaliseParams( $image, &$params );
*
* @param File $image The image object, or false if there isn't one
* @param string $path the filename
- * @return array Follow the format of PHP getimagesize() internal function. See http://www.php.net/getimagesize
+ * @return array Follow the format of PHP getimagesize() internal function.
+ * See http://www.php.net/getimagesize
*/
abstract function getImageSize( $image, $path );
* By default just returns $metadata, but can be used to allow
* media handlers to convert between metadata versions.
*
- * @param mixed|string|array $metadata Metadata array (serialized if string)
+ * @param string|array $metadata Metadata array (serialized if string)
* @param int $version Target version
* @return array Serialized metadata in specified version, or $metadata on fail.
*/
/**
* Get a string describing the type of metadata, for display purposes.
- * @param $image
+ * @param File $image
* @return string
*/
function getMetadataType( $image ) {
* MediaHandler::METADATA_GOOD for if the metadata is a-ok,
* MediaHanlder::METADATA_COMPATIBLE if metadata is old but backwards
* compatible (which may or may not trigger a metadata reload).
+ * @param File $image
+ * @param array $metadata
* @return bool
*/
function isMetadataValid( $image, $metadata ) {
* this interface, it should return an empty array, not false.
*
* @param File $file
- *
* @return array|bool False if interface not supported
* @since 1.23
*/
* Used when the repository has a thumbnailScriptUrl option configured.
*
* Return false to fall back to the regular getTransform().
- * @return bool
+ * @param File $image
+ * @param string $script
+ * @param array $params
+ * @return bool|ThumbnailImage
*/
function getScriptedTransform( $image, $script, $params ) {
return false;
* actually do the transform.
*
* @param File $image The image object
- * @param string $dstPath filesystem destination path
+ * @param string $dstPath Filesystem destination path
* @param string $dstUrl Destination URL to use in output HTML
* @param array $params Arbitrary set of parameters validated by $this->validateParam()
* @return MediaTransformOutput
* transform unless $flags contains self::TRANSFORM_LATER.
*
* @param File $image The image object
- * @param string $dstPath filesystem destination path
- * @param string $dstUrl destination URL to use in output HTML
- * @param array $params arbitrary set of parameters validated by $this->validateParam()
+ * @param string $dstPath Filesystem destination path
+ * @param string $dstUrl Destination URL to use in output HTML
+ * @param array $params Arbitrary set of parameters validated by $this->validateParam()
* Note: These parameters have *not* gone through $this->normaliseParams()
* @param int $flags A bitfield, may contain self::TRANSFORM_LATER
- *
* @return MediaTransformOutput
*/
abstract function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 );
* Get the thumbnail extension and MIME type for a given source MIME type
*
* @param string $ext Extension of original file
- * @param string $mime Mime type of original file
+ * @param string $mime MIME type of original file
* @param array $params Handler specific rendering parameters
* @return array thumbnail extension and MIME type
*/
/**
* Get useful response headers for GET/HEAD requests for a file with the given metadata
+ *
* @param mixed $metadata Result of the getMetadata() function of this handler for a file
* @return array
*/
/**
* True if the handled types can be transformed
+ *
+ * @param File $file
* @return bool
*/
function canRender( $file ) {
/**
* True if handled types cannot be displayed directly in a browser
* but can be rendered
+ *
+ * @param File $file
* @return bool
*/
function mustRender( $file ) {
/**
* True if the type has multi-page capabilities
+ *
+ * @param File $file
* @return bool
*/
function isMultiPage( $file ) {
/**
* Page count for a multi-page document, false if unsupported or unknown
+ *
+ * @param File $file
* @return bool
*/
function pageCount( $file ) {
/**
* The material is vectorized and thus scaling is lossless
+ *
+ * @param File $file
* @return bool
*/
function isVectorized( $file ) {
* The material is an image, and is animated.
* In particular, video material need not return true.
* @note Before 1.20, this was a method of ImageHandler only
+ *
+ * @param File $file
* @return bool
*/
function isAnimatedImage( $file ) {
/**
* If the material is animated, we can animate the thumbnail
* @since 1.20
+ *
+ * @param File $file
* @return bool If material is not animated, handler may return any value.
*/
function canAnimateThumbnail( $file ) {
/**
* Generic getter for text layer.
* Currently overloaded by PDF and DjVu handlers
- * @return bool
+ * @param File $image
+ * @param int $page Page number to get information for
+ * @return bool|string Page text or false when no text found.
*/
function getPageText( $image, $page ) {
return false;
*/
/**
- * @todo FIXME: I don't really like this interface, it's not very flexible
- * I think the media handler should generate HTML instead. It can do
- * all the formatting according to some standard. That makes it possible
- * to do things like visual indication of grouped and chained streams
- * in ogg container files.
- * @return bool
+ * @todo FIXME: This interface is not very flexible. The media handler
+ * should generate HTML instead. It can do all the formatting according
+ * to some standard. That makes it possible to do things like visual
+ * indication of grouped and chained streams in ogg container files.
+ * @param File $image
+ * @return array|bool
*/
function formatMetadata( $image ) {
return false;
*
* This is used by the media handlers that use the FormatMetadata class
*
- * @param array $metadataArray metadata array
+ * @param array $metadataArray Metadata array
* @return array for use displaying metadata.
*/
function formatMetadataHelper( $metadataArray ) {
* the metadata table is collapsed.
*
* @return array of strings
- * @access protected
*/
function visibleMetadataFields() {
return FormatMetadata::getVisibleFields();
* That array is then used to generate the table of metadata values
* on the image page
*
- * @param &$array Array An array containing elements for each type of visibility
- * and each of those elements being an array of metadata items. This function adds
- * a value to that array.
+ * @param array &$array An array containing elements for each type of visibility
+ * and each of those elements being an array of metadata items. This function adds
+ * a value to that array.
* @param string $visibility ('visible' or 'collapsed') if this value is hidden
- * by default.
- * @param string $type type of metadata tag (currently always 'exif')
- * @param string $id the name of the metadata tag (like 'artist' for example).
- * its name in the table displayed is the message "$type-$id" (Ex exif-artist ).
- * @param string $value thingy goes into a wikitext table; it used to be escaped but
- * that was incompatible with previous practise of customized display
- * with wikitext formatting via messages such as 'exif-model-value'.
- * So the escaping is taken back out, but generally this seems a confusing
- * interface.
- * @param string $param value to pass to the message for the name of the field
- * as $1. Currently this parameter doesn't seem to ever be used.
+ * by default.
+ * @param string $type Type of metadata tag (currently always 'exif')
+ * @param string $id The name of the metadata tag (like 'artist' for example).
+ * its name in the table displayed is the message "$type-$id" (Ex exif-artist ).
+ * @param string $value Thingy goes into a wikitext table; it used to be escaped but
+ * that was incompatible with previous practise of customized display
+ * with wikitext formatting via messages such as 'exif-model-value'.
+ * So the escaping is taken back out, but generally this seems a confusing
+ * interface.
+ * @param bool|string $param Value to pass to the message for the name of the field
+ * as $1. Currently this parameter doesn't seem to ever be used.
*
* Note, everything here is passed through the parser later on (!)
*/
/**
* Used instead of getLongDesc if there is no handler registered for file.
*
- * @param $file File
+ * @param File $file
* @return string
*/
function getShortDesc( $file ) {
/**
* Short description. Shown on Special:Search results.
*
- * @param $file File
+ * @param File $file
* @return string
*/
function getLongDesc( $file ) {
/**
* Long description. Shown under image on image description page surounded by ().
*
- * @param $file File
+ * @param File $file
* @return string
*/
static function getGeneralShortDesc( $file ) {
/**
* Used instead of getShortDesc if there is no handler registered for file.
*
- * @param $file File
+ * @param File $file
* @return string
*/
static function getGeneralLongDesc( $file ) {
/**
* Calculate the largest thumbnail width for a given original file size
* such that the thumbnail's height is at most $maxHeight.
- * @param $boxWidth Integer Width of the thumbnail box.
- * @param $boxHeight Integer Height of the thumbnail box.
- * @param $maxHeight Integer Maximum height expected for the thumbnail.
- * @return Integer.
+ * @param int $boxWidth Width of the thumbnail box.
+ * @param int $boxHeight Height of the thumbnail box.
+ * @param int $maxHeight Maximum height expected for the thumbnail.
+ * @return int
*/
public static function fitBoxWidth( $boxWidth, $boxHeight, $maxHeight ) {
$idealWidth = $boxWidth * $maxHeight / $boxHeight;
*
* For files we don't know, we return 0.
*
- * @param $file File
+ * @param File $file
* @return int 0, 90, 180 or 270
*/
public function getRotation( $file ) {
return 0;
}
+
+ /**
+ * Log an error that occurred in an external process
+ *
+ * Moved from BitmapHandler to MediaHandler with MediaWiki 1.23
+ *
+ * @since 1.23
+ * @param int $retval
+ * @param string $err Error reported by command. Anything longer than
+ * MediaHandler::MAX_ERR_LOG_SIZE is stripped off.
+ * @param string $cmd
+ */
+ protected function logErrorForExternalProcess( $retval, $err, $cmd ) {
+ # Keep error output limited (bug 57985)
+ $errMessage = trim( substr( $err, 0, self::MAX_ERR_LOG_SIZE ) );
+
+ wfDebugLog( 'thumbnail',
+ sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"',
+ wfHostname(), $retval, $errMessage, $cmd ) );
+ }
+
+ /**
+ * Get list of languages file can be viewed in.
+ *
+ * @param File $file
+ * @return Array Array of language codes, or empty array if unsupported.
+ * @since 1.23
+ */
+ public function getAvailableLanguages( File $file ) {
+ return array();
+ }
+
+ /**
+ * On file types that support renderings in multiple languages,
+ * which language is used by default if unspecified.
+ *
+ * If getAvailableLanguages returns a non-empty array, this must return
+ * a valid language code. Otherwise can return null if files of this
+ * type do not support alternative language renderings.
+ *
+ * @param File $file
+ * @return String language code or null if multi-language not supported for filetype.
+ * @since 1.23
+ */
+ public function getDefaultRenderLanguage( File $file ) {
+ return null;
+ }
}
* @ingroup Media
*/
abstract class MediaTransformOutput {
- /**
- * @var array Associative array mapping optional supplementary image files
- * from pixel density (eg 1.5 or 2) to additional URLs.
+ /** @var array Associative array mapping optional supplementary image files
+ * from pixel density (eg 1.5 or 2) to additional URLs.
*/
public $responsiveUrls = array();
protected $storagePath = false;
/**
- * @return integer Width of the output box
+ * @return int Width of the output box
*/
public function getWidth() {
return $this->width;
}
/**
- * @return integer Height of the output box
+ * @return int Height of the output box
*/
public function getHeight() {
return $this->height;
* thumbnail is to be handled client-side only, or if
* transformation was deferred via TRANSFORM_LATER.
*
- * @return Bool
+ * @return bool
*/
public function hasFile() {
// If TRANSFORM_LATER, $this->path will be false.
* Check if the output thumbnail is the same as the source.
* This can occur if the requested width was bigger than the source.
*
- * @return Bool
+ * @return bool
*/
public function fileIsSource() {
return ( !$this->isError() && $this->path === null );
* Stream the file if there were no errors
*
* @param array $headers Additional HTTP headers to send on success
- * @return Bool success
+ * @return bool Success
*/
public function streamFile( $headers = array() ) {
if ( !$this->path ) {
/**
* Wrap some XHTML text in an anchor tag with the given attributes
*
- * @param $linkAttribs array
- * @param $contents string
- *
+ * @param array $linkAttribs
+ * @param string $contents
* @return string
*/
protected function linkWrap( $linkAttribs, $contents ) {
/**
* @param $title string
- * @param $params string|array Query parameters to add
+ * @param string|array $params Query parameters to add
* @return array
*/
public function getDescLinkAttribs( $title = null, $params = array() ) {
* $parameters should include, as a minimum, (file) 'width' and 'height'.
* It may also include a 'page' parameter for multipage files.
*
- * @param $file File object
+ * @param File $file
* @param string $url URL path to the thumb
- * @param $path String|bool|null: filesystem path to the thumb
+ * @param string|bool $path Filesystem path to the thumb
* @param array $parameters Associative array of parameters
- * @private
*/
function __construct( $file, $url, $path = false, $parameters = array() ) {
# Previous parameters:
* desc-query String, description link query params
* override-width Override width attribute. Should generally not set
* override-height Override height attribute. Should generally not set
+ * no-dimensions Boolean, skip width and height attributes (useful if
+ * set in CSS)
* custom-url-link Custom URL to link to
* custom-title-link Custom Title object to link to
* custom target-link Value of the target attribute, for custom-target-link
$linkAttribs['rel'] = $options['parser-extlink-rel'];
}
} elseif ( !empty( $options['custom-title-link'] ) ) {
+ /** @var Title $title */
$title = $options['custom-title-link'];
$linkAttribs = array(
'href' => $title->getLinkURL(),
$attribs = array(
'alt' => $alt,
'src' => $this->url,
- 'width' => $this->width,
- 'height' => $this->height
);
+ if ( empty( $options['no-dimensions'] ) ) {
+ $attribs['width'] = $this->width;
+ $attribs['height'] = $this->height;
+ }
if ( !empty( $options['valign'] ) ) {
$attribs['style'] = "vertical-align: {$options['valign']}";
}
}
/**
- * @param $image File
+ * @param File $image
* @return array|bool
*/
function formatMetadata( $image ) {
/**
* Get a file type independent array of metadata.
*
- * @param $image File
+ * @param File $image
* @return array The metadata array
*/
public function getCommonMetaArray( File $image ) {
}
/**
- * @param $image File
+ * @param File $image
* @return bool
*/
function isAnimatedImage( $image ) {
/**
* We do not support making APNG thumbnails, so always false
- * @param $image File
+ * @param File $image
* @return bool false
*/
function canAnimateThumbnail( $image ) {
}
/**
- * @param $image File
+ * @param File $image
* @return string
*/
function getLongDesc( $image ) {
/**
* Read a chunk, checking to make sure its not too big.
*
- * @param $fh resource The file handle
- * @param $size Integer size in bytes.
+ * @param resource $fh The file handle
+ * @param int $size Size in bytes.
* @throws Exception if too big.
- * @return String The chunk.
+ * @return string The chunk.
*/
private static function read( $fh, $size ) {
if ( $size > self::MAX_CHUNK_SIZE ) {
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',
}
/**
- * @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 );
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
*/
}
/**
- * @param $image File
- * @param $params
+ * @param File $image
+ * @param array $params
* @return bool
*/
function normaliseParams( $image, &$params ) {
}
/**
- * @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
*/
$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 );
* @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
*/
}
$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 );
}
}
/**
- * @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 ) {
* 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 ) {
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 {
}
/**
- * @param $file File
+ * @param File $file
* @return array|bool
*/
function formatMetadata( $file ) {
return false;
}
- /* TODO: add a formatter
+ /* @todo Add a formatter
$format = new FormatSVG( $metadata );
$formatted = $format->getFormattedData();
*/
/**
* @param string $name Parameter name
- * @param $string $value Parameter value
+ * @param mixed $value Parameter value
* @return bool Validity
*/
function validateParam( $name, $value ) {
}
/**
- * @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 ) {
const DEFAULT_WIDTH = 512;
const DEFAULT_HEIGHT = 512;
const NS_SVG = 'http://www.w3.org/2000/svg';
+ const LANG_PREFIX_MATCH = 1;
+ const LANG_FULL_MATCH = 2;
+ /** @var null|XMLReader */
private $reader = null;
+ /** @var bool */
private $mDebug = false;
+ /** @var array */
private $metadata = array();
+ private $languages = array();
+ private $languagePrefixes = array();
/**
* Constructor
} elseif ( $tag !== '#text' ) {
$this->debug( "Unhandled top-level XML tag $tag" );
- if ( !isset( $this->metadata['animated'] ) ) {
- // Recurse into children of current tag, looking for animation.
- $this->animateFilter( $tag );
- }
+ // Recurse into children of current tag, looking for animation and languages.
+ $this->animateFilterAndLang( $tag );
}
// Goto next element, which is sibling of current (Skip children).
$this->reader->close();
+ $this->metadata['translations'] = $this->languages + $this->languagePrefixes;
+
return true;
}
/**
* Read a textelement from an element
*
- * @param string $name of the element that we are reading from
- * @param string $metafield that we will fill with the result
+ * @param string $name Name of the element that we are reading from
+ * @param string $metafield Field that we will fill with the result
*/
private function readField( $name, $metafield = null ) {
$this->debug( "Read field $metafield" );
/**
* Read an XML snippet from an element
*
- * @param string $metafield that we will fill with the result
+ * @param string $metafield Field that we will fill with the result
* @throws MWException
*/
private function readXml( $metafield = null ) {
if ( !$metafield || $this->reader->nodeType != XmlReader::ELEMENT ) {
return;
}
- // TODO: find and store type of xml snippet. metadata['metadataType'] = "rdf"
+ // @todo Find and store type of xml snippet. metadata['metadataType'] = "rdf"
if ( method_exists( $this->reader, 'readInnerXML' ) ) {
$this->metadata[$metafield] = trim( $this->reader->readInnerXML() );
} else {
}
/**
- * Filter all children, looking for animate elements
+ * Filter all children, looking for animated elements.
+ * Also get a list of languages that can be targeted.
*
- * @param string $name of the element that we are reading from
+ * @param string $name Name of the element that we are reading from
*/
- private function animateFilter( $name ) {
+ private function animateFilterAndLang( $name ) {
$this->debug( "animate filter for tag $name" );
if ( $this->reader->nodeType != XmlReader::ELEMENT ) {
return;
&& $this->reader->nodeType == XmlReader::END_ELEMENT
) {
break;
- } elseif ( $this->reader->namespaceURI ==
- self::NS_SVG && $this->reader->nodeType == XmlReader::ELEMENT
+ } elseif ( $this->reader->namespaceURI == self::NS_SVG
+ && $this->reader->nodeType == XmlReader::ELEMENT
) {
+
+ $sysLang = $this->reader->getAttribute( 'systemLanguage' );
+ if ( !is_null( $sysLang ) && $sysLang !== '' ) {
+ // See http://www.w3.org/TR/SVG/struct.html#SystemLanguageAttribute
+ $langList = explode( ',', $sysLang );
+ foreach( $langList as $langItem ) {
+ $langItem = trim( $langItem );
+ if ( Language::isWellFormedLanguageTag( $langItem ) ) {
+ $this->languages[$langItem] = self::LANG_FULL_MATCH;
+ }
+ // Note, the standard says that any prefix should work,
+ // here we do only the initial prefix, since that will catch
+ // 99% of cases, and we are going to compare against fallbacks.
+ // This differs mildly from how the spec says languages should be
+ // handled, however it matches better how the MediaWiki language
+ // preference is generally handled.
+ $dash = strpos( $langItem, '-' );
+ // Intentionally checking both !false and > 0 at the same time.
+ if ( $dash ) {
+ $itemPrefix = substr( $langItem, 0, $dash );
+ if ( Language::isWellFormedLanguageTag( $itemPrefix ) ) {
+ $this->languagePrefixes[$itemPrefix] = self::LANG_PREFIX_MATCH;
+ }
+ }
+ }
+ }
switch ( $this->reader->localName ) {
case 'script':
// Normally we disallow files with
}
}
+ // @todo FIXME: Unused, remove?
private function throwXmlError( $err ) {
$this->debug( "FAILURE: $err" );
wfDebug( "SVGReader XML error: $err\n" );
}
}
+ // @todo FIXME: Unused, remove?
private function warn( $data ) {
wfDebug( "SVGReader: $data\n" );
}
+ // @todo FIXME: Unused, remove?
private function notice( $data ) {
wfDebug( "SVGReader WARN: $data\n" );
}
* http://www.w3.org/TR/SVG11/coords.html#UnitIdentifiers
*
* @param string $length CSS/SVG length.
- * @param $viewportSize : Float optional scale for percentage units...
- * @return float: length in pixels
+ * @param float|int $viewportSize Optional scale for percentage units...
+ * @return float Length in pixels
*/
static function scaleSVGUnit( $length, $viewportSize = 512 ) {
static $unitLength = array(
* InstantCommons will have thumbnails managed from the remote instance,
* so we can skip this check.
*
- * @param $file
- *
+ * @param File $file
* @return bool
*/
function canRender( $file ) {
* Browsers don't support TIFF inline generally...
* For inline display, we need to convert to PNG.
*
- * @param $file
- *
+ * @param File $file
* @return bool
*/
function mustRender( $file ) {
}
/**
- * @param $ext
- * @param $mime
- * @param $params
+ * @param string $ext
+ * @param string $mime
+ * @param array $params
* @return bool
*/
function getThumbType( $ext, $mime, $params = null ) {
*/
class XCFHandler extends BitmapHandler {
/**
- * @param $file
+ * @param File $file
* @return bool
*/
function mustRender( $file ) {
/**
* Render files as PNG
*
- * @param $ext
- * @param $mime
- * @param $params
+ * @param string $ext
+ * @param string $mime
+ * @param array $params
* @return array
*/
function getThumbType( $ext, $mime, $params = null ) {
/**
* Get width and height from the XCF header.
*
- * @param $image
- * @param $filename
+ * @param File $image
+ * @param string $filename
* @return array
*/
function getImageSize( $image, $filename ) {
/**
* Must use "im" for XCF
*
+ * @param string $dstPath
+ * @param bool $checkDstPath
* @return string
*/
protected static function getScalerType( $dstPath, $checkDstPath = true ) {
*
*/
class XMPReader {
- private $curItem = array(); // array to hold the current element (and previous element, and so on)
+ /** @var array XMP item configuration array */
+ protected $items;
+
+ /** @var array Array to hold the current element (and previous element, and so on) */
+ private $curItem = array();
- private $ancestorStruct = false; // the structure name when processing nested structures.
+ /** @var bool|string The structure name when processing nested structures. */
+ private $ancestorStruct = false;
- private $charContent = false; // temporary holder for character data that appears in xmp doc.
+ /** @var bool|string Temporary holder for character data that appears in xmp doc. */
+ private $charContent = false;
- private $mode = array(); // stores the state the xmpreader is in (see MODE_FOO constants)
+ /** @var array Stores the state the xmpreader is in (see MODE_FOO constants) */
+ private $mode = array();
- private $results = array(); // array to hold results
+ /** @var array Array to hold results */
+ private $results = array();
- private $processingArray = false; // if we're doing a seq or bag.
+ /** @var bool If we're doing a seq or bag. */
+ private $processingArray = false;
- private $itemLang = false; // used for lang alts only
+ /** @var bool|string Used for lang alts only */
+ private $itemLang = false;
+ /** @var resource A resource handle for the XML parser */
private $xmlParser;
+ /** @var bool|string Character set like 'UTF-8' */
private $charset = false;
+ /** @var int */
private $extendedXMPOffset = 0;
- protected $items;
-
/**
* These are various mode constants.
* they are used to figure out what to do
* debug log, blanks result array and returns false.
*
* @param string $content XMP data
- * @param $allOfIt Boolean: If this is all the data (true) or if its split up (false). Default true
- * @param $reset Boolean: does xml parser need to be reset. Default false
+ * @param bool $allOfIt If this is all the data (true) or if its split up (false). Default true
+ * @param bool $reset Does xml parser need to be reset. Default false
* @throws MWException
- * @return Boolean success.
+ * @return bool Success.
*/
public function parse( $content, $allOfIt = true, $reset = false ) {
if ( $reset ) {
* @todo In serious need of testing
* @see http://www.adobe.ge/devnet/xmp/pdfs/XMPSpecificationPart3.pdf XMP spec part 3 page 20
* @param string $content XMPExtended block minus the namespace signature
- * @return Boolean If it succeeded.
+ * @return bool If it succeeded.
*/
public function parseExtended( $content ) {
// @todo FIXME: This is untested. Hard to find example files
* <exif:DigitalZoomRatio>0/10</exif:DigitalZoomRatio>
* and are processing the 0/10 bit.
*
- * @param $parser XMLParser reference to the xml parser
+ * @param XMLParser $parser XMLParser reference to the xml parser
* @param string $data Character data
* @throws MWException on invalid data
*/
* Or it could be if we hit the end element of a property
* of a compound data structure (like a member of an array).
*
- * @param string $elm namespace, space, and tag name.
+ * @param string $elm Namespace, space, and tag name.
*/
private function endElementModeSimple( $elm ) {
if ( $this->charContent !== false ) {
*
* This method is called when we hit the "</exif:ISOSpeedRatings>" tag.
*
- * @param string $elm namespace . space . tag name.
+ * @param string $elm Namespace . space . tag name.
* @throws MWException
*/
private function endElementNested( $elm ) {
* (For comparison, we call endElementModeSimple when we
* hit the "</rdf:li>")
*
- * @param string $elm namespace . ' ' . element name
+ * @param string $elm Namespace . ' ' . element name
* @throws MWException
*/
private function endElementModeLi( $elm ) {
* Qualifiers aren't all that common, and we don't do anything
* with them.
*
- * @param string $elm namespace and element
+ * @param string $elm Namespace and element
*/
private function endElementModeQDesc( $elm ) {
* Ignores the outer wrapping elements that are optional in
* xmp and have no meaning.
*
- * @param $parser XMLParser
- * @param string $elm namespace . ' ' . element name
+ * @param XMLParser $parser
+ * @param string $elm Namespace . ' ' . element name
* @throws MWException
*/
function endElement( $parser, $elm ) {
* in which case we add it to the item stack, so we can ignore things
* that are nested, correctly.
*
- * @param string $elm namespace . ' ' . tag name
+ * @param string $elm Namespace . ' ' . tag name
*/
private function startElementModeIgnore( $elm ) {
if ( $elm === $this->curItem[0] ) {
* Start element in MODE_BAG (unordered array)
* this should always be <rdf:Bag>
*
- * @param string $elm namespace . ' ' . tag
+ * @param string $elm Namespace . ' ' . tag
* @throws MWException if we have an element that's not <rdf:Bag>
*/
private function startElementModeBag( $elm ) {
* Start element in MODE_SEQ (ordered array)
* this should always be <rdf:Seq>
*
- * @param string $elm namespace . ' ' . tag
+ * @param string $elm Namespace . ' ' . tag
* @throws MWException if we have an element that's not <rdf:Seq>
*/
private function startElementModeSeq( $elm ) {
* which are really only used for thumbnails, which
* we don't care about.
*
- * @param string $elm namespace . ' ' . tag
+ * @param string $elm Namespace . ' ' . tag
* @throws MWException if we have an element that's not <rdf:Alt>
*/
private function startElementModeLang( $elm ) {
*
* This method is called when processing the <rdf:Description> element
*
- * @param string $elm namespace and tag names separated by space.
+ * @param string $elm Namespace and tag names separated by space.
* @param array $attribs Attributes of the element.
* @throws MWException
*/
* </exif:DigitalZoomRatio>
* Called when processing the <rdf:value> or <foo:someQualifier>.
*
- * @param string $elm namespace and tag name separated by a space.
+ * @param string $elm Namespace and tag name separated by a space.
*
*/
private function startElementModeQDesc( $elm ) {
* <exif:Flash rdf:parseType='Resource'> <exif:Fired>True</exif:Fired>
* <exif:Mode>1</exif:Mode></exif:Flash>
*
- * @param string $ns namespace
- * @param string $tag tag name (no ns)
- * @param array $attribs array of attribs w/ values.
+ * @param string $ns Namespace
+ * @param string $tag Tag name (no ns)
+ * @param array $attribs Array of attribs w/ values.
* @throws MWException
*/
private function startElementModeStruct( $ns, $tag, $attribs ) {
* </rdf:Seq> </exif:ISOSpeedRatings>
* This method is called when we hit the <rdf:li> element.
*
- * @param string $elm namespace . ' ' . tagname
+ * @param string $elm Namespace . ' ' . tagname
* @param array $attribs Attributes. (needed for BAGSTRUCTS)
* @throws MWException if gets a tag other than <rdf:li>
*/
*
* This method is called when we hit the <rdf:li> element.
*
- * @param string $elm namespace . ' ' . tag
- * @param array $attribs array of elements (most importantly xml:lang)
- * @throws MWException if gets a tag other than <rdf:li> or if no xml:lang
+ * @param string $elm Namespace . ' ' . tag
+ * @param array $attribs Array of elements (most importantly xml:lang)
+ * @throws MWException If gets a tag other than <rdf:li> or if no xml:lang
*/
private function startElementModeLiLang( $elm, $attribs ) {
if ( $elm !== self::NS_RDF . ' li' ) {
* Also does some initial set up for the wrapper element
*
* @param $parser XMLParser
- * @param string $elm namespace "<space>" element
- * @param array $attribs attribute name => value
+ * @param string $elm Namespace "<space>" element
+ * @param array $attribs Attribute name => value
* @throws MWException
*/
function startElement( $parser, $elm, $attribs ) {
* <rdf:Description rdf:about="" xmlns:exif="http://ns.adobe.com/exif/1.0/" exif:DigitalZoomRatio="0/10">
* @endcode
*
- * @param array $attribs attribute=>value array.
+ * @param array $attribs Array attribute=>value
* @throws MWException
*/
// @codingStandardsIgnoreEnd
* $this->processingArray to determine what name to
* save the value under. (in addition to $tag).
*
- * @param string $ns namespace of tag this is for
- * @param string $tag tag name
- * @param string $val value to save
+ * @param string $ns Namespace of tag this is for
+ * @param string $tag Tag name
+ * @param string $val Value to save
*/
private function saveValue( $ns, $tag, $val ) {
* extract.
*/
class XMPInfo {
- /** get the items array
- * @return Array XMP item configuration array.
+ /** Get the items array
+ * @return array XMP item configuration array.
*/
public static function getItems() {
if ( !self::$ranHooks ) {
* * children - for MODE_STRUCT items, allowed children.
* * structPart - Indicates that this element can only appear as a member of a structure.
*
- * currently this just has a bunch of exif values as this class is only half-done
+ * Currently this just has a bunch of exif values as this class is only half-done
*/
static private $items = array(
'http://ns.adobe.com/exif/1.0/' => array(
*/
class XMPValidate {
/**
- * function to validate boolean properties ( True or False )
+ * Function to validate boolean properties ( True or False )
*
- * @param array $info information about current property
- * @param &$val Mixed current value to validate
- * @param $standalone Boolean if this is a simple property or array
+ * @param array $info Information about current property
+ * @param mixed &$val Current value to validate
+ * @param bool $standalone If this is a simple property or array
*/
public static function validateBoolean( $info, &$val, $standalone ) {
if ( !$standalone ) {
/**
* function to validate rational properties ( 12/10 )
*
- * @param array $info information about current property
- * @param &$val Mixed current value to validate
- * @param $standalone Boolean if this is a simple property or array
+ * @param array $info Information about current property
+ * @param mixed &$val Current value to validate
+ * @param bool $standalone If this is a simple property or array
*/
public static function validateRational( $info, &$val, $standalone ) {
if ( !$standalone ) {
* if its outside of range put it into range.
*
* @see MWG spec
- * @param array $info information about current property
- * @param &$val Mixed current value to validate
- * @param $standalone Boolean if this is a simple property or array
+ * @param array $info Information about current property
+ * @param mixed &$val Current value to validate
+ * @param bool $standalone If this is a simple property or array
*/
public static function validateRating( $info, &$val, $standalone ) {
if ( !$standalone ) {
/**
* function to validate integers
*
- * @param array $info information about current property
- * @param &$val Mixed current value to validate
- * @param $standalone Boolean if this is a simple property or array
+ * @param array $info Information about current property
+ * @param mixed &$val Current value to validate
+ * @param bool $standalone If this is a simple property or array
*/
public static function validateInteger( $info, &$val, $standalone ) {
if ( !$standalone ) {
* function to validate properties with a fixed number of allowed
* choices. (closed choice)
*
- * @param array $info information about current property
+ * @param array $info Information about current property
* @param &$val Mixed current value to validate
- * @param $standalone Boolean if this is a simple property or array
+ * @param bool $standalone If this is a simple property or array
*/
public static function validateClosed( $info, &$val, $standalone ) {
if ( !$standalone ) {
/**
* function to validate and modify flash structure
*
- * @param array $info information about current property
+ * @param array $info Information about current property
* @param &$val Mixed current value to validate
- * @param $standalone Boolean if this is a simple property or array
+ * @param bool $standalone If this is a simple property or array
*/
public static function validateFlash( $info, &$val, $standalone ) {
if ( $standalone ) {
* @see rfc 3066
* @see http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart1.pdf page 30 (section 8.2.2.5)
*
- * @param array $info information about current property
+ * @param array $info Information about current property
* @param &$val Mixed current value to validate
- * @param $standalone Boolean if this is a simple property or array
+ * @param bool $standalone If this is a simple property or array
*/
public static function validateLangCode( $info, &$val, $standalone ) {
if ( !$standalone ) {
* YYYY-MM-DDThh:mm:ssTZD
* YYYY-MM-DDThh:mm:ss.sTZD
*
- * @param array $info information about current property
- * @param &$val Mixed current value to validate. Converts to TS_EXIF as a side-effect.
+ * @param array $info Information about current property
+ * @param mixed &$val Current value to validate. Converts to TS_EXIF as a side-effect.
* in cases where there's only a partial date, it will give things like
* 2011:04.
- * @param $standalone Boolean if this is a simple property or array
+ * @param bool $standalone If this is a simple property or array
*/
public static function validateDate( $info, &$val, $standalone ) {
if ( !$standalone ) {
* @see http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart2.pdf
* section 1.2.7.4 on page 23
*
- * @param array $info unused (info about prop)
- * @param &$val String GPS string in either DDD,MM,SSk or
- * or DDD,MM.mmk form
- * @param $standalone Boolean if its a simple prop (should always be true)
+ * @param array $info Unused (info about prop)
+ * @param string &$val GPS string in either DDD,MM,SSk or
+ * or DDD,MM.mmk form
+ * @param bool $standalone If its a simple prop (should always be true)
*/
public static function validateGPS( $info, &$val, $standalone ) {
if ( !$standalone ) {
( $options['underline'] ? 'underline' : 'none' ) . "; }";
} else {
# The scripts of these languages are very hard to read with underlines
- $rules[] = 'a:lang(ar), a:lang(ckb), a:lang(kk-arab), ' .
- 'a:lang(mzn), a:lang(ps), a:lang(ur) { text-decoration: none; }';
+ $rules[] = 'a:lang(ar), a:lang(kk-arab), a:lang(mzn), ' .
+ 'a:lang(ps), a:lang(ur) { text-decoration: none; }';
}
if ( $options['justify'] ) {
$rules[] = "#article, #bodyContent, #mw_content { text-align: justify; }\n";
$pages = array();
foreach ( $user->getEffectiveGroups() as $group ) {
- if ( in_array( $group, array( '*', 'user' ) ) ) {
+ if ( $group == '*' ) {
continue;
}
if ( $wgUseSiteJs ) {
<div id="languagelinks">
<p><?php $this->html( 'languages' ); ?></p>
</div>
+ <?php }
+ if ( !wfMessage( 'signupstart' )->isDisabled() ) { ?>
+ <div id="signupstart"><?php $this->msgWiki( 'signupstart' ); ?></div>
<?php } ?>
<div id="userloginForm">
<h2 class="createaccount-join">
<?php if ( $this->haveData( 'uselang' ) ) { ?><input type="hidden" name="uselang" value="<?php $this->text( 'uselang' ); ?>" /><?php } ?>
<?php if ( $this->haveData( 'token' ) ) { ?><input type="hidden" name="wpCreateaccountToken" value="<?php $this->text( 'token' ); ?>" /><?php } ?>
</form>
+ <?php if ( !wfMessage( 'signupend' )->isDisabled() ) { ?>
+ <div id="signupend"><?php $this->html( 'signupend' ); ?></div>
+ <?php } ?>
</div>
<div class="mw-createacct-benefits-container">
<h2><?php $this->msg( 'createacct-benefit-heading' ); ?></h2>
'print.css' => '/* CSS placed here will affect the print output */', # only translate this message to other languages if you have to change it
'noscript.css' => '/* CSS placed here will affect users with JavaScript disabled */', # only translate this message to other languages if you have to change it
'group-autoconfirmed.css' => '/* CSS placed here will affect autoconfirmed users only */', # only translate this message to other languages if you have to change it
+'group-user.css' => '/* CSS placed here will affect registered users only */', # only translate this message to other languages if you have to change it
'group-bot.css' => '/* CSS placed here will affect bots only */', # only translate this message to other languages if you have to change it
'group-sysop.css' => '/* CSS placed here will affect sysops only */', # only translate this message to other languages if you have to change it
'group-bureaucrat.css' => '/* CSS placed here will affect bureaucrats only */', # only translate this message to other languages if you have to change it
'modern.js' => '/* Any JavaScript here will be loaded for users using the Modern skin */', # only translate this message to other languages if you have to change it
'vector.js' => '/* Any JavaScript here will be loaded for users using the Vector skin */', # only translate this message to other languages if you have to change it
'group-autoconfirmed.js' => '/* Any JavaScript here will be loaded for autoconfirmed users only */', # only translate this message to other languages if you have to change it
+'group-user.js' => '/* Any JavaScript here will be loaded for registered users only */', # only translate this message to other languages if you have to change it
'group-bot.js' => '/* Any JavaScript here will be loaded for bots only */', # only translate this message to other languages if you have to change it
'group-sysop.js' => '/* Any JavaScript here will be loaded for sysops only */', # only translate this message to other languages if you have to change it
'group-bureaucrat.js' => '/* Any JavaScript here will be loaded for bureaucrats only */', # only translate this message to other languages if you have to change it
'imgmultigo' => 'Go!',
'imgmultigoto' => 'Go to page $1',
+'img-lang-opt' => '$2 ($1)',
+'img-lang-default' => '(default language)',
+'img-lang-info' => 'Render this image in $1 $2.',
+'img-lang-go' => 'Go',
+
# Table pager
'ascending_abbrev' => 'asc',
'descending_abbrev' => 'desc',
'print.css' => '{{optional}}',
'noscript.css' => '{{optional}}',
'group-autoconfirmed.css' => '{{doc-group|autoconfirmed|css}}',
+'group-user.css' => '{{doc-group|user|css}}',
'group-bot.css' => '{{doc-group|bot|css}}',
'group-sysop.css' => '{{doc-group|sysop|css}}',
'group-bureaucrat.css' => '{{doc-group|bureaucrat|css}}',
'modern.js' => '{{optional}}',
'vector.js' => '{{optional}}',
'group-autoconfirmed.js' => '{{doc-group|autoconfirmed|js}}',
+'group-user.js' => '{{doc-group|user|js}}',
'group-bot.js' => '{{doc-group|bot|js}}',
'group-sysop.js' => '{{doc-group|sysop|js}}',
'group-bureaucrat.js' => '{{doc-group|bureaucrat|js}}',
See also:
* {{msg-mw|Imgmultigo|Submit button text}}',
+'img-lang-opt' => '{{optional}} Items in the language drop down on the image page for a translated SVG file. For an example see [[:File:Gerrit patchset 25838 test.svg]]. See also {{msg-mw|img-lang-info}}
+
+* $1 Language code
+* $2 Language name (Either in the language in question, or the name of that language translated to the current users interface language)',
+'img-lang-default' => 'An option in the drop down of a translatable file. For example see [[:File:Gerrit patchset 25838 test.svg]]. Used when it cannot be determined what the default fallback language is. However it should be noted that most of the time, the content displayed for this option would be in English.',
+'img-lang-info' => 'Label for drop down box. Appears underneath the image on the image description page. See [[:File:Gerrit patchset 25838 test.svg]] for an example.
+
+* $1 is a drop down box with language options (See also {{msg-mw|img-lang-opt}})
+* $2 is a submit button, which uses the text from {{msg-mw|img-lang-go}}',
+'img-lang-go' => 'Go button for the language select for translatable files. See [[:File:Gerrit patchset 25838 test.svg]] for an example. See {{msg-mw|img-lang-info}}.',
+
# Table pager
'ascending_abbrev' => 'Abbreviation of ascending order.
See also:
'print.css',
'noscript.css',
'group-autoconfirmed.css',
+ 'group-user.css',
'group-bot.css',
'group-sysop.css',
'group-bureaucrat.css',
'modern.js',
'vector.js',
'group-autoconfirmed.js',
+ 'group-user.js',
'group-bot.js',
'group-sysop.js',
'group-bureaucrat.js',
'limitreport-expansiondepth-value',
'limitreport-expensivefunctioncount-value',
'interlanguage-link-title',
+ 'img-lang-opt',
);
/** Exif messages, which may be set as optional in several checks, but are generally mandatory */
'print.css',
'noscript.css',
'group-autoconfirmed.css',
+ 'group-user.css',
'group-bot.css',
'group-sysop.css',
'group-bureaucrat.css',
'modern.js',
'vector.js',
'group-autoconfirmed.js',
+ 'group-user.js',
'group-bot.js',
'group-sysop.js',
'group-bureaucrat.js',
'imgmultigo',
'imgmultigoto',
),
+ 'img-lang' => array(
+ 'img-lang-opt',
+ 'img-lang-default',
+ 'img-lang-info',
+ 'img-lang-go',
+ ),
'tablepager' => array(
'ascending_abbrev',
'descending_abbrev',
'watch-unwatch' => 'action=watch/unwatch',
'separators' => 'Separators for various lists, etc.',
'imgmulti' => 'Multipage image navigation',
+ 'img-lang' => 'Language selector for translatable SVGs',
'tablepager' => 'Table pager',
'autosumm' => 'Auto-summaries',
'autoblock_whitelist' => 'Autoblock whitelist',
Larry Ewing, Simon Budig, Anja Gerwinski
"The copyright holder of this file allows anyone to use it for any purpose, provided that the copyright holder is properly attributed. Redistribution, derivative work, commercial use, and all other use is permitted."
+Speech_bubbles.svg (Modified slightly)
+https://commons.wikimedia.org/wiki/File:Speech_bubbles.svg
+CC-BY-SA 3.0
+Jarry1250
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="17.7cm" height="13cm" id="svg2" version="1.1" inkscape:version="0.48.2 r9819" sodipodi:docname="New document 1">
+ <defs id="defs4"/>
+ <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.7" inkscape:cx="296.43458" inkscape:cy="130.17435" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" inkscape:window-width="1366" inkscape:window-height="706" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1"/>
+ <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-0.28125,-1.21875)">
+ <switch style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><text xml:space="preserve" x="90" y="108.07646" id="text2985-de" sodipodi:linespacing="125%" systemLanguage="de"><tspan text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2987-de">Hallo!</tspan></text><text xml:space="preserve" x="90" y="108.07646" id="text2985-fr" sodipodi:linespacing="125%" systemLanguage="fr"><tspan x="80" y="108.07646" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2987-fr">Bonjour</tspan></text><text xml:space="preserve" x="90" y="108.07646" id="text2985-nl" sodipodi:linespacing="125%" systemLanguage="nl, tlh-ca"><tspan x="90" y="108.07646" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2987-nl">Hallo!</tspan></text><text xml:space="preserve" x="90" y="108.07646" id="text2985" sodipodi:linespacing="125%"><tspan x="90" y="108.07646" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2987" sodipodi:role="line">Hello!</tspan></text></switch>
+ <switch style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><text xml:space="preserve" x="330" y="188.07648" id="text2989-de" sodipodi:linespacing="125%" systemLanguage="de"><tspan x="323" y="188.07648" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2991-de">Hallo! Wie</tspan><tspan x="350" y="238.07648" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2993-de" sodipodi:role="line">geht's?</tspan></text><text xml:space="preserve" x="330" y="188.07648" id="text2989-fr" sodipodi:linespacing="125%" systemLanguage="fr"><tspan x="335" y="188.07648" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2991-fr">Bonjour,</tspan><tspan x="350" y="238.07648" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2993-fr">ça va?</tspan></text><text xml:space="preserve" x="330" y="188.07648" id="text2989-nl" sodipodi:linespacing="125%" systemLanguage="nl, tlh-ca"><tspan x="310" y="188.07648" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2991-nl">Hallo! Hoe</tspan><tspan x="330" y="238.07648" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2993-nl">gaat het?</tspan></text><text xml:space="preserve" x="330" y="188.07648" id="text2989" sodipodi:linespacing="125%"><tspan x="330" y="188.07648" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2991" sodipodi:role="line">Hello! How</tspan><tspan x="330" y="238.07648" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2993" sodipodi:role="line">are you?</tspan></text></switch>
+ <switch style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><text xml:space="preserve" x="101.42857" y="318.64789" id="text2995-fr" sodipodi:linespacing="125%" systemLanguage="fr"><tspan x="82" y="323" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2997-fr">Ça va bien,</tspan><tspan x="117.42857" y="368.64789" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2999-fr">et toi?</tspan></text><text xml:space="preserve" x="101.42857" y="318.64789" id="text2995-nl" sodipodi:linespacing="125%" systemLanguage="nl, tlh-ca"><tspan x="101.42857" y="318.64789" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2997-nl">Goed,</tspan><tspan x="101.42857" y="368.64789" font-size="90%" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2999-nl">met jou?</tspan></text><text xml:space="preserve" x="101.42857" y="318.64789" id="text2995" sodipodi:linespacing="125%"><tspan x="101.42857" y="318.64789" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2997" sodipodi:role="line">I'm well,</tspan><tspan x="101.42857" y="368.64789" text-decoration="normal" font-style="normal" font-weight="normal" id="tspan2999" sodipodi:role="line"> you?</tspan></text></switch>
+ <path style="color:#000000;fill:none;stroke:#808080;stroke-width:8.19999980999999960;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="m 145.41518,24.660714 c -54.439497,0 -98.562501,30.043022 -98.562501,67.125 0,9.936246 3.188468,19.358966 8.875,27.843746 -3.477405,24.25473 -24,58.71875 -24,58.71875 0,0 55.316401,-29.49598 68.544641,-28.55804 2.17169,0.15398 -0.660951,4.01645 -2.044641,0.93304 14.019951,5.22007 30.083661,8.21875 47.187501,8.21875 54.4395,0 98.59375,-30.07427 98.59375,-67.156246 0,-37.081978 -44.15425,-67.125 -98.59375,-67.125 z" id="path3769" inkscape:connector-curvature="0" sodipodi:nodetypes="ssccscsss"/>
+ <path style="color:#000000;fill:none;stroke:#808080;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="m 416.54255,99.214524 c 73.5252,0 133.11712,43.566276 133.11712,97.339926 0,14.40884 -4.3063,28.073 -11.98645,40.37703 4.69653,35.1725 32.41406,85.14978 32.41406,85.14978 0,0 -74.70955,-42.77297 -92.57542,-41.41284 -2.93306,0.22328 0.89266,5.82436 2.76145,1.35303 -18.93514,7.56977 -40.63057,11.91824 -63.73076,11.91824 -73.52523,0 -133.15935,-43.61157 -133.15935,-97.38524 0,-53.77365 59.63412,-97.339926 133.15935,-97.339926 z" id="path3769-1" inkscape:connector-curvature="0" sodipodi:nodetypes="ssccscsss"/>
+ <path style="color:#000000;fill:none;stroke:#808080;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="m 173.1621,250.34923 c -64.02996,0 -115.926026,34.29807 -115.926026,76.63201 0,11.34353 3.750173,22.1008 10.438488,31.7873 -4.090007,27.68997 -28.228023,67.03517 -28.228023,67.03517 0,0 65.061361,-33.67353 80.619991,-32.60275 2.55427,0.17578 -0.77738,4.5853 -2.40483,1.06519 16.4898,5.95939 35.38343,9.38278 55.5004,9.38278 64.02999,0 115.96279,-34.33373 115.96279,-76.66769 0,-42.33394 -51.9328,-76.63201 -115.96279,-76.63201 z" id="path3769-1-7" inkscape:connector-curvature="0" sodipodi:nodetypes="ssccscsss"/>
+ </g>
+</svg>
'height' => 1024,
'originalWidth' => '1024',
'originalHeight' => '1024',
+ 'translations' => array(),
)
),
array(
'height' => 60,
'originalWidth' => '60',
'originalHeight' => '60',
+ 'translations' => array(),
)
),
array(
'height' => 60,
'originalWidth' => '60.0000000',
'originalHeight' => '60.0000000',
+ 'translations' => array(),
)
),
array(
'height' => 385,
'originalWidth' => '385',
'originalHeight' => '385.0004883',
+ 'translations' => array(),
)
),
array(
'originalWidth' => '100%',
'originalHeight' => '100%',
'title' => 'Tux',
+ 'translations' => array(),
'description' => 'For more information see: http://commons.wikimedia.org/wiki/Image:Tux.svg',
)
- )
+ ),
+ array(
+ "$base/Speech_bubbles.svg",
+ array(
+ 'width' => 627,
+ 'height' => 461,
+ 'originalWidth' => '17.7cm',
+ 'originalHeight' => '13cm',
+ 'translations' => array(
+ 'de' => SVGReader::LANG_FULL_MATCH,
+ 'fr' => SVGReader::LANG_FULL_MATCH,
+ 'nl' => SVGReader::LANG_FULL_MATCH,
+ 'tlh-ca' => SVGReader::LANG_FULL_MATCH,
+ 'tlh' => SVGReader::LANG_PREFIX_MATCH
+ ),
+ )
+ ),
);
}
'width' => 959,
'originalWidth' => '958.69',
'originalHeight' => '592.78998',
+ 'translations' => array(),
)
),
);