MediaWiki  REL1_23
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     }
00110 
00131     abstract public function toHtml( $options = array() );
00132 
00137     public function isError() {
00138         return false;
00139     }
00140 
00149     public function hasFile() {
00150         // If TRANSFORM_LATER, $this->path will be false.
00151         // Note: a null path means "use the source file".
00152         return ( !$this->isError() && ( $this->path || $this->path === null ) );
00153     }
00154 
00161     public function fileIsSource() {
00162         return ( !$this->isError() && $this->path === null );
00163     }
00164 
00171     public function getLocalCopyPath() {
00172         if ( $this->isError() ) {
00173             return false;
00174         } elseif ( $this->path === null ) {
00175             return $this->file->getLocalRefPath(); // assume thumb was not scaled
00176         } elseif ( FileBackend::isStoragePath( $this->path ) ) {
00177             $be = $this->file->getRepo()->getBackend();
00178             // The temp file will be process cached by FileBackend
00179             $fsFile = $be->getLocalReference( array( 'src' => $this->path ) );
00180 
00181             return $fsFile ? $fsFile->getPath() : false;
00182         } else {
00183             return $this->path; // may return false
00184         }
00185     }
00186 
00193     public function streamFile( $headers = array() ) {
00194         if ( !$this->path ) {
00195             return false;
00196         } elseif ( FileBackend::isStoragePath( $this->path ) ) {
00197             $be = $this->file->getRepo()->getBackend();
00198 
00199             return $be->streamFile( array( 'src' => $this->path, 'headers' => $headers ) )->isOK();
00200         } else { // FS-file
00201             return StreamFile::stream( $this->getLocalCopyPath(), $headers );
00202         }
00203     }
00204 
00212     protected function linkWrap( $linkAttribs, $contents ) {
00213         if ( $linkAttribs ) {
00214             return Xml::tags( 'a', $linkAttribs, $contents );
00215         } else {
00216             return $contents;
00217         }
00218     }
00219 
00225     public function getDescLinkAttribs( $title = null, $params = array() ) {
00226         if ( is_array( $params ) ) {
00227             $query = $params;
00228         } else {
00229             $query = array();
00230         }
00231         if ( $this->page && $this->page !== 1 ) {
00232             $query['page'] = $this->page;
00233         }
00234         if ( $this->lang ) {
00235             $query['lang'] = $this->lang;
00236         }
00237 
00238         if ( is_string( $params ) && $params !== '' ) {
00239             $query = $params . '&' . wfArrayToCgi( $query );
00240         }
00241 
00242         $attribs = array(
00243             'href' => $this->file->getTitle()->getLocalURL( $query ),
00244             'class' => 'image',
00245         );
00246         if ( $title ) {
00247             $attribs['title'] = $title;
00248         }
00249 
00250         return $attribs;
00251     }
00252 }
00253 
00259 class ThumbnailImage extends MediaTransformOutput {
00272     function __construct( $file, $url, $path = false, $parameters = array() ) {
00273         # Previous parameters:
00274         #   $file, $url, $width, $height, $path = false, $page = false
00275 
00276         $defaults = array(
00277             'page' => false,
00278             'lang' => false
00279         );
00280 
00281         if ( is_array( $parameters ) ) {
00282             $actualParams = $parameters + $defaults;
00283         } else {
00284             # Using old format, should convert. Later a warning could be added here.
00285             $numArgs = func_num_args();
00286             $actualParams = array(
00287                 'width' => $path,
00288                 'height' => $parameters,
00289                 'page' => ( $numArgs > 5 ) ? func_get_arg( 5 ) : false
00290             ) + $defaults;
00291             $path = ( $numArgs > 4 ) ? func_get_arg( 4 ) : false;
00292         }
00293 
00294         $this->file = $file;
00295         $this->url = $url;
00296         $this->path = $path;
00297 
00298         # These should be integers when they get here.
00299         # If not, there's a bug somewhere.  But let's at
00300         # least produce valid HTML code regardless.
00301         $this->width = round( $actualParams['width'] );
00302         $this->height = round( $actualParams['height'] );
00303 
00304         $this->page = $actualParams['page'];
00305         $this->lang = $actualParams['lang'];
00306     }
00307 
00340     function toHtml( $options = array() ) {
00341         if ( count( func_get_args() ) == 2 ) {
00342             throw new MWException( __METHOD__ . ' called in the old style' );
00343         }
00344 
00345         $alt = empty( $options['alt'] ) ? '' : $options['alt'];
00346 
00347         $query = empty( $options['desc-query'] ) ? '' : $options['desc-query'];
00348 
00349         if ( !empty( $options['custom-url-link'] ) ) {
00350             $linkAttribs = array( 'href' => $options['custom-url-link'] );
00351             if ( !empty( $options['title'] ) ) {
00352                 $linkAttribs['title'] = $options['title'];
00353             }
00354             if ( !empty( $options['custom-target-link'] ) ) {
00355                 $linkAttribs['target'] = $options['custom-target-link'];
00356             } elseif ( !empty( $options['parser-extlink-target'] ) ) {
00357                 $linkAttribs['target'] = $options['parser-extlink-target'];
00358             }
00359             if ( !empty( $options['parser-extlink-rel'] ) ) {
00360                 $linkAttribs['rel'] = $options['parser-extlink-rel'];
00361             }
00362         } elseif ( !empty( $options['custom-title-link'] ) ) {
00364             $title = $options['custom-title-link'];
00365             $linkAttribs = array(
00366                 'href' => $title->getLinkURL(),
00367                 'title' => empty( $options['title'] ) ? $title->getFullText() : $options['title']
00368             );
00369         } elseif ( !empty( $options['desc-link'] ) ) {
00370             $linkAttribs = $this->getDescLinkAttribs(
00371                 empty( $options['title'] ) ? null : $options['title'],
00372                 $query
00373             );
00374         } elseif ( !empty( $options['file-link'] ) ) {
00375             $linkAttribs = array( 'href' => $this->file->getURL() );
00376         } else {
00377             $linkAttribs = false;
00378         }
00379 
00380         $attribs = array(
00381             'alt' => $alt,
00382             'src' => $this->url,
00383         );
00384 
00385         if ( empty( $options['no-dimensions'] ) ) {
00386             $attribs['width'] = $this->width;
00387             $attribs['height'] = $this->height;
00388         }
00389         if ( !empty( $options['valign'] ) ) {
00390             $attribs['style'] = "vertical-align: {$options['valign']}";
00391         }
00392         if ( !empty( $options['img-class'] ) ) {
00393             $attribs['class'] = $options['img-class'];
00394         }
00395         if ( isset( $options['override-height'] ) ) {
00396             $attribs['height'] = $options['override-height'];
00397         }
00398         if ( isset( $options['override-width'] ) ) {
00399             $attribs['width'] = $options['override-width'];
00400         }
00401 
00402         // Additional densities for responsive images, if specified.
00403         if ( !empty( $this->responsiveUrls ) ) {
00404             $attribs['srcset'] = Html::srcSet( $this->responsiveUrls );
00405         }
00406 
00407         wfRunHooks( 'ThumbnailBeforeProduceHTML', array( $this, &$attribs, &$linkAttribs ) );
00408 
00409         return $this->linkWrap( $linkAttribs, Xml::element( 'img', $attribs ) );
00410     }
00411 }
00412 
00418 class MediaTransformError extends MediaTransformOutput {
00420     private $htmlMsg;
00421 
00423     private $textMsg;
00424 
00425     function __construct( $msg, $width, $height /*, ... */ ) {
00426         $args = array_slice( func_get_args(), 3 );
00427         $htmlArgs = array_map( 'htmlspecialchars', $args );
00428         $htmlArgs = array_map( 'nl2br', $htmlArgs );
00429 
00430         $this->htmlMsg = wfMessage( $msg )->rawParams( $htmlArgs )->escaped();
00431         $this->textMsg = wfMessage( $msg )->rawParams( $htmlArgs )->text();
00432         $this->width = intval( $width );
00433         $this->height = intval( $height );
00434         $this->url = false;
00435         $this->path = false;
00436     }
00437 
00438     function toHtml( $options = array() ) {
00439         return "<div class=\"MediaTransformError\" style=\"" .
00440             "width: {$this->width}px; height: {$this->height}px; display:inline-block;\">" .
00441             $this->htmlMsg .
00442             "</div>";
00443     }
00444 
00445     function toText() {
00446         return $this->textMsg;
00447     }
00448 
00449     function getHtmlMsg() {
00450         return $this->htmlMsg;
00451     }
00452 
00453     function isError() {
00454         return true;
00455     }
00456 }
00457 
00463 class TransformParameterError extends MediaTransformError {
00464     function __construct( $params ) {
00465         parent::__construct( 'thumbnail_error',
00466             max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
00467             max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
00468             wfMessage( 'thumbnail_invalid_params' )->text() );
00469     }
00470 }