r16820 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r16819‎ | r16820 | r16821 >
Date:01:02, 6 October 2006
Author:yurik
Status:old
Tags:
Comment:
* API: Optimized PageSet object to avoid executing queries against page table twice.
Modified paths:
  • /trunk/phase3/includes/api/ApiMain.php (modified) (history)
  • /trunk/phase3/includes/api/ApiPageSet.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQuery.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryAllpages.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/api/ApiQuery.php
@@ -96,13 +96,13 @@
9797 * #5 Execute all requested modules
9898 */
9999 public function execute() {
100 - $prop = $list = $meta = $generator = null;
 100+ $prop = $list = $meta = $generator = $redirects = null;
101101 extract($this->extractRequestParams());
102102
103103 //
104104 // Create PageSet
105105 //
106 - $this->mPageSet = new ApiPageSet($this);
 106+ $this->mPageSet = new ApiPageSet($this, $redirects);
107107
108108 // Instantiate required modules
109109 $modules = array ();
@@ -126,7 +126,7 @@
127127 // If given, execute generator to substitute user supplied data with generated data.
128128 //
129129 if (isset ($generator))
130 - $this->executeGenerator($generator);
 130+ $this->executeGeneratorModule($generator, $redirects);
131131
132132 //
133133 // Populate page information for the given pageSet
@@ -212,7 +212,7 @@
213213 }
214214 }
215215
216 - protected function executeGenerator($generatorName) {
 216+ protected function executeGeneratorModule($generatorName, $redirects) {
217217
218218 // Find class that implements requested generator
219219 if (isset ($this->mQueryListModules[$generatorName])) {
@@ -226,7 +226,7 @@
227227
228228 // Use current pageset as the result, and create a new one just for the generator
229229 $resultPageSet = $this->mPageSet;
230 - $this->mPageSet = new ApiPageSet($this);
 230+ $this->mPageSet = new ApiPageSet($this, $redirects);
231231
232232 // Create and execute the generator
233233 $generator = new $className ($this, $generatorName);
@@ -242,6 +242,7 @@
243243 // populate resultPageSet with the generator output
244244 $generator->profileIn();
245245 $generator->executeGenerator($resultPageSet);
 246+ $resultPageSet->finishPageSetGeneration();
246247 $generator->profileOut();
247248
248249 // Swap the resulting pageset back in
@@ -264,7 +265,8 @@
265266 ),
266267 'generator' => array (
267268 ApiBase :: PARAM_TYPE => $this->mAllowedGenerators
268 - )
 269+ ),
 270+ 'redirects' => false
269271 );
270272 }
271273
@@ -322,7 +324,8 @@
323325 'prop' => 'Which properties to get for the titles/revisions/pageids',
324326 'list' => 'Which lists to get',
325327 'meta' => 'Which meta data to get about the site',
326 - 'generator' => 'Use the output of a list as the input for other prop/list/meta items'
 328+ 'generator' => 'Use the output of a list as the input for other prop/list/meta items',
 329+ 'redirects' => 'Automatically resolve redirects'
327330 );
328331 }
329332
Index: trunk/phase3/includes/api/ApiQueryAllpages.php
@@ -40,6 +40,9 @@
4141 }
4242
4343 public function executeGenerator($resultPageSet) {
 44+ if ($resultPageSet->isResolvingRedirects())
 45+ $this->dieUsage('Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params');
 46+
4447 $this->run($resultPageSet);
4548 }
4649
@@ -52,9 +55,11 @@
5356 $where = array (
5457 'page_namespace' => $namespace
5558 );
 59+
5660 if (isset ($from)) {
5761 $where[] = 'page_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($from));
5862 }
 63+
5964 if ($filterredir === 'redirects') {
6065 $where['page_is_redirect'] = 1;
6166 }
@@ -62,12 +67,18 @@
6368 $where['page_is_redirect'] = 0;
6469 }
6570
 71+ if (is_null($resultPageSet)) {
 72+ $fields = array (
 73+ 'page_id',
 74+ 'page_namespace',
 75+ 'page_title'
 76+ );
 77+ } else {
 78+ $fields = $resultPageSet->getPageTableFields();
 79+ }
 80+
