MediaWiki  master
ApiPageSet.php
Go to the documentation of this file.
1 <?php
27 
42 class ApiPageSet extends ApiBase {
47  const DISABLE_GENERATORS = 1;
48 
49  private $mDbSource;
50  private $mParams = [];
52  private $mConvertTitles;
54 
55  private $mAllPages = []; // [ns][dbkey] => page_id or negative when missing
56  private $mTitles = [];
57  private $mGoodAndMissingPages = []; // [ns][dbkey] => page_id or negative when missing
58  private $mGoodPages = []; // [ns][dbkey] => page_id
59  private $mGoodTitles = [];
60  private $mMissingPages = []; // [ns][dbkey] => fake page_id
61  private $mMissingTitles = [];
63  private $mInvalidTitles = [];
64  private $mMissingPageIDs = [];
65  private $mRedirectTitles = [];
66  private $mSpecialTitles = [];
67  private $mAllSpecials = []; // separate from mAllPages to avoid breaking getAllTitlesByNamespace()
68  private $mNormalizedTitles = [];
69  private $mInterwikiTitles = [];
71  private $mPendingRedirectIDs = [];
72  private $mPendingRedirectSpecialPages = []; // [dbkey] => [ Title $from, Title $to ]
74  private $mConvertedTitles = [];
75  private $mGoodRevIDs = [];
76  private $mLiveRevIDs = [];
77  private $mDeletedRevIDs = [];
78  private $mMissingRevIDs = [];
79  private $mGeneratorData = []; // [ns][dbkey] => data array
80  private $mFakePageId = -1;
81  private $mCacheMode = 'public';
83  private $mRequestedPageFields = [];
88 
96  private static function addValues( array &$result, $values, $flags = [], $name = null ) {
97  foreach ( $values as $val ) {
98  if ( $val instanceof Title ) {
99  $v = [];
100  ApiQueryBase::addTitleInfo( $v, $val );
101  } elseif ( $name !== null ) {
102  $v = [ $name => $val ];
103  } else {
104  $v = $val;
105  }
106  foreach ( $flags as $flag ) {
107  $v[$flag] = true;
108  }
109  $result[] = $v;
110  }
111  }
112 
120  public function __construct( ApiBase $dbSource, $flags = 0, $defaultNamespace = NS_MAIN ) {
121  parent::__construct( $dbSource->getMain(), $dbSource->getModuleName() );
122  $this->mDbSource = $dbSource;
123  $this->mAllowGenerator = ( $flags & self::DISABLE_GENERATORS ) == 0;
124  $this->mDefaultNamespace = $defaultNamespace;
125 
126  $this->mParams = $this->extractRequestParams();
127  $this->mResolveRedirects = $this->mParams['redirects'];
128  $this->mConvertTitles = $this->mParams['converttitles'];
129  }
130 
135  public function executeDryRun() {
136  $this->executeInternal( true );
137  }
138 
142  public function execute() {
143  $this->executeInternal( false );
144  }
145 
151  private function executeInternal( $isDryRun ) {
152  $generatorName = $this->mAllowGenerator ? $this->mParams['generator'] : null;
153  if ( isset( $generatorName ) ) {
154  $dbSource = $this->mDbSource;
155  if ( !$dbSource instanceof ApiQuery ) {
156  // If the parent container of this pageset is not ApiQuery, we must create it to run generator
157  $dbSource = $this->getMain()->getModuleManager()->getModule( 'query' );
158  }
159  $generator = $dbSource->getModuleManager()->getModule( $generatorName, null, true );
160  if ( $generator === null ) {
161  $this->dieWithError( [ 'apierror-badgenerator-unknown', $generatorName ], 'badgenerator' );
162  }
163  if ( !$generator instanceof ApiQueryGeneratorBase ) {
164  $this->dieWithError( [ 'apierror-badgenerator-notgenerator', $generatorName ], 'badgenerator' );
165  }
166  // Create a temporary pageset to store generator's output,
167  // add any additional fields generator may need, and execute pageset to populate titles/pageids
168  $tmpPageSet = new ApiPageSet( $dbSource, self::DISABLE_GENERATORS );
169  $generator->setGeneratorMode( $tmpPageSet );
170  $this->mCacheMode = $generator->getCacheMode( $generator->extractRequestParams() );
171 
172  if ( !$isDryRun ) {
173  $generator->requestExtraData( $tmpPageSet );
174  }
175  $tmpPageSet->executeInternal( $isDryRun );
176 
177  // populate this pageset with the generator output
178  if ( !$isDryRun ) {
179  $generator->executeGenerator( $this );
180 
181  // Avoid PHP 7.1 warning of passing $this by reference
182  $apiModule = $this;
183  Hooks::run( 'APIQueryGeneratorAfterExecute', [ &$generator, &$apiModule ] );
184  } else {
185  // Prevent warnings from being reported on these parameters
186  $main = $this->getMain();
187  foreach ( $generator->extractRequestParams() as $paramName => $param ) {
188  $main->markParamsUsed( $generator->encodeParamName( $paramName ) );
189  }
190  }
191 
192  if ( !$isDryRun ) {
193  $this->resolvePendingRedirects();
194  }
195  } else {
196  // Only one of the titles/pageids/revids is allowed at the same time
197  $dataSource = null;
198  if ( isset( $this->mParams['titles'] ) ) {
199  $dataSource = 'titles';
200  }
201  if ( isset( $this->mParams['pageids'] ) ) {
202  if ( isset( $dataSource ) ) {
203  $this->dieWithError(
204  [
205  'apierror-invalidparammix-cannotusewith',
206  $this->encodeParamName( 'pageids' ),
207  $this->encodeParamName( $dataSource )
208  ],
209  'multisource'
210  );
211  }
212  $dataSource = 'pageids';
213  }
214  if ( isset( $this->mParams['revids'] ) ) {
215  if ( isset( $dataSource ) ) {
216  $this->dieWithError(
217  [
218  'apierror-invalidparammix-cannotusewith',
219  $this->encodeParamName( 'revids' ),
220  $this->encodeParamName( $dataSource )
221  ],
222  'multisource'
223  );
224  }
225  $dataSource = 'revids';
226  }
227 
228  if ( !$isDryRun ) {
229  // Populate page information with the original user input
230  switch ( $dataSource ) {
231  case 'titles':
232  $this->initFromTitles( $this->mParams['titles'] );
233  break;
234  case 'pageids':
235  $this->initFromPageIds( $this->mParams['pageids'] );
236  break;
237  case 'revids':
238  if ( $this->mResolveRedirects ) {
239  $this->addWarning( 'apiwarn-redirectsandrevids' );
240  }
241  $this->mResolveRedirects = false;
242  $this->initFromRevIDs( $this->mParams['revids'] );
243  break;
244  default:
245  // Do nothing - some queries do not need any of the data sources.
246  break;
247  }
248  }
249  }
250  }
251 
256  public function isResolvingRedirects() {
258  }
259 
268  public function getDataSource() {
269  if ( $this->mAllowGenerator && isset( $this->mParams['generator'] ) ) {
270  return 'generator';
271  }
272  if ( isset( $this->mParams['titles'] ) ) {
273  return 'titles';
274  }
275  if ( isset( $this->mParams['pageids'] ) ) {
276  return 'pageids';
277  }
278  if ( isset( $this->mParams['revids'] ) ) {
279  return 'revids';
280  }
281 
282  return null;
283  }
284 
290  public function requestField( $fieldName ) {
291  $this->mRequestedPageFields[$fieldName] = null;
292  }
293 
300  public function getCustomField( $fieldName ) {
301  return $this->mRequestedPageFields[$fieldName];
302  }
303 
310  public function getPageTableFields() {
311  // Ensure we get minimum required fields
312  // DON'T change this order
313  $pageFlds = [
314  'page_namespace' => null,
315  'page_title' => null,
316  'page_id' => null,
317  ];
318 
319  if ( $this->mResolveRedirects ) {
320  $pageFlds['page_is_redirect'] = null;
321  }
322 
323  $pageFlds['page_content_model'] = null;
324 
325  if ( $this->getConfig()->get( 'PageLanguageUseDB' ) ) {
326  $pageFlds['page_lang'] = null;
327  }
328 
329  foreach ( LinkCache::getSelectFields() as $field ) {
330  $pageFlds[$field] = null;
331  }
332 
333  $pageFlds = array_merge( $pageFlds, $this->mRequestedPageFields );
334 
335  return array_keys( $pageFlds );
336  }
337 
344  public function getAllTitlesByNamespace() {
345  return $this->mAllPages;
346  }
347 
352  public function getTitles() {
353  return $this->mTitles;
354  }
355 
360  public function getTitleCount() {
361  return count( $this->mTitles );
362  }
363 
368  public function getGoodTitlesByNamespace() {
369  return $this->mGoodPages;
370  }
371 
376  public function getGoodTitles() {
377  return $this->mGoodTitles;
378  }
379 
384  public function getGoodTitleCount() {
385  return count( $this->mGoodTitles );
386  }
387 
393  public function getMissingTitlesByNamespace() {
394  return $this->mMissingPages;
395  }
396 
402  public function getMissingTitles() {
403  return $this->mMissingTitles;
404  }
405 
412  }
413 
418  public function getGoodAndMissingTitles() {
419  return $this->mGoodTitles + $this->mMissingTitles;
420  }
421 
427  public function getInvalidTitlesAndReasons() {
428  return $this->mInvalidTitles;
429  }
430 
435  public function getMissingPageIDs() {
436  return $this->mMissingPageIDs;
437  }
438 
444  public function getRedirectTitles() {
445  return $this->mRedirectTitles;
446  }
447 
455  public function getRedirectTitlesAsResult( $result = null ) {
456  $values = [];
457  foreach ( $this->getRedirectTitles() as $titleStrFrom => $titleTo ) {
458  $r = [
459  'from' => strval( $titleStrFrom ),
460  'to' => $titleTo->getPrefixedText(),
461  ];
462  if ( $titleTo->hasFragment() ) {
463  $r['tofragment'] = $titleTo->getFragment();
464  }
465  if ( $titleTo->isExternal() ) {
466  $r['tointerwiki'] = $titleTo->getInterwiki();
467  }
468  if ( isset( $this->mResolvedRedirectTitles[$titleStrFrom] ) ) {
469  $titleFrom = $this->mResolvedRedirectTitles[$titleStrFrom];
470  $ns = $titleFrom->getNamespace();
471  $dbkey = $titleFrom->getDBkey();
472  if ( isset( $this->mGeneratorData[$ns][$dbkey] ) ) {
473  $r = array_merge( $this->mGeneratorData[$ns][$dbkey], $r );
474  }
475  }
476 
477  $values[] = $r;
478  }
479  if ( !empty( $values ) && $result ) {
480  ApiResult::setIndexedTagName( $values, 'r' );
481  }
482 
483  return $values;
484  }
485 
491  public function getNormalizedTitles() {
493  }
494 
502  public function getNormalizedTitlesAsResult( $result = null ) {
503  $values = [];
504  $contLang = MediaWikiServices::getInstance()->getContentLanguage();
505  foreach ( $this->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
506  $encode = $contLang->normalize( $rawTitleStr ) !== $rawTitleStr;
507  $values[] = [
508  'fromencoded' => $encode,
509  'from' => $encode ? rawurlencode( $rawTitleStr ) : $rawTitleStr,
510  'to' => $titleStr
511  ];
512  }
513  if ( !empty( $values ) && $result ) {
514  ApiResult::setIndexedTagName( $values, 'n' );
515  }
516 
517  return $values;
518  }
519 
525  public function getConvertedTitles() {
527  }
528 
536  public function getConvertedTitlesAsResult( $result = null ) {
537  $values = [];
538  foreach ( $this->getConvertedTitles() as $rawTitleStr => $titleStr ) {
539  $values[] = [
540  'from' => $rawTitleStr,
541  'to' => $titleStr
542  ];
543  }
544  if ( !empty( $values ) && $result ) {
545  ApiResult::setIndexedTagName( $values, 'c' );
546  }
547 
548  return $values;
549  }
550 
556  public function getInterwikiTitles() {
558  }
559 
568  public function getInterwikiTitlesAsResult( $result = null, $iwUrl = false ) {
569  $values = [];
570  foreach ( $this->getInterwikiTitles() as $rawTitleStr => $interwikiStr ) {
571  $item = [
572  'title' => $rawTitleStr,
573  'iw' => $interwikiStr,
574  ];
575  if ( $iwUrl ) {
576  $title = Title::newFromText( $rawTitleStr );
577  $item['url'] = $title->getFullURL( '', false, PROTO_CURRENT );
578  }
579  $values[] = $item;
580  }
581  if ( !empty( $values ) && $result ) {
582  ApiResult::setIndexedTagName( $values, 'i' );
583  }
584 
585  return $values;
586  }
587 
602  public function getInvalidTitlesAndRevisions( $invalidChecks = [ 'invalidTitles',
603  'special', 'missingIds', 'missingRevIds', 'missingTitles', 'interwikiTitles' ]
604  ) {
605  $result = [];
606  if ( in_array( 'invalidTitles', $invalidChecks ) ) {
607  self::addValues( $result, $this->getInvalidTitlesAndReasons(), [ 'invalid' ] );
608  }
609  if ( in_array( 'special', $invalidChecks ) ) {
610  $known = [];
611  $unknown = [];
612  foreach ( $this->getSpecialTitles() as $title ) {
613  if ( $title->isKnown() ) {
614  $known[] = $title;
615  } else {
616  $unknown[] = $title;
617  }
618  }
619  self::addValues( $result, $unknown, [ 'special', 'missing' ] );
620  self::addValues( $result, $known, [ 'special' ] );
621  }
622  if ( in_array( 'missingIds', $invalidChecks ) ) {
623  self::addValues( $result, $this->getMissingPageIDs(), [ 'missing' ], 'pageid' );
624  }
625  if ( in_array( 'missingRevIds', $invalidChecks ) ) {
626  self::addValues( $result, $this->getMissingRevisionIDs(), [ 'missing' ], 'revid' );
627  }
628  if ( in_array( 'missingTitles', $invalidChecks ) ) {
629  $known = [];
630  $unknown = [];
631  foreach ( $this->getMissingTitles() as $title ) {
632  if ( $title->isKnown() ) {
633  $known[] = $title;
634  } else {
635  $unknown[] = $title;
636  }
637  }
638  self::addValues( $result, $unknown, [ 'missing' ] );
639  self::addValues( $result, $known, [ 'missing', 'known' ] );
640  }
641  if ( in_array( 'interwikiTitles', $invalidChecks ) ) {
642  self::addValues( $result, $this->getInterwikiTitlesAsResult() );
643  }
644 
645  return $result;
646  }
647 
652  public function getRevisionIDs() {
653  return $this->mGoodRevIDs;
654  }
655 
660  public function getLiveRevisionIDs() {
661  return $this->mLiveRevIDs;
662  }
663 
668  public function getDeletedRevisionIDs() {
669  return $this->mDeletedRevIDs;
670  }
671 
676  public function getMissingRevisionIDs() {
677  return $this->mMissingRevIDs;
678  }
679 
686  public function getMissingRevisionIDsAsResult( $result = null ) {
687  $values = [];
688  foreach ( $this->getMissingRevisionIDs() as $revid ) {
689  $values[$revid] = [
690  'revid' => $revid
691  ];
692  }
693  if ( !empty( $values ) && $result ) {
694  ApiResult::setIndexedTagName( $values, 'rev' );
695  }
696 
697  return $values;
698  }
699 
704  public function getSpecialTitles() {
705  return $this->mSpecialTitles;
706  }
707 
712  public function getRevisionCount() {
713  return count( $this->getRevisionIDs() );
714  }
715 
720  public function populateFromTitles( $titles ) {
721  $this->initFromTitles( $titles );
722  }
723 
728  public function populateFromPageIDs( $pageIDs ) {
729  $this->initFromPageIds( $pageIDs );
730  }
731 
741  public function populateFromQueryResult( $db, $queryResult ) {
742  $this->initFromQueryResult( $queryResult );
743  }
744 
749  public function populateFromRevisionIDs( $revIDs ) {
750  $this->initFromRevIDs( $revIDs );
751  }
752 
757  public function processDbRow( $row ) {
758  // Store Title object in various data structures
759  $title = Title::newFromRow( $row );
760 
761  $linkCache = MediaWikiServices::getInstance()->getLinkCache();
762  $linkCache->addGoodLinkObjFromRow( $title, $row );
763 
764  $pageId = (int)$row->page_id;
765  $this->mAllPages[$row->page_namespace][$row->page_title] = $pageId;
766  $this->mTitles[] = $title;
767 
768  if ( $this->mResolveRedirects && $row->page_is_redirect == '1' ) {
769  $this->mPendingRedirectIDs[$pageId] = $title;
770  } else {
771  $this->mGoodPages[$row->page_namespace][$row->page_title] = $pageId;
772  $this->mGoodAndMissingPages[$row->page_namespace][$row->page_title] = $pageId;
773  $this->mGoodTitles[$pageId] = $title;
774  }
775 
776  foreach ( $this->mRequestedPageFields as $fieldName => &$fieldValues ) {
777  $fieldValues[$pageId] = $row->$fieldName;
778  }
779  }
780 
797  private function initFromTitles( $titles ) {
798  // Get validated and normalized title objects
799  $linkBatch = $this->processTitlesArray( $titles );
800  if ( $linkBatch->isEmpty() ) {
801  // There might be special-page redirects
802  $this->resolvePendingRedirects();
803  return;
804  }
805 
806  $db = $this->getDB();
807  $set = $linkBatch->constructSet( 'page', $db );
808 
809  // Get pageIDs data from the `page` table
810  $res = $db->select( 'page', $this->getPageTableFields(), $set,
811  __METHOD__ );
812 
813  // Hack: get the ns:titles stored in [ ns => [ titles ] ] format
814  $this->initFromQueryResult( $res, $linkBatch->data, true ); // process Titles
815 
816  // Resolve any found redirects
817  $this->resolvePendingRedirects();
818  }
819 
825  private function initFromPageIds( $pageids, $filterIds = true ) {
826  if ( !$pageids ) {
827  return;
828  }
829 
830  $pageids = array_map( 'intval', $pageids ); // paranoia
831  $remaining = array_flip( $pageids );
832 
833  if ( $filterIds ) {
834  $pageids = $this->filterIDs( [ [ 'page', 'page_id' ] ], $pageids );
835  }
836 
837  $res = null;
838  if ( !empty( $pageids ) ) {
839  $set = [
840  'page_id' => $pageids
841  ];
842  $db = $this->getDB();
843 
844  // Get pageIDs data from the `page` table
845  $res = $db->select( 'page', $this->getPageTableFields(), $set,
846  __METHOD__ );
847  }
848 
849  $this->initFromQueryResult( $res, $remaining, false ); // process PageIDs
850 
851  // Resolve any found redirects
852  $this->resolvePendingRedirects();
853  }
854 
865  private function initFromQueryResult( $res, &$remaining = null, $processTitles = null ) {
866  if ( $remaining !== null && $processTitles === null ) {
867  ApiBase::dieDebug( __METHOD__, 'Missing $processTitles parameter when $remaining is provided' );
868  }
869 
870  $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
871 
872  $usernames = [];
873  if ( $res ) {
874  foreach ( $res as $row ) {
875  $pageId = (int)$row->page_id;
876 
877  // Remove found page from the list of remaining items
878  if ( isset( $remaining ) ) {
879  if ( $processTitles ) {
880  unset( $remaining[$row->page_namespace][$row->page_title] );
881  } else {
882  unset( $remaining[$pageId] );
883  }
884  }
885 
886  // Store any extra fields requested by modules
887  $this->processDbRow( $row );
888 
889  // Need gender information
890  if ( $nsInfo->hasGenderDistinction( $row->page_namespace ) ) {
891  $usernames[] = $row->page_title;
892  }
893  }
894  }
895 
896  if ( isset( $remaining ) ) {
897  // Any items left in the $remaining list are added as missing
898  if ( $processTitles ) {
899  // The remaining titles in $remaining are non-existent pages
900  $linkCache = MediaWikiServices::getInstance()->getLinkCache();
901  foreach ( $remaining as $ns => $dbkeys ) {
902  foreach ( array_keys( $dbkeys ) as $dbkey ) {
903  $title = Title::makeTitle( $ns, $dbkey );
904  $linkCache->addBadLinkObj( $title );
905  $this->mAllPages[$ns][$dbkey] = $this->mFakePageId;
906  $this->mMissingPages[$ns][$dbkey] = $this->mFakePageId;
907  $this->mGoodAndMissingPages[$ns][$dbkey] = $this->mFakePageId;
908  $this->mMissingTitles[$this->mFakePageId] = $title;
909  $this->mFakePageId--;
910  $this->mTitles[] = $title;
911 
912  // need gender information
913  if ( $nsInfo->hasGenderDistinction( $ns ) ) {
914  $usernames[] = $dbkey;
915  }
916  }
917  }
918  } else {
919  // The remaining pageids do not exist
920  if ( !$this->mMissingPageIDs ) {
921  $this->mMissingPageIDs = array_keys( $remaining );
922  } else {
923  $this->mMissingPageIDs = array_merge( $this->mMissingPageIDs, array_keys( $remaining ) );
924  }
925  }
926  }
927 
928  // Get gender information
929  $genderCache = MediaWikiServices::getInstance()->getGenderCache();
930  $genderCache->doQuery( $usernames, __METHOD__ );
931  }
932 
938  private function initFromRevIDs( $revids ) {
939  if ( !$revids ) {
940  return;
941  }
942 
943  $revids = array_map( 'intval', $revids ); // paranoia
944  $db = $this->getDB();
945  $pageids = [];
946  $remaining = array_flip( $revids );
947 
948  $revids = $this->filterIDs( [ [ 'revision', 'rev_id' ], [ 'archive', 'ar_rev_id' ] ], $revids );
949  $goodRemaining = array_flip( $revids );
950 
951  if ( $revids ) {
952  $tables = [ 'revision', 'page' ];
953  $fields = [ 'rev_id', 'rev_page' ];
954  $where = [ 'rev_id' => $revids, 'rev_page = page_id' ];
955 
956  // Get pageIDs data from the `page` table
957  $res = $db->select( $tables, $fields, $where, __METHOD__ );
958  foreach ( $res as $row ) {
959  $revid = (int)$row->rev_id;
960  $pageid = (int)$row->rev_page;
961  $this->mGoodRevIDs[$revid] = $pageid;
962  $this->mLiveRevIDs[$revid] = $pageid;
963  $pageids[$pageid] = '';
964  unset( $remaining[$revid] );
965  unset( $goodRemaining[$revid] );
966  }
967  }
968 
969  // Populate all the page information
970  $this->initFromPageIds( array_keys( $pageids ), false );
971 
972  // If the user can see deleted revisions, pull out the corresponding
973  // titles from the archive table and include them too. We ignore
974  // ar_page_id because deleted revisions are tied by title, not page_id.
975  if ( $goodRemaining &&
976  $this->getPermissionManager()->userHasRight( $this->getUser(), 'deletedhistory' ) ) {
977  $tables = [ 'archive' ];
978  $fields = [ 'ar_rev_id', 'ar_namespace', 'ar_title' ];
979  $where = [ 'ar_rev_id' => array_keys( $goodRemaining ) ];
980 
981  $res = $db->select( $tables, $fields, $where, __METHOD__ );
982  $titles = [];
983  foreach ( $res as $row ) {
984  $revid = (int)$row->ar_rev_id;
985  $titles[$revid] = Title::makeTitle( $row->ar_namespace, $row->ar_title );
986  unset( $remaining[$revid] );
987  }
988 
989  $this->initFromTitles( $titles );
990 
991  foreach ( $titles as $revid => $title ) {
992  $ns = $title->getNamespace();
993  $dbkey = $title->getDBkey();
994 
995  // Handle converted titles
996  if ( !isset( $this->mAllPages[$ns][$dbkey] ) &&
997  isset( $this->mConvertedTitles[$title->getPrefixedText()] )
998  ) {
999  $title = Title::newFromText( $this->mConvertedTitles[$title->getPrefixedText()] );
1000  $ns = $title->getNamespace();
1001  $dbkey = $title->getDBkey();
1002  }
1003 
1004  if ( isset( $this->mAllPages[$ns][$dbkey] ) ) {
1005  $this->mGoodRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
1006  $this->mDeletedRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
1007  } else {
1008  $remaining[$revid] = true;
1009  }
1010  }
1011  }
1012 
1013  $this->mMissingRevIDs = array_keys( $remaining );
1014  }
1015 
1021  private function resolvePendingRedirects() {
1022  if ( $this->mResolveRedirects ) {
1023  $db = $this->getDB();
1024  $pageFlds = $this->getPageTableFields();
1025 
1026  // Repeat until all redirects have been resolved
1027  // The infinite loop is prevented by keeping all known pages in $this->mAllPages
1028  while ( $this->mPendingRedirectIDs || $this->mPendingRedirectSpecialPages ) {
1029  // Resolve redirects by querying the pagelinks table, and repeat the process
1030  // Create a new linkBatch object for the next pass
1031  $linkBatch = $this->getRedirectTargets();
1032 
1033  if ( $linkBatch->isEmpty() ) {
1034  break;
1035  }
1036 
1037  $set = $linkBatch->constructSet( 'page', $db );
1038  if ( $set === false ) {
1039  break;
1040  }
1041 
1042  // Get pageIDs data from the `page` table
1043  $res = $db->select( 'page', $pageFlds, $set, __METHOD__ );
1044 
1045  // Hack: get the ns:titles stored in [ns => array(titles)] format
1046  $this->initFromQueryResult( $res, $linkBatch->data, true );
1047  }
1048  }
1049  }
1050 
1058  private function getRedirectTargets() {
1059  $titlesToResolve = [];
1060  $db = $this->getDB();
1061 
1062  if ( $this->mPendingRedirectIDs ) {
1063  $res = $db->select(
1064  'redirect',
1065  [
1066  'rd_from',
1067  'rd_namespace',
1068  'rd_fragment',
1069  'rd_interwiki',
1070  'rd_title'
1071  ], [ 'rd_from' => array_keys( $this->mPendingRedirectIDs ) ],
1072  __METHOD__
1073  );
1074  foreach ( $res as $row ) {
1075  $rdfrom = (int)$row->rd_from;
1076  $from = $this->mPendingRedirectIDs[$rdfrom]->getPrefixedText();
1077  $to = Title::makeTitle(
1078  $row->rd_namespace,
1079  $row->rd_title,
1080  $row->rd_fragment,
1081  $row->rd_interwiki
1082  );
1083  $this->mResolvedRedirectTitles[$from] = $this->mPendingRedirectIDs[$rdfrom];
1084  unset( $this->mPendingRedirectIDs[$rdfrom] );
1085  if ( $to->isExternal() ) {
1086  $this->mInterwikiTitles[$to->getPrefixedText()] = $to->getInterwiki();
1087  } elseif ( !isset( $this->mAllPages[$to->getNamespace()][$to->getDBkey()] ) ) {
1088  $titlesToResolve[] = $to;
1089  }
1090  $this->mRedirectTitles[$from] = $to;
1091  }
1092 
1093  if ( $this->mPendingRedirectIDs ) {
1094  // We found pages that aren't in the redirect table
1095  // Add them
1096  foreach ( $this->mPendingRedirectIDs as $id => $title ) {
1097  $page = WikiPage::factory( $title );
1098  $rt = $page->insertRedirect();
1099  if ( !$rt ) {
1100  // What the hell. Let's just ignore this
1101  continue;
1102  }
1103  if ( $rt->isExternal() ) {
1104  $this->mInterwikiTitles[$rt->getPrefixedText()] = $rt->getInterwiki();
1105  } elseif ( !isset( $this->mAllPages[$rt->getNamespace()][$rt->getDBkey()] ) ) {
1106  $titlesToResolve[] = $rt;
1107  }
1108  $from = $title->getPrefixedText();
1109  $this->mResolvedRedirectTitles[$from] = $title;
1110  $this->mRedirectTitles[$from] = $rt;
1111  unset( $this->mPendingRedirectIDs[$id] );
1112  }
1113  }
1114  }
1115 
1116  if ( $this->mPendingRedirectSpecialPages ) {
1117  foreach ( $this->mPendingRedirectSpecialPages as $key => list( $from, $to ) ) {
1119  $fromKey = $from->getPrefixedText();
1120  $this->mResolvedRedirectTitles[$fromKey] = $from;
1121  $this->mRedirectTitles[$fromKey] = $to;
1122  if ( $to->isExternal() ) {
1123  $this->mInterwikiTitles[$to->getPrefixedText()] = $to->getInterwiki();
1124  } elseif ( !isset( $this->mAllPages[$to->getNamespace()][$to->getDBkey()] ) ) {
1125  $titlesToResolve[] = $to;
1126  }
1127  }
1128  $this->mPendingRedirectSpecialPages = [];
1129 
1130  // Set private caching since we don't know what criteria the
1131  // special pages used to decide on these redirects.
1132  $this->mCacheMode = 'private';
1133  }
1134 
1135  return $this->processTitlesArray( $titlesToResolve );
1136  }
1137 
1151  public function getCacheMode( $params = null ) {
1152  return $this->mCacheMode;
1153  }
1154 
1164  private function processTitlesArray( $titles ) {
1165  $linkBatch = new LinkBatch();
1166  $services = MediaWikiServices::getInstance();
1167  $contLang = $services->getContentLanguage();
1168 
1169  $titleObjects = [];
1170  foreach ( $titles as $index => $title ) {
1171  if ( is_string( $title ) ) {
1172  try {
1174  $titleObj = Title::newFromTextThrow( $title, $this->mDefaultNamespace );
1175  } catch ( MalformedTitleException $ex ) {
1176  // Handle invalid titles gracefully
1177  if ( !isset( $this->mAllPages[0][$title] ) ) {
1178  $this->mAllPages[0][$title] = $this->mFakePageId;
1179  $this->mInvalidTitles[$this->mFakePageId] = [
1180  'title' => $title,
1181  'invalidreason' => $this->getErrorFormatter()->formatException( $ex, [ 'bc' => true ] ),
1182  ];
1183  $this->mFakePageId--;
1184  }
1185  continue; // There's nothing else we can do
1186  }
1187  } else {
1188  $titleObj = $title;
1189  }
1190 
1191  $titleObjects[$index] = $titleObj;
1192  }
1193 
1194  // Get gender information
1195  $genderCache = $services->getGenderCache();
1196  $genderCache->doTitlesArray( $titleObjects, __METHOD__ );
1197 
1198  foreach ( $titleObjects as $index => $titleObj ) {
1199  $title = is_string( $titles[$index] ) ? $titles[$index] : false;
1200  $unconvertedTitle = $titleObj->getPrefixedText();
1201  $titleWasConverted = false;
1202  if ( $titleObj->isExternal() ) {
1203  // This title is an interwiki link.
1204  $this->mInterwikiTitles[$unconvertedTitle] = $titleObj->getInterwiki();
1205  } else {
1206  // Variants checking
1207  if (
1208  $this->mConvertTitles && $contLang->hasVariants() && !$titleObj->exists()
1209  ) {
1210  // Language::findVariantLink will modify titleText and titleObj into
1211  // the canonical variant if possible
1212  $titleText = $title !== false ? $title : $titleObj->getPrefixedText();
1213  $contLang->findVariantLink( $titleText, $titleObj );
1214  $titleWasConverted = $unconvertedTitle !== $titleObj->getPrefixedText();
1215  }
1216 
1217  if ( $titleObj->getNamespace() < 0 ) {
1218  // Handle Special and Media pages
1219  $titleObj = $titleObj->fixSpecialName();
1220  $ns = $titleObj->getNamespace();
1221  $dbkey = $titleObj->getDBkey();
1222  if ( !isset( $this->mAllSpecials[$ns][$dbkey] ) ) {
1223  $this->mAllSpecials[$ns][$dbkey] = $this->mFakePageId;
1224  $target = null;
1225  if ( $ns === NS_SPECIAL && $this->mResolveRedirects ) {
1226  $spFactory = $services->getSpecialPageFactory();
1227  $special = $spFactory->getPage( $dbkey );
1228  if ( $special instanceof RedirectSpecialArticle ) {
1229  // Only RedirectSpecialArticle is intended to redirect to an article, other kinds of
1230  // RedirectSpecialPage are probably applying weird URL parameters we don't want to
1231  // handle.
1232  $context = new DerivativeContext( $this );
1233  $context->setTitle( $titleObj );
1234  $context->setRequest( new FauxRequest );
1235  $special->setContext( $context );
1236  list( /* $alias */, $subpage ) = $spFactory->resolveAlias( $dbkey );
1237  $target = $special->getRedirect( $subpage );
1238  }
1239  }
1240  if ( $target ) {
1241  $this->mPendingRedirectSpecialPages[$dbkey] = [ $titleObj, $target ];
1242  } else {
1243  $this->mSpecialTitles[$this->mFakePageId] = $titleObj;
1244  $this->mFakePageId--;
1245  }
1246  }
1247  } else {
1248  // Regular page
1249  $linkBatch->addObj( $titleObj );
1250  }
1251  }
1252 
1253  // Make sure we remember the original title that was
1254  // given to us. This way the caller can correlate new
1255  // titles with the originally requested when e.g. the
1256  // namespace is localized or the capitalization is
1257  // different
1258  if ( $titleWasConverted ) {
1259  $this->mConvertedTitles[$unconvertedTitle] = $titleObj->getPrefixedText();
1260  // In this case the page can't be Special.
1261  if ( $title !== false && $title !== $unconvertedTitle ) {
1262  $this->mNormalizedTitles[$title] = $unconvertedTitle;
1263  }
1264  } elseif ( $title !== false && $title !== $titleObj->getPrefixedText() ) {
1265  $this->mNormalizedTitles[$title] = $titleObj->getPrefixedText();
1266  }
1267  }
1268 
1269  return $linkBatch;
1270  }
1271 
1287  public function setGeneratorData( Title $title, array $data ) {
1288  $ns = $title->getNamespace();
1289  $dbkey = $title->getDBkey();
1290  $this->mGeneratorData[$ns][$dbkey] = $data;
1291  }
1292 
1312  public function setRedirectMergePolicy( $callable ) {
1313  $this->mRedirectMergePolicy = $callable;
1314  }
1315 
1336  public function populateGeneratorData( &$result, array $path = [] ) {
1337  if ( $result instanceof ApiResult ) {
1338  $data = $result->getResultData( $path );
1339  if ( $data === null ) {
1340  return true;
1341  }
1342  } else {
1343  $data = &$result;
1344  foreach ( $path as $key ) {
1345  if ( !isset( $data[$key] ) ) {
1346  // Path isn't in $result, so nothing to add, so everything
1347  // "fits"
1348  return true;
1349  }
1350  $data = &$data[$key];
1351  }
1352  }
1353  foreach ( $this->mGeneratorData as $ns => $dbkeys ) {
1354  if ( $ns === NS_SPECIAL ) {
1355  $pages = [];
1356  foreach ( $this->mSpecialTitles as $id => $title ) {
1357  $pages[$title->getDBkey()] = $id;
1358  }
1359  } else {
1360  if ( !isset( $this->mAllPages[$ns] ) ) {
1361  // No known titles in the whole namespace. Skip it.
1362  continue;
1363  }
1364  $pages = $this->mAllPages[$ns];
1365  }
1366  foreach ( $dbkeys as $dbkey => $genData ) {
1367  if ( !isset( $pages[$dbkey] ) ) {
1368  // Unknown title. Forget it.
1369  continue;
1370  }
1371  $pageId = $pages[$dbkey];
1372  if ( !isset( $data[$pageId] ) ) {
1373  // $pageId didn't make it into the result. Ignore it.
1374  continue;
1375  }
1376 
1377  if ( $result instanceof ApiResult ) {
1378  $path2 = array_merge( $path, [ $pageId ] );
1379  foreach ( $genData as $key => $value ) {
1380  if ( !$result->addValue( $path2, $key, $value ) ) {
1381  return false;
1382  }
1383  }
1384  } else {
1385  $data[$pageId] = array_merge( $data[$pageId], $genData );
1386  }
1387  }
1388  }
1389 
1390  // Merge data generated about redirect titles into the redirect destination
1391  if ( $this->mRedirectMergePolicy ) {
1392  foreach ( $this->mResolvedRedirectTitles as $titleFrom ) {
1393  $dest = $titleFrom;
1394  while ( isset( $this->mRedirectTitles[$dest->getPrefixedText()] ) ) {
1395  $dest = $this->mRedirectTitles[$dest->getPrefixedText()];
1396  }
1397  $fromNs = $titleFrom->getNamespace();
1398  $fromDBkey = $titleFrom->getDBkey();
1399  $toPageId = $dest->getArticleID();
1400  if ( isset( $data[$toPageId] ) &&
1401  isset( $this->mGeneratorData[$fromNs][$fromDBkey] )
1402  ) {
1403  // It is necessary to set both $data and add to $result, if an ApiResult,
1404  // to ensure multiple redirects to the same destination are all merged.
1405  $data[$toPageId] = call_user_func(
1406  $this->mRedirectMergePolicy,
1407  $data[$toPageId],
1408  $this->mGeneratorData[$fromNs][$fromDBkey]
1409  );
1410  if ( $result instanceof ApiResult &&
1411  !$result->addValue( $path, $toPageId, $data[$toPageId], ApiResult::OVERRIDE )
1412  ) {
1413  return false;
1414  }
1415  }
1416  }
1417  }
1418 
1419  return true;
1420  }
1421 
1426  protected function getDB() {
1427  return $this->mDbSource->getDB();
1428  }
1429 
1430  public function getAllowedParams( $flags = 0 ) {
1431  $result = [
1432  'titles' => [
1433  ApiBase::PARAM_ISMULTI => true,
1434  ApiBase::PARAM_HELP_MSG => 'api-pageset-param-titles',
1435  ],
1436  'pageids' => [
1437  ApiBase::PARAM_TYPE => 'integer',
1438  ApiBase::PARAM_ISMULTI => true,
1439  ApiBase::PARAM_HELP_MSG => 'api-pageset-param-pageids',
1440  ],
1441  'revids' => [
1442  ApiBase::PARAM_TYPE => 'integer',
1443  ApiBase::PARAM_ISMULTI => true,
1444  ApiBase::PARAM_HELP_MSG => 'api-pageset-param-revids',
1445  ],
1446  'generator' => [
1447  ApiBase::PARAM_TYPE => null,
1448  ApiBase::PARAM_HELP_MSG => 'api-pageset-param-generator',
1450  ],
1451  'redirects' => [
1452  ApiBase::PARAM_DFLT => false,
1453  ApiBase::PARAM_HELP_MSG => $this->mAllowGenerator
1454  ? 'api-pageset-param-redirects-generator'
1455  : 'api-pageset-param-redirects-nogenerator',
1456  ],
1457  'converttitles' => [
1458  ApiBase::PARAM_DFLT => false,
1460  'api-pageset-param-converttitles',
1461  [ Message::listParam( LanguageConverter::$languagesWithVariants, 'text' ) ],
1462  ],
1463  ],
1464  ];
1465 
1466  if ( !$this->mAllowGenerator ) {
1467  unset( $result['generator'] );
1468  } elseif ( $flags & ApiBase::GET_VALUES_FOR_HELP ) {
1469  $result['generator'][ApiBase::PARAM_TYPE] = 'submodule';
1470  $result['generator'][ApiBase::PARAM_SUBMODULE_MAP] = $this->getGenerators();
1471  }
1472 
1473  return $result;
1474  }
1475 
1476  public function handleParamNormalization( $paramName, $value, $rawValue ) {
1477  parent::handleParamNormalization( $paramName, $value, $rawValue );
1478 
1479  if ( $paramName === 'titles' ) {
1480  // For the 'titles' parameter, we want to split it like ApiBase would
1481  // and add any changed titles to $this->mNormalizedTitles
1482  $value = ParamValidator::explodeMultiValue( $value, self::LIMIT_SML2 + 1 );
1483  $l = count( $value );
1484  $rawValue = ParamValidator::explodeMultiValue( $rawValue, $l );
1485  for ( $i = 0; $i < $l; $i++ ) {
1486  if ( $value[$i] !== $rawValue[$i] ) {
1487  $this->mNormalizedTitles[$rawValue[$i]] = $value[$i];
1488  }
1489  }
1490  }
1491  }
1492 
1493  private static $generators = null;
1494 
1499  private function getGenerators() {
1500  if ( self::$generators === null ) {
1501  $query = $this->mDbSource;
1502  if ( !( $query instanceof ApiQuery ) ) {
1503  // If the parent container of this pageset is not ApiQuery,
1504  // we must create it to get module manager
1505  $query = $this->getMain()->getModuleManager()->getModule( 'query' );
1506  }
1507  $gens = [];
1508  $prefix = $query->getModulePath() . '+';
1509  $mgr = $query->getModuleManager();
1510  foreach ( $mgr->getNamesWithClasses() as $name => $class ) {
1511  if ( is_subclass_of( $class, ApiQueryGeneratorBase::class ) ) {
1512  $gens[$name] = $prefix . $name;
1513  }
1514  }
1515  ksort( $gens );
1516  self::$generators = $gens;
1517  }
1518 
1519  return self::$generators;
1520  }
1521 }
ApiPageSet\$mPendingRedirectIDs
Title[] $mPendingRedirectIDs
Definition: ApiPageSet.php:71
ApiPageSet\$mConvertedTitles
$mConvertedTitles
Definition: ApiPageSet.php:74
ApiPageSet\getTitleCount
getTitleCount()
Returns the number of unique pages (not revisions) in the set.
Definition: ApiPageSet.php:360
ApiPageSet\$mRedirectTitles
$mRedirectTitles
Definition: ApiPageSet.php:65
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:33
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:63
ApiBase\PARAM_SUBMODULE_MAP
const PARAM_SUBMODULE_MAP
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:67
ApiPageSet\initFromTitles
initFromTitles( $titles)
This method populates internal variables with page information based on the given array of title stri...
Definition: ApiPageSet.php:797
ApiPageSet\$mSpecialTitles
$mSpecialTitles
Definition: ApiPageSet.php:66
FauxRequest
WebRequest clone which takes values from a provided array.
Definition: FauxRequest.php:33
ApiPageSet\$mMissingTitles
$mMissingTitles
Definition: ApiPageSet.php:61
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:332
ApiQuery
This is the main query class.
Definition: ApiQuery.php:37
ApiBase\addWarning
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition: ApiBase.php:1298
ApiPageSet\processDbRow
processDbRow( $row)
Extract all requested fields from the row received from the database.
Definition: ApiPageSet.php:757
ApiPageSet\$mResolveRedirects
$mResolveRedirects
Definition: ApiPageSet.php:51
LinkBatch
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:35
ApiPageSet\getGoodTitleCount
getGoodTitleCount()
Returns the number of found unique pages (not revisions) in the set.
Definition: ApiPageSet.php:384
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:137
ApiPageSet\processTitlesArray
processTitlesArray( $titles)
Given an array of title strings, convert them into Title objects.
Definition: ApiPageSet.php:1164
if
if(ini_get( 'mbstring.func_overload')) if(!defined('MW_ENTRY_POINT'))
Pre-config setup: Before loading LocalSettings.php.
Definition: Setup.php:71
ApiPageSet\getTitles
getTitles()
All Title objects provided.
Definition: ApiPageSet.php:352
ApiPageSet\getConvertedTitles
getConvertedTitles()
Get a list of title conversions - maps a title to its converted version.
Definition: ApiPageSet.php:525
ApiBase\dieWithError
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
Definition: ApiBase.php:1379
ApiBase\PARAM_HELP_MSG
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition: ApiBase.php:96
ApiPageSet\__construct
__construct(ApiBase $dbSource, $flags=0, $defaultNamespace=NS_MAIN)
Definition: ApiPageSet.php:120
ApiPageSet\getLiveRevisionIDs
getLiveRevisionIDs()
Get the list of non-deleted revision IDs (requested with the revids= parameter)
Definition: ApiPageSet.php:660
ApiBase\PARAM_TYPE
const PARAM_TYPE
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:60
ApiPageSet\initFromQueryResult
initFromQueryResult( $res, &$remaining=null, $processTitles=null)
Iterate through the result of the query on 'page' table, and for each row create and store title obje...
Definition: ApiPageSet.php:865
ApiPageSet\requestField
requestField( $fieldName)
Request an additional field from the page table.
Definition: ApiPageSet.php:290
ApiPageSet\execute
execute()
Populate the PageSet from the request parameters.
Definition: ApiPageSet.php:142
Title\getPrefixedText
getPrefixedText()
Get the prefixed title with spaces.
Definition: Title.php:1852
ApiPageSet\$mDefaultNamespace
int $mDefaultNamespace
Definition: ApiPageSet.php:85
ApiPageSet\$mCacheMode
$mCacheMode
Definition: ApiPageSet.php:81
ApiPageSet\$mInterwikiTitles
$mInterwikiTitles
Definition: ApiPageSet.php:69
ApiPageSet\$mGoodPages
$mGoodPages
Definition: ApiPageSet.php:58
ApiPageSet\$mRedirectMergePolicy
callable null $mRedirectMergePolicy
Definition: ApiPageSet.php:87
ApiPageSet\initFromPageIds
initFromPageIds( $pageids, $filterIds=true)
Does the same as initFromTitles(), but is based on page IDs instead.
Definition: ApiPageSet.php:825
ApiPageSet\resolvePendingRedirects
resolvePendingRedirects()
Resolve any redirects in the result if redirect resolution was requested.
Definition: ApiPageSet.php:1021
ApiPageSet\getDeletedRevisionIDs
getDeletedRevisionIDs()
Get the list of revision IDs that were associated with deleted titles.
Definition: ApiPageSet.php:668
ApiPageSet\$mLiveRevIDs
$mLiveRevIDs
Definition: ApiPageSet.php:76
ApiPageSet\populateFromRevisionIDs
populateFromRevisionIDs( $revIDs)
Populate this PageSet from a list of revision IDs.
Definition: ApiPageSet.php:749
ApiPageSet\addValues
static addValues(array &$result, $values, $flags=[], $name=null)
Add all items from $values into the result.
Definition: ApiPageSet.php:96
ApiPageSet\$mConvertTitles
$mConvertTitles
Definition: ApiPageSet.php:52
ApiPageSet\$mGeneratorData
$mGeneratorData
Definition: ApiPageSet.php:79
$res
$res
Definition: testCompression.php:57
ContextSource\getUser
getUser()
Definition: ContextSource.php:120
ApiPageSet\$mMissingPages
$mMissingPages
Definition: ApiPageSet.php:60
ApiPageSet\getGoodAndMissingTitlesByNamespace
getGoodAndMissingTitlesByNamespace()
Returns an array [ns][dbkey] => page_id for all good and missing titles.
Definition: ApiPageSet.php:410
ApiPageSet\$mPendingRedirectSpecialPages
$mPendingRedirectSpecialPages
Definition: ApiPageSet.php:72
ApiPageSet\populateFromTitles
populateFromTitles( $titles)
Populate this PageSet from a list of Titles.
Definition: ApiPageSet.php:720
LinkCache\getSelectFields
static getSelectFields()
Fields that LinkCache needs to select.
Definition: LinkCache.php:219
ApiPageSet\setGeneratorData
setGeneratorData(Title $title, array $data)
Set data for a title.
Definition: ApiPageSet.php:1287
ApiPageSet\$mGoodRevIDs
$mGoodRevIDs
Definition: ApiPageSet.php:75
ApiPageSet
This class contains a list of pages that the client has requested.
Definition: ApiPageSet.php:42
ApiBase
This abstract class implements many basic API functions, and is the base of all API classes.
Definition: ApiBase.php:48
ApiPageSet\executeDryRun
executeDryRun()
In case execute() is not called, call this method to mark all relevant parameters as used This preven...
Definition: ApiPageSet.php:135
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
ApiPageSet\getRedirectTitlesAsResult
getRedirectTitlesAsResult( $result=null)
Get a list of redirect resolutions - maps a title to its redirect target.
Definition: ApiPageSet.php:455
ApiPageSet\getPageTableFields
getPageTableFields()
Get the fields that have to be queried from the page table: the ones requested through requestField()...
Definition: ApiPageSet.php:310
ApiPageSet\$mInvalidTitles
array $mInvalidTitles
[fake_page_id] => [ 'title' => $title, 'invalidreason' => $reason ]
Definition: ApiPageSet.php:63
ApiPageSet\$mAllowGenerator
$mAllowGenerator
Definition: ApiPageSet.php:53
ApiPageSet\getConvertedTitlesAsResult
getConvertedTitlesAsResult( $result=null)
Get a list of title conversions - maps a title to its converted version as a result array.
Definition: ApiPageSet.php:536
ApiPageSet\$mParams
$mParams
Definition: ApiPageSet.php:50
NS_MAIN
const NS_MAIN
Definition: Defines.php:69
ApiPageSet\getMissingTitles
getMissingTitles()
Title objects that were NOT found in the database.
Definition: ApiPageSet.php:402
NS_SPECIAL
const NS_SPECIAL
Definition: Defines.php:58
DerivativeContext
An IContextSource implementation which will inherit context from another source but allow individual ...
Definition: DerivativeContext.php:30
ApiPageSet\getMissingTitlesByNamespace
getMissingTitlesByNamespace()
Returns an array [ns][dbkey] => fake_page_id for all missing titles.
Definition: ApiPageSet.php:393
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:143
ApiPageSet\populateFromQueryResult
populateFromQueryResult( $db, $queryResult)
Populate this PageSet from a rowset returned from the database.
Definition: ApiPageSet.php:741
Wikimedia\Rdbms\IResultWrapper
Result wrapper for grabbing data queried from an IDatabase object.
Definition: IResultWrapper.php:24
ApiResult
This class represents the result of the API operations.
Definition: ApiResult.php:35
Title\newFromRow
static newFromRow( $row)
Make a Title object from a DB row.
Definition: Title.php:527
ApiPageSet\$mGoodAndMissingPages
$mGoodAndMissingPages
Definition: ApiPageSet.php:57
ApiPageSet\getGenerators
getGenerators()
Get an array of all available generators.
Definition: ApiPageSet.php:1499
ApiPageSet\getDataSource
getDataSource()
Return the parameter name that is the source of data for this PageSet.
Definition: ApiPageSet.php:268
PROTO_CURRENT
const PROTO_CURRENT
Definition: Defines.php:211
ApiPageSet\$mRequestedPageFields
array $mRequestedPageFields
Definition: ApiPageSet.php:83
ApiBase\extractRequestParams
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:659
ApiPageSet\getRevisionIDs
getRevisionIDs()
Get the list of valid revision IDs (requested with the revids= parameter)
Definition: ApiPageSet.php:652
ApiPageSet\$mTitles
$mTitles
Definition: ApiPageSet.php:56
$generator
$generator
Definition: generateLocalAutoload.php:13
$title
$title
Definition: testCompression.php:38
ApiPageSet\getRedirectTitles
getRedirectTitles()
Get a list of redirect resolutions - maps a title to its redirect target, as an array of output-ready...
Definition: ApiPageSet.php:444
Title\makeTitle
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:595
ApiPageSet\getGoodTitles
getGoodTitles()
Title objects that were found in the database.
Definition: ApiPageSet.php:376
ApiResult\addValue
addValue( $path, $name, $value, $flags=0)
Add value to the output data at the given path.
Definition: ApiResult.php:393
RedirectSpecialArticle
Superclass for any RedirectSpecialPage which redirects the user to a particular article (as opposed t...
Definition: RedirectSpecialArticle.php:87
Title\newFromTextThrow
static newFromTextThrow( $text, $defaultNamespace=NS_MAIN)
Like Title::newFromText(), but throws MalformedTitleException when the title is invalid,...
Definition: Title.php:367
ApiPageSet\isResolvingRedirects
isResolvingRedirects()
Check whether this PageSet is resolving redirects.
Definition: ApiPageSet.php:256
ApiPageSet\$mGoodTitles
$mGoodTitles
Definition: ApiPageSet.php:59
ApiPageSet\getGoodAndMissingTitles
getGoodAndMissingTitles()
Title objects for good and missing titles.
Definition: ApiPageSet.php:418
ApiResult\setIndexedTagName
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Definition: ApiResult.php:604
ApiPageSet\getCacheMode
getCacheMode( $params=null)
Get the cache mode for the data generated by this module.
Definition: ApiPageSet.php:1151
ApiPageSet\initFromRevIDs
initFromRevIDs( $revids)
Does the same as initFromTitles(), but is based on revision IDs instead.
Definition: ApiPageSet.php:938
ApiBase\encodeParamName
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
Definition: ApiBase.php:637
ApiBase\GET_VALUES_FOR_HELP
const GET_VALUES_FOR_HELP
getAllowedParams() flag: When set, the result could take longer to generate, but should be more thoro...
Definition: ApiBase.php:167
ApiPageSet\getInterwikiTitles
getInterwikiTitles()
Get a list of interwiki titles - maps a title to its interwiki prefix.
Definition: ApiPageSet.php:556
ApiPageSet\getAllTitlesByNamespace
getAllTitlesByNamespace()
Returns an array [ns][dbkey] => page_id for all requested titles.
Definition: ApiPageSet.php:344
ApiPageSet\$mMissingRevIDs
$mMissingRevIDs
Definition: ApiPageSet.php:78
ApiPageSet\$generators
static $generators
Definition: ApiPageSet.php:1493
ApiPageSet\$mDbSource
$mDbSource
Definition: ApiPageSet.php:49
ApiBase\getPermissionManager
getPermissionManager()
Obtain a PermissionManager instance that subclasses may use in their authorization checks.
Definition: ApiBase.php:608
ApiPageSet\$mMissingPageIDs
$mMissingPageIDs
Definition: ApiPageSet.php:64
ApiPageSet\getNormalizedTitlesAsResult
getNormalizedTitlesAsResult( $result=null)
Get a list of title normalizations - maps a title to its normalized version in the form of result arr...
Definition: ApiPageSet.php:502
ApiPageSet\populateFromPageIDs
populateFromPageIDs( $pageIDs)
Populate this PageSet from a list of page IDs.
Definition: ApiPageSet.php:728
ApiPageSet\getDB
getDB()
Get the database connection (read-only)
Definition: ApiPageSet.php:1426
ApiPageSet\getAllowedParams
getAllowedParams( $flags=0)
Definition: ApiPageSet.php:1430
ApiPageSet\getInterwikiTitlesAsResult
getInterwikiTitlesAsResult( $result=null, $iwUrl=false)
Get a list of interwiki titles - maps a title to its interwiki prefix as result.
Definition: ApiPageSet.php:568
ApiPageSet\getMissingPageIDs
getMissingPageIDs()
Page IDs that were not found in the database.
Definition: ApiPageSet.php:435
ApiPageSet\$mDeletedRevIDs
$mDeletedRevIDs
Definition: ApiPageSet.php:77
ApiPageSet\$mResolvedRedirectTitles
$mResolvedRedirectTitles
Definition: ApiPageSet.php:73
ApiPageSet\getRedirectTargets
getRedirectTargets()
Get the targets of the pending redirects from the database.
Definition: ApiPageSet.php:1058
ApiQueryGeneratorBase
Definition: ApiQueryGeneratorBase.php:26
Title
Represents a title within MediaWiki.
Definition: Title.php:42
ApiBase\filterIDs
filterIDs( $fields, array $ids)
Filter out-of-range values from a list of positive integer IDs.
Definition: ApiBase.php:1250
ApiPageSet\getMissingRevisionIDsAsResult
getMissingRevisionIDsAsResult( $result=null)
Revision IDs that were not found in the database as result array.
Definition: ApiPageSet.php:686
MalformedTitleException
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
Definition: MalformedTitleException.php:25
ApiPageSet\getInvalidTitlesAndRevisions
getInvalidTitlesAndRevisions( $invalidChecks=[ 'invalidTitles', 'special', 'missingIds', 'missingRevIds', 'missingTitles', 'interwikiTitles'])
Get an array of invalid/special/missing titles.
Definition: ApiPageSet.php:602
ApiPageSet\getGoodTitlesByNamespace
getGoodTitlesByNamespace()
Returns an array [ns][dbkey] => page_id for all good titles.
Definition: ApiPageSet.php:368
ApiPageSet\executeInternal
executeInternal( $isDryRun)
Populate the PageSet from the request parameters.
Definition: ApiPageSet.php:151
ApiPageSet\handleParamNormalization
handleParamNormalization( $paramName, $value, $rawValue)
Handle when a parameter was Unicode-normalized.
Definition: ApiPageSet.php:1476
ApiPageSet\setRedirectMergePolicy
setRedirectMergePolicy( $callable)
Controls how generator data about a redirect source is merged into the generator data for the redirec...
Definition: ApiPageSet.php:1312
$path
$path
Definition: NoLocalSettings.php:25
ApiBase\PARAM_DFLT
const PARAM_DFLT
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:58
ApiBase\getModuleName
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:418
ApiBase\PARAM_ISMULTI
const PARAM_ISMULTI
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:59
ApiPageSet\getMissingRevisionIDs
getMissingRevisionIDs()
Revision IDs that were not found in the database.
Definition: ApiPageSet.php:676
ApiResult\OVERRIDE
const OVERRIDE
Override existing value in addValue(), setValue(), and similar functions.
Definition: ApiResult.php:41
ApiPageSet\getInvalidTitlesAndReasons
getInvalidTitlesAndReasons()
Titles that were deemed invalid by Title::newFromText() The array's index will be unique and negative...
Definition: ApiPageSet.php:427
ApiBase\getMain
getMain()
Get the main module.
Definition: ApiBase.php:434
ApiPageSet\$mAllSpecials
$mAllSpecials
Definition: ApiPageSet.php:67
ApiPageSet\getCustomField
getCustomField( $fieldName)
Get the value of a custom field previously requested through requestField()
Definition: ApiPageSet.php:300
ApiPageSet\getRevisionCount
getRevisionCount()
Returns the number of revisions (requested with revids= parameter).
Definition: ApiPageSet.php:712
ApiPageSet\$mAllPages
$mAllPages
Definition: ApiPageSet.php:55
ApiBase\PARAM_SUBMODULE_PARAM_PREFIX
const PARAM_SUBMODULE_PARAM_PREFIX
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:68
ApiPageSet\DISABLE_GENERATORS
const DISABLE_GENERATORS
Constructor flag: The new instance of ApiPageSet will ignore the 'generator=' parameter.
Definition: ApiPageSet.php:47
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
ApiPageSet\$mFakePageId
$mFakePageId
Definition: ApiPageSet.php:80
ApiPageSet\getSpecialTitles
getSpecialTitles()
Get the list of titles with negative namespace.
Definition: ApiPageSet.php:704
ApiPageSet\getNormalizedTitles
getNormalizedTitles()
Get a list of title normalizations - maps a title to its normalized version.
Definition: ApiPageSet.php:491
ApiBase\dieDebug
static dieDebug( $method, $message)
Internal code errors should be reported with this method.
Definition: ApiBase.php:1571
ApiPageSet\$mNormalizedTitles
$mNormalizedTitles
Definition: ApiPageSet.php:68
ApiBase\getErrorFormatter
getErrorFormatter()
Get the error formatter.
Definition: ApiBase.php:552
Wikimedia\ParamValidator\ParamValidator
Service for formatting and validating API parameters.
Definition: ParamValidator.php:42
ApiPageSet\populateGeneratorData
populateGeneratorData(&$result, array $path=[])
Populate the generator data for all titles in the result.
Definition: ApiPageSet.php:1336
ApiQueryBase\addTitleInfo
static addTitleInfo(&$arr, $title, $prefix='')
Add information (title and namespace) about a Title object to a result array.
Definition: ApiQueryBase.php:462