MediaWiki  REL1_22
ApiQueryImageInfo.php
Go to the documentation of this file.
00001 <?php
00032 class ApiQueryImageInfo extends ApiQueryBase {
00033     const TRANSFORM_LIMIT = 50;
00034     private static $transformCount = 0;
00035 
00036     public function __construct( $query, $moduleName, $prefix = 'ii' ) {
00037         // We allow a subclass to override the prefix, to create a related API module.
00038         // Some other parts of MediaWiki construct this with a null $prefix, which used to be ignored when this only took two arguments
00039         if ( is_null( $prefix ) ) {
00040             $prefix = 'ii';
00041         }
00042         parent::__construct( $query, $moduleName, $prefix );
00043     }
00044 
00045     public function execute() {
00046         $params = $this->extractRequestParams();
00047 
00048         $prop = array_flip( $params['prop'] );
00049 
00050         $scale = $this->getScale( $params );
00051 
00052         $pageIds = $this->getPageSet()->getAllTitlesByNamespace();
00053         if ( !empty( $pageIds[NS_FILE] ) ) {
00054             $titles = array_keys( $pageIds[NS_FILE] );
00055             asort( $titles ); // Ensure the order is always the same
00056 
00057             $fromTitle = null;
00058             if ( !is_null( $params['continue'] ) ) {
00059                 $cont = explode( '|', $params['continue'] );
00060                 $this->dieContinueUsageIf( count( $cont ) != 2 );
00061                 $fromTitle = strval( $cont[0] );
00062                 $fromTimestamp = $cont[1];
00063                 // Filter out any titles before $fromTitle
00064                 foreach ( $titles as $key => $title ) {
00065                     if ( $title < $fromTitle ) {
00066                         unset( $titles[$key] );
00067                     } else {
00068                         break;
00069                     }
00070                 }
00071             }
00072 
00073             $result = $this->getResult();
00074             //search only inside the local repo
00075             if ( $params['localonly'] ) {
00076                 $images = RepoGroup::singleton()->getLocalRepo()->findFiles( $titles );
00077             } else {
00078                 $images = RepoGroup::singleton()->findFiles( $titles );
00079             }
00080             foreach ( $titles as $title ) {
00081                 $pageId = $pageIds[NS_FILE][$title];
00082                 $start = $title === $fromTitle ? $fromTimestamp : $params['start'];
00083 
00084                 if ( !isset( $images[$title] ) ) {
00085                     if ( isset( $prop['uploadwarning'] ) ) {
00086                         // Uploadwarning needs info about non-existing files
00087                         $images[$title] = wfLocalFile( $title );
00088                     } else {
00089                         $result->addValue(
00090                             array( 'query', 'pages', intval( $pageId ) ),
00091                             'imagerepository', ''
00092                         );
00093                         // The above can't fail because it doesn't increase the result size
00094                         continue;
00095                     }
00096                 }
00097 
00099                 $img = $images[$title];
00100 
00101                 if ( self::getTransformCount() >= self::TRANSFORM_LIMIT ) {
00102                     if ( count( $pageIds[NS_FILE] ) == 1 ) {
00103                         // See the 'the user is screwed' comment below
00104                         $this->setContinueEnumParameter( 'start',
00105                             $start !== null ? $start : wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
00106                         );
00107                     } else {
00108                         $this->setContinueEnumParameter( 'continue',
00109                             $this->getContinueStr( $img, $start ) );
00110                     }
00111                     break;
00112                 }
00113 
00114                 $fit = $result->addValue(
00115                     array( 'query', 'pages', intval( $pageId ) ),
00116                     'imagerepository', $img->getRepoName()
00117                 );
00118                 if ( !$fit ) {
00119                     if ( count( $pageIds[NS_FILE] ) == 1 ) {
00120                         // The user is screwed. imageinfo can't be solely
00121                         // responsible for exceeding the limit in this case,
00122                         // so set a query-continue that just returns the same
00123                         // thing again. When the violating queries have been
00124                         // out-continued, the result will get through
00125                         $this->setContinueEnumParameter( 'start',
00126                             $start !== null ? $start : wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
00127                         );
00128                     } else {
00129                         $this->setContinueEnumParameter( 'continue',
00130                             $this->getContinueStr( $img, $start ) );
00131                     }
00132                     break;
00133                 }
00134 
00135                 // Check if we can make the requested thumbnail, and get transform parameters.
00136                 $finalThumbParams = $this->mergeThumbParams( $img, $scale, $params['urlparam'] );
00137 
00138                 // Get information about the current version first
00139                 // Check that the current version is within the start-end boundaries
00140                 $gotOne = false;
00141                 if (
00142                     ( is_null( $start ) || $img->getTimestamp() <= $start ) &&
00143                     ( is_null( $params['end'] ) || $img->getTimestamp() >= $params['end'] )
00144                 ) {
00145                     $gotOne = true;
00146 
00147                     $fit = $this->addPageSubItem( $pageId,
00148                         self::getInfo( $img, $prop, $result,
00149                             $finalThumbParams, $params['metadataversion'] ) );
00150                     if ( !$fit ) {
00151                         if ( count( $pageIds[NS_FILE] ) == 1 ) {
00152                             // See the 'the user is screwed' comment above
00153                             $this->setContinueEnumParameter( 'start',
00154                                 wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) );
00155                         } else {
00156                             $this->setContinueEnumParameter( 'continue',
00157                                 $this->getContinueStr( $img ) );
00158                         }
00159                         break;
00160                     }
00161                 }
00162 
00163                 // Now get the old revisions
00164                 // Get one more to facilitate query-continue functionality
00165                 $count = ( $gotOne ? 1 : 0 );
00166                 $oldies = $img->getHistory( $params['limit'] - $count + 1, $start, $params['end'] );
00168                 foreach ( $oldies as $oldie ) {
00169                     if ( ++$count > $params['limit'] ) {
00170                         // We've reached the extra one which shows that there are additional pages to be had. Stop here...
00171                         // Only set a query-continue if there was only one title
00172                         if ( count( $pageIds[NS_FILE] ) == 1 ) {
00173                             $this->setContinueEnumParameter( 'start',
00174                                 wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) );
00175                         }
00176                         break;
00177                     }
00178                     $fit = self::getTransformCount() < self::TRANSFORM_LIMIT &&
00179                         $this->addPageSubItem( $pageId,
00180                             self::getInfo( $oldie, $prop, $result,
00181                                 $finalThumbParams, $params['metadataversion']
00182                             )
00183                         );
00184                     if ( !$fit ) {
00185                         if ( count( $pageIds[NS_FILE] ) == 1 ) {
00186                             $this->setContinueEnumParameter( 'start',
00187                                 wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) );
00188                         } else {
00189                             $this->setContinueEnumParameter( 'continue',
00190                                 $this->getContinueStr( $oldie ) );
00191                         }
00192                         break;
00193                     }
00194                 }
00195                 if ( !$fit ) {
00196                     break;
00197                 }
00198             }
00199         }
00200     }
00201 
00207     public function getScale( $params ) {
00208         $p = $this->getModulePrefix();
00209 
00210         if ( $params['urlwidth'] != -1 ) {
00211             $scale = array();
00212             $scale['width'] = $params['urlwidth'];
00213             $scale['height'] = $params['urlheight'];
00214         } elseif ( $params['urlheight'] != -1 ) {
00215             // Height is specified but width isn't
00216             // Don't set $scale['width']; this signals mergeThumbParams() to fill it with the image's width
00217             $scale = array();
00218             $scale['height'] = $params['urlheight'];
00219         } else {
00220             $scale = null;
00221             if ( $params['urlparam'] ) {
00222                 $this->dieUsage( "{$p}urlparam requires {$p}urlwidth", "urlparam_no_width" );
00223             }
00224         }
00225 
00226         return $scale;
00227     }
00228 
00238     protected function mergeThumbParams( $image, $thumbParams, $otherParams ) {
00239         global $wgThumbLimits;
00240 
00241         if ( !isset( $thumbParams['width'] ) && isset( $thumbParams['height'] ) ) {
00242             // We want to limit only by height in this situation, so pass the
00243             // image's full width as the limiting width. But some file types
00244             // don't have a width of their own, so pick something arbitrary so
00245             // thumbnailing the default icon works.
00246             if ( $image->getWidth() <= 0 ) {
00247                 $thumbParams['width'] = max( $wgThumbLimits );
00248             } else {
00249                 $thumbParams['width'] = $image->getWidth();
00250             }
00251         }
00252 
00253         if ( !$otherParams ) {
00254             return $thumbParams;
00255         }
00256         $p = $this->getModulePrefix();
00257 
00258         $h = $image->getHandler();
00259         if ( !$h ) {
00260             $this->setWarning( 'Could not create thumbnail because ' .
00261                 $image->getName() . ' does not have an associated image handler' );
00262             return $thumbParams;
00263         }
00264 
00265         $paramList = $h->parseParamString( $otherParams );
00266         if ( !$paramList ) {
00267             // Just set a warning (instead of dieUsage), as in many cases
00268             // we could still render the image using width and height parameters,
00269             // and this type of thing could happen between different versions of
00270             // handlers.
00271             $this->setWarning( "Could not parse {$p}urlparam for " . $image->getName()
00272                 . '. Using only width and height' );
00273             return $thumbParams;
00274         }
00275 
00276         if ( isset( $paramList['width'] ) ) {
00277             if ( intval( $paramList['width'] ) != intval( $thumbParams['width'] ) ) {
00278                 $this->setWarning( "Ignoring width value set in {$p}urlparam ({$paramList['width']}) "
00279                     . "in favor of width value derived from {$p}urlwidth/{$p}urlheight ({$thumbParams['width']})" );
00280             }
00281         }
00282 
00283         foreach ( $paramList as $name => $value ) {
00284             if ( !$h->validateParam( $name, $value ) ) {
00285                 $this->dieUsage( "Invalid value for {$p}urlparam ($name=$value)", "urlparam" );
00286             }
00287         }
00288 
00289         return $thumbParams + $paramList;
00290     }
00291 
00302     static function getInfo( $file, $prop, $result, $thumbParams = null, $version = 'latest' ) {
00303         $vals = array();
00304         // Timestamp is shown even if the file is revdelete'd in interface
00305         // so do same here.
00306         if ( isset( $prop['timestamp'] ) ) {
00307             $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $file->getTimestamp() );
00308         }
00309 
00310         $user = isset( $prop['user'] );
00311         $userid = isset( $prop['userid'] );
00312 
00313         if ( $user || $userid ) {
00314             if ( $file->isDeleted( File::DELETED_USER ) ) {
00315                 $vals['userhidden'] = '';
00316             } else {
00317                 if ( $user ) {
00318                     $vals['user'] = $file->getUser();
00319                 }
00320                 if ( $userid ) {
00321                     $vals['userid'] = $file->getUser( 'id' );
00322                 }
00323                 if ( !$file->getUser( 'id' ) ) {
00324                     $vals['anon'] = '';
00325                 }
00326             }
00327         }
00328 
00329         // This is shown even if the file is revdelete'd in interface
00330         // so do same here.
00331         if ( isset( $prop['size'] ) || isset( $prop['dimensions'] ) ) {
00332             $vals['size'] = intval( $file->getSize() );
00333             $vals['width'] = intval( $file->getWidth() );
00334             $vals['height'] = intval( $file->getHeight() );
00335 
00336             $pageCount = $file->pageCount();
00337             if ( $pageCount !== false ) {
00338                 $vals['pagecount'] = $pageCount;
00339             }
00340         }
00341 
00342         $pcomment = isset( $prop['parsedcomment'] );
00343         $comment = isset( $prop['comment'] );
00344 
00345         if ( $pcomment || $comment ) {
00346             if ( $file->isDeleted( File::DELETED_COMMENT ) ) {
00347                 $vals['commenthidden'] = '';
00348             } else {
00349                 if ( $pcomment ) {
00350                     $vals['parsedcomment'] = Linker::formatComment(
00351                         $file->getDescription(), $file->getTitle() );
00352                 }
00353                 if ( $comment ) {
00354                     $vals['comment'] = $file->getDescription();
00355                 }
00356             }
00357         }
00358 
00359         $url = isset( $prop['url'] );
00360         $sha1 = isset( $prop['sha1'] );
00361         $meta = isset( $prop['metadata'] );
00362         $mime = isset( $prop['mime'] );
00363         $mediatype = isset( $prop['mediatype'] );
00364         $archive = isset( $prop['archivename'] );
00365         $bitdepth = isset( $prop['bitdepth'] );
00366         $uploadwarning = isset( $prop['uploadwarning'] );
00367 
00368         if ( ( $url || $sha1 || $meta || $mime || $mediatype || $archive || $bitdepth )
00369                 && $file->isDeleted( File::DELETED_FILE ) ) {
00370             $vals['filehidden'] = '';
00371 
00372             //Early return, tidier than indenting all following things one level
00373             return $vals;
00374         }
00375 
00376         if ( $url ) {
00377             if ( !is_null( $thumbParams ) ) {
00378                 $mto = $file->transform( $thumbParams );
00379                 self::$transformCount++;
00380                 if ( $mto && !$mto->isError() ) {
00381                     $vals['thumburl'] = wfExpandUrl( $mto->getUrl(), PROTO_CURRENT );
00382 
00383                     // bug 23834 - If the URL's are the same, we haven't resized it, so shouldn't give the wanted
00384                     // thumbnail sizes for the thumbnail actual size
00385                     if ( $mto->getUrl() !== $file->getUrl() ) {
00386                         $vals['thumbwidth'] = intval( $mto->getWidth() );
00387                         $vals['thumbheight'] = intval( $mto->getHeight() );
00388                     } else {
00389                         $vals['thumbwidth'] = intval( $file->getWidth() );
00390                         $vals['thumbheight'] = intval( $file->getHeight() );
00391                     }
00392 
00393                     if ( isset( $prop['thumbmime'] ) && $file->getHandler() ) {
00394                         list( , $mime ) = $file->getHandler()->getThumbType(
00395                             $mto->getExtension(), $file->getMimeType(), $thumbParams );
00396                         $vals['thumbmime'] = $mime;
00397                     }
00398                 } elseif ( $mto && $mto->isError() ) {
00399                     $vals['thumberror'] = $mto->toText();
00400                 }
00401             }
00402             $vals['url'] = wfExpandUrl( $file->getFullURL(), PROTO_CURRENT );
00403             $vals['descriptionurl'] = wfExpandUrl( $file->getDescriptionUrl(), PROTO_CURRENT );
00404         }
00405 
00406         if ( $sha1 ) {
00407             $vals['sha1'] = wfBaseConvert( $file->getSha1(), 36, 16, 40 );
00408         }
00409 
00410         if ( $meta ) {
00411             wfSuppressWarnings();
00412             $metadata = unserialize( $file->getMetadata() );
00413             wfRestoreWarnings();
00414             if ( $metadata && $version !== 'latest' ) {
00415                 $metadata = $file->convertMetadataVersion( $metadata, $version );
00416             }
00417             $vals['metadata'] = $metadata ? self::processMetaData( $metadata, $result ) : null;
00418         }
00419 
00420         if ( $mime ) {
00421             $vals['mime'] = $file->getMimeType();
00422         }
00423 
00424         if ( $mediatype ) {
00425             $vals['mediatype'] = $file->getMediaType();
00426         }
00427 
00428         if ( $archive && $file->isOld() ) {
00429             $vals['archivename'] = $file->getArchiveName();
00430         }
00431 
00432         if ( $bitdepth ) {
00433             $vals['bitdepth'] = $file->getBitDepth();
00434         }
00435 
00436         if ( $uploadwarning ) {
00437             $vals['html'] = SpecialUpload::getExistsWarning( UploadBase::getExistsWarning( $file ) );
00438         }
00439 
00440         return $vals;
00441     }
00442 
00450     static function getTransformCount() {
00451         return self::$transformCount;
00452     }
00453 
00460     public static function processMetaData( $metadata, $result ) {
00461         $retval = array();
00462         if ( is_array( $metadata ) ) {
00463             foreach ( $metadata as $key => $value ) {
00464                 $r = array( 'name' => $key );
00465                 if ( is_array( $value ) ) {
00466                     $r['value'] = self::processMetaData( $value, $result );
00467                 } else {
00468                     $r['value'] = $value;
00469                 }
00470                 $retval[] = $r;
00471             }
00472         }
00473         $result->setIndexedTagName( $retval, 'metadata' );
00474         return $retval;
00475     }
00476 
00477     public function getCacheMode( $params ) {
00478         return 'public';
00479     }
00480 
00486     protected function getContinueStr( $img, $start = null ) {
00487         if ( $start === null ) {
00488             $start = $img->getTimestamp();
00489         }
00490         return $img->getOriginalTitle()->getDBkey() . '|' . $start;
00491     }
00492 
00493     public function getAllowedParams() {
00494         return array(
00495             'prop' => array(
00496                 ApiBase::PARAM_ISMULTI => true,
00497                 ApiBase::PARAM_DFLT => 'timestamp|user',
00498                 ApiBase::PARAM_TYPE => self::getPropertyNames()
00499             ),
00500             'limit' => array(
00501                 ApiBase::PARAM_TYPE => 'limit',
00502                 ApiBase::PARAM_DFLT => 1,
00503                 ApiBase::PARAM_MIN => 1,
00504                 ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
00505                 ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
00506             ),
00507             'start' => array(
00508                 ApiBase::PARAM_TYPE => 'timestamp'
00509             ),
00510             'end' => array(
00511                 ApiBase::PARAM_TYPE => 'timestamp'
00512             ),
00513             'urlwidth' => array(
00514                 ApiBase::PARAM_TYPE => 'integer',
00515                 ApiBase::PARAM_DFLT => -1
00516             ),
00517             'urlheight' => array(
00518                 ApiBase::PARAM_TYPE => 'integer',
00519                 ApiBase::PARAM_DFLT => -1
00520             ),
00521             'metadataversion' => array(
00522                 ApiBase::PARAM_TYPE => 'string',
00523                 ApiBase::PARAM_DFLT => '1',
00524             ),
00525             'urlparam' => array(
00526                 ApiBase::PARAM_DFLT => '',
00527                 ApiBase::PARAM_TYPE => 'string',
00528             ),
00529             'continue' => null,
00530             'localonly' => false,
00531         );
00532     }
00533 
00541     public static function getPropertyNames( $filter = array() ) {
00542         return array_diff( array_keys( self::getProperties() ), $filter );
00543     }
00544 
00551     private static function getProperties( $modulePrefix = '' ) {
00552         return array(
00553             'timestamp' =>      ' timestamp     - Adds timestamp for the uploaded version',
00554             'user' =>           ' user          - Adds the user who uploaded the image version',
00555             'userid' =>         ' userid        - Add the user ID that uploaded the image version',
00556             'comment' =>        ' comment       - Comment on the version',
00557             'parsedcomment' =>  ' parsedcomment - Parse the comment on the version',
00558             'url' =>            ' url           - Gives URL to the image and the description page',
00559             'size' =>           ' size          - Adds the size of the image in bytes and the height, width and page count (if applicable)',
00560             'dimensions' =>     ' dimensions    - Alias for size', // For backwards compatibility with Allimages
00561             'sha1' =>           ' sha1          - Adds SHA-1 hash for the image',
00562             'mime' =>           ' mime          - Adds MIME type of the image',
00563             'thumbmime' =>      ' thumbmime     - Adds MIME type of the image thumbnail' .
00564                 ' (requires url and param ' . $modulePrefix . 'urlwidth)',
00565             'mediatype' =>      ' mediatype     - Adds the media type of the image',
00566             'metadata' =>       ' metadata      - Lists Exif metadata for the version of the image',
00567             'archivename' =>    ' archivename   - Adds the file name of the archive version for non-latest versions',
00568             'bitdepth' =>       ' bitdepth      - Adds the bit depth of the version',
00569             'uploadwarning' =>  ' uploadwarning - Used by the Special:Upload page to get information about an existing file. Not intended for use outside MediaWiki core',
00570         );
00571     }
00572 
00580     public static function getPropertyDescriptions( $filter = array(), $modulePrefix = '' ) {
00581         return array_merge(
00582             array( 'What image information to get:' ),
00583             array_values( array_diff_key( self::getProperties( $modulePrefix ), array_flip( $filter ) ) )
00584         );
00585     }
00586 
00591     public function getParamDescription() {
00592         $p = $this->getModulePrefix();
00593         return array(
00594             'prop' => self::getPropertyDescriptions( array(), $p ),
00595             'urlwidth' => array( "If {$p}prop=url is set, a URL to an image scaled to this width will be returned.",
00596                 'For performance reasons if this option is used, ' .
00597                     'no more than ' . self::TRANSFORM_LIMIT . ' scaled images will be returned.' ),
00598             'urlheight' => "Similar to {$p}urlwidth.",
00599             'urlparam' => array( "A handler specific parameter string. For example, pdf's ",
00600                 "might use 'page15-100px'. {$p}urlwidth must be used and be consistent with {$p}urlparam" ),
00601             'limit' => 'How many image revisions to return per image',
00602             'start' => 'Timestamp to start listing from',
00603             'end' => 'Timestamp to stop listing at',
00604             'metadataversion' => array( "Version of metadata to use. if 'latest' is specified, use latest version.",
00605                         "Defaults to '1' for backwards compatibility" ),
00606             'continue' => 'If the query response includes a continue value, use it here to get another page of results',
00607             'localonly' => 'Look only for files in the local repository',
00608         );
00609     }
00610 
00611     public static function getResultPropertiesFiltered( $filter = array() ) {
00612         $props = array(
00613             'timestamp' => array(
00614                 'timestamp' => 'timestamp'
00615             ),
00616             'user' => array(
00617                 'userhidden' => 'boolean',
00618                 'user' => 'string',
00619                 'anon' => 'boolean'
00620             ),
00621             'userid' => array(
00622                 'userhidden' => 'boolean',
00623                 'userid' => 'integer',
00624                 'anon' => 'boolean'
00625             ),
00626             'size' => array(
00627                 'size' => 'integer',
00628                 'width' => 'integer',
00629                 'height' => 'integer',
00630                 'pagecount' => array(
00631                     ApiBase::PROP_TYPE => 'integer',
00632                     ApiBase::PROP_NULLABLE => true
00633                 )
00634             ),
00635             'dimensions' => array(
00636                 'size' => 'integer',
00637                 'width' => 'integer',
00638                 'height' => 'integer',
00639                 'pagecount' => array(
00640                     ApiBase::PROP_TYPE => 'integer',
00641                     ApiBase::PROP_NULLABLE => true
00642                 )
00643             ),
00644             'comment' => array(
00645                 'commenthidden' => 'boolean',
00646                 'comment' => array(
00647                     ApiBase::PROP_TYPE => 'string',
00648                     ApiBase::PROP_NULLABLE => true
00649                 )
00650             ),
00651             'parsedcomment' => array(
00652                 'commenthidden' => 'boolean',
00653                 'parsedcomment' => array(
00654                     ApiBase::PROP_TYPE => 'string',
00655                     ApiBase::PROP_NULLABLE => true
00656                 )
00657             ),
00658             'url' => array(
00659                 'filehidden' => 'boolean',
00660                 'thumburl' => array(
00661                     ApiBase::PROP_TYPE => 'string',
00662                     ApiBase::PROP_NULLABLE => true
00663                 ),
00664                 'thumbwidth' => array(
00665                     ApiBase::PROP_TYPE => 'integer',
00666                     ApiBase::PROP_NULLABLE => true
00667                 ),
00668                 'thumbheight' => array(
00669                     ApiBase::PROP_TYPE => 'integer',
00670                     ApiBase::PROP_NULLABLE => true
00671                 ),
00672                 'thumberror' => array(
00673                     ApiBase::PROP_TYPE => 'string',
00674                     ApiBase::PROP_NULLABLE => true
00675                 ),
00676                 'url' => array(
00677                     ApiBase::PROP_TYPE => 'string',
00678                     ApiBase::PROP_NULLABLE => true
00679                 ),
00680                 'descriptionurl' => array(
00681                     ApiBase::PROP_TYPE => 'string',
00682                     ApiBase::PROP_NULLABLE => true
00683                 )
00684             ),
00685             'sha1' => array(
00686                 'filehidden' => 'boolean',
00687                 'sha1' => array(
00688                     ApiBase::PROP_TYPE => 'string',
00689                     ApiBase::PROP_NULLABLE => true
00690                 )
00691             ),
00692             'mime' => array(
00693                 'filehidden' => 'boolean',
00694                 'mime' => array(
00695                     ApiBase::PROP_TYPE => 'string',
00696                     ApiBase::PROP_NULLABLE => true
00697                 )
00698             ),
00699             'thumbmime' => array(
00700                 'filehidden' => 'boolean',
00701                 'thumbmime' => array(
00702                     ApiBase::PROP_TYPE => 'string',
00703                     ApiBase::PROP_NULLABLE => true
00704                 )
00705             ),
00706             'mediatype' => array(
00707                 'filehidden' => 'boolean',
00708                 'mediatype' => array(
00709                     ApiBase::PROP_TYPE => 'string',
00710                     ApiBase::PROP_NULLABLE => true
00711                 )
00712             ),
00713             'archivename' => array(
00714                 'filehidden' => 'boolean',
00715                 'archivename' => array(
00716                     ApiBase::PROP_TYPE => 'string',
00717                     ApiBase::PROP_NULLABLE => true
00718                 )
00719             ),
00720             'bitdepth' => array(
00721                 'filehidden' => 'boolean',
00722                 'bitdepth' => array(
00723                     ApiBase::PROP_TYPE => 'integer',
00724                     ApiBase::PROP_NULLABLE => true
00725                 )
00726             ),
00727         );
00728         return array_diff_key( $props, array_flip( $filter ) );
00729     }
00730 
00731     public function getResultProperties() {
00732         return self::getResultPropertiesFiltered();
00733     }
00734 
00735     public function getDescription() {
00736         return 'Returns image information and upload history';
00737     }
00738 
00739     public function getPossibleErrors() {
00740         $p = $this->getModulePrefix();
00741         return array_merge( parent::getPossibleErrors(), array(
00742             array( 'code' => "{$p}urlwidth", 'info' => "{$p}urlheight cannot be used without {$p}urlwidth" ),
00743             array( 'code' => 'urlparam', 'info' => "Invalid value for {$p}urlparam" ),
00744             array( 'code' => 'urlparam_no_width', 'info' => "{$p}urlparam requires {$p}urlwidth" ),
00745         ) );
00746     }
00747 
00748     public function getExamples() {
00749         return array(
00750             'api.php?action=query&titles=File:Albert%20Einstein%20Head.jpg&prop=imageinfo',
00751             'api.php?action=query&titles=File:Test.jpg&prop=imageinfo&iilimit=50&iiend=20071231235959&iiprop=timestamp|user|url',
00752         );
00753     }
00754 
00755     public function getHelpUrls() {
00756         return 'https://www.mediawiki.org/wiki/API:Properties#imageinfo_.2F_ii';
00757     }
00758 }