]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/api/ApiQueryImageInfo.php
MediaWiki 1.15.5
[autoinstallsdev/mediawiki.git] / includes / api / ApiQueryImageInfo.php
1 <?php
2
3 /*
4  * Created on July 6, 2007
5  *
6  * API for MediaWiki 1.8+
7  *
8  * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23  * http://www.gnu.org/copyleft/gpl.html
24  */
25
26 if (!defined('MEDIAWIKI')) {
27         // Eclipse helper - will be ignored in production
28         require_once ('ApiQueryBase.php');
29 }
30
31 /**
32  * A query action to get image information and upload history.
33  *
34  * @ingroup API
35  */
36 class ApiQueryImageInfo extends ApiQueryBase {
37
38         public function __construct($query, $moduleName) {
39                 parent :: __construct($query, $moduleName, 'ii');
40         }
41
42         public function execute() {
43                 $params = $this->extractRequestParams();
44
45                 $prop = array_flip($params['prop']);
46
47                 if($params['urlheight'] != -1 && $params['urlwidth'] == -1)
48                         $this->dieUsage("iiurlheight cannot be used without iiurlwidth", 'iiurlwidth');
49                 
50                 if ( $params['urlwidth'] != -1 ) {
51                         $scale = array();
52                         $scale['width'] = $params['urlwidth'];
53                         $scale['height'] = $params['urlheight'];
54                 } else {
55                         $scale = null;
56                 }
57
58                 $pageIds = $this->getPageSet()->getAllTitlesByNamespace();
59                 if ( !empty( $pageIds[NS_FILE] ) ) {
60                         $titles = array_keys($pageIds[NS_FILE]);
61                         asort($titles); // Ensure the order is always the same
62
63                         $skip = false;
64                         if(!is_null($params['continue']))
65                         {
66                                 $skip = true;
67                                 $cont = explode('|', $params['continue']);
68                                 if(count($cont) != 2)
69                                         $this->dieUsage("Invalid continue param. You should pass the original " .
70                                                         "value returned by the previous query", "_badcontinue");
71                                 $fromTitle = strval($cont[0]);
72                                 $fromTimestamp = $cont[1];
73                                 // Filter out any titles before $fromTitle
74                                 foreach($titles as $key => $title)
75                                         if($title < $fromTitle)
76                                                 unset($titles[$key]);
77                                         else
78                                                 break;
79                         }
80
81                         $result = $this->getResult();
82                         $images = RepoGroup::singleton()->findFiles( $titles );
83                         foreach ( $images as $img ) {
84                                 $start = $skip ? $fromTimestamp : $params['start'];
85                                 $pageId = $pageIds[NS_IMAGE][ $img->getOriginalTitle()->getDBkey() ];
86
87                                 $fit = $result->addValue(
88                                         array('query', 'pages', intval($pageId)),
89                                         'imagerepository', $img->getRepoName()
90                                 );
91                                 if(!$fit)
92                                 {
93                                         if(count($pageIds[NS_IMAGE]) == 1)
94                                                 # The user is screwed. imageinfo can't be solely
95                                                 # responsible for exceeding the limit in this case,
96                                                 # so set a query-continue that just returns the same
97                                                 # thing again. When the violating queries have been
98                                                 # out-continued, the result will get through
99                                                 $this->setContinueEnumParameter('start',
100                                                         wfTimestamp(TS_ISO_8601, $img->getTimestamp()));
101                                         else
102                                                 $this->setContinueEnumParameter('continue',
103                                                         $this->getContinueStr($img));
104                                         break;
105                                 }
106
107                                 // Get information about the current version first
108                                 // Check that the current version is within the start-end boundaries
109                                 $gotOne = false;
110                                 if((is_null($start) || $img->getTimestamp() <= $start) &&
111                                                 (is_null($params['end']) || $img->getTimestamp() >= $params['end'])) {
112                                         $gotOne = true;
113                                         $fit = $this->addPageSubItem($pageId,
114                                                 self::getInfo( $img, $prop, $result, $scale));
115                                         if(!$fit)
116                                         {
117                                                 if(count($pageIds[NS_IMAGE]) == 1)
118                                                         # See the 'the user is screwed' comment above
119                                                         $this->setContinueEnumParameter('start',
120                                                                 wfTimestamp(TS_ISO_8601, $img->getTimestamp()));
121                                                 else
122                                                         $this->setContinueEnumParameter('continue',
123                                                                 $this->getContinueStr($img));
124                                                 break;
125                                         }
126                                 }
127
128                                 // Now get the old revisions
129                                 // Get one more to facilitate query-continue functionality
130                                 $count = ($gotOne ? 1 : 0);
131                                 $oldies = $img->getHistory($params['limit'] - $count + 1, $start, $params['end']);
132                                 foreach($oldies as $oldie) {
133                                         if(++$count > $params['limit']) {
134                                                 // We've reached the extra one which shows that there are additional pages to be had. Stop here...
135                                                 // Only set a query-continue if there was only one title
136                                                 if(count($pageIds[NS_FILE]) == 1)
137                                                 {
138                                                         $this->setContinueEnumParameter('start',
139                                                                 wfTimestamp(TS_ISO_8601, $oldie->getTimestamp()));
140                                                 }
141                                                 break;
142                                         }
143                                         $fit = $this->addPageSubItem($pageId,
144                                                 self::getInfo($oldie, $prop, $result));
145                                         if(!$fit)
146                                         {
147                                                 if(count($pageIds[NS_IMAGE]) == 1)
148                                                         $this->setContinueEnumParameter('start',
149                                                                 wfTimestamp(TS_ISO_8601, $oldie->getTimestamp()));
150                                                 else
151                                                         $this->setContinueEnumParameter('continue',
152                                                                 $this->getContinueStr($oldie));
153                                                 break;
154                                         }
155                                 }
156                                 if(!$fit)
157                                         break;
158                                 $skip = false;
159                         }
160                         
161                         $missing = array_diff( array_keys( $pageIds[NS_FILE] ), array_keys( $images ) );
162                         foreach ($missing as $title) {
163                                 $result->addValue(
164                                         array('query', 'pages', intval($pageIds[NS_FILE][$title])),
165                                         'imagerepository', ''
166                                 );
167                                 // The above can't fail because it doesn't increase the result size
168                         }
169                 }
170         }
171
172         /**
173          * Get result information for an image revision
174          * @param File f The image
175          * @return array Result array
176          */
177         static function getInfo($file, $prop, $result, $scale = null) {
178                 $vals = array();
179                 if( isset( $prop['timestamp'] ) )
180                         $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $file->getTimestamp());
181                 if( isset( $prop['user'] ) ) {
182                         $vals['user'] = $file->getUser();
183                         if( !$file->getUser( 'id' ) )
184                                 $vals['anon'] = '';
185                 }
186                 if( isset( $prop['size'] ) || isset( $prop['dimensions'] ) ) {
187                         $vals['size'] = intval( $file->getSize() );
188                         $vals['width'] = intval( $file->getWidth() );
189                         $vals['height'] = intval( $file->getHeight() );
190                 }
191                 if( isset( $prop['url'] ) ) {
192                         if( !is_null( $scale ) && !$file->isOld() ) {
193                                 $mto = $file->transform( array( 'width' => $scale['width'], 'height' => $scale['height'] ) );
194                                 if( $mto && !$mto->isError() )
195                                 {
196                                         $vals['thumburl'] = $mto->getUrl();
197                                         $vals['thumbwidth'] = intval( $mto->getWidth() );
198                                         $vals['thumbheight'] = intval( $mto->getHeight() );
199                                 }
200                         }
201                         $vals['url'] = $file->getFullURL();
202                         $vals['descriptionurl'] = wfExpandUrl( $file->getDescriptionUrl() );
203                 }
204                 if( isset( $prop['comment'] ) )
205                         $vals['comment'] = $file->getDescription();
206                 if( isset( $prop['sha1'] ) )
207                         $vals['sha1'] = wfBaseConvert( $file->getSha1(), 36, 16, 40 );
208                 if( isset( $prop['metadata'] ) ) {
209                         $metadata = $file->getMetadata();
210                         $vals['metadata'] = $metadata ? self::processMetaData( unserialize( $metadata ), $result ) : null;
211                 }
212                 if( isset( $prop['mime'] ) ) 
213                         $vals['mime'] = $file->getMimeType();
214                 
215                 if( isset( $prop['archivename'] ) && $file->isOld() )
216                         $vals['archivename'] = $file->getArchiveName();
217                         
218                 if( isset( $prop['bitdepth'] ) )
219                         $vals['bitdepth'] = $file->getBitDepth();
220
221                 return $vals;
222         }
223         
224         public static function processMetaData($metadata, $result)
225         {
226                 $retval = array();
227                 if ( is_array( $metadata ) ) {
228                         foreach($metadata as $key => $value)
229                         {
230                                 $r = array('name' => $key);
231                                 if(is_array($value))
232                                         $r['value'] = self::processMetaData($value, $result);
233                                 else
234                                         $r['value'] = $value;
235                                 $retval[] = $r;
236                         }
237                 }
238                 $result->setIndexedTagName($retval, 'metadata');
239                 return $retval;
240         }
241
242         public function getCacheMode( $params ) {
243                 return 'public';
244         }
245
246         private function getContinueStr($img)
247         {
248                 return $img->getOriginalTitle()->getText() .
249                         '|' .  $img->getTimestamp();
250         }
251
252         public function getAllowedParams() {
253                 return array (
254                         'prop' => array (
255                                 ApiBase :: PARAM_ISMULTI => true,
256                                 ApiBase :: PARAM_DFLT => 'timestamp|user',
257                                 ApiBase :: PARAM_TYPE => array (
258                                         'timestamp',
259                                         'user',
260                                         'comment',
261                                         'url',
262                                         'size',
263                                         'sha1',
264                                         'mime',
265                                         'metadata',
266                                         'archivename',
267                                         'bitdepth',
268                                 )
269                         ),
270                         'limit' => array(
271                                 ApiBase :: PARAM_TYPE => 'limit',
272                                 ApiBase :: PARAM_DFLT => 1,
273                                 ApiBase :: PARAM_MIN => 1,
274                                 ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
275                                 ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
276                         ),
277                         'start' => array(
278                                 ApiBase :: PARAM_TYPE => 'timestamp'
279                         ),
280                         'end' => array(
281                                 ApiBase :: PARAM_TYPE => 'timestamp'
282                         ),
283                         'urlwidth' => array(
284                                 ApiBase :: PARAM_TYPE => 'integer',
285                                 ApiBase :: PARAM_DFLT => -1
286                         ),
287                         'urlheight' => array(
288                                 ApiBase :: PARAM_TYPE => 'integer',
289                                 ApiBase :: PARAM_DFLT => -1
290                         ),
291                         'continue' => null,
292                 );
293         }
294
295         public function getParamDescription() {
296                 return array (
297                         'prop' => 'What image information to get.',
298                         'limit' => 'How many image revisions to return',
299                         'start' => 'Timestamp to start listing from',
300                         'end' => 'Timestamp to stop listing at',
301                         'urlwidth' => array('If iiprop=url is set, a URL to an image scaled to this width will be returned.',
302                                             'Only the current version of the image can be scaled.'),
303                         'urlheight' => 'Similar to iiurlwidth. Cannot be used without iiurlwidth',
304                         'continue' => 'When more results are available, use this to continue',
305                 );
306         }
307
308         public function getDescription() {
309                 return array (
310                         'Returns image information and upload history'
311                 );
312         }
313
314         protected function getExamples() {
315                 return array (
316                         'api.php?action=query&titles=File:Albert%20Einstein%20Head.jpg&prop=imageinfo',
317                         'api.php?action=query&titles=File:Test.jpg&prop=imageinfo&iilimit=50&iiend=20071231235959&iiprop=timestamp|user|url',
318                 );
319         }
320
321         public function getVersion() {
322                 return __CLASS__ . ': $Id: ApiQueryImageInfo.php 69986 2010-07-27 03:57:39Z tstarling $';
323         }
324 }