6681 $this->profileDBIn();
67 - $res = $db->select('page', array (
68 - 'page_id',
69 - 'page_namespace',
70 - 'page_title'
71 - ), $where, __CLASS__ . '::' . __METHOD__, array (
 82+ $res = $db->select('page', $fields, $where, __CLASS__ . '::' . __METHOD__, array (
7283 'USE INDEX' => 'name_title',
7384 'LIMIT' => $limit +1,
7485 'ORDER BY' => 'page_namespace, page_title'
@@ -80,7 +91,8 @@
8192 if (++ $count > $limit) {
8293 // We've reached the one extra which shows that there are additional pages to be had. Stop here...
8394 $msg = array (
84 - 'continue' => $this->encodeParamName('from') . '='. ApiQueryBase :: keyToTitle($row->page_title));
 95+ 'continue' => $this->encodeParamName('from'
 96+ ) . '=' . ApiQueryBase :: keyToTitle($row->page_title));
8597 $this->getResult()->addValue('query-status', 'allpages', $msg);
8698 break;
8799 }
@@ -88,18 +100,12 @@
89101 $title = Title :: makeTitle($row->page_namespace, $row->page_title);
90102 // skip any pages that user has no rights to read
91103 if ($title->userCanRead()) {
92 - $id = intval($row->page_id);
93104
94105 if (is_null($resultPageSet)) {
95 - $pagedata = array ();
96 - $pagedata['id'] = $id;
97 - if ($title->getNamespace() !== 0)
98 - $pagedata['ns'] = $title->getNamespace();
99 - $pagedata['title'] = $title->getPrefixedText();
100 -
101 - $data[$id] = $pagedata;
 106+ $id = intval($row->page_id);
 107+ $data[] = $id; // in generator mode, just assemble a list of page IDs.
102108 } else {
103 - $data[] = $id; // in generator mode, just assemble a list of page IDs.
 109+ $resultPageSet->processDbRow($row);
104110 }
105111 }
106112 }
@@ -108,8 +114,6 @@
109115 if (is_null($resultPageSet)) {
110116 ApiResult :: setIndexedTagName($data, 'p');
111117 $this->getResult()->addValue('query', 'allpages', $data);
112 - } else {
113 - $resultPageSet->executeForPageIDs($data);
114118 }
115119 }
116120
@@ -161,9 +165,14 @@
162166
163167 protected function getExamples() {
164168 return array (
165 - 'api.php?action=query&list=allpages',
166 - 'api.php?action=query&list=allpages&apfrom=B&aplimit=5',
167 - 'api.php?action=query&generator=allpages&gaplimit=4&prop=info (generator)'
 169+ 'Simple Use',
 170+ ' api.php?action=query&list=allpages',
 171+ ' api.php?action=query&list=allpages&apfrom=B&aplimit=5',
 172+ 'Using as Generator',
 173+ ' Show info about 4 pages starting at the letter "T"',
 174+ ' api.php?action=query&generator=allpages&gaplimit=4&gapfrom=T&prop=info',
 175+ ' Show content of first 2 non-redirect pages begining at "Re"',
 176+ ' api.php?action=query&generator=allpages&gaplimit=2&gapfilterredir=nonredirects&gapfrom=Re&prop=revisions&rvprop=content'
168177 );
169178 }
170179
Index: trunk/phase3/includes/api/ApiMain.php
@@ -148,7 +148,8 @@
149149 header($errorCode, true, $httpRespCode);
150150
151151 $data = array (
152 - 'code' => $errorCode
 152+ 'code' => $errorCode,
 153+ 'info' => $description
153154 );
154155 ApiResult :: setContent($data, $this->makeHelpMsg());
155156 $this->mResult->addValue(null, 'error', $data);
Index: trunk/phase3/includes/api/ApiPageSet.php
@@ -33,10 +33,11 @@
3434
3535 private $mAllPages; // [ns][dbkey] => page_id or 0 when missing
3636 private $mGoodTitles, $mMissingTitles, $mMissingPageIDs, $mRedirectTitles, $mNormalizedTitles;
 37+ private $mResolveRedirects, $mPendingRedirectIDs;
3738
38 - private $mRequestedFields;
 39+ private $mRequestedPageFields;
3940
40 - public function __construct($query) {
 41+ public function __construct($query, $resolveRedirects = false) {
4142 parent :: __construct($query, __CLASS__);
4243
4344 $this->mAllPages = array ();
@@ -46,18 +47,45 @@
4748 $this->mRedirectTitles = array ();
4849 $this->mNormalizedTitles = array ();
4950
50 - $this->mRequestedFields = array ();
 51+ $this->mRequestedPageFields = array ();
 52+ $this->mResolveRedirects = $resolveRedirects;
 53+ if($resolveRedirects)
 54+ $this->mPendingRedirectIDs = array();
5155 }
5256
 57+ public function isResolvingRedirects() {
 58+ return $this->mResolveRedirects;
 59+ }
 60+
5361 public function requestField($fieldName) {
54 - $this->mRequestedFields[$fieldName] = null;
 62+ $this->mRequestedPageFields[$fieldName] = null;
5563 }
5664
5765 public function getCustomField($fieldName) {
58 - return $this->mRequestedFields[$fieldName];
 66+ return $this->mRequestedPageFields[$fieldName];
5967 }
6068
6169 /**
 70+ * Get fields that modules have requested from the page table
 71+ */
 72+ public function getPageTableFields() {
 73+ // Ensure we get minimum required fields
 74+ $pageFlds = array (
 75+ 'page_id' => null,
 76+ 'page_namespace' => null,
 77+ 'page_title' => null
 78+ );
 79+
 80+ // only store non-default fields
 81+ $this->mRequestedPageFields = array_diff_key($this->mRequestedPageFields, $pageFlds);
 82+
 83+ if ($this->mResolveRedirects)
 84+ $pageFlds['page_is_redirect'] = null;
 85+
 86+ return array_keys(array_merge($pageFlds, $this->mRequestedPageFields));
 87+ }
 88+
 89+ /**
6290 * Title objects that were found in the database.
6391 * @return array page_id (int) => Title (obj)
6492 */
@@ -66,6 +94,13 @@
6795 }
6896
6997 /**
 98+ * Returns the number of unique pages (not revisions) in the set.
 99+ */
 100+ public function getGoodTitleCount() {
 101+ return count($this->getGoodTitles());
 102+ }
 103+
 104+ /**
70105 * Title objects that were NOT found in the database.
71106 * @return array of Title objects
72107 */
@@ -99,13 +134,6 @@
100135 }
101136
102137 /**
103 - * Returns the number of unique pages (not revisions) in the set.
104 - */
105 - public function getGoodTitleCount() {
106 - return count($this->getGoodTitles());
107 - }
108 -
109 - /**
110138 * Get the list of revision IDs (requested with revids= parameter)
111139 */
112140 public function getRevisionIDs() {
@@ -120,6 +148,100 @@
121149 }
122150
123151 /**
 152+ * Populate from the request parameters
 153+ */
 154+ public function execute() {
 155+ $this->profileIn();
 156+ $titles = $pageids = $revids = null;
 157+ extract($this->extractRequestParams());
 158+
 159+ // Only one of the titles/pageids/revids is allowed at the same time
 160+ $dataSource = null;
 161+ if (isset ($titles))
 162+ $dataSource = 'titles';
 163+ if (isset ($pageids)) {
 164+ if (isset ($dataSource))
 165+ $this->dieUsage("Cannot use 'pageids' at the same time as '$dataSource'", 'multisource');
 166+ $dataSource = 'pageids';
 167+ }
 168+ if (isset ($revids)) {
 169+ if (isset ($dataSource))
 170+ $this->dieUsage("Cannot use 'revids' at the same time as '$dataSource'", 'multisource');
 171+ $dataSource = 'revids';
 172+ }
 173+
 174+ switch ($dataSource) {
 175+ case 'titles' :
 176+ $this->initFromTitles($titles);
 177+ break;
 178+ case 'pageids' :
 179+ $this->initFromPageIds($pageids);
 180+ break;
 181+ case 'revids' :
 182+ $this->initFromRevIDs($revids);
 183+ break;
 184+ default :
 185+ // Do nothing - some queries do not need any of the data sources.
 186+ break;
 187+ }
 188+ $this->profileOut();
 189+ }
 190+
 191+ /**
 192+ * Initialize PageSet from a list of Titles
 193+ */
 194+ public function populateFromTitles($titles) {
 195+ $this->profileIn();
 196+ $this->initFromTitles($titles);
 197+ $this->profileOut();
 198+ }
 199+
 200+ /**
 201+ * Initialize PageSet from a list of Page IDs
 202+ */
 203+ public function populateFromPageIDs($pageIDs) {
 204+ $this->profileIn();
 205+ $pageIDs = array_map('intval', $pageIDs); // paranoia
 206+ $this->initFromPageIds($pageIDs);
 207+ $this->profileOut();
 208+ }
 209+
 210+ /**
 211+ * Initialize PageSet from a rowset returned from the database
 212+ */
 213+ public function populateFromQueryResult($db, $queryResult) {
 214+ $this->profileIn();
 215+ $this->initFromQueryResult($db, $queryResult);
 216+ $this->profileOut();
 217+ }
 218+
 219+ /**
 220+ * Extract all requested fields from the row received from the database
 221+ */
 222+ public function processDbRow($row) {
 223+ $pageId = intval($row->page_id);
 224+
 225+ // Store Title object in various data structures
 226+ $title = Title :: makeTitle($row->page_namespace, $row->page_title);
 227+ $this->mAllPages[$row->page_namespace][$row->page_title] = $pageId;
 228+
 229+ if ($this->mResolveRedirects && $row->page_is_redirect == '1') {
 230+ $this->mPendingRedirectIDs[$pageId] = $title;
 231+ } else {
 232+ $this->mGoodTitles[$pageId] = $title;
 233+ }
 234+
 235+ foreach ($this->mRequestedPageFields as $fieldName => & $fieldValues)
 236+ $fieldValues[$pageId] = $row-> $fieldName;
 237+ }
 238+
 239+ public function finishPageSetGeneration() {
 240+ $this->profileIn();
 241+ $this->resolvePendingRedirects();
 242+ $this->profileOut();
 243+ }
 244+
 245+ /**
124246 * This method populates internal variables with page information
125247 * based on the given array of title strings.
126248 *
@@ -133,85 +255,79 @@
134256 * #5 Substitute the original LinkBatch object with the new list
135257 * #6 Repeat from step #1
136258 */
137 - private function populatePages($titles, $pageids, $redirects) {
138 - if (!is_null($titles) && !is_null($pageids))
139 - ApiBase :: dieDebug(__METHOD__, 'bad parameters');
140 - $processTitles = !is_null($titles);
 259+ private function initFromTitles($titles) {
 260+ $db = $this->getDB();
141261
142 - // Ensure we get minimum required fields
143 - $pageFlds = array (
144 - 'page_id' => null,
145 - 'page_namespace' => null,
146 - 'page_title' => null
147 - );
 262+ // Get validated and normalized title objects
 263+ $linkBatch = $this->processTitlesStrArray($titles);
 264+ $set = $linkBatch->constructSet('page', $db);
148265
149 - // only store non-default fields
150 - $this->mRequestedFields = array_diff_key($this->mRequestedFields, $pageFlds);
 266+ // Get pageIDs data from the `page` table
 267+ $this->profileDBIn();
 268+ $res = $db->select('page', $this->getPageTableFields(), $set, __METHOD__);
 269+ $this->profileDBOut();
151270
152 - if ($redirects)
153 - $pageFlds['page_is_redirect'] = null;
 271+ // Hack: get the ns:titles stored in array(ns => array(titles)) format
 272+ $this->initFromQueryResult($db, $res, $linkBatch->data, true); // process Titles
154273
155 - $pageFlds = array_keys(array_merge($pageFlds, $this->mRequestedFields));
 274+ // Resolve any found redirects
 275+ $this->resolvePendingRedirects();
 276+ }
156277
 278+ private function initFromPageIds($pageids) {
157279 $db = $this->getDB();
158280
159 - if ($processTitles) {
 281+ $set = array (
 282+ 'page_id' => $pageids
 283+ );
160284
161 - // Get validated and normalized title objects
162 - $linkBatch = $this->processTitlesStrArray($titles);
 285+ // Get pageIDs data from the `page` table
 286+ $this->profileDBIn();
 287+ $res = $db->select('page', $this->getPageTableFields(), $set, __METHOD__);
 288+ $this->profileDBOut();
 289+
 290+ $this->initFromQueryResult($db, $res, array_flip($pageids), false); // process PageIDs
163291
164 - $set = $linkBatch->constructSet('page', $db);
165 - } else {
166 - $set = array (
167 - 'page_id' => $pageids
168 - );
169 - }
 292+ // Resolve any found redirects
 293+ $this->resolvePendingRedirects();
 294+ }
 295+
 296+ /**
 297+ * Iterate through the result of the query on 'page' table,
 298+ * and for each row create and store title object and save any extra fields requested.
 299+ * @param $db Database
 300+ * @param $res DB Query result
 301+ * @param $remaining Array of either pageID or ns/title elements (optional).
 302+ * If given, any missing items will go to $mMissingPageIDs and $mMissingTitles
 303+ * @param $processTitles bool Must be provided together with $remaining.
 304+ * If true, treat $remaining as an array of [ns][title]
 305+ * If false, treat it as an array of [pageIDs]
 306+ * @return Array of redirect IDs (only when resolving redirects)
 307+ */
 308+ private function initFromQueryResult($db, $res, &$remaining = null, $processTitles = null) {
 309+ if (!is_null($remaining) && is_null($processTitles))
 310+ $this->dieDebug('Missing $processTitles parameter when $remaining is provided');
 311+
 312+ while ($row = $db->fetchObject($res)) {
170313
171 - //
172 - // Repeat until all redirects have been resolved
173 - // The infinite loop is prevented by keeping all known pages in $this->mAllPages
174 - //
175 - do {
176 - if ($processTitles) {
177 - // Hack: get the ns:titles stored in array(ns => array(titles)) format
178 - $remaining = $linkBatch->data;
179 - } else {
180 - $remaining = array_flip($pageids); // turn pageids into keys
181 - }
 314+ $pageId = intval($row->page_id);
182315
183 - $redirectIds = array ();
184 -
185 - //
186 - // Get data about $linkBatch from `page` table
187 - //
188 - $this->profileDBIn();
189 - $res = $db->select('page', $pageFlds, $set, __METHOD__);
190 - $this->profileDBOut();
191 - while ($row = $db->fetchObject($res)) {
192 -
193 - $pageId = intval($row->page_id);
194 -
 316+ // Remove found page from the list of remaining items
 317+ if (isset($remaining)) {
195318 if ($processTitles)
196319 unset ($remaining[$row->page_namespace][$row->page_title]);
197320 else
198321 unset ($remaining[$pageId]);
199 -
200 - $title = Title :: makeTitle($row->page_namespace, $row->page_title);
201 - $this->mAllPages[$row->page_namespace][$row->page_title] = $pageId;
202 -
203 - if ($redirects && $row->page_is_redirect == '1') {
204 - $redirectIds[$pageId] = $title;
205 - } else {
206 - $this->mGoodTitles[$pageId] = $title;
207 - }
208 -
209 - foreach ($this->mRequestedFields as $fieldName => & $fieldValues) {
210 - $fieldValues[$pageId] = $row-> $fieldName;
211 - }
212322 }
213 - $db->freeResult($res);
214 -
215 - if ($processTitles) {
 323+
 324+ // Store any extra fields requested by modules
 325+ $this->processDbRow($row);
 326+ }
 327+ $db->freeResult($res);
 328+
 329+ if(isset($remaining)) {
 330+ // Any items left in the $remaining list are added as missing
 331+ if($processTitles) {
216332 // The remaining titles in $remaining are non-existant pages
217333 foreach ($remaining as $ns => $dbkeys) {
218334 foreach ($dbkeys as $dbkey => $nothing) {
@@ -219,29 +335,55 @@
220336 $this->mAllPages[$ns][$dbkey] = 0;
221337 }
222338 }
223 - } else {
224 - // The remaining pageids in $remaining do not exist
225 - foreach ($remaining as $pageid => $ignore) {
226 - $this->mMissingPageIDs[] = $pageid;
227 - }
228339 }
 340+ else
 341+ {
 342+ // The remaining pageids do not exist
 343+ if(empty($this->mMissingPageIDs))
 344+ $this->mMissingPageIDs = array_keys($remaining);
 345+ else
 346+ $this->mMissingPageIDs = array_merge($this->mMissingPageIDs, array_keys($remaining));
 347+ }
 348+ }
 349+ }
229350
230 - if (!$redirects || empty ($redirectIds))
231 - break;
 351+ private function initFromRevIDs($revids) {
 352+ $this->dieUsage(__METHOD__ . ' is not implemented', 'notimplemented');
 353+ }
232354
233 - //
234 - // Resolve redirects by querying the pagelinks table, and repeat the process
235 - // Create a new linkBatch object for the next pass
236 - //
237 - $linkBatch = $this->resolveRedirectList($redirectIds);
 355+ private function resolvePendingRedirects() {
238356
239 - // Redirects are always titles
240 - $processTitles = true;
 357+ if($this->mResolveRedirects) {
 358+ $db = $this->getDB();
 359+ $pageFlds = $this->getPageTableFields();
 360+
 361+ // Repeat until all redirects have been resolved
 362+ // The infinite loop is prevented by keeping all known pages in $this->mAllPages
 363+ while (!empty ($this->mPendingRedirectIDs)) {
 364+
 365+ // Resolve redirects by querying the pagelinks table, and repeat the process
 366+ // Create a new linkBatch object for the next pass
 367+ $linkBatch = $this->getRedirectTargets();
 368+
 369+ if ($linkBatch->isEmpty())
 370+ break;
 371+
 372+ $set = $linkBatch->constructSet('page', $db);
 373+ if(false === $set)
 374+ break;
 375+
 376+ // Get pageIDs data from the `page` table
 377+ $this->profileDBIn();
 378+ $res = $db->select('page', $pageFlds, $set, __METHOD__);
 379+ $this->profileDBOut();
 380+
 381+ // Hack: get the ns:titles stored in array(ns => array(titles)) format
 382+ $this->initFromQueryResult($db, $res, $linkBatch->data, true);
 383+ }
241384 }
242 - while (false !== ($set = $linkBatch->constructSet('page', $db)));
243385 }
244386
245 - private function resolveRedirectList($redirectIds) {
 387+ private function getRedirectTargets() {
246388
247389 $linkBatch = new LinkBatch();
248390 $db = $this->getDB();
@@ -253,7 +395,7 @@
254396 'pl_namespace',
255397 'pl_title'
256398 ), array (
257 - 'pl_from' => array_keys($redirectIds
 399+ 'pl_from' => array_keys($this->mPendingRedirectIDs
258400 )), __METHOD__);
259401 $this->profileDBOut();
260402
@@ -265,11 +407,11 @@
266408 // ( http://bugzilla.wikipedia.org/show_bug.cgi?id=7304 )
267409 // A redirect page may have more than one link.
268410 // This code will only use the first link returned.
269 - if (isset ($redirectIds[$plfrom])) { // remove line when bug 7304 is fixed
 411+ if (isset ($this->mPendingRedirectIDs[$plfrom])) { // remove line when bug 7304 is fixed
270412
271 - $titleStrFrom = $redirectIds[$plfrom]->getPrefixedText();
 413+ $titleStrFrom = $this->mPendingRedirectIDs[$plfrom]->getPrefixedText();
272414 $titleStrTo = Title :: makeTitle($row->pl_namespace, $row->pl_title)->getPrefixedText();
273 - unset ($redirectIds[$plfrom]); // remove line when bug 7304 is fixed
 415+ unset ($this->mPendingRedirectIDs[$plfrom]); // remove line when bug 7304 is fixed
274416
275417 // Avoid an infinite loop by checking if we have already processed this target
276418 if (!isset ($this->mAllPages[$row->pl_namespace][$row->pl_title])) {
@@ -299,6 +441,10 @@
300442 }
301443 $db->freeResult($res);
302444
 445+ // All IDs must exist in the page table
 446+ if (!empty($this->mPendingRedirectIDs[$plfrom]))
 447+ $this->dieDebug('Invalid redirect IDs were found');
 448+
303449 return $linkBatch;
304450 }
305451
@@ -337,55 +483,6 @@
338484 return $linkBatch;
339485 }
340486
341 - private function populateRevIDs($revids) {
342 - $this->dieUsage(__METHOD__ . ' is not implemented', 'notimplemented');
343 - }
344 -
345 - public function execute() {
346 - $this->profileIn();
347 - $titles = $pageids = $revids = $redirects = null;
348 - extract($this->extractRequestParams());
349 -
350 - // Only one of the titles/pageids/revids is allowed at the same time
351 - $dataSource = null;
352 - if (isset ($titles))
353 - $dataSource = 'titles';
354 - if (isset ($pageids)) {
355 - if (isset ($dataSource))
356 - $this->dieUsage("Cannot use 'pageids' at the same time as '$dataSource'", 'multisource');
357 - $dataSource = 'pageids';
358 - }
359 - if (isset ($revids)) {
360 - if (isset ($dataSource))
361 - $this->dieUsage("Cannot use 'revids' at the same time as '$dataSource'", 'multisource');
362 - $dataSource = 'revids';
363 - }
364 -
365 - switch ($dataSource) {
366 - case 'titles' :
367 - case 'pageids' :
368 - $this->populatePages($titles, $pageids, $redirects);
369 - break;
370 - case 'revids' :
371 - $this->populateRevIDs($revids);
372 - break;
373 - default :
374 - // Do nothing - some queries do not need any of the data sources.
375 - break;
376 - }
377 - $this->profileOut();
378 - }
379 -
380 - /**
381 - * This method is used by generators to pass the list of pageIDs internaly
382 - */
383 - public function executeForPageIDs($pageIDs) {
384 - $this->profileIn();
385 - $pageIDs = array_map( 'intval', $pageIDs ); // paranoia
386 - $this->populatePages(null, $pageIDs, $this->getParameter('redirects'));
387 - $this->profileOut();
388 - }
389 -
390487 protected function getAllowedParams() {
391488 return array (
392489 'titles' => array (
@@ -398,8 +495,7 @@
399496 'revids' => array (
400497 ApiBase :: PARAM_TYPE => 'integer',
401498 ApiBase :: PARAM_ISMULTI => true
402 - ),
403 - 'redirects' => false
 499+ )
404500 );
405501 }
406502
@@ -407,8 +503,7 @@
408504 return array (
409505 'titles' => 'A list of titles to work on',
410506 'pageids' => 'A list of page IDs to work on',
411 - 'revids' => 'A list of revision IDs to work on',
412 - 'redirects' => 'Automatically resolve redirects'
 507+ 'revids' => 'A list of revision IDs to work on'
413508 );
414509 }
415510