X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fmedia%2FGeneric.php;h=c3bd102c7a0ab93812e1aea036b07f2272d14811;hb=5c3a804b6ca1657fd0de746fc7dc4dc8ebd1e33f;hp=c21ad79187dea51c5fc09116d46b6850ecbf3e05;hpb=ed4303922f4e850418168595c2a22cdd895081cc;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/media/Generic.php b/includes/media/Generic.php index c21ad79187..c3bd102c7a 100644 --- a/includes/media/Generic.php +++ b/includes/media/Generic.php @@ -1,17 +1,21 @@ validateParam() + * @param $image File: the image object + * @param $dstPath String: filesystem destination path + * @param $dstUrl String: Destination URL to use in output HTML + * @param $params Array: Arbitrary set of parameters validated by $this->validateParam() */ function getTransform( $image, $dstPath, $dstUrl, $params ) { return $this->doTransform( $image, $dstPath, $dstUrl, $params, self::TRANSFORM_LATER ); } /** - * Get a MediaTransformOutput object representing the transformed output. Does the + * Get a MediaTransformOutput object representing the transformed output. Does the * transform unless $flags contains self::TRANSFORM_LATER. * - * @param Image $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 integer $flags A bitfield, may contain self::TRANSFORM_LATER + * @param $image File: the image object + * @param $dstPath String: filesystem destination path + * @param $dstUrl String: destination URL to use in output HTML + * @param $params Array: arbitrary set of parameters validated by $this->validateParam() + * @param $flags Integer: a bitfield, may contain self::TRANSFORM_LATER */ abstract function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ); @@ -119,27 +194,43 @@ abstract class MediaHandler { * Get the thumbnail extension and MIME type for a given source MIME type * @return array thumbnail extension and MIME type */ - function getThumbType( $ext, $mime ) { + function getThumbType( $ext, $mime, $params = null ) { + $magic = MimeMagic::singleton(); + if ( !$ext || $magic->isMatchingExtension( $ext, $mime ) === false ) { + // The extension is not valid for this mime type and we do + // recognize the mime type + $extensions = $magic->getExtensionsForType( $mime ); + if ( $extensions ) { + return array( strtok( $extensions, ' ' ), $mime ); + } + } + + // The extension is correct (true) or the mime type is unknown to + // MediaWiki (null) return array( $ext, $mime ); - } + } /** * True if the handled types can be transformed */ - function canRender() { return true; } + function canRender( $file ) { return true; } /** - * True if handled types cannot be displayed directly in a browser + * True if handled types cannot be displayed directly in a browser * but can be rendered */ - function mustRender() { return false; } + function mustRender( $file ) { return false; } /** * True if the type has multi-page capabilities */ - function isMultiPage() { return false; } + function isMultiPage( $file ) { return false; } /** * Page count for a multi-page document, false if unsupported or unknown */ - function pageCount() { return false; } + function pageCount( $file ) { return false; } + /** + * The material is vectorized and thus scaling is lossless + */ + function isVectorized( $file ) { return false; } /** * False if the handler is disabled for all files */ @@ -147,9 +238,11 @@ abstract class MediaHandler { /** * Get an associative array of page dimensions - * Currently "width" and "height" are understood, but this might be + * Currently "width" and "height" are understood, but this might be * expanded in the future. * Returns false if unknown or if the document is not multi-page. + * + * @param $image File */ function getPageDimensions( $image, $page ) { $gis = $this->getImageSize( $image, $image->getPath() ); @@ -158,14 +251,252 @@ abstract class MediaHandler { 'height' => $gis[1] ); } + + /** + * Generic getter for text layer. + * Currently overloaded by PDF and DjVu handlers + */ + function getPageText( $image, $page ) { + return false; + } + + /** + * Get an array structure that looks like this: + * + * array( + * 'visible' => array( + * 'Human-readable name' => 'Human readable value', + * ... + * ), + * 'collapsed' => array( + * 'Human-readable name' => 'Human readable value', + * ... + * ) + * ) + * The UI will format this into a table where the visible fields are always + * visible, and the collapsed fields are optionally visible. + * + * The function should return false if there is no metadata to display. + */ + + /** + * 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. + */ + function formatMetadata( $image ) { + return false; + } + + /** sorts the visible/invisible field. + * Split off from ImageHandler::formatMetadata, as used by more than + * one type of handler. + * + * This is used by the media handlers that use the FormatMetadata class + * + * @param $metadataArray Array metadata array + * @return array for use displaying metadata. + */ + function formatMetadataHelper( $metadataArray ) { + $result = array( + 'visible' => array(), + 'collapsed' => array() + ); + + $formatted = FormatMetadata::getFormattedData( $metadataArray ); + // Sort fields into visible and collapsed + $visibleFields = $this->visibleMetadataFields(); + foreach ( $formatted as $name => $value ) { + $tag = strtolower( $name ); + self::addMeta( $result, + in_array( $tag, $visibleFields ) ? 'visible' : 'collapsed', + 'exif', + $tag, + $value + ); + } + return $result; + } + + /** + * Get a list of metadata items which should be displayed when + * the metadata table is collapsed. + * + * @return array of strings + * @access private + */ + function visibleMetadataFields() { + $fields = array(); + $lines = explode( "\n", wfMsgForContent( 'metadata-fields' ) ); + foreach( $lines as $line ) { + $matches = array(); + if( preg_match( '/^\\*\s*(.*?)\s*$/', $line, $matches ) ) { + $fields[] = $matches[1]; + } + } + $fields = array_map( 'strtolower', $fields ); + return $fields; + } + + + /** + * This is used to generate an array element for each metadata value + * 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 $visibility String ('visible' or 'collapsed') if this value is hidden + * by default. + * @param $type String type of metadata tag (currently always 'exif') + * @param $id String 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 $value String 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 $param String value to pass to the message for the name of the field + * as $1. Currently this parameter doesn't seem to ever be used. + * + * @return Array $array but with the new metadata field added. + * + * Note, everything here is passed through the parser later on (!) + */ + protected static function addMeta( &$array, $visibility, $type, $id, $value, $param = false ) { + $msgName = "$type-$id"; + if ( wfEmptyMsg( $msgName ) ) { + // This is for future compatibility when using instant commons. + // So as to not display as ugly a name if a new metadata + // property is defined that we don't know about + // (not a major issue since such a property would be collapsed + // by default). + wfDebug( __METHOD__ . ' Unknown metadata name: ' . $id . "\n" ); + $name = wfEscapeWikiText( $id ); + } else { + $name = wfMsg( $msgName, $param ); + } + $array[$visibility][] = array( + 'id' => "$type-$id", + 'name' => $name, + 'value' => $value + ); + } + + /** + * @param $file File + * @return string + */ + function getShortDesc( $file ) { + global $wgLang; + $nbytes = wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ), + $wgLang->formatNum( $file->getSize() ) ); + return "$nbytes"; + } + + /** + * @param $file File + * @return string + */ + function getLongDesc( $file ) { + global $wgUser; + $sk = $wgUser->getSkin(); + return wfMsgExt( 'file-info', 'parseinline', + $sk->formatSize( $file->getSize() ), + $file->getMimeType() ); + } + + /** + * @param $file File + * @return string + */ + static function getGeneralShortDesc( $file ) { + global $wgLang; + $nbytes = wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ), + $wgLang->formatNum( $file->getSize() ) ); + return "$nbytes"; + } + + /** + * @param $file File + * @return string + */ + static function getGeneralLongDesc( $file ) { + global $wgUser; + $sk = $wgUser->getSkin(); + return wfMsgExt( 'file-info', 'parseinline', + $sk->formatSize( $file->getSize() ), + $file->getMimeType() ); + } + + function getDimensionsString( $file ) { + return ''; + } + + /** + * Modify the parser object post-transform + */ + function parserTransformHook( $parser, $file ) {} + + /** + * File validation hook called on upload. + * + * If the file at the given local path is not valid, or its MIME type does not + * match the handler class, a Status object should be returned containing + * relevant errors. + * + * @param $fileName The local path to the file. + * @return Status object + */ + function verifyUpload( $fileName ) { + return Status::newGood(); + } + + /** + * Check for zero-sized thumbnails. These can be generated when + * no disk space is available or some other error occurs + * + * @param $dstPath The location of the suspect file + * @param $retval Return value of some shell process, file will be deleted if this is non-zero + * @return true if removed, false otherwise + */ + function removeBadFile( $dstPath, $retval = 0 ) { + if( file_exists( $dstPath ) ) { + $thumbstat = stat( $dstPath ); + if( $thumbstat['size'] == 0 || $retval != 0 ) { + wfDebugLog( 'thumbnail', + sprintf( 'Removing bad %d-byte thumbnail "%s"', + $thumbstat['size'], $dstPath ) ); + unlink( $dstPath ); + return true; + } + } + return false; + } } /** * Media handler abstract base class for images * - * @addtogroup Media + * @ingroup Media */ abstract class ImageHandler extends MediaHandler { + + /** + * @param $file File + * @return bool + */ + function canRender( $file ) { + return ( $file->getWidth() && $file->getHeight() ); + } + + function getParamMap() { + return array( 'img_width' => 'width' ); + } + function validateParam( $name, $value ) { if ( in_array( $name, array( 'width', 'height' ) ) ) { if ( $value <= 0 ) { @@ -204,15 +535,30 @@ abstract class ImageHandler extends MediaHandler { return array( 'width' => $params['width'] ); } + /** + * @param $image File + * @param $params + * @return bool + */ function normaliseParams( $image, &$params ) { $mimeType = $image->getMimeType(); if ( !isset( $params['width'] ) ) { return false; } + if ( !isset( $params['page'] ) ) { $params['page'] = 1; + } else { + if ( $params['page'] > $image->pageCount() ) { + $params['page'] = $image->pageCount(); + } + + if ( $params['page'] < 1 ) { + $params['page'] = 1; + } } + $srcWidth = $image->getWidth( $params['page'] ); $srcHeight = $image->getHeight( $params['page'] ); if ( isset( $params['height'] ) && $params['height'] != -1 ) { @@ -233,13 +579,16 @@ abstract class ImageHandler extends MediaHandler { function getTransform( $image, $dstPath, $dstUrl, $params ) { return $this->doTransform( $image, $dstPath, $dstUrl, $params, self::TRANSFORM_LATER ); } - + /** * Validate thumbnail parameters and fill in the correct height * - * @param integer &$width Specified width (input/output) - * @param integer &$height Height (output only) - * @return false to indicate that an error should be returned to the user. + * @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 Unused + * @return false to indicate that an error should be returned to the user. */ function validateThumbParams( &$width, &$height, $srcWidth, $srcHeight, $mimeType ) { $width = intval( $width ); @@ -258,34 +607,22 @@ abstract class ImageHandler extends MediaHandler { return true; } + /** + * @param $image File + * @param $script + * @param $params + * @return bool|ThumbnailImage + */ function getScriptedTransform( $image, $script, $params ) { if ( !$this->normaliseParams( $image, $params ) ) { return false; } $url = $script . '&' . wfArrayToCGI( $this->getScriptParams( $params ) ); - return new ThumbnailImage( $url, $params['width'], $params['height'] ); - } + $page = isset( $params['page'] ) ? $params['page'] : false; - /** - * Check for zero-sized thumbnails. These can be generated when - * no disk space is available or some other error occurs - * - * @param $dstPath The location of the suspect file - * @param $retval Return value of some shell process, file will be deleted if this is non-zero - * @return true if removed, false otherwise - */ - function removeBadFile( $dstPath, $retval = 0 ) { - if( file_exists( $dstPath ) ) { - $thumbstat = stat( $dstPath ); - if( $thumbstat['size'] == 0 || $retval != 0 ) { - wfDebugLog( 'thumbnail', - sprintf( 'Removing bad %d-byte thumbnail "%s"', - $thumbstat['size'], $dstPath ) ); - unlink( $dstPath ); - return true; - } + if( $image->mustRender() || $params['width'] < $image->getWidth() ) { + return new ThumbnailImage( $image, $url, $params['width'], $params['height'], $page ); } - return false; } function getImageSize( $image, $path ) { @@ -294,6 +631,52 @@ abstract class ImageHandler extends MediaHandler { wfRestoreWarnings(); return $gis; } -} -?> + function isAnimatedImage( $image ) { + return false; + } + + /** + * @param $file File + * @return string + */ + function getShortDesc( $file ) { + global $wgLang; + $nbytes = wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ), + $wgLang->formatNum( $file->getSize() ) ); + $widthheight = wfMsgHtml( 'widthheight', $wgLang->formatNum( $file->getWidth() ) ,$wgLang->formatNum( $file->getHeight() ) ); + + return "$widthheight ($nbytes)"; + } + + /** + * @param $file File + * @return string + */ + function getLongDesc( $file ) { + global $wgLang; + return wfMsgExt('file-info-size', 'parseinline', + $wgLang->formatNum( $file->getWidth() ), + $wgLang->formatNum( $file->getHeight() ), + $wgLang->formatSize( $file->getSize() ), + $file->getMimeType() ); + } + + /** + * @param $file File + * @return string + */ + function getDimensionsString( $file ) { + global $wgLang; + $pages = $file->pageCount(); + $width = $wgLang->formatNum( $file->getWidth() ); + $height = $wgLang->formatNum( $file->getHeight() ); + $pagesFmt = $wgLang->formatNum( $pages ); + + if ( $pages > 1 ) { + return wfMsgExt( 'widthheightpage', 'parsemag', $width, $height, $pagesFmt ); + } else { + return wfMsg( 'widthheight', $width, $height ); + } + } +}