MediaWiki  REL1_24
MediaTransformOutput.php
Go to the documentation of this file.
00001 <?php
00029 abstract class MediaTransformOutput {
00033     public $responsiveUrls = array();
00034 
00036     protected $file;
00037 
00039     protected $width;
00040 
00042     protected $height;
00043 
00045     protected $url;
00046 
00048     protected $page;
00049 
00051     protected $path;
00052 
00054     protected $lang;
00055 
00057     protected $storagePath = false;
00058 
00062     public function getWidth() {
00063         return $this->width;
00064     }
00065 
00069     public function getHeight() {
00070         return $this->height;
00071     }
00072 
00076     public function getFile() {
00077         return $this->file;
00078     }
00079 
00085     public function getExtension() {
00086         return $this->path ? FileBackend::extensionFromPath( $this->path ) : false;
00087     }
00088 
00092     public function getUrl() {
00093         return $this->url;
00094     }
00095 
00099     public function getStoragePath() {
00100         return $this->storagePath;
00101     }
00102 
00107     public function setStoragePath( $storagePath ) {
00108         $this->storagePath = $storagePath;
00109         if ( $this->path === false ) {
00110             $this->path = $storagePath;
00111         }
00112     }
00113 
00134     abstract public function toHtml( $options = array() );
00135 
00140     public function isError() {
00141         return false;
00142     }
00143 
00155     public function hasFile() {
00156         // If TRANSFORM_LATER, $this->path will be false.
00157         // Note: a null path means "use the source file".
00158         return ( !$this->isError() && ( $this->path || $this->path === null ) );
00159     }
00160 
00167     public function fileIsSource() {
00168         return ( !$this->isError() && $this->path === null );
00169     }
00170 
00177     public function getLocalCopyPath() {
00178         if ( $this->isError() ) {
00179             return false;
00180         } elseif ( $this->path === null ) {
00181             return $this->file->getLocalRefPath(); // assume thumb was not scaled
00182         } elseif ( FileBackend::isStoragePath( $this->path ) ) {
00183             $be = $this->file->getRepo()->getBackend();
00184             // The temp file will be process cached by FileBackend
00185             $fsFile = $be->getLocalReference( array( 'src' => $this->path ) );
00186 
00187             return $fsFile ? $fsFile->getPath() : false;
00188         } else {
00189             return $this->path; // may return false
00190         }
00191     }
00192 
00199     public function streamFile( $headers = array() ) {
00200         if ( !$this->path ) {
00201             return false;
00202         } elseif ( FileBackend::isStoragePath( $this->path ) ) {
00203             $be = $this->file->getRepo()->getBackend();
00204 
00205             return $be->streamFile( array( 'src' => $this->path, 'headers' => $headers ) )->isOK();
00206         } else { // FS-file
00207             return StreamFile::stream( $this->getLocalCopyPath(), $headers );
00208         }
00209     }
00210 
00218     protected function linkWrap( $linkAttribs, $contents ) {
00219         if ( $linkAttribs ) {
00220             return Xml::tags( 'a', $linkAttribs, $contents );
00221         } else {
00222             return $contents;
00223         }
00224     }
00225 
00231     public function getDescLinkAttribs( $title = null, $params = array() ) {
00232         if ( is_array( $params ) ) {
00233             $query = $params;
00234         } else {
00235             $query = array();
00236         }
00237         if ( $this->page && $this->page !== 1 ) {
00238             $query['page'] = $this->page;
00239         }
00240         if ( $this->lang ) {
00241             $query['lang'] = $this->lang;
00242         }
00243 
00244         if ( is_string( $params ) && $params !== '' ) {
00245             $query = $params . '&' . wfArrayToCgi( $query );
00246         }
00247 
00248         $attribs = array(
00249             'href' => $this->file->getTitle()->getLocalURL( $query ),
00250             'class' => 'image',
00251         );
00252         if ( $title ) {
00253             $attribs['title'] = $title;
00254         }
00255 
00256         return $attribs;
00257     }
00258 }
00259 
00265 class ThumbnailImage extends MediaTransformOutput {
00278     function __construct( $file, $url, $path = false, $parameters = array() ) {
00279         # Previous parameters:
00280         #   $file, $url, $width, $height, $path = false, $page = false
00281 
00282         $defaults = array(
00283             'page' => false,
00284             'lang' => false
00285         );
00286 
00287         if ( is_array( $parameters ) ) {
00288             $actualParams = $parameters + $defaults;
00289         } else {
00290             # Using old format, should convert. Later a warning could be added here.
00291             $numArgs = func_num_args();
00292             $actualParams = array(
00293                 'width' => $path,
00294                 'height' => $parameters,
00295                 'page' => ( $numArgs > 5 ) ? func_get_arg( 5 ) : false
00296             ) + $defaults;
00297             $path = ( $numArgs > 4 ) ? func_get_arg( 4 ) : false;
00298         }
00299 
00300         $this->file = $file;
00301         $this->url = $url;
00302         $this->path = $path;
00303 
00304         # These should be integers when they get here.
00305         # If not, there's a bug somewhere.  But let's at
00306         # least produce valid HTML code regardless.
00307         $this->width = round( $actualParams['width'] );
00308         $this->height = round( $actualParams['height'] );
00309 
00310         $this->page = $actualParams['page'];
00311         $this->lang = $actualParams['lang'];
00312     }
00313 
00346     function toHtml( $options = array() ) {
00347         if ( count( func_get_args() ) == 2 ) {
00348             throw new MWException( __METHOD__ . ' called in the old style' );
00349         }
00350 
00351         $alt = empty( $options['alt'] ) ? '' : $options['alt'];
00352 
00353         $query = empty( $options['desc-query'] ) ? '' : $options['desc-query'];
00354 
00355         if ( !empty( $options['custom-url-link'] ) ) {
00356             $linkAttribs = array( 'href' => $options['custom-url-link'] );
00357             if ( !empty( $options['title'] ) ) {
00358                 $linkAttribs['title'] = $options['title'];
00359             }
00360             if ( !empty( $options['custom-target-link'] ) ) {
00361                 $linkAttribs['target'] = $options['custom-target-link'];
00362             } elseif ( !empty( $options['parser-extlink-target'] ) ) {
00363                 $linkAttribs['target'] = $options['parser-extlink-target'];
00364             }
00365             if ( !empty( $options['parser-extlink-rel'] ) ) {
00366                 $linkAttribs['rel'] = $options['parser-extlink-rel'];
00367             }
00368         } elseif ( !empty( $options['custom-title-link'] ) ) {
00370             $title = $options['custom-title-link'];
00371             $linkAttribs = array(
00372                 'href' => $title->getLinkURL(),
00373                 'title' => empty( $options['title'] ) ? $title->getFullText() : $options['title']
00374             );
00375         } elseif ( !empty( $options['desc-link'] ) ) {
00376             $linkAttribs = $this->getDescLinkAttribs(
00377                 empty( $options['title'] ) ? null : $options['title'],
00378                 $query
00379             );
00380         } elseif ( !empty( $options['file-link'] ) ) {
00381             $linkAttribs = array( 'href' => $this->file->getURL() );
00382         } else {
00383             $linkAttribs = false;
00384         }
00385 
00386         $attribs = array(
00387             'alt' => $alt,
00388             'src' => $this->url,
00389         );
00390 
00391         if ( empty( $options['no-dimensions'] ) ) {
00392             $attribs['width'] = $this->width;
00393             $attribs['height'] = $this->height;
00394         }
00395         if ( !empty( $options['valign'] ) ) {
00396             $attribs['style'] = "vertical-align: {$options['valign']}";
00397         }
00398         if ( !empty( $options['img-class'] ) ) {
00399             $attribs['class'] = $options['img-class'];
00400         }
00401         if ( isset( $options['override-height'] ) ) {
00402             $attribs['height'] = $options['override-height'];
00403         }
00404         if ( isset( $options['override-width'] ) ) {
00405             $attribs['width'] = $options['override-width'];
00406         }
00407 
00408         // Additional densities for responsive images, if specified.
00409         if ( !empty( $this->responsiveUrls ) ) {
00410             $attribs['srcset'] = Html::srcSet( $this->responsiveUrls );
00411         }
00412 
00413         wfRunHooks( 'ThumbnailBeforeProduceHTML', array( $this, &$attribs, &$linkAttribs ) );
00414 
00415         return $this->linkWrap( $linkAttribs, Xml::element( 'img', $attribs ) );
00416     }
00417 }
00418 
00424 class MediaTransformError extends MediaTransformOutput {
00426     private $htmlMsg;
00427 
00429     private $textMsg;
00430 
00431     function __construct( $msg, $width, $height /*, ... */ ) {
00432         $args = array_slice( func_get_args(), 3 );
00433         $htmlArgs = array_map( 'htmlspecialchars', $args );
00434         $htmlArgs = array_map( 'nl2br', $htmlArgs );
00435 
00436         $this->htmlMsg = wfMessage( $msg )->rawParams( $htmlArgs )->escaped();
00437         $this->textMsg = wfMessage( $msg )->rawParams( $htmlArgs )->text();
00438         $this->width = intval( $width );
00439         $this->height = intval( $height );
00440         $this->url = false;
00441         $this->path = false;
00442     }
00443 
00444     function toHtml( $options = array() ) {
00445         return "<div class=\"MediaTransformError\" style=\"" .
00446             "width: {$this->width}px; height: {$this->height}px; display:inline-block;\">" .
00447             $this->htmlMsg .
00448             "</div>";
00449     }
00450 
00451     function toText() {
00452         return $this->textMsg;
00453     }
00454 
00455     function getHtmlMsg() {
00456         return $this->htmlMsg;
00457     }
00458 
00459     function isError() {
00460         return true;
00461     }
00462 }
00463 
00469 class TransformParameterError extends MediaTransformError {
00470     function __construct( $params ) {
00471         parent::__construct( 'thumbnail_error',
00472             max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
00473             max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
00474             wfMessage( 'thumbnail_invalid_params' )->text() );
00475     }
00476 }