MediaWiki
REL1_24
|
00001 <?php 00032 class ApiQueryImageInfo extends ApiQueryBase { 00033 const TRANSFORM_LIMIT = 50; 00034 private static $transformCount = 0; 00035 00036 public function __construct( ApiQuery $query, $moduleName, $prefix = 'ii' ) { 00037 // We allow a subclass to override the prefix, to create a related API 00038 // module. Some other parts of MediaWiki construct this with a null 00039 // $prefix, which used to be ignored when this only took two arguments 00040 if ( is_null( $prefix ) ) { 00041 $prefix = 'ii'; 00042 } 00043 parent::__construct( $query, $moduleName, $prefix ); 00044 } 00045 00046 public function execute() { 00047 $params = $this->extractRequestParams(); 00048 00049 $prop = array_flip( $params['prop'] ); 00050 00051 $scale = $this->getScale( $params ); 00052 00053 $opts = array( 00054 'version' => $params['metadataversion'], 00055 'language' => $params['extmetadatalanguage'], 00056 'multilang' => $params['extmetadatamultilang'], 00057 'extmetadatafilter' => $params['extmetadatafilter'], 00058 'revdelUser' => $this->getUser(), 00059 ); 00060 00061 $pageIds = $this->getPageSet()->getAllTitlesByNamespace(); 00062 if ( !empty( $pageIds[NS_FILE] ) ) { 00063 $titles = array_keys( $pageIds[NS_FILE] ); 00064 asort( $titles ); // Ensure the order is always the same 00065 00066 $fromTitle = null; 00067 if ( !is_null( $params['continue'] ) ) { 00068 $cont = explode( '|', $params['continue'] ); 00069 $this->dieContinueUsageIf( count( $cont ) != 2 ); 00070 $fromTitle = strval( $cont[0] ); 00071 $fromTimestamp = $cont[1]; 00072 // Filter out any titles before $fromTitle 00073 foreach ( $titles as $key => $title ) { 00074 if ( $title < $fromTitle ) { 00075 unset( $titles[$key] ); 00076 } else { 00077 break; 00078 } 00079 } 00080 } 00081 00082 $user = $this->getUser(); 00083 $findTitles = array_map( function ( $title ) use ( $user ) { 00084 return array( 00085 'title' => $title, 00086 'private' => $user, 00087 ); 00088 }, $titles ); 00089 00090 if ( $params['localonly'] ) { 00091 $images = RepoGroup::singleton()->getLocalRepo()->findFiles( $findTitles ); 00092 } else { 00093 $images = RepoGroup::singleton()->findFiles( $findTitles ); 00094 } 00095 00096 $result = $this->getResult(); 00097 foreach ( $titles as $title ) { 00098 $pageId = $pageIds[NS_FILE][$title]; 00099 $start = $title === $fromTitle ? $fromTimestamp : $params['start']; 00100 00101 if ( !isset( $images[$title] ) ) { 00102 if ( isset( $prop['uploadwarning'] ) ) { 00103 // Uploadwarning needs info about non-existing files 00104 $images[$title] = wfLocalFile( $title ); 00105 } else { 00106 $result->addValue( 00107 array( 'query', 'pages', intval( $pageId ) ), 00108 'imagerepository', '' 00109 ); 00110 // The above can't fail because it doesn't increase the result size 00111 continue; 00112 } 00113 } 00114 00116 $img = $images[$title]; 00117 00118 if ( self::getTransformCount() >= self::TRANSFORM_LIMIT ) { 00119 if ( count( $pageIds[NS_FILE] ) == 1 ) { 00120 // See the 'the user is screwed' comment below 00121 $this->setContinueEnumParameter( 'start', 00122 $start !== null ? $start : wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) 00123 ); 00124 } else { 00125 $this->setContinueEnumParameter( 'continue', 00126 $this->getContinueStr( $img, $start ) ); 00127 } 00128 break; 00129 } 00130 00131 $fit = $result->addValue( 00132 array( 'query', 'pages', intval( $pageId ) ), 00133 'imagerepository', $img->getRepoName() 00134 ); 00135 if ( !$fit ) { 00136 if ( count( $pageIds[NS_FILE] ) == 1 ) { 00137 // The user is screwed. imageinfo can't be solely 00138 // responsible for exceeding the limit in this case, 00139 // so set a query-continue that just returns the same 00140 // thing again. When the violating queries have been 00141 // out-continued, the result will get through 00142 $this->setContinueEnumParameter( 'start', 00143 $start !== null ? $start : wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) 00144 ); 00145 } else { 00146 $this->setContinueEnumParameter( 'continue', 00147 $this->getContinueStr( $img, $start ) ); 00148 } 00149 break; 00150 } 00151 00152 // Check if we can make the requested thumbnail, and get transform parameters. 00153 $finalThumbParams = $this->mergeThumbParams( $img, $scale, $params['urlparam'] ); 00154 00155 // Get information about the current version first 00156 // Check that the current version is within the start-end boundaries 00157 $gotOne = false; 00158 if ( 00159 ( is_null( $start ) || $img->getTimestamp() <= $start ) && 00160 ( is_null( $params['end'] ) || $img->getTimestamp() >= $params['end'] ) 00161 ) { 00162 $gotOne = true; 00163 00164 $fit = $this->addPageSubItem( $pageId, 00165 self::getInfo( $img, $prop, $result, 00166 $finalThumbParams, $opts 00167 ) 00168 ); 00169 if ( !$fit ) { 00170 if ( count( $pageIds[NS_FILE] ) == 1 ) { 00171 // See the 'the user is screwed' comment above 00172 $this->setContinueEnumParameter( 'start', 00173 wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) ); 00174 } else { 00175 $this->setContinueEnumParameter( 'continue', 00176 $this->getContinueStr( $img ) ); 00177 } 00178 break; 00179 } 00180 } 00181 00182 // Now get the old revisions 00183 // Get one more to facilitate query-continue functionality 00184 $count = ( $gotOne ? 1 : 0 ); 00185 $oldies = $img->getHistory( $params['limit'] - $count + 1, $start, $params['end'] ); 00187 foreach ( $oldies as $oldie ) { 00188 if ( ++$count > $params['limit'] ) { 00189 // We've reached the extra one which shows that there are 00190 // additional pages to be had. Stop here... 00191 // Only set a query-continue if there was only one title 00192 if ( count( $pageIds[NS_FILE] ) == 1 ) { 00193 $this->setContinueEnumParameter( 'start', 00194 wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) ); 00195 } 00196 break; 00197 } 00198 $fit = self::getTransformCount() < self::TRANSFORM_LIMIT && 00199 $this->addPageSubItem( $pageId, 00200 self::getInfo( $oldie, $prop, $result, 00201 $finalThumbParams, $opts 00202 ) 00203 ); 00204 if ( !$fit ) { 00205 if ( count( $pageIds[NS_FILE] ) == 1 ) { 00206 $this->setContinueEnumParameter( 'start', 00207 wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) ); 00208 } else { 00209 $this->setContinueEnumParameter( 'continue', 00210 $this->getContinueStr( $oldie ) ); 00211 } 00212 break; 00213 } 00214 } 00215 if ( !$fit ) { 00216 break; 00217 } 00218 } 00219 } 00220 } 00221 00227 public function getScale( $params ) { 00228 $p = $this->getModulePrefix(); 00229 00230 if ( $params['urlwidth'] != -1 ) { 00231 $scale = array(); 00232 $scale['width'] = $params['urlwidth']; 00233 $scale['height'] = $params['urlheight']; 00234 } elseif ( $params['urlheight'] != -1 ) { 00235 // Height is specified but width isn't 00236 // Don't set $scale['width']; this signals mergeThumbParams() to fill it with the image's width 00237 $scale = array(); 00238 $scale['height'] = $params['urlheight']; 00239 } else { 00240 if ( $params['urlparam'] ) { 00241 // Audio files might not have a width/height. 00242 $scale = array(); 00243 } else { 00244 $scale = null; 00245 } 00246 } 00247 00248 return $scale; 00249 } 00250 00260 protected function mergeThumbParams( $image, $thumbParams, $otherParams ) { 00261 if ( $thumbParams === null ) { 00262 // No scaling requested 00263 return null; 00264 } 00265 if ( !isset( $thumbParams['width'] ) && isset( $thumbParams['height'] ) ) { 00266 // We want to limit only by height in this situation, so pass the 00267 // image's full width as the limiting width. But some file types 00268 // don't have a width of their own, so pick something arbitrary so 00269 // thumbnailing the default icon works. 00270 if ( $image->getWidth() <= 0 ) { 00271 $thumbParams['width'] = max( $this->getConfig()->get( 'ThumbLimits' ) ); 00272 } else { 00273 $thumbParams['width'] = $image->getWidth(); 00274 } 00275 } 00276 00277 if ( !$otherParams ) { 00278 $this->checkParameterNormalise( $image, $thumbParams ); 00279 return $thumbParams; 00280 } 00281 $p = $this->getModulePrefix(); 00282 00283 $h = $image->getHandler(); 00284 if ( !$h ) { 00285 $this->setWarning( 'Could not create thumbnail because ' . 00286 $image->getName() . ' does not have an associated image handler' ); 00287 00288 return $thumbParams; 00289 } 00290 00291 $paramList = $h->parseParamString( $otherParams ); 00292 if ( !$paramList ) { 00293 // Just set a warning (instead of dieUsage), as in many cases 00294 // we could still render the image using width and height parameters, 00295 // and this type of thing could happen between different versions of 00296 // handlers. 00297 $this->setWarning( "Could not parse {$p}urlparam for " . $image->getName() 00298 . '. Using only width and height' ); 00299 $this->checkParameterNormalise( $image, $thumbParams ); 00300 return $thumbParams; 00301 } 00302 00303 if ( isset( $paramList['width'] ) && isset( $thumbParams['width'] ) ) { 00304 if ( intval( $paramList['width'] ) != intval( $thumbParams['width'] ) ) { 00305 $this->setWarning( "Ignoring width value set in {$p}urlparam ({$paramList['width']}) " 00306 . "in favor of width value derived from {$p}urlwidth/{$p}urlheight " 00307 . "({$thumbParams['width']})" ); 00308 } 00309 } 00310 00311 foreach ( $paramList as $name => $value ) { 00312 if ( !$h->validateParam( $name, $value ) ) { 00313 $this->dieUsage( "Invalid value for {$p}urlparam ($name=$value)", "urlparam" ); 00314 } 00315 } 00316 00317 $finalParams = $thumbParams + $paramList; 00318 $this->checkParameterNormalise( $image, $finalParams ); 00319 return $finalParams; 00320 } 00321 00333 protected function checkParameterNormalise( $image, $finalParams ) { 00334 $h = $image->getHandler(); 00335 if ( !$h ) { 00336 return; 00337 } 00338 // Note: normaliseParams modifies the array in place, but we aren't interested 00339 // in the actual normalised version, only if we can actually normalise them, 00340 // so we use the functions scope to throw away the normalisations. 00341 if ( !$h->normaliseParams( $image, $finalParams ) ) { 00342 $this->dieUsage( "Could not normalise image parameters for " . $image->getName(), "urlparamnormal" ); 00343 } 00344 } 00345 00361 static function getInfo( $file, $prop, $result, $thumbParams = null, $opts = false ) { 00362 global $wgContLang; 00363 00364 $anyHidden = false; 00365 00366 if ( !$opts || is_string( $opts ) ) { 00367 $opts = array( 00368 'version' => $opts ?: 'latest', 00369 'language' => $wgContLang, 00370 'multilang' => false, 00371 'extmetadatafilter' => array(), 00372 'revdelUser' => null, 00373 ); 00374 } 00375 $version = $opts['version']; 00376 $vals = array(); 00377 // Timestamp is shown even if the file is revdelete'd in interface 00378 // so do same here. 00379 if ( isset( $prop['timestamp'] ) ) { 00380 $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $file->getTimestamp() ); 00381 } 00382 00383 // Handle external callers who don't pass revdelUser 00384 if ( isset( $opts['revdelUser'] ) && $opts['revdelUser'] ) { 00385 $revdelUser = $opts['revdelUser']; 00386 $canShowField = function ( $field ) use ( $file, $revdelUser ) { 00387 return $file->userCan( $field, $revdelUser ); 00388 }; 00389 } else { 00390 $canShowField = function ( $field ) use ( $file ) { 00391 return !$file->isDeleted( $field ); 00392 }; 00393 } 00394 00395 $user = isset( $prop['user'] ); 00396 $userid = isset( $prop['userid'] ); 00397 00398 if ( $user || $userid ) { 00399 if ( $file->isDeleted( File::DELETED_USER ) ) { 00400 $vals['userhidden'] = ''; 00401 $anyHidden = true; 00402 } 00403 if ( $canShowField( File::DELETED_USER ) ) { 00404 if ( $user ) { 00405 $vals['user'] = $file->getUser(); 00406 } 00407 if ( $userid ) { 00408 $vals['userid'] = $file->getUser( 'id' ); 00409 } 00410 if ( !$file->getUser( 'id' ) ) { 00411 $vals['anon'] = ''; 00412 } 00413 } 00414 } 00415 00416 // This is shown even if the file is revdelete'd in interface 00417 // so do same here. 00418 if ( isset( $prop['size'] ) || isset( $prop['dimensions'] ) ) { 00419 $vals['size'] = intval( $file->getSize() ); 00420 $vals['width'] = intval( $file->getWidth() ); 00421 $vals['height'] = intval( $file->getHeight() ); 00422 00423 $pageCount = $file->pageCount(); 00424 if ( $pageCount !== false ) { 00425 $vals['pagecount'] = $pageCount; 00426 } 00427 00428 // length as in how many seconds long a video is. 00429 $length = $file->getLength(); 00430 if ( $length ) { 00431 // Call it duration, because "length" can be ambiguous. 00432 $vals['duration'] = (float)$length; 00433 } 00434 } 00435 00436 $pcomment = isset( $prop['parsedcomment'] ); 00437 $comment = isset( $prop['comment'] ); 00438 00439 if ( $pcomment || $comment ) { 00440 if ( $file->isDeleted( File::DELETED_COMMENT ) ) { 00441 $vals['commenthidden'] = ''; 00442 $anyHidden = true; 00443 } 00444 if ( $canShowField( File::DELETED_COMMENT ) ) { 00445 if ( $pcomment ) { 00446 $vals['parsedcomment'] = Linker::formatComment( 00447 $file->getDescription( File::RAW ), $file->getTitle() ); 00448 } 00449 if ( $comment ) { 00450 $vals['comment'] = $file->getDescription( File::RAW ); 00451 } 00452 } 00453 } 00454 00455 $canonicaltitle = isset( $prop['canonicaltitle'] ); 00456 $url = isset( $prop['url'] ); 00457 $sha1 = isset( $prop['sha1'] ); 00458 $meta = isset( $prop['metadata'] ); 00459 $extmetadata = isset( $prop['extmetadata'] ); 00460 $commonmeta = isset( $prop['commonmetadata'] ); 00461 $mime = isset( $prop['mime'] ); 00462 $mediatype = isset( $prop['mediatype'] ); 00463 $archive = isset( $prop['archivename'] ); 00464 $bitdepth = isset( $prop['bitdepth'] ); 00465 $uploadwarning = isset( $prop['uploadwarning'] ); 00466 00467 if ( $uploadwarning ) { 00468 $vals['html'] = SpecialUpload::getExistsWarning( UploadBase::getExistsWarning( $file ) ); 00469 } 00470 00471 if ( $file->isDeleted( File::DELETED_FILE ) ) { 00472 $vals['filehidden'] = ''; 00473 $anyHidden = true; 00474 } 00475 00476 if ( $anyHidden && $file->isDeleted( File::DELETED_RESTRICTED ) ) { 00477 $vals['suppressed'] = true; 00478 } 00479 00480 if ( !$canShowField( File::DELETED_FILE ) ) { 00481 //Early return, tidier than indenting all following things one level 00482 return $vals; 00483 } 00484 00485 if ( $canonicaltitle ) { 00486 $vals['canonicaltitle'] = $file->getTitle()->getPrefixedText(); 00487 } 00488 00489 if ( $url ) { 00490 if ( !is_null( $thumbParams ) ) { 00491 $mto = $file->transform( $thumbParams ); 00492 self::$transformCount++; 00493 if ( $mto && !$mto->isError() ) { 00494 $vals['thumburl'] = wfExpandUrl( $mto->getUrl(), PROTO_CURRENT ); 00495 00496 // bug 23834 - If the URL's are the same, we haven't resized it, so shouldn't give the wanted 00497 // thumbnail sizes for the thumbnail actual size 00498 if ( $mto->getUrl() !== $file->getUrl() ) { 00499 $vals['thumbwidth'] = intval( $mto->getWidth() ); 00500 $vals['thumbheight'] = intval( $mto->getHeight() ); 00501 } else { 00502 $vals['thumbwidth'] = intval( $file->getWidth() ); 00503 $vals['thumbheight'] = intval( $file->getHeight() ); 00504 } 00505 00506 if ( isset( $prop['thumbmime'] ) && $file->getHandler() ) { 00507 list( , $mime ) = $file->getHandler()->getThumbType( 00508 $mto->getExtension(), $file->getMimeType(), $thumbParams ); 00509 $vals['thumbmime'] = $mime; 00510 } 00511 } elseif ( $mto && $mto->isError() ) { 00512 $vals['thumberror'] = $mto->toText(); 00513 } 00514 } 00515 $vals['url'] = wfExpandUrl( $file->getFullURL(), PROTO_CURRENT ); 00516 $vals['descriptionurl'] = wfExpandUrl( $file->getDescriptionUrl(), PROTO_CURRENT ); 00517 } 00518 00519 if ( $sha1 ) { 00520 $vals['sha1'] = wfBaseConvert( $file->getSha1(), 36, 16, 40 ); 00521 } 00522 00523 if ( $meta ) { 00524 wfSuppressWarnings(); 00525 $metadata = unserialize( $file->getMetadata() ); 00526 wfRestoreWarnings(); 00527 if ( $metadata && $version !== 'latest' ) { 00528 $metadata = $file->convertMetadataVersion( $metadata, $version ); 00529 } 00530 $vals['metadata'] = $metadata ? self::processMetaData( $metadata, $result ) : null; 00531 } 00532 if ( $commonmeta ) { 00533 $metaArray = $file->getCommonMetaArray(); 00534 $vals['commonmetadata'] = $metaArray ? self::processMetaData( $metaArray, $result ) : array(); 00535 } 00536 00537 if ( $extmetadata ) { 00538 // Note, this should return an array where all the keys 00539 // start with a letter, and all the values are strings. 00540 // Thus there should be no issue with format=xml. 00541 $format = new FormatMetadata; 00542 $format->setSingleLanguage( !$opts['multilang'] ); 00543 $format->getContext()->setLanguage( $opts['language'] ); 00544 $extmetaArray = $format->fetchExtendedMetadata( $file ); 00545 if ( $opts['extmetadatafilter'] ) { 00546 $extmetaArray = array_intersect_key( 00547 $extmetaArray, array_flip( $opts['extmetadatafilter'] ) 00548 ); 00549 } 00550 $vals['extmetadata'] = $extmetaArray; 00551 } 00552 00553 if ( $mime ) { 00554 $vals['mime'] = $file->getMimeType(); 00555 } 00556 00557 if ( $mediatype ) { 00558 $vals['mediatype'] = $file->getMediaType(); 00559 } 00560 00561 if ( $archive && $file->isOld() ) { 00562 $vals['archivename'] = $file->getArchiveName(); 00563 } 00564 00565 if ( $bitdepth ) { 00566 $vals['bitdepth'] = $file->getBitDepth(); 00567 } 00568 00569 return $vals; 00570 } 00571 00579 static function getTransformCount() { 00580 return self::$transformCount; 00581 } 00582 00589 public static function processMetaData( $metadata, $result ) { 00590 $retval = array(); 00591 if ( is_array( $metadata ) ) { 00592 foreach ( $metadata as $key => $value ) { 00593 $r = array( 'name' => $key ); 00594 if ( is_array( $value ) ) { 00595 $r['value'] = self::processMetaData( $value, $result ); 00596 } else { 00597 $r['value'] = $value; 00598 } 00599 $retval[] = $r; 00600 } 00601 } 00602 $result->setIndexedTagName( $retval, 'metadata' ); 00603 00604 return $retval; 00605 } 00606 00607 public function getCacheMode( $params ) { 00608 if ( $this->userCanSeeRevDel() ) { 00609 return 'private'; 00610 } 00611 00612 return 'public'; 00613 } 00614 00620 protected function getContinueStr( $img, $start = null ) { 00621 if ( $start === null ) { 00622 $start = $img->getTimestamp(); 00623 } 00624 00625 return $img->getOriginalTitle()->getDBkey() . '|' . $start; 00626 } 00627 00628 public function getAllowedParams() { 00629 global $wgContLang; 00630 00631 return array( 00632 'prop' => array( 00633 ApiBase::PARAM_ISMULTI => true, 00634 ApiBase::PARAM_DFLT => 'timestamp|user', 00635 ApiBase::PARAM_TYPE => self::getPropertyNames() 00636 ), 00637 'limit' => array( 00638 ApiBase::PARAM_TYPE => 'limit', 00639 ApiBase::PARAM_DFLT => 1, 00640 ApiBase::PARAM_MIN => 1, 00641 ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1, 00642 ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2 00643 ), 00644 'start' => array( 00645 ApiBase::PARAM_TYPE => 'timestamp' 00646 ), 00647 'end' => array( 00648 ApiBase::PARAM_TYPE => 'timestamp' 00649 ), 00650 'urlwidth' => array( 00651 ApiBase::PARAM_TYPE => 'integer', 00652 ApiBase::PARAM_DFLT => -1 00653 ), 00654 'urlheight' => array( 00655 ApiBase::PARAM_TYPE => 'integer', 00656 ApiBase::PARAM_DFLT => -1 00657 ), 00658 'metadataversion' => array( 00659 ApiBase::PARAM_TYPE => 'string', 00660 ApiBase::PARAM_DFLT => '1', 00661 ), 00662 'extmetadatalanguage' => array( 00663 ApiBase::PARAM_TYPE => 'string', 00664 ApiBase::PARAM_DFLT => $wgContLang->getCode(), 00665 ), 00666 'extmetadatamultilang' => array( 00667 ApiBase::PARAM_TYPE => 'boolean', 00668 ApiBase::PARAM_DFLT => false, 00669 ), 00670 'extmetadatafilter' => array( 00671 ApiBase::PARAM_TYPE => 'string', 00672 ApiBase::PARAM_ISMULTI => true, 00673 ), 00674 'urlparam' => array( 00675 ApiBase::PARAM_DFLT => '', 00676 ApiBase::PARAM_TYPE => 'string', 00677 ), 00678 'continue' => null, 00679 'localonly' => false, 00680 ); 00681 } 00682 00690 public static function getPropertyNames( $filter = array() ) { 00691 return array_diff( array_keys( self::getProperties() ), $filter ); 00692 } 00693 00700 private static function getProperties( $modulePrefix = '' ) { 00701 return array( 00702 'timestamp' => ' timestamp - Adds timestamp for the uploaded version', 00703 'user' => ' user - Adds the user who uploaded the image version', 00704 'userid' => ' userid - Add the user ID that uploaded the image version', 00705 'comment' => ' comment - Comment on the version', 00706 'parsedcomment' => ' parsedcomment - Parse the comment on the version', 00707 'canonicaltitle' => ' canonicaltitle - Adds the canonical title of the image file', 00708 'url' => ' url - Gives URL to the image and the description page', 00709 'size' => ' size - Adds the size of the image in bytes, ' . 00710 'its height and its width. Page count and duration are added if applicable', 00711 'dimensions' => ' dimensions - Alias for size', // B/C with Allimages 00712 'sha1' => ' sha1 - Adds SHA-1 hash for the image', 00713 'mime' => ' mime - Adds MIME type of the image', 00714 'thumbmime' => ' thumbmime - Adds MIME type of the image thumbnail' . 00715 ' (requires url and param ' . $modulePrefix . 'urlwidth)', 00716 'mediatype' => ' mediatype - Adds the media type of the image', 00717 'metadata' => ' metadata - Lists Exif metadata for the version of the image', 00718 'commonmetadata' => ' commonmetadata - Lists file format generic metadata ' . 00719 'for the version of the image', 00720 'extmetadata' => ' extmetadata - Lists formatted metadata combined ' . 00721 'from multiple sources. Results are HTML formatted.', 00722 'archivename' => ' archivename - Adds the file name of the archive ' . 00723 'version for non-latest versions', 00724 'bitdepth' => ' bitdepth - Adds the bit depth of the version', 00725 'uploadwarning' => ' uploadwarning - Used by the Special:Upload page to ' . 00726 'get information about an existing file. Not intended for use outside MediaWiki core', 00727 ); 00728 } 00729 00737 public static function getPropertyDescriptions( $filter = array(), $modulePrefix = '' ) { 00738 return array_merge( 00739 array( 'What image information to get:' ), 00740 array_values( array_diff_key( self::getProperties( $modulePrefix ), array_flip( $filter ) ) ) 00741 ); 00742 } 00743 00748 public function getParamDescription() { 00749 $p = $this->getModulePrefix(); 00750 00751 return array( 00752 'prop' => self::getPropertyDescriptions( array(), $p ), 00753 'urlwidth' => array( 00754 "If {$p}prop=url is set, a URL to an image scaled to this width will be returned.", 00755 'For performance reasons if this option is used, ' . 00756 'no more than ' . self::TRANSFORM_LIMIT . ' scaled images will be returned.' 00757 ), 00758 'urlheight' => "Similar to {$p}urlwidth.", 00759 'urlparam' => array( 00760 "A handler specific parameter string. For example, pdf's ", 00761 "might use 'page15-100px'." 00762 ), 00763 'limit' => 'How many image revisions to return per image', 00764 'start' => 'Timestamp to start listing from', 00765 'end' => 'Timestamp to stop listing at', 00766 'metadataversion' 00767 => array( "Version of metadata to use. if 'latest' is specified, use latest version.", 00768 "Defaults to '1' for backwards compatibility" ), 00769 'extmetadatalanguage' => array( 00770 'What language to fetch extmetadata in. This affects both which', 00771 'translation to fetch, if multiple are available, as well as how things', 00772 'like numbers and various values are formatted.' 00773 ), 00774 'extmetadatamultilang' 00775 =>'If translations for extmetadata property are available, fetch all of them.', 00776 'extmetadatafilter' 00777 => "If specified and non-empty, only these keys will be returned for {$p}prop=extmetadata", 00778 'continue' => 'If the query response includes a continue value, ' . 00779 'use it here to get another page of results', 00780 'localonly' => 'Look only for files in the local repository', 00781 ); 00782 } 00783 00784 public function getDescription() { 00785 return 'Returns image information and upload history.'; 00786 } 00787 00788 public function getExamples() { 00789 return array( 00790 'api.php?action=query&titles=File:Albert%20Einstein%20Head.jpg&prop=imageinfo', 00791 'api.php?action=query&titles=File:Test.jpg&prop=imageinfo&iilimit=50&' . 00792 'iiend=20071231235959&iiprop=timestamp|user|url', 00793 ); 00794 } 00795 00796 public function getHelpUrls() { 00797 return 'https://www.mediawiki.org/wiki/API:Properties#imageinfo_.2F_ii'; 00798 } 00799 }