00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 if (!defined('MEDIAWIKI')) {
00027
00028 require_once ('ApiQueryBase.php');
00029 }
00030
00036 class ApiQueryImageInfo extends ApiQueryBase {
00037
00038 public function __construct($query, $moduleName) {
00039 parent :: __construct($query, $moduleName, 'ii');
00040 }
00041
00042 public function execute() {
00043 $params = $this->extractRequestParams();
00044
00045 $prop = array_flip($params['prop']);
00046
00047 if($params['urlheight'] != -1 && $params['urlwidth'] == -1)
00048 $this->dieUsage("iiurlheight cannot be used without iiurlwidth", 'iiurlwidth');
00049
00050 if ( $params['urlwidth'] != -1 ) {
00051 $scale = array();
00052 $scale['width'] = $params['urlwidth'];
00053 $scale['height'] = $params['urlheight'];
00054 } else {
00055 $scale = null;
00056 }
00057
00058 $pageIds = $this->getPageSet()->getAllTitlesByNamespace();
00059 if ( !empty( $pageIds[NS_FILE] ) ) {
00060 $titles = array_keys($pageIds[NS_FILE]);
00061 asort($titles);
00062
00063 $skip = false;
00064 if(!is_null($params['continue']))
00065 {
00066 $skip = true;
00067 $cont = explode('|', $params['continue']);
00068 if(count($cont) != 2)
00069 $this->dieUsage("Invalid continue param. You should pass the original " .
00070 "value returned by the previous query", "_badcontinue");
00071 $fromTitle = strval($cont[0]);
00072 $fromTimestamp = $cont[1];
00073
00074 foreach($titles as $key => $title)
00075 if($title < $fromTitle)
00076 unset($titles[$key]);
00077 else
00078 break;
00079 }
00080
00081 $result = $this->getResult();
00082 $images = RepoGroup::singleton()->findFiles( $titles );
00083 foreach ( $images as $img ) {
00084 $start = $skip ? $fromTimestamp : $params['start'];
00085 $pageId = $pageIds[NS_IMAGE][ $img->getOriginalTitle()->getDBkey() ];
00086
00087 $fit = $result->addValue(
00088 array('query', 'pages', intval($pageId)),
00089 'imagerepository', $img->getRepoName()
00090 );
00091 if(!$fit)
00092 {
00093 if(count($pageIds[NS_IMAGE]) == 1)
00094 # The user is screwed. imageinfo can't be solely
00095 # responsible for exceeding the limit in this case,
00096 # so set a query-continue that just returns the same
00097 # thing again. When the violating queries have been
00098 # out-continued, the result will get through
00099 $this->setContinueEnumParameter('start',
00100 wfTimestamp(TS_ISO_8601, $img->getTimestamp()));
00101 else
00102 $this->setContinueEnumParameter('continue',
00103 $this->getContinueStr($img));
00104 break;
00105 }
00106
00107 // Get information about the current version first
00108 // Check that the current version is within the start-end boundaries
00109 $gotOne = false;
00110 if((is_null($start) || $img->getTimestamp() <= $start) &&
00111 (is_null($params['end']) || $img->getTimestamp() >= $params['end'])) {
00112 $gotOne = true;
00113 $fit = $this->addPageSubItem($pageId,
00114 self::getInfo( $img, $prop, $result, $scale));
00115 if(!$fit)
00116 {
00117 if(count($pageIds[NS_IMAGE]) == 1)
00118 # See the 'the user is screwed' comment above
00119 $this->setContinueEnumParameter('start',
00120 wfTimestamp(TS_ISO_8601, $img->getTimestamp()));
00121 else
00122 $this->setContinueEnumParameter('continue',
00123 $this->getContinueStr($img));
00124 break;
00125 }
00126 }
00127
00128 // Now get the old revisions
00129 // Get one more to facilitate query-continue functionality
00130 $count = ($gotOne ? 1 : 0);
00131 $oldies = $img->getHistory($params['limit'] - $count + 1, $start, $params['end']);
00132 foreach($oldies as $oldie) {
00133 if(++$count > $params['limit']) {
00134 // We've reached the extra one which shows that there are additional pages to be had. Stop here...
00135
00136 if(count($pageIds[NS_FILE]) == 1)
00137 {
00138 $this->setContinueEnumParameter('start',
00139 wfTimestamp(TS_ISO_8601, $oldie->getTimestamp()));
00140 }
00141 break;
00142 }
00143 $fit = $this->addPageSubItem($pageId,
00144 self::getInfo($oldie, $prop, $result));
00145 if(!$fit)
00146 {
00147 if(count($pageIds[NS_IMAGE]) == 1)
00148 $this->setContinueEnumParameter('start',
00149 wfTimestamp(TS_ISO_8601, $oldie->getTimestamp()));
00150 else
00151 $this->setContinueEnumParameter('continue',
00152 $this->getContinueStr($oldie));
00153 break;
00154 }
00155 }
00156 if(!$fit)
00157 break;
00158 $skip = false;
00159 }
00160
00161 $missing = array_diff( array_keys( $pageIds[NS_FILE] ), array_keys( $images ) );
00162 foreach ($missing as $title) {
00163 $result->addValue(
00164 array('query', 'pages', intval($pageIds[NS_FILE][$title])),
00165 'imagerepository', ''
00166 );
00167
00168 }
00169 }
00170 }
00171
00177 static function getInfo($file, $prop, $result, $scale = null) {
00178 $vals = array();
00179 if( isset( $prop['timestamp'] ) )
00180 $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $file->getTimestamp());
00181 if( isset( $prop['user'] ) ) {
00182 $vals['user'] = $file->getUser();
00183 if( !$file->getUser( 'id' ) )
00184 $vals['anon'] = '';
00185 }
00186 if( isset( $prop['size'] ) || isset( $prop['dimensions'] ) ) {
00187 $vals['size'] = intval( $file->getSize() );
00188 $vals['width'] = intval( $file->getWidth() );
00189 $vals['height'] = intval( $file->getHeight() );
00190 }
00191 if( isset( $prop['url'] ) ) {
00192 if( !is_null( $scale ) && !$file->isOld() ) {
00193 $mto = $file->transform( array( 'width' => $scale['width'], 'height' => $scale['height'] ) );
00194 if( $mto && !$mto->isError() )
00195 {
00196 $vals['thumburl'] = $mto->getUrl();
00197 $vals['thumbwidth'] = intval( $mto->getWidth() );
00198 $vals['thumbheight'] = intval( $mto->getHeight() );
00199 }
00200 }
00201 $vals['url'] = $file->getFullURL();
00202 $vals['descriptionurl'] = wfExpandUrl( $file->getDescriptionUrl() );
00203 }
00204 if( isset( $prop['comment'] ) )
00205 $vals['comment'] = $file->getDescription();
00206 if( isset( $prop['sha1'] ) )
00207 $vals['sha1'] = wfBaseConvert( $file->getSha1(), 36, 16, 40 );
00208 if( isset( $prop['metadata'] ) ) {
00209 $metadata = $file->getMetadata();
00210 $vals['metadata'] = $metadata ? self::processMetaData( unserialize( $metadata ), $result ) : null;
00211 }
00212 if( isset( $prop['mime'] ) )
00213 $vals['mime'] = $file->getMimeType();
00214
00215 if( isset( $prop['archivename'] ) && $file->isOld() )
00216 $vals['archivename'] = $file->getArchiveName();
00217
00218 if( isset( $prop['bitdepth'] ) )
00219 $vals['bitdepth'] = $file->getBitDepth();
00220
00221 return $vals;
00222 }
00223
00224 public static function processMetaData($metadata, $result)
00225 {
00226 $retval = array();
00227 if ( is_array( $metadata ) ) {
00228 foreach($metadata as $key => $value)
00229 {
00230 $r = array('name' => $key);
00231 if(is_array($value))
00232 $r['value'] = self::processMetaData($value, $result);
00233 else
00234 $r['value'] = $value;
00235 $retval[] = $r;
00236 }
00237 }
00238 $result->setIndexedTagName($retval, 'metadata');
00239 return $retval;
00240 }
00241
00242 private function getContinueStr($img)
00243 {
00244 return $img->getOriginalTitle()->getText() .
00245 '|' . $img->getTimestamp();
00246 }
00247
00248 public function getAllowedParams() {
00249 return array (
00250 'prop' => array (
00251 ApiBase :: PARAM_ISMULTI => true,
00252 ApiBase :: PARAM_DFLT => 'timestamp|user',
00253 ApiBase :: PARAM_TYPE => array (
00254 'timestamp',
00255 'user',
00256 'comment',
00257 'url',
00258 'size',
00259 'sha1',
00260 'mime',
00261 'metadata',
00262 'archivename',
00263 'bitdepth',
00264 )
00265 ),
00266 'limit' => array(
00267 ApiBase :: PARAM_TYPE => 'limit',
00268 ApiBase :: PARAM_DFLT => 1,
00269 ApiBase :: PARAM_MIN => 1,
00270 ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
00271 ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
00272 ),
00273 'start' => array(
00274 ApiBase :: PARAM_TYPE => 'timestamp'
00275 ),
00276 'end' => array(
00277 ApiBase :: PARAM_TYPE => 'timestamp'
00278 ),
00279 'urlwidth' => array(
00280 ApiBase :: PARAM_TYPE => 'integer',
00281 ApiBase :: PARAM_DFLT => -1
00282 ),
00283 'urlheight' => array(
00284 ApiBase :: PARAM_TYPE => 'integer',
00285 ApiBase :: PARAM_DFLT => -1
00286 ),
00287 'continue' => null,
00288 );
00289 }
00290
00291 public function getParamDescription() {
00292 return array (
00293 'prop' => 'What image information to get.',
00294 'limit' => 'How many image revisions to return',
00295 'start' => 'Timestamp to start listing from',
00296 'end' => 'Timestamp to stop listing at',
00297 'urlwidth' => array('If iiprop=url is set, a URL to an image scaled to this width will be returned.',
00298 'Only the current version of the image can be scaled.'),
00299 'urlheight' => 'Similar to iiurlwidth. Cannot be used without iiurlwidth',
00300 'continue' => 'When more results are available, use this to continue',
00301 );
00302 }
00303
00304 public function getDescription() {
00305 return array (
00306 'Returns image information and upload history'
00307 );
00308 }
00309
00310 protected function getExamples() {
00311 return array (
00312 'api.php?action=query&titles=File:Albert%20Einstein%20Head.jpg&prop=imageinfo',
00313 'api.php?action=query&titles=File:Test.jpg&prop=imageinfo&iilimit=50&iiend=20071231235959&iiprop=timestamp|user|url',
00314 );
00315 }
00316
00317 public function getVersion() {
00318 return __CLASS__ . ': $Id: ApiQueryImageInfo.php 50097 2009-05-01 06:35:57Z tstarling $';
00319 }
00320 }