00001 <?php
00002
00022 abstract class File {
00023 const DELETED_FILE = 1;
00024 const DELETED_COMMENT = 2;
00025 const DELETED_USER = 4;
00026 const DELETED_RESTRICTED = 8;
00027 const RENDER_NOW = 1;
00028
00029 const DELETE_SOURCE = 1;
00030
00049 var $repo, $title, $lastError, $redirected, $redirectedTitle;
00050
00054 function __construct( $title, $repo ) {
00055 $this->title = $title;
00056 $this->repo = $repo;
00057 }
00058
00059 function __get( $name ) {
00060 $function = array( $this, 'get' . ucfirst( $name ) );
00061 if ( !is_callable( $function ) ) {
00062 return null;
00063 } else {
00064 $this->$name = call_user_func( $function );
00065 return $this->$name;
00066 }
00067 }
00068
00076 static function normalizeExtension( $ext ) {
00077 $lower = strtolower( $ext );
00078 $squish = array(
00079 'htm' => 'html',
00080 'jpeg' => 'jpg',
00081 'mpeg' => 'mpg',
00082 'tiff' => 'tif',
00083 'ogv' => 'ogg' );
00084 if( isset( $squish[$lower] ) ) {
00085 return $squish[$lower];
00086 } elseif( preg_match( '/^[0-9a-z]+$/', $lower ) ) {
00087 return $lower;
00088 } else {
00089 return '';
00090 }
00091 }
00092
00099 static function checkExtensionCompatibility( File $old, $new ) {
00100 $oldMime = $old->getMimeType();
00101 $n = strrpos( $new, '.' );
00102 $newExt = self::normalizeExtension(
00103 $n ? substr( $new, $n + 1 ) : '' );
00104 $mimeMagic = MimeMagic::singleton();
00105 return $mimeMagic->isMatchingExtension( $newExt, $oldMime );
00106 }
00107
00113 function upgradeRow() {}
00114
00122 static function splitMime( $mime ) {
00123 if( strpos( $mime, '/' ) !== false ) {
00124 return explode( '/', $mime, 2 );
00125 } else {
00126 return array( $mime, 'unknown' );
00127 }
00128 }
00129
00133 public function getName() {
00134 if ( !isset( $this->name ) ) {
00135 $this->name = $this->repo->getNameFromTitle( $this->title );
00136 }
00137 return $this->name;
00138 }
00139
00143 function getExtension() {
00144 if ( !isset( $this->extension ) ) {
00145 $n = strrpos( $this->getName(), '.' );
00146 $this->extension = self::normalizeExtension(
00147 $n ? substr( $this->getName(), $n + 1 ) : '' );
00148 }
00149 return $this->extension;
00150 }
00151
00155 public function getTitle() { return $this->title; }
00156
00160 public function getOriginalTitle() {
00161 if ( $this->redirected )
00162 return $this->getRedirectedTitle();
00163 return $this->title;
00164 }
00165
00169 public function getUrl() {
00170 if ( !isset( $this->url ) ) {
00171 $this->url = $this->repo->getZoneUrl( 'public' ) . '/' . $this->getUrlRel();
00172 }
00173 return $this->url;
00174 }
00175
00182 public function getFullUrl() {
00183 return wfExpandUrl( $this->getUrl() );
00184 }
00185
00186 function getViewURL() {
00187 if( $this->mustRender()) {
00188 if( $this->canRender() ) {
00189 return $this->createThumb( $this->getWidth() );
00190 }
00191 else {
00192 wfDebug(__METHOD__.': supposed to render '.$this->getName().' ('.$this->getMimeType()."), but can't!\n");
00193 return $this->getURL(); #hm... return NULL?
00194 }
00195 } else {
00196 return $this->getURL();
00197 }
00198 }
00199
00210 public function getPath() {
00211 if ( !isset( $this->path ) ) {
00212 $this->path = $this->repo->getZonePath('public') . '/' . $this->getRel();
00213 }
00214 return $this->path;
00215 }
00216
00220 public function getFullPath() {
00221 return $this->getPath();
00222 }
00223
00231 public function getWidth( $page = 1 ) { return false; }
00232
00240 public function getHeight( $page = 1 ) { return false; }
00241
00248 public function getUser( $type='text' ) { return null; }
00249
00253 public function getLength() {
00254 $handler = $this->getHandler();
00255 if ( $handler ) {
00256 return $handler->getLength( $this );
00257 } else {
00258 return 0;
00259 }
00260 }
00261
00267 public function getMetadata() { return false; }
00268
00274 public function getBitDepth() { return 0; }
00275
00281 public function getSize() { return false; }
00282
00288 function getMimeType() { return 'unknown/unknown'; }
00289
00296 function getMediaType() { return MEDIATYPE_UNKNOWN; }
00297
00308 function canRender() {
00309 if ( !isset( $this->canRender ) ) {
00310 $this->canRender = $this->getHandler() && $this->handler->canRender( $this );
00311 }
00312 return $this->canRender;
00313 }
00314
00318 protected function getCanRender() {
00319 return $this->canRender();
00320 }
00321
00332 function mustRender() {
00333 return $this->getHandler() && $this->handler->mustRender( $this );
00334 }
00335
00339 function allowInlineDisplay() {
00340 return $this->canRender();
00341 }
00342
00354 function isSafeFile() {
00355 if ( !isset( $this->isSafeFile ) ) {
00356 $this->isSafeFile = $this->_getIsSafeFile();
00357 }
00358 return $this->isSafeFile;
00359 }
00360
00362 protected function getIsSafeFile() {
00363 return $this->isSafeFile();
00364 }
00365
00367 protected function _getIsSafeFile() {
00368 if ($this->allowInlineDisplay()) return true;
00369 if ($this->isTrustedFile()) return true;
00370
00371 global $wgTrustedMediaFormats;
00372
00373 $type= $this->getMediaType();
00374 $mime= $this->getMimeType();
00375 #wfDebug("LocalFile::isSafeFile: type= $type, mime= $mime\n");
00376
00377 if (!$type || $type===MEDIATYPE_UNKNOWN) return false; #unknown type, not trusted
00378 if ( in_array( $type, $wgTrustedMediaFormats) ) return true;
00379
00380 if ($mime==="unknown/unknown") return false; #unknown type, not trusted
00381 if ( in_array( $mime, $wgTrustedMediaFormats) ) return true;
00382
00383 return false;
00384 }
00385
00396 function isTrustedFile() {
00397 #this could be implemented to check a flag in the databas,
00398 #look for signatures, etc
00399 return false;
00400 }
00401
00409 public function exists() {
00410 return $this->getPath() && file_exists( $this->path );
00411 }
00412
00420 function isVisible() {
00421 return $this->exists();
00422 }
00423
00424 function getTransformScript() {
00425 if ( !isset( $this->transformScript ) ) {
00426 $this->transformScript = false;
00427 if ( $this->repo ) {
00428 $script = $this->repo->getThumbScriptUrl();
00429 if ( $script ) {
00430 $this->transformScript = "$script?f=" . urlencode( $this->getName() );
00431 }
00432 }
00433 }
00434 return $this->transformScript;
00435 }
00436
00440 function getUnscaledThumb( $page = false ) {
00441 $width = $this->getWidth( $page );
00442 if ( !$width ) {
00443 return $this->iconThumb();
00444 }
00445 if ( $page ) {
00446 $params = array(
00447 'page' => $page,
00448 'width' => $this->getWidth( $page )
00449 );
00450 } else {
00451 $params = array( 'width' => $this->getWidth() );
00452 }
00453 return $this->transform( $params );
00454 }
00455
00462 function thumbName( $params ) {
00463 if ( !$this->getHandler() ) {
00464 return null;
00465 }
00466 $extension = $this->getExtension();
00467 list( $thumbExt, $thumbMime ) = $this->handler->getThumbType( $extension, $this->getMimeType() );
00468 $thumbName = $this->handler->makeParamString( $params ) . '-' . $this->getName();
00469 if ( $thumbExt != $extension ) {
00470 $thumbName .= ".$thumbExt";
00471 }
00472 return $thumbName;
00473 }
00474
00490 public function createThumb( $width, $height = -1 ) {
00491 $params = array( 'width' => $width );
00492 if ( $height != -1 ) {
00493 $params['height'] = $height;
00494 }
00495 $thumb = $this->transform( $params );
00496 if( is_null( $thumb ) || $thumb->isError() ) return '';
00497 return $thumb->getUrl();
00498 }
00499
00515 public function getThumbnail( $width, $height=-1, $render = true ) {
00516 $params = array( 'width' => $width );
00517 if ( $height != -1 ) {
00518 $params['height'] = $height;
00519 }
00520 return $this->transform( $params, 0 );
00521 }
00522
00531 function transform( $params, $flags = 0 ) {
00532 global $wgUseSquid, $wgIgnoreImageErrors, $wgThumbnailEpoch, $wgServer;
00533
00534 wfProfileIn( __METHOD__ );
00535 do {
00536 if ( !$this->canRender() ) {
00537
00538 $thumb = $this->iconThumb();
00539 break;
00540 }
00541
00542
00543 $descriptionUrl = $this->getDescriptionUrl();
00544 if ( $descriptionUrl ) {
00545 $params['descriptionUrl'] = $wgServer . $descriptionUrl;
00546 }
00547
00548 $script = $this->getTransformScript();
00549 if ( $script && !($flags & self::RENDER_NOW) ) {
00550
00551 $thumb = $this->handler->getScriptedTransform( $this, $script, $params );
00552 if( $thumb ) {
00553 break;
00554 }
00555 }
00556
00557 $normalisedParams = $params;
00558 $this->handler->normaliseParams( $this, $normalisedParams );
00559 $thumbName = $this->thumbName( $normalisedParams );
00560 $thumbPath = $this->getThumbPath( $thumbName );
00561 $thumbUrl = $this->getThumbUrl( $thumbName );
00562
00563 if ( $this->repo->canTransformVia404() && !($flags & self::RENDER_NOW ) ) {
00564 $thumb = $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
00565 break;
00566 }
00567
00568 wfDebug( __METHOD__.": Doing stat for $thumbPath\n" );
00569 $this->migrateThumbFile( $thumbName );
00570 if ( file_exists( $thumbPath )) {
00571 $thumbTime = filemtime( $thumbPath );
00572 if ( $thumbTime !== FALSE &&
00573 gmdate( 'YmdHis', $thumbTime ) >= $wgThumbnailEpoch ) {
00574
00575 $thumb = $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
00576 break;
00577 }
00578 }
00579 $thumb = $this->handler->doTransform( $this, $thumbPath, $thumbUrl, $params );
00580
00581
00582 if ( !$thumb ) {
00583 $thumb = null;
00584 } elseif ( $thumb->isError() ) {
00585 $this->lastError = $thumb->toText();
00586 if ( $wgIgnoreImageErrors && !($flags & self::RENDER_NOW) ) {
00587 $thumb = $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
00588 }
00589 }
00590
00591
00592
00593
00594 if ( $wgUseSquid && ( !$thumb || $thumb->isError() || $thumb->getUrl() != $this->getURL()) ) {
00595 SquidUpdate::purge( array( $thumbUrl ) );
00596 }
00597 } while (false);
00598
00599 wfProfileOut( __METHOD__ );
00600 return is_object( $thumb ) ? $thumb : false;
00601 }
00602
00608 function migrateThumbFile( $thumbName ) {}
00609
00613 function getHandler() {
00614 if ( !isset( $this->handler ) ) {
00615 $this->handler = MediaHandler::getHandler( $this->getMimeType() );
00616 }
00617 return $this->handler;
00618 }
00619
00624 function iconThumb() {
00625 global $wgStylePath, $wgStyleDirectory;
00626
00627 $try = array( 'fileicon-' . $this->getExtension() . '.png', 'fileicon.png' );
00628 foreach( $try as $icon ) {
00629 $path = '/common/images/icons/' . $icon;
00630 $filepath = $wgStyleDirectory . $path;
00631 if( file_exists( $filepath ) ) {
00632 return new ThumbnailImage( $this, $wgStylePath . $path, 120, 120 );
00633 }
00634 }
00635 return null;
00636 }
00637
00642 function getLastError() {
00643 return $this->lastError;
00644 }
00645
00651 function getThumbnails() { return array(); }
00652
00658 function purgeCache() {}
00659
00665 function purgeDescription() {
00666 $title = $this->getTitle();
00667 if ( $title ) {
00668 $title->invalidateCache();
00669 $title->purgeSquid();
00670 }
00671 }
00672
00677 function purgeEverything() {
00678
00679 $this->purgeCache();
00680 $this->purgeDescription();
00681
00682
00683 $title = $this->getTitle();
00684 if ( $title ) {
00685 $update = new HTMLCacheUpdate( $title, 'imagelinks' );
00686 $update->doUpdate();
00687 }
00688 }
00689
00699 function getHistory($limit = null, $start = null, $end = null, $inc=true) {
00700 return array();
00701 }
00702
00711 public function nextHistoryLine() {
00712 return false;
00713 }
00714
00721 public function resetHistory() {}
00722
00728 function getHashPath() {
00729 if ( !isset( $this->hashPath ) ) {
00730 $this->hashPath = $this->repo->getHashPath( $this->getName() );
00731 }
00732 return $this->hashPath;
00733 }
00734
00738 function getRel() {
00739 return $this->getHashPath() . $this->getName();
00740 }
00741
00745 function getUrlRel() {
00746 return $this->getHashPath() . rawurlencode( $this->getName() );
00747 }
00748
00750 function getArchiveRel( $suffix = false ) {
00751 $path = 'archive/' . $this->getHashPath();
00752 if ( $suffix === false ) {
00753 $path = substr( $path, 0, -1 );
00754 } else {
00755 $path .= $suffix;
00756 }
00757 return $path;
00758 }
00759
00761 function getArchivePath( $suffix = false ) {
00762 return $this->repo->getZonePath('public') . '/' . $this->getArchiveRel( $suffix );
00763 }
00764
00766 function getThumbPath( $suffix = false ) {
00767 $path = $this->repo->getZonePath('thumb') . '/' . $this->getRel();
00768 if ( $suffix !== false ) {
00769 $path .= '/' . $suffix;
00770 }
00771 return $path;
00772 }
00773
00775 function getArchiveUrl( $suffix = false ) {
00776 $path = $this->repo->getZoneUrl('public') . '/archive/' . $this->getHashPath();
00777 if ( $suffix === false ) {
00778 $path = substr( $path, 0, -1 );
00779 } else {
00780 $path .= rawurlencode( $suffix );
00781 }
00782 return $path;
00783 }
00784
00786 function getThumbUrl( $suffix = false ) {
00787 $path = $this->repo->getZoneUrl('thumb') . '/' . $this->getUrlRel();
00788 if ( $suffix !== false ) {
00789 $path .= '/' . rawurlencode( $suffix );
00790 }
00791 return $path;
00792 }
00793
00795 function getArchiveVirtualUrl( $suffix = false ) {
00796 $path = $this->repo->getVirtualUrl() . '/public/archive/' . $this->getHashPath();
00797 if ( $suffix === false ) {
00798 $path = substr( $path, 0, -1 );
00799 } else {
00800 $path .= rawurlencode( $suffix );
00801 }
00802 return $path;
00803 }
00804
00806 function getThumbVirtualUrl( $suffix = false ) {
00807 $path = $this->repo->getVirtualUrl() . '/thumb/' . $this->getUrlRel();
00808 if ( $suffix !== false ) {
00809 $path .= '/' . rawurlencode( $suffix );
00810 }
00811 return $path;
00812 }
00813
00815 function getVirtualUrl( $suffix = false ) {
00816 $path = $this->repo->getVirtualUrl() . '/public/' . $this->getUrlRel();
00817 if ( $suffix !== false ) {
00818 $path .= '/' . rawurlencode( $suffix );
00819 }
00820 return $path;
00821 }
00822
00826 function isHashed() {
00827 return $this->repo->isHashed();
00828 }
00829
00830 function readOnlyError() {
00831 throw new MWException( get_class($this) . ': write operations are not supported' );
00832 }
00833
00839 function recordUpload( $oldver, $desc, $license = '', $copyStatus = '', $source = '', $watch = false ) {
00840 $this->readOnlyError();
00841 }
00842
00862 function publish( $srcPath, $flags = 0 ) {
00863 $this->readOnlyError();
00864 }
00865
00874 function getLinksTo( $options = array() ) {
00875 wfProfileIn( __METHOD__ );
00876
00877
00878 if ( count( $options ) > 0 ) {
00879 $db = wfGetDB( DB_MASTER );
00880 } else {
00881 $db = wfGetDB( DB_SLAVE );
00882 }
00883 $linkCache = LinkCache::singleton();
00884
00885 $encName = $db->addQuotes( $this->getName() );
00886 $res = $db->select( array( 'page', 'imagelinks'),
00887 array( 'page_namespace', 'page_title', 'page_id', 'page_len', 'page_is_redirect' ),
00888 array( 'page_id' => 'il_from', 'il_to' => $encName ),
00889 __METHOD__,
00890 $options );
00891
00892 $retVal = array();
00893 if ( $db->numRows( $res ) ) {
00894 while ( $row = $db->fetchObject( $res ) ) {
00895 if ( $titleObj = Title::newFromRow( $row ) ) {
00896 $linkCache->addGoodLinkObj( $row->page_id, $titleObj, $row->page_len, $row->page_is_redirect );
00897 $retVal[] = $titleObj;
00898 }
00899 }
00900 }
00901 $db->freeResult( $res );
00902 wfProfileOut( __METHOD__ );
00903 return $retVal;
00904 }
00905
00906 function formatMetadata() {
00907 if ( !$this->getHandler() ) {
00908 return false;
00909 }
00910 return $this->getHandler()->formatMetadata( $this, $this->getMetadata() );
00911 }
00912
00918 function isLocal() {
00919 return $this->getRepoName() == 'local';
00920 }
00921
00927 function getRepoName() {
00928 return $this->repo ? $this->repo->getName() : 'unknown';
00929 }
00930
00931
00932
00933 function getRepo() {
00934 return $this->repo;
00935 }
00936
00941 function isOld() {
00942 return false;
00943 }
00944
00949 function isDeleted( $field ) {
00950 return false;
00951 }
00952
00957 function getVisibility() {
00958 return 0;
00959 }
00960
00966 function wasDeleted() {
00967 $title = $this->getTitle();
00968 return $title && $title->isDeletedQuick();
00969 }
00970
00983 function move( $target ) {
00984 $this->readOnlyError();
00985 }
00986
01001 function delete( $reason, $suppress = false ) {
01002 $this->readOnlyError();
01003 }
01004
01019 function restore( $versions=array(), $unsuppress=false ) {
01020 $this->readOnlyError();
01021 }
01022
01030 function isMultipage() {
01031 return $this->getHandler() && $this->handler->isMultiPage( $this );
01032 }
01033
01038 function pageCount() {
01039 if ( !isset( $this->pageCount ) ) {
01040 if ( $this->getHandler() && $this->handler->isMultiPage( $this ) ) {
01041 $this->pageCount = $this->handler->pageCount( $this );
01042 } else {
01043 $this->pageCount = false;
01044 }
01045 }
01046 return $this->pageCount;
01047 }
01048
01052 static function scaleHeight( $srcWidth, $srcHeight, $dstWidth ) {
01053
01054 if ( $srcWidth == 0 ) {
01055 return 0;
01056 } else {
01057 return round( $srcHeight * $dstWidth / $srcWidth );
01058 }
01059 }
01060
01068 function getImageSize( $fileName ) {
01069 if ( !$this->getHandler() ) {
01070 return false;
01071 }
01072 return $this->handler->getImageSize( $this, $fileName );
01073 }
01074
01079 function getDescriptionUrl() {
01080 return $this->repo->getDescriptionUrl( $this->getName() );
01081 }
01082
01086 function getDescriptionText() {
01087 global $wgMemc, $wgLang;
01088 if ( !$this->repo->fetchDescription ) {
01089 return false;
01090 }
01091 $renderUrl = $this->repo->getDescriptionRenderUrl( $this->getName(), $wgLang->getCode() );
01092 if ( $renderUrl ) {
01093 if ( $this->repo->descriptionCacheExpiry > 0 ) {
01094 wfDebug("Attempting to get the description from cache...");
01095 $key = $this->repo->getLocalCacheKey( 'RemoteFileDescription', 'url', $wgLang->getCode(),
01096 $this->getName() );
01097 $obj = $wgMemc->get($key);
01098 if ($obj) {
01099 wfDebug("success!\n");
01100 return $obj;
01101 }
01102 wfDebug("miss\n");
01103 }
01104 wfDebug( "Fetching shared description from $renderUrl\n" );
01105 $res = Http::get( $renderUrl );
01106 if ( $res && $this->repo->descriptionCacheExpiry > 0 ) {
01107 $wgMemc->set( $key, $res, $this->repo->descriptionCacheExpiry );
01108 }
01109 return $res;
01110 } else {
01111 return false;
01112 }
01113 }
01114
01119 function getDescription() {
01120 return null;
01121 }
01122
01127 function getTimestamp() {
01128 $path = $this->getPath();
01129 if ( !file_exists( $path ) ) {
01130 return false;
01131 }
01132 return wfTimestamp( TS_MW, filemtime( $path ) );
01133 }
01134
01138 function getSha1() {
01139 return self::sha1Base36( $this->getPath() );
01140 }
01141
01145 function getStorageKey() {
01146 $hash = $this->getSha1();
01147 if ( !$hash ) {
01148 return false;
01149 }
01150 $ext = $this->getExtension();
01151 $dotExt = $ext === '' ? '' : ".$ext";
01152 return $hash . $dotExt;
01153 }
01154
01162 function userCan( $field ) {
01163 return true;
01164 }
01165
01173 static function getPropsFromPath( $path, $ext = true ) {
01174 wfProfileIn( __METHOD__ );
01175 wfDebug( __METHOD__.": Getting file info for $path\n" );
01176 $info = array(
01177 'fileExists' => file_exists( $path ) && !is_dir( $path )
01178 );
01179 $gis = false;
01180 if ( $info['fileExists'] ) {
01181 $magic = MimeMagic::singleton();
01182
01183 $info['mime'] = $magic->guessMimeType( $path, $ext );
01184 list( $info['major_mime'], $info['minor_mime'] ) = self::splitMime( $info['mime'] );
01185 $info['media_type'] = $magic->getMediaType( $path, $info['mime'] );
01186
01187 # Get size in bytes
01188 $info['size'] = filesize( $path );
01189
01190 # Height, width and metadata
01191 $handler = MediaHandler::getHandler( $info['mime'] );
01192 if ( $handler ) {
01193 $tempImage = (object)array();
01194 $info['metadata'] = $handler->getMetadata( $tempImage, $path );
01195 $gis = $handler->getImageSize( $tempImage, $path, $info['metadata'] );
01196 } else {
01197 $gis = false;
01198 $info['metadata'] = '';
01199 }
01200 $info['sha1'] = self::sha1Base36( $path );
01201
01202 wfDebug(__METHOD__.": $path loaded, {$info['size']} bytes, {$info['mime']}.\n");
01203 } else {
01204 $info['mime'] = null;
01205 $info['media_type'] = MEDIATYPE_UNKNOWN;
01206 $info['metadata'] = '';
01207 $info['sha1'] = '';
01208 wfDebug(__METHOD__.": $path NOT FOUND!\n");
01209 }
01210 if( $gis ) {
01211 # NOTE: $gis[2] contains a code for the image type. This is no longer used.
01212 $info['width'] = $gis[0];
01213 $info['height'] = $gis[1];
01214 if ( isset( $gis['bits'] ) ) {
01215 $info['bits'] = $gis['bits'];
01216 } else {
01217 $info['bits'] = 0;
01218 }
01219 } else {
01220 $info['width'] = 0;
01221 $info['height'] = 0;
01222 $info['bits'] = 0;
01223 }
01224 wfProfileOut( __METHOD__ );
01225 return $info;
01226 }
01227
01237 static function sha1Base36( $path ) {
01238 wfSuppressWarnings();
01239 $hash = sha1_file( $path );
01240 wfRestoreWarnings();
01241 if ( $hash === false ) {
01242 return false;
01243 } else {
01244 return wfBaseConvert( $hash, 16, 36, 31 );
01245 }
01246 }
01247
01248 function getLongDesc() {
01249 $handler = $this->getHandler();
01250 if ( $handler ) {
01251 return $handler->getLongDesc( $this );
01252 } else {
01253 return MediaHandler::getGeneralLongDesc( $this );
01254 }
01255 }
01256
01257 function getShortDesc() {
01258 $handler = $this->getHandler();
01259 if ( $handler ) {
01260 return $handler->getShortDesc( $this );
01261 } else {
01262 return MediaHandler::getGeneralShortDesc( $this );
01263 }
01264 }
01265
01266 function getDimensionsString() {
01267 $handler = $this->getHandler();
01268 if ( $handler ) {
01269 return $handler->getDimensionsString( $this );
01270 } else {
01271 return '';
01272 }
01273 }
01274
01275 function getRedirected() {
01276 return $this->redirected;
01277 }
01278
01279 function getRedirectedTitle() {
01280 if ( $this->redirected ) {
01281 if ( !$this->redirectTitle )
01282 $this->redirectTitle = Title::makeTitle( NS_FILE, $this->redirected );
01283 return $this->redirectTitle;
01284 }
01285 }
01286
01287 function redirectedFrom( $from ) {
01288 $this->redirected = $from;
01289 }
01290
01291 function isMissing() {
01292 return false;
01293 }
01294 }
01298 define( 'MW_IMG_DELETED_FILE', File::DELETED_FILE );
01299 define( 'MW_IMG_DELETED_COMMENT', File::DELETED_COMMENT );
01300 define( 'MW_IMG_DELETED_USER', File::DELETED_USER );
01301 define( 'MW_IMG_DELETED_RESTRICTED', File::DELETED_RESTRICTED );