MediaWiki  1.27.4
ApiPageSet.php
Go to the documentation of this file.
1 <?php
41 class ApiPageSet extends ApiBase {
46  const DISABLE_GENERATORS = 1;
47 
48  private $mDbSource;
49  private $mParams;
51  private $mConvertTitles;
53 
54  private $mAllPages = []; // [ns][dbkey] => page_id or negative when missing
55  private $mTitles = [];
56  private $mGoodAndMissingPages = []; // [ns][dbkey] => page_id or negative when missing
57  private $mGoodPages = []; // [ns][dbkey] => page_id
58  private $mGoodTitles = [];
59  private $mMissingPages = []; // [ns][dbkey] => fake page_id
60  private $mMissingTitles = [];
62  private $mInvalidTitles = [];
63  private $mMissingPageIDs = [];
64  private $mRedirectTitles = [];
65  private $mSpecialTitles = [];
66  private $mNormalizedTitles = [];
67  private $mInterwikiTitles = [];
69  private $mPendingRedirectIDs = [];
71  private $mConvertedTitles = [];
72  private $mGoodRevIDs = [];
73  private $mLiveRevIDs = [];
74  private $mDeletedRevIDs = [];
75  private $mMissingRevIDs = [];
76  private $mGeneratorData = []; // [ns][dbkey] => data array
77  private $mFakePageId = -1;
78  private $mCacheMode = 'public';
79  private $mRequestedPageFields = [];
84 
92  private static function addValues( array &$result, $values, $flag = null, $name = null ) {
93  foreach ( $values as $val ) {
94  if ( $val instanceof Title ) {
95  $v = [];
96  ApiQueryBase::addTitleInfo( $v, $val );
97  } elseif ( $name !== null ) {
98  $v = [ $name => $val ];
99  } else {
100  $v = $val;
101  }
102  if ( $flag !== null ) {
103  $v[$flag] = true;
104  }
105  $result[] = $v;
106  }
107  }
108 
116  public function __construct( ApiBase $dbSource, $flags = 0, $defaultNamespace = NS_MAIN ) {
117  parent::__construct( $dbSource->getMain(), $dbSource->getModuleName() );
118  $this->mDbSource = $dbSource;
119  $this->mAllowGenerator = ( $flags & ApiPageSet::DISABLE_GENERATORS ) == 0;
120  $this->mDefaultNamespace = $defaultNamespace;
121 
122  $this->mParams = $this->extractRequestParams();
123  $this->mResolveRedirects = $this->mParams['redirects'];
124  $this->mConvertTitles = $this->mParams['converttitles'];
125  }
126 
131  public function executeDryRun() {
132  $this->executeInternal( true );
133  }
134 
138  public function execute() {
139  $this->executeInternal( false );
140  }
141 
147  private function executeInternal( $isDryRun ) {
148  $generatorName = $this->mAllowGenerator ? $this->mParams['generator'] : null;
149  if ( isset( $generatorName ) ) {
150  $dbSource = $this->mDbSource;
151  if ( !$dbSource instanceof ApiQuery ) {
152  // If the parent container of this pageset is not ApiQuery, we must create it to run generator
153  $dbSource = $this->getMain()->getModuleManager()->getModule( 'query' );
154  }
155  $generator = $dbSource->getModuleManager()->getModule( $generatorName, null, true );
156  if ( $generator === null ) {
157  $this->dieUsage( 'Unknown generator=' . $generatorName, 'badgenerator' );
158  }
159  if ( !$generator instanceof ApiQueryGeneratorBase ) {
160  $this->dieUsage( "Module $generatorName cannot be used as a generator", 'badgenerator' );
161  }
162  // Create a temporary pageset to store generator's output,
163  // add any additional fields generator may need, and execute pageset to populate titles/pageids
164  $tmpPageSet = new ApiPageSet( $dbSource, ApiPageSet::DISABLE_GENERATORS );
165  $generator->setGeneratorMode( $tmpPageSet );
166  $this->mCacheMode = $generator->getCacheMode( $generator->extractRequestParams() );
167 
168  if ( !$isDryRun ) {
169  $generator->requestExtraData( $tmpPageSet );
170  }
171  $tmpPageSet->executeInternal( $isDryRun );
172 
173  // populate this pageset with the generator output
174  if ( !$isDryRun ) {
175  $generator->executeGenerator( $this );
176 
177  // Avoid PHP 7.1 warning of passing $this by reference
178  $apiModule = $this;
179  Hooks::run( 'APIQueryGeneratorAfterExecute', [ &$generator, &$apiModule ] );
180  } else {
181  // Prevent warnings from being reported on these parameters
182  $main = $this->getMain();
183  foreach ( $generator->extractRequestParams() as $paramName => $param ) {
184  $main->markParamsUsed( $generator->encodeParamName( $paramName ) );
185  }
186  }
187 
188  if ( !$isDryRun ) {
189  $this->resolvePendingRedirects();
190  }
191  } else {
192  // Only one of the titles/pageids/revids is allowed at the same time
193  $dataSource = null;
194  if ( isset( $this->mParams['titles'] ) ) {
195  $dataSource = 'titles';
196  }
197  if ( isset( $this->mParams['pageids'] ) ) {
198  if ( isset( $dataSource ) ) {
199  $this->dieUsage( "Cannot use 'pageids' at the same time as '$dataSource'", 'multisource' );
200  }
201  $dataSource = 'pageids';
202  }
203  if ( isset( $this->mParams['revids'] ) ) {
204  if ( isset( $dataSource ) ) {
205  $this->dieUsage( "Cannot use 'revids' at the same time as '$dataSource'", 'multisource' );
206  }
207  $dataSource = 'revids';
208  }
209 
210  if ( !$isDryRun ) {
211  // Populate page information with the original user input
212  switch ( $dataSource ) {
213  case 'titles':
214  $this->initFromTitles( $this->mParams['titles'] );
215  break;
216  case 'pageids':
217  $this->initFromPageIds( $this->mParams['pageids'] );
218  break;
219  case 'revids':
220  if ( $this->mResolveRedirects ) {
221  $this->setWarning( 'Redirect resolution cannot be used ' .
222  'together with the revids= parameter. Any redirects ' .
223  'the revids= point to have not been resolved.' );
224  }
225  $this->mResolveRedirects = false;
226  $this->initFromRevIDs( $this->mParams['revids'] );
227  break;
228  default:
229  // Do nothing - some queries do not need any of the data sources.
230  break;
231  }
232  }
233  }
234  }
235 
240  public function isResolvingRedirects() {
242  }
243 
252  public function getDataSource() {
253  if ( $this->mAllowGenerator && isset( $this->mParams['generator'] ) ) {
254  return 'generator';
255  }
256  if ( isset( $this->mParams['titles'] ) ) {
257  return 'titles';
258  }
259  if ( isset( $this->mParams['pageids'] ) ) {
260  return 'pageids';
261  }
262  if ( isset( $this->mParams['revids'] ) ) {
263  return 'revids';
264  }
265 
266  return null;
267  }
268 
274  public function requestField( $fieldName ) {
275  $this->mRequestedPageFields[$fieldName] = null;
276  }
277 
284  public function getCustomField( $fieldName ) {
285  return $this->mRequestedPageFields[$fieldName];
286  }
287 
294  public function getPageTableFields() {
295  // Ensure we get minimum required fields
296  // DON'T change this order
297  $pageFlds = [
298  'page_namespace' => null,
299  'page_title' => null,
300  'page_id' => null,
301  ];
302 
303  if ( $this->mResolveRedirects ) {
304  $pageFlds['page_is_redirect'] = null;
305  }
306 
307  if ( $this->getConfig()->get( 'ContentHandlerUseDB' ) ) {
308  $pageFlds['page_content_model'] = null;
309  }
310 
311  if ( $this->getConfig()->get( 'PageLanguageUseDB' ) ) {
312  $pageFlds['page_lang'] = null;
313  }
314 
315  // only store non-default fields
316  $this->mRequestedPageFields = array_diff_key( $this->mRequestedPageFields, $pageFlds );
317 
318  $pageFlds = array_merge( $pageFlds, $this->mRequestedPageFields );
319 
320  return array_keys( $pageFlds );
321  }
322 
329  public function getAllTitlesByNamespace() {
330  return $this->mAllPages;
331  }
332 
337  public function getTitles() {
338  return $this->mTitles;
339  }
340 
345  public function getTitleCount() {
346  return count( $this->mTitles );
347  }
348 
353  public function getGoodTitlesByNamespace() {
354  return $this->mGoodPages;
355  }
356 
361  public function getGoodTitles() {
362  return $this->mGoodTitles;
363  }
364 
369  public function getGoodTitleCount() {
370  return count( $this->mGoodTitles );
371  }
372 
378  public function getMissingTitlesByNamespace() {
379  return $this->mMissingPages;
380  }
381 
387  public function getMissingTitles() {
388  return $this->mMissingTitles;
389  }
390 
397  }
398 
403  public function getGoodAndMissingTitles() {
404  return $this->mGoodTitles + $this->mMissingTitles;
405  }
406 
413  public function getInvalidTitles() {
414  wfDeprecated( __METHOD__, '1.26' );
415  return array_map( function ( $t ) {
416  return $t['title'];
418  }
419 
425  public function getInvalidTitlesAndReasons() {
426  return $this->mInvalidTitles;
427  }
428 
433  public function getMissingPageIDs() {
434  return $this->mMissingPageIDs;
435  }
436 
442  public function getRedirectTitles() {
443  return $this->mRedirectTitles;
444  }
445 
453  public function getRedirectTitlesAsResult( $result = null ) {
454  $values = [];
455  foreach ( $this->getRedirectTitles() as $titleStrFrom => $titleTo ) {
456  $r = [
457  'from' => strval( $titleStrFrom ),
458  'to' => $titleTo->getPrefixedText(),
459  ];
460  if ( $titleTo->hasFragment() ) {
461  $r['tofragment'] = $titleTo->getFragment();
462  }
463  if ( $titleTo->isExternal() ) {
464  $r['tointerwiki'] = $titleTo->getInterwiki();
465  }
466  if ( isset( $this->mResolvedRedirectTitles[$titleStrFrom] ) ) {
467  $titleFrom = $this->mResolvedRedirectTitles[$titleStrFrom];
468  $ns = $titleFrom->getNamespace();
469  $dbkey = $titleFrom->getDBkey();
470  if ( isset( $this->mGeneratorData[$ns][$dbkey] ) ) {
471  $r = array_merge( $this->mGeneratorData[$ns][$dbkey], $r );
472  }
473  }
474 
475  $values[] = $r;
476  }
477  if ( !empty( $values ) && $result ) {
478  ApiResult::setIndexedTagName( $values, 'r' );
479  }
480 
481  return $values;
482  }
483 
489  public function getNormalizedTitles() {
491  }
492 
500  public function getNormalizedTitlesAsResult( $result = null ) {
501  $values = [];
502  foreach ( $this->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
503  $values[] = [
504  'from' => $rawTitleStr,
505  'to' => $titleStr
506  ];
507  }
508  if ( !empty( $values ) && $result ) {
509  ApiResult::setIndexedTagName( $values, 'n' );
510  }
511 
512  return $values;
513  }
514 
520  public function getConvertedTitles() {
522  }
523 
531  public function getConvertedTitlesAsResult( $result = null ) {
532  $values = [];
533  foreach ( $this->getConvertedTitles() as $rawTitleStr => $titleStr ) {
534  $values[] = [
535  'from' => $rawTitleStr,
536  'to' => $titleStr
537  ];
538  }
539  if ( !empty( $values ) && $result ) {
540  ApiResult::setIndexedTagName( $values, 'c' );
541  }
542 
543  return $values;
544  }
545 
551  public function getInterwikiTitles() {
553  }
554 
563  public function getInterwikiTitlesAsResult( $result = null, $iwUrl = false ) {
564  $values = [];
565  foreach ( $this->getInterwikiTitles() as $rawTitleStr => $interwikiStr ) {
566  $item = [
567  'title' => $rawTitleStr,
568  'iw' => $interwikiStr,
569  ];
570  if ( $iwUrl ) {
571  $title = Title::newFromText( $rawTitleStr );
572  $item['url'] = $title->getFullURL( '', false, PROTO_CURRENT );
573  }
574  $values[] = $item;
575  }
576  if ( !empty( $values ) && $result ) {
577  ApiResult::setIndexedTagName( $values, 'i' );
578  }
579 
580  return $values;
581  }
582 
597  public function getInvalidTitlesAndRevisions( $invalidChecks = [ 'invalidTitles',
598  'special', 'missingIds', 'missingRevIds', 'missingTitles', 'interwikiTitles' ]
599  ) {
600  $result = [];
601  if ( in_array( 'invalidTitles', $invalidChecks ) ) {
602  self::addValues( $result, $this->getInvalidTitlesAndReasons(), 'invalid' );
603  }
604  if ( in_array( 'special', $invalidChecks ) ) {
605  self::addValues( $result, $this->getSpecialTitles(), 'special', 'title' );
606  }
607  if ( in_array( 'missingIds', $invalidChecks ) ) {
608  self::addValues( $result, $this->getMissingPageIDs(), 'missing', 'pageid' );
609  }
610  if ( in_array( 'missingRevIds', $invalidChecks ) ) {
611  self::addValues( $result, $this->getMissingRevisionIDs(), 'missing', 'revid' );
612  }
613  if ( in_array( 'missingTitles', $invalidChecks ) ) {
614  self::addValues( $result, $this->getMissingTitles(), 'missing' );
615  }
616  if ( in_array( 'interwikiTitles', $invalidChecks ) ) {
617  self::addValues( $result, $this->getInterwikiTitlesAsResult() );
618  }
619 
620  return $result;
621  }
622 
627  public function getRevisionIDs() {
628  return $this->mGoodRevIDs;
629  }
630 
635  public function getLiveRevisionIDs() {
636  return $this->mLiveRevIDs;
637  }
638 
643  public function getDeletedRevisionIDs() {
644  return $this->mDeletedRevIDs;
645  }
646 
651  public function getMissingRevisionIDs() {
652  return $this->mMissingRevIDs;
653  }
654 
661  public function getMissingRevisionIDsAsResult( $result = null ) {
662  $values = [];
663  foreach ( $this->getMissingRevisionIDs() as $revid ) {
664  $values[$revid] = [
665  'revid' => $revid
666  ];
667  }
668  if ( !empty( $values ) && $result ) {
669  ApiResult::setIndexedTagName( $values, 'rev' );
670  }
671 
672  return $values;
673  }
674 
679  public function getSpecialTitles() {
680  return $this->mSpecialTitles;
681  }
682 
687  public function getRevisionCount() {
688  return count( $this->getRevisionIDs() );
689  }
690 
695  public function populateFromTitles( $titles ) {
696  $this->initFromTitles( $titles );
697  }
698 
703  public function populateFromPageIDs( $pageIDs ) {
704  $this->initFromPageIds( $pageIDs );
705  }
706 
716  public function populateFromQueryResult( $db, $queryResult ) {
717  $this->initFromQueryResult( $queryResult );
718  }
719 
724  public function populateFromRevisionIDs( $revIDs ) {
725  $this->initFromRevIDs( $revIDs );
726  }
727 
732  public function processDbRow( $row ) {
733  // Store Title object in various data structures
734  $title = Title::newFromRow( $row );
735 
736  $pageId = intval( $row->page_id );
737  $this->mAllPages[$row->page_namespace][$row->page_title] = $pageId;
738  $this->mTitles[] = $title;
739 
740  if ( $this->mResolveRedirects && $row->page_is_redirect == '1' ) {
741  $this->mPendingRedirectIDs[$pageId] = $title;
742  } else {
743  $this->mGoodPages[$row->page_namespace][$row->page_title] = $pageId;
744  $this->mGoodAndMissingPages[$row->page_namespace][$row->page_title] = $pageId;
745  $this->mGoodTitles[$pageId] = $title;
746  }
747 
748  foreach ( $this->mRequestedPageFields as $fieldName => &$fieldValues ) {
749  $fieldValues[$pageId] = $row->$fieldName;
750  }
751  }
752 
769  private function initFromTitles( $titles ) {
770  // Get validated and normalized title objects
771  $linkBatch = $this->processTitlesArray( $titles );
772  if ( $linkBatch->isEmpty() ) {
773  return;
774  }
775 
776  $db = $this->getDB();
777  $set = $linkBatch->constructSet( 'page', $db );
778 
779  // Get pageIDs data from the `page` table
780  $res = $db->select( 'page', $this->getPageTableFields(), $set,
781  __METHOD__ );
782 
783  // Hack: get the ns:titles stored in array(ns => array(titles)) format
784  $this->initFromQueryResult( $res, $linkBatch->data, true ); // process Titles
785 
786  // Resolve any found redirects
787  $this->resolvePendingRedirects();
788  }
789 
794  private function initFromPageIds( $pageids ) {
795  if ( !$pageids ) {
796  return;
797  }
798 
799  $pageids = array_map( 'intval', $pageids ); // paranoia
800  $remaining = array_flip( $pageids );
801 
802  $pageids = self::getPositiveIntegers( $pageids );
803 
804  $res = null;
805  if ( !empty( $pageids ) ) {
806  $set = [
807  'page_id' => $pageids
808  ];
809  $db = $this->getDB();
810 
811  // Get pageIDs data from the `page` table
812  $res = $db->select( 'page', $this->getPageTableFields(), $set,
813  __METHOD__ );
814  }
815 
816  $this->initFromQueryResult( $res, $remaining, false ); // process PageIDs
817 
818  // Resolve any found redirects
819  $this->resolvePendingRedirects();
820  }
821 
832  private function initFromQueryResult( $res, &$remaining = null, $processTitles = null ) {
833  if ( !is_null( $remaining ) && is_null( $processTitles ) ) {
834  ApiBase::dieDebug( __METHOD__, 'Missing $processTitles parameter when $remaining is provided' );
835  }
836 
837  $usernames = [];
838  if ( $res ) {
839  foreach ( $res as $row ) {
840  $pageId = intval( $row->page_id );
841 
842  // Remove found page from the list of remaining items
843  if ( isset( $remaining ) ) {
844  if ( $processTitles ) {
845  unset( $remaining[$row->page_namespace][$row->page_title] );
846  } else {
847  unset( $remaining[$pageId] );
848  }
849  }
850 
851  // Store any extra fields requested by modules
852  $this->processDbRow( $row );
853 
854  // Need gender information
855  if ( MWNamespace::hasGenderDistinction( $row->page_namespace ) ) {
856  $usernames[] = $row->page_title;
857  }
858  }
859  }
860 
861  if ( isset( $remaining ) ) {
862  // Any items left in the $remaining list are added as missing
863  if ( $processTitles ) {
864  // The remaining titles in $remaining are non-existent pages
865  foreach ( $remaining as $ns => $dbkeys ) {
866  foreach ( array_keys( $dbkeys ) as $dbkey ) {
867  $title = Title::makeTitle( $ns, $dbkey );
868  $this->mAllPages[$ns][$dbkey] = $this->mFakePageId;
869  $this->mMissingPages[$ns][$dbkey] = $this->mFakePageId;
870  $this->mGoodAndMissingPages[$ns][$dbkey] = $this->mFakePageId;
871  $this->mMissingTitles[$this->mFakePageId] = $title;
872  $this->mFakePageId--;
873  $this->mTitles[] = $title;
874 
875  // need gender information
876  if ( MWNamespace::hasGenderDistinction( $ns ) ) {
877  $usernames[] = $dbkey;
878  }
879  }
880  }
881  } else {
882  // The remaining pageids do not exist
883  if ( !$this->mMissingPageIDs ) {
884  $this->mMissingPageIDs = array_keys( $remaining );
885  } else {
886  $this->mMissingPageIDs = array_merge( $this->mMissingPageIDs, array_keys( $remaining ) );
887  }
888  }
889  }
890 
891  // Get gender information
892  $genderCache = GenderCache::singleton();
893  $genderCache->doQuery( $usernames, __METHOD__ );
894  }
895 
901  private function initFromRevIDs( $revids ) {
902  if ( !$revids ) {
903  return;
904  }
905 
906  $revids = array_map( 'intval', $revids ); // paranoia
907  $db = $this->getDB();
908  $pageids = [];
909  $remaining = array_flip( $revids );
910 
911  $revids = self::getPositiveIntegers( $revids );
912 
913  if ( !empty( $revids ) ) {
914  $tables = [ 'revision', 'page' ];
915  $fields = [ 'rev_id', 'rev_page' ];
916  $where = [ 'rev_id' => $revids, 'rev_page = page_id' ];
917 
918  // Get pageIDs data from the `page` table
919  $res = $db->select( $tables, $fields, $where, __METHOD__ );
920  foreach ( $res as $row ) {
921  $revid = intval( $row->rev_id );
922  $pageid = intval( $row->rev_page );
923  $this->mGoodRevIDs[$revid] = $pageid;
924  $this->mLiveRevIDs[$revid] = $pageid;
925  $pageids[$pageid] = '';
926  unset( $remaining[$revid] );
927  }
928  }
929 
930  $this->mMissingRevIDs = array_keys( $remaining );
931 
932  // Populate all the page information
933  $this->initFromPageIds( array_keys( $pageids ) );
934 
935  // If the user can see deleted revisions, pull out the corresponding
936  // titles from the archive table and include them too. We ignore
937  // ar_page_id because deleted revisions are tied by title, not page_id.
938  if ( !empty( $this->mMissingRevIDs ) && $this->getUser()->isAllowed( 'deletedhistory' ) ) {
939  $remaining = array_flip( $this->mMissingRevIDs );
940  $tables = [ 'archive' ];
941  $fields = [ 'ar_rev_id', 'ar_namespace', 'ar_title' ];
942  $where = [ 'ar_rev_id' => $this->mMissingRevIDs ];
943 
944  $res = $db->select( $tables, $fields, $where, __METHOD__ );
945  $titles = [];
946  foreach ( $res as $row ) {
947  $revid = intval( $row->ar_rev_id );
948  $titles[$revid] = Title::makeTitle( $row->ar_namespace, $row->ar_title );
949  unset( $remaining[$revid] );
950  }
951 
952  $this->initFromTitles( $titles );
953 
954  foreach ( $titles as $revid => $title ) {
955  $ns = $title->getNamespace();
956  $dbkey = $title->getDBkey();
957 
958  // Handle converted titles
959  if ( !isset( $this->mAllPages[$ns][$dbkey] ) &&
960  isset( $this->mConvertedTitles[$title->getPrefixedText()] )
961  ) {
962  $title = Title::newFromText( $this->mConvertedTitles[$title->getPrefixedText()] );
963  $ns = $title->getNamespace();
964  $dbkey = $title->getDBkey();
965  }
966 
967  if ( isset( $this->mAllPages[$ns][$dbkey] ) ) {
968  $this->mGoodRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
969  $this->mDeletedRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
970  } else {
971  $remaining[$revid] = true;
972  }
973  }
974 
975  $this->mMissingRevIDs = array_keys( $remaining );
976  }
977  }
978 
984  private function resolvePendingRedirects() {
985  if ( $this->mResolveRedirects ) {
986  $db = $this->getDB();
987  $pageFlds = $this->getPageTableFields();
988 
989  // Repeat until all redirects have been resolved
990  // The infinite loop is prevented by keeping all known pages in $this->mAllPages
991  while ( $this->mPendingRedirectIDs ) {
992  // Resolve redirects by querying the pagelinks table, and repeat the process
993  // Create a new linkBatch object for the next pass
994  $linkBatch = $this->getRedirectTargets();
995 
996  if ( $linkBatch->isEmpty() ) {
997  break;
998  }
999 
1000  $set = $linkBatch->constructSet( 'page', $db );
1001  if ( $set === false ) {
1002  break;
1003  }
1004 
1005  // Get pageIDs data from the `page` table
1006  $res = $db->select( 'page', $pageFlds, $set, __METHOD__ );
1007 
1008  // Hack: get the ns:titles stored in array(ns => array(titles)) format
1009  $this->initFromQueryResult( $res, $linkBatch->data, true );
1010  }
1011  }
1012  }
1013 
1021  private function getRedirectTargets() {
1022  $lb = new LinkBatch();
1023  $db = $this->getDB();
1024 
1025  $res = $db->select(
1026  'redirect',
1027  [
1028  'rd_from',
1029  'rd_namespace',
1030  'rd_fragment',
1031  'rd_interwiki',
1032  'rd_title'
1033  ], [ 'rd_from' => array_keys( $this->mPendingRedirectIDs ) ],
1034  __METHOD__
1035  );
1036  foreach ( $res as $row ) {
1037  $rdfrom = intval( $row->rd_from );
1038  $from = $this->mPendingRedirectIDs[$rdfrom]->getPrefixedText();
1039  $to = Title::makeTitle(
1040  $row->rd_namespace,
1041  $row->rd_title,
1042  $row->rd_fragment,
1043  $row->rd_interwiki
1044  );
1045  $this->mResolvedRedirectTitles[$from] = $this->mPendingRedirectIDs[$rdfrom];
1046  unset( $this->mPendingRedirectIDs[$rdfrom] );
1047  if ( $to->isExternal() ) {
1048  $this->mInterwikiTitles[$to->getPrefixedText()] = $to->getInterwiki();
1049  } elseif ( !isset( $this->mAllPages[$row->rd_namespace][$row->rd_title] ) ) {
1050  $lb->add( $row->rd_namespace, $row->rd_title );
1051  }
1052  $this->mRedirectTitles[$from] = $to;
1053  }
1054 
1055  if ( $this->mPendingRedirectIDs ) {
1056  // We found pages that aren't in the redirect table
1057  // Add them
1058  foreach ( $this->mPendingRedirectIDs as $id => $title ) {
1060  $rt = $page->insertRedirect();
1061  if ( !$rt ) {
1062  // What the hell. Let's just ignore this
1063  continue;
1064  }
1065  $lb->addObj( $rt );
1066  $from = $title->getPrefixedText();
1067  $this->mResolvedRedirectTitles[$from] = $title;
1068  $this->mRedirectTitles[$from] = $rt;
1069  unset( $this->mPendingRedirectIDs[$id] );
1070  }
1071  }
1072 
1073  return $lb;
1074  }
1075 
1089  public function getCacheMode( $params = null ) {
1090  return $this->mCacheMode;
1091  }
1092 
1102  private function processTitlesArray( $titles ) {
1103  $usernames = [];
1104  $linkBatch = new LinkBatch();
1105 
1106  foreach ( $titles as $title ) {
1107  if ( is_string( $title ) ) {
1108  try {
1109  $titleObj = Title::newFromTextThrow( $title, $this->mDefaultNamespace );
1110  } catch ( MalformedTitleException $ex ) {
1111  // Handle invalid titles gracefully
1112  $this->mAllPages[0][$title] = $this->mFakePageId;
1113  $this->mInvalidTitles[$this->mFakePageId] = [
1114  'title' => $title,
1115  'invalidreason' => $ex->getMessage(),
1116  ];
1117  $this->mFakePageId--;
1118  continue; // There's nothing else we can do
1119  }
1120  } else {
1121  $titleObj = $title;
1122  }
1123  $unconvertedTitle = $titleObj->getPrefixedText();
1124  $titleWasConverted = false;
1125  if ( $titleObj->isExternal() ) {
1126  // This title is an interwiki link.
1127  $this->mInterwikiTitles[$unconvertedTitle] = $titleObj->getInterwiki();
1128  } else {
1129  // Variants checking
1131  if ( $this->mConvertTitles &&
1132  count( $wgContLang->getVariants() ) > 1 &&
1133  !$titleObj->exists()
1134  ) {
1135  // Language::findVariantLink will modify titleText and titleObj into
1136  // the canonical variant if possible
1137  $titleText = is_string( $title ) ? $title : $titleObj->getPrefixedText();
1138  $wgContLang->findVariantLink( $titleText, $titleObj );
1139  $titleWasConverted = $unconvertedTitle !== $titleObj->getPrefixedText();
1140  }
1141 
1142  if ( $titleObj->getNamespace() < 0 ) {
1143  // Handle Special and Media pages
1144  $titleObj = $titleObj->fixSpecialName();
1145  $this->mSpecialTitles[$this->mFakePageId] = $titleObj;
1146  $this->mFakePageId--;
1147  } else {
1148  // Regular page
1149  $linkBatch->addObj( $titleObj );
1150  }
1151  }
1152 
1153  // Make sure we remember the original title that was
1154  // given to us. This way the caller can correlate new
1155  // titles with the originally requested when e.g. the
1156  // namespace is localized or the capitalization is
1157  // different
1158  if ( $titleWasConverted ) {
1159  $this->mConvertedTitles[$unconvertedTitle] = $titleObj->getPrefixedText();
1160  // In this case the page can't be Special.
1161  if ( is_string( $title ) && $title !== $unconvertedTitle ) {
1162  $this->mNormalizedTitles[$title] = $unconvertedTitle;
1163  }
1164  } elseif ( is_string( $title ) && $title !== $titleObj->getPrefixedText() ) {
1165  $this->mNormalizedTitles[$title] = $titleObj->getPrefixedText();
1166  }
1167 
1168  // Need gender information
1169  if ( MWNamespace::hasGenderDistinction( $titleObj->getNamespace() ) ) {
1170  $usernames[] = $titleObj->getText();
1171  }
1172  }
1173  // Get gender information
1174  $genderCache = GenderCache::singleton();
1175  $genderCache->doQuery( $usernames, __METHOD__ );
1176 
1177  return $linkBatch;
1178  }
1179 
1195  public function setGeneratorData( Title $title, array $data ) {
1196  $ns = $title->getNamespace();
1197  $dbkey = $title->getDBkey();
1198  $this->mGeneratorData[$ns][$dbkey] = $data;
1199  }
1200 
1220  public function setRedirectMergePolicy( $callable ) {
1221  $this->mRedirectMergePolicy = $callable;
1222  }
1223 
1244  public function populateGeneratorData( &$result, array $path = [] ) {
1245  if ( $result instanceof ApiResult ) {
1246  $data = $result->getResultData( $path );
1247  if ( $data === null ) {
1248  return true;
1249  }
1250  } else {
1251  $data = &$result;
1252  foreach ( $path as $key ) {
1253  if ( !isset( $data[$key] ) ) {
1254  // Path isn't in $result, so nothing to add, so everything
1255  // "fits"
1256  return true;
1257  }
1258  $data = &$data[$key];
1259  }
1260  }
1261  foreach ( $this->mGeneratorData as $ns => $dbkeys ) {
1262  if ( $ns === -1 ) {
1263  $pages = [];
1264  foreach ( $this->mSpecialTitles as $id => $title ) {
1265  $pages[$title->getDBkey()] = $id;
1266  }
1267  } else {
1268  if ( !isset( $this->mAllPages[$ns] ) ) {
1269  // No known titles in the whole namespace. Skip it.
1270  continue;
1271  }
1272  $pages = $this->mAllPages[$ns];
1273  }
1274  foreach ( $dbkeys as $dbkey => $genData ) {
1275  if ( !isset( $pages[$dbkey] ) ) {
1276  // Unknown title. Forget it.
1277  continue;
1278  }
1279  $pageId = $pages[$dbkey];
1280  if ( !isset( $data[$pageId] ) ) {
1281  // $pageId didn't make it into the result. Ignore it.
1282  continue;
1283  }
1284 
1285  if ( $result instanceof ApiResult ) {
1286  $path2 = array_merge( $path, [ $pageId ] );
1287  foreach ( $genData as $key => $value ) {
1288  if ( !$result->addValue( $path2, $key, $value ) ) {
1289  return false;
1290  }
1291  }
1292  } else {
1293  $data[$pageId] = array_merge( $data[$pageId], $genData );
1294  }
1295  }
1296  }
1297 
1298  // Merge data generated about redirect titles into the redirect destination
1299  if ( $this->mRedirectMergePolicy ) {
1300  foreach ( $this->mResolvedRedirectTitles as $titleFrom ) {
1301  $dest = $titleFrom;
1302  while ( isset( $this->mRedirectTitles[$dest->getPrefixedText()] ) ) {
1303  $dest = $this->mRedirectTitles[$dest->getPrefixedText()];
1304  }
1305  $fromNs = $titleFrom->getNamespace();
1306  $fromDBkey = $titleFrom->getDBkey();
1307  $toPageId = $dest->getArticleID();
1308  if ( isset( $data[$toPageId] ) &&
1309  isset( $this->mGeneratorData[$fromNs][$fromDBkey] )
1310  ) {
1311  // It is necesary to set both $data and add to $result, if an ApiResult,
1312  // to ensure multiple redirects to the same destination are all merged.
1313  $data[$toPageId] = call_user_func(
1314  $this->mRedirectMergePolicy,
1315  $data[$toPageId],
1316  $this->mGeneratorData[$fromNs][$fromDBkey]
1317  );
1318  if ( $result instanceof ApiResult ) {
1319  if ( !$result->addValue( $path, $toPageId, $data[$toPageId], ApiResult::OVERRIDE ) ) {
1320  return false;
1321  }
1322  }
1323  }
1324  }
1325  }
1326 
1327  return true;
1328  }
1329 
1334  protected function getDB() {
1335  return $this->mDbSource->getDB();
1336  }
1337 
1344  private static function getPositiveIntegers( $array ) {
1345  // bug 25734 API: possible issue with revids validation
1346  // It seems with a load of revision rows, MySQL gets upset
1347  // Remove any < 0 integers, as they can't be valid
1348  foreach ( $array as $i => $int ) {
1349  if ( $int < 0 ) {
1350  unset( $array[$i] );
1351  }
1352  }
1353 
1354  return $array;
1355  }
1356 
1357  public function getAllowedParams( $flags = 0 ) {
1358  $result = [
1359  'titles' => [
1360  ApiBase::PARAM_ISMULTI => true,
1361  ApiBase::PARAM_HELP_MSG => 'api-pageset-param-titles',
1362  ],
1363  'pageids' => [
1364  ApiBase::PARAM_TYPE => 'integer',
1365  ApiBase::PARAM_ISMULTI => true,
1366  ApiBase::PARAM_HELP_MSG => 'api-pageset-param-pageids',
1367  ],
1368  'revids' => [
1369  ApiBase::PARAM_TYPE => 'integer',
1370  ApiBase::PARAM_ISMULTI => true,
1371  ApiBase::PARAM_HELP_MSG => 'api-pageset-param-revids',
1372  ],
1373  'generator' => [
1374  ApiBase::PARAM_TYPE => null,
1375  ApiBase::PARAM_HELP_MSG => 'api-pageset-param-generator',
1377  ],
1378  'redirects' => [
1379  ApiBase::PARAM_DFLT => false,
1380  ApiBase::PARAM_HELP_MSG => $this->mAllowGenerator
1381  ? 'api-pageset-param-redirects-generator'
1382  : 'api-pageset-param-redirects-nogenerator',
1383  ],
1384  'converttitles' => [
1385  ApiBase::PARAM_DFLT => false,
1386  ApiBase::PARAM_HELP_MSG => [
1387  'api-pageset-param-converttitles',
1388  new DeferredStringifier(
1389  function ( IContextSource $context ) {
1390  return $context->getLanguage()
1392  },
1393  $this
1394  )
1395  ],
1396  ],
1397  ];
1398 
1399  if ( !$this->mAllowGenerator ) {
1400  unset( $result['generator'] );
1401  } elseif ( $flags & ApiBase::GET_VALUES_FOR_HELP ) {
1402  $result['generator'][ApiBase::PARAM_TYPE] = 'submodule';
1403  $result['generator'][ApiBase::PARAM_SUBMODULE_MAP] = $this->getGenerators();
1404  }
1405 
1406  return $result;
1407  }
1408 
1409  private static $generators = null;
1410 
1415  private function getGenerators() {
1416  if ( self::$generators === null ) {
1418  if ( !( $query instanceof ApiQuery ) ) {
1419  // If the parent container of this pageset is not ApiQuery,
1420  // we must create it to get module manager
1421  $query = $this->getMain()->getModuleManager()->getModule( 'query' );
1422  }
1423  $gens = [];
1424  $prefix = $query->getModulePath() . '+';
1425  $mgr = $query->getModuleManager();
1426  foreach ( $mgr->getNamesWithClasses() as $name => $class ) {
1427  if ( is_subclass_of( $class, 'ApiQueryGeneratorBase' ) ) {
1428  $gens[$name] = $prefix . $name;
1429  }
1430  }
1431  ksort( $gens );
1432  self::$generators = $gens;
1433  }
1434 
1435  return self::$generators;
1436  }
1437 }
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:99
static $generators
static newFromRow($row)
Make a Title object from a DB row.
Definition: Title.php:465
const PARAM_TYPE
(string|string[]) Either an array of allowed value strings, or a string type as described below...
Definition: ApiBase.php:88
Interface for objects which can provide a MediaWiki context on request.
static hasGenderDistinction($index)
Does the namespace (potentially) have different aliases for different genders.
setGeneratorData(Title $title, array $data)
Set data for a title.
getRedirectTitles()
Get a list of redirect resolutions - maps a title to its redirect target, as an array of output-ready...
Definition: ApiPageSet.php:442
the array() calling protocol came about after MediaWiki 1.4rc1.
null for the local wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1422
initFromRevIDs($revids)
Does the same as initFromTitles(), but is based on revision IDs instead.
Definition: ApiPageSet.php:901
magic word the default is to use $key to get the and $key value or $key value text $key value html to format the value $key
Definition: hooks.txt:2325
$mGoodAndMissingPages
Definition: ApiPageSet.php:56
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
getRedirectTitlesAsResult($result=null)
Get a list of redirect resolutions - maps a title to its redirect target.
Definition: ApiPageSet.php:453
getSpecialTitles()
Get the list of titles with negative namespace.
Definition: ApiPageSet.php:679
const NS_MAIN
Definition: Defines.php:70
getDataSource()
Return the parameter name that is the source of data for this PageSet.
Definition: ApiPageSet.php:252
This class contains a list of pages that the client has requested.
Definition: ApiPageSet.php:41
populateFromRevisionIDs($revIDs)
Populate this PageSet from a list of revision IDs.
Definition: ApiPageSet.php:724
const PARAM_DFLT
(null|boolean|integer|string) Default value of the parameter.
Definition: ApiBase.php:50
getMain()
Get the main module.
Definition: ApiBase.php:480
const GET_VALUES_FOR_HELP
getAllowedParams() flag: When set, the result could take longer to generate, but should be more thoro...
Definition: ApiBase.php:197
static singleton()
Definition: GenderCache.php:39
getConvertedTitles()
Get a list of title conversions - maps a title to its converted version.
Definition: ApiPageSet.php:520
processDbRow($row)
Extract all requested fields from the row received from the database.
Definition: ApiPageSet.php:732
getMissingRevisionIDs()
Revision IDs that were not found in the database.
Definition: ApiPageSet.php:651
extractRequestParams($parseLimit=true)
Using getAllowedParams(), this function makes an array of the values provided by the user...
Definition: ApiBase.php:685
$value
getConvertedTitlesAsResult($result=null)
Get a list of title conversions - maps a title to its converted version as a result array...
Definition: ApiPageSet.php:531
const PROTO_CURRENT
Definition: Defines.php:265
getInvalidTitles()
Titles that were deemed invalid by Title::newFromText() The array's index will be unique and negative...
Definition: ApiPageSet.php:413
it s the revision text itself In either if gzip is the revision text is gzipped $flags
Definition: hooks.txt:2552
getInvalidTitlesAndRevisions($invalidChecks=[ 'invalidTitles', 'special', 'missingIds', 'missingRevIds', 'missingTitles', 'interwikiTitles'])
Get an array of invalid/special/missing titles.
Definition: ApiPageSet.php:597
requestField($fieldName)
Request an additional field from the page table.
Definition: ApiPageSet.php:274
getMissingTitlesByNamespace()
Returns an array [ns][dbkey] => fake_page_id for all missing titles.
Definition: ApiPageSet.php:378
static newFromText($text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:277
Represents a title within MediaWiki.
Definition: Title.php:34
when a variable name is used in a it is silently declared as a new local masking the global
Definition: design.txt:93
getRevisionIDs()
Get the list of valid revision IDs (requested with the revids= parameter)
Definition: ApiPageSet.php:627
getTitleCount()
Returns the number of unique pages (not revisions) in the set.
Definition: ApiPageSet.php:345
IContextSource $context
getAllTitlesByNamespace()
Returns an array [ns][dbkey] => page_id for all requested titles.
Definition: ApiPageSet.php:329
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Definition: ApiResult.php:618
populateFromTitles($titles)
Populate this PageSet from a list of Titles.
Definition: ApiPageSet.php:695
getPageTableFields()
Get the fields that have to be queried from the page table: the ones requested through requestField()...
Definition: ApiPageSet.php:294
getTitles()
All Title objects provided.
Definition: ApiPageSet.php:337
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist & $tables
Definition: hooks.txt:969
getLiveRevisionIDs()
Get the list of non-deleted revision IDs (requested with the revids= parameter)
Definition: ApiPageSet.php:635
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message.Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item.Return false to stop further processing of the tag $reader:XMLReader object $logInfo:Array of information 'ImportHandlePageXMLTag':When parsing a XML tag in a page.Return false to stop further processing of the tag $reader:XMLReader object &$pageInfo:Array of information 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision.Return false to stop further processing of the tag $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information 'ImportHandleToplevelXMLTag':When parsing a top level XML tag.Return false to stop further processing of the tag $reader:XMLReader object 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload.Return false to stop further processing of the tag $reader:XMLReader object $revisionInfo:Array of information 'ImportLogInterwikiLink':Hook to change the interwiki link used in log entries and edit summaries for transwiki imports.&$fullInterwikiPrefix:Interwiki prefix, may contain colons.&$pageTitle:String that contains page title. 'ImportSources':Called when reading from the $wgImportSources configuration variable.Can be used to lazy-load the import sources list.&$importSources:The value of $wgImportSources.Modify as necessary.See the comment in DefaultSettings.php for the detail of how to structure this array. 'InfoAction':When building information to display on the action=info page.$context:IContextSource object &$pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect.&$title:Title object for the current page &$request:WebRequest &$ignoreRedirect:boolean to skip redirect check &$target:Title/string of redirect target &$article:Article object 'InternalParseBeforeLinks':during Parser's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings.&$parser:Parser object &$text:string containing partially parsed text &$stripState:Parser's internal StripState object 'InternalParseBeforeSanitize':during Parser's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings.Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments.&$parser:Parser object &$text:string containing partially parsed text &$stripState:Parser's internal StripState object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not.Return true without providing an interwiki to continue interwiki search.$prefix:interwiki prefix we are looking for.&$iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InvalidateEmailComplete':Called after a user's email has been invalidated successfully.$user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification.Callee may modify $url and $query, URL will be constructed as $url.$query &$url:URL to index.php &$query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) &$article:article(object) being checked 'IsTrustedProxy':Override the result of IP::isTrustedProxy() &$ip:IP being check &$result:Change this value to override the result of IP::isTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from &$allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of Sanitizer::validateEmail(), for instance to return false if the domain name doesn't match your organization.$addr:The e-mail address entered by the user &$result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user &$result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we're looking for a messages file for &$file:The messages file path, you can override this to change the location. 'LanguageGetMagic':DEPRECATED!Use $magicWords in a file listed in $wgExtensionMessagesFiles instead.Use this to define synonyms of magic words depending of the language &$magicExtensions:associative array of magic words synonyms $lang:language code(string) 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces.Do not use this hook to add namespaces.Use CanonicalNamespaces for that.&$namespaces:Array of namespaces indexed by their numbers 'LanguageGetSpecialPageAliases':DEPRECATED!Use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead.Use to define aliases of special pages names depending of the language &$specialPageAliases:associative array of magic words synonyms $lang:language code(string) 'LanguageGetTranslatedLanguageNames':Provide translated language names.&$names:array of language code=> language name $code:language of the preferred translations 'LanguageLinks':Manipulate a page's language links.This is called in various places to allow extensions to define the effective language links for a page.$title:The page's Title.&$links:Associative array mapping language codes to prefixed links of the form"language:title".&$linkFlags:Associative array mapping prefixed links to arrays of flags.Currently unused, but planned to provide support for marking individual language links in the UI, e.g.for featured articles. 'LanguageSelector':Hook to change the language selector available on a page.$out:The output page.$cssClassName:CSS class name of the language selector. 'LinkBegin':Used when generating internal and interwiki links in Linker::link(), before processing starts.Return false to skip default processing and return $ret.See documentation for Linker::link() for details on the expected meanings of parameters.$skin:the Skin object $target:the Title that the link is pointing to &$html:the contents that the< a > tag should have(raw HTML) $result
Definition: hooks.txt:1800
callable null $mRedirectMergePolicy
Definition: ApiPageSet.php:83
resolvePendingRedirects()
Resolve any redirects in the result if redirect resolution was requested.
Definition: ApiPageSet.php:984
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:31
getGoodAndMissingTitlesByNamespace()
Returns an array [ns][dbkey] => page_id for all good and missing titles.
Definition: ApiPageSet.php:395
populateFromQueryResult($db, $queryResult)
Populate this PageSet from a rowset returned from the database.
Definition: ApiPageSet.php:716
getGoodTitleCount()
Returns the number of found unique pages (not revisions) in the set.
Definition: ApiPageSet.php:369
const PARAM_SUBMODULE_PARAM_PREFIX
(string) When PARAM_TYPE is 'submodule', used to indicate the 'g' prefix added by ApiQueryGeneratorBa...
Definition: ApiBase.php:172
getInvalidTitlesAndReasons()
Titles that were deemed invalid by Title::newFromText() The array's index will be unique and negative...
Definition: ApiPageSet.php:425
populateGeneratorData(&$result, array $path=[])
Populate the generator data for all titles in the result.
getGoodAndMissingTitles()
Title objects for good and missing titles.
Definition: ApiPageSet.php:403
getDBkey()
Get the main part with underscores.
Definition: Title.php:911
getGoodTitlesByNamespace()
Returns an array [ns][dbkey] => page_id for all good titles.
Definition: ApiPageSet.php:353
$res
Definition: database.txt:21
getGenerators()
Get an array of all available generators.
initFromPageIds($pageids)
Does the same as initFromTitles(), but is based on page IDs instead.
Definition: ApiPageSet.php:794
executeDryRun()
In case execute() is not called, call this method to mark all relevant parameters as used This preven...
Definition: ApiPageSet.php:131
getConfig()
Get the Config object.
getMissingRevisionIDsAsResult($result=null)
Revision IDs that were not found in the database as result array.
Definition: ApiPageSet.php:661
const PARAM_SUBMODULE_MAP
(string[]) When PARAM_TYPE is 'submodule', map parameter values to submodule paths.
Definition: ApiBase.php:165
getGoodTitles()
Title objects that were found in the database.
Definition: ApiPageSet.php:361
$params
static addValues(array &$result, $values, $flag=null, $name=null)
Add all items from $values into the result.
Definition: ApiPageSet.php:92
getMissingTitles()
Title objects that were NOT found in the database.
Definition: ApiPageSet.php:387
getDB()
Get the database connection (read-only)
wfDeprecated($function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
populateFromPageIDs($pageIDs)
Populate this PageSet from a list of page IDs.
Definition: ApiPageSet.php:703
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:916
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:464
This class represents the result of the API operations.
Definition: ApiResult.php:33
static run($event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:131
getNamespace()
Get the namespace index, i.e.
Definition: Title.php:934
initFromTitles($titles)
This method populates internal variables with page information based on the given array of title stri...
Definition: ApiPageSet.php:769
This is the main query class.
Definition: ApiQuery.php:38
setWarning($warning)
Set warning section for this module.
Definition: ApiBase.php:1495
getLanguage()
Get the Language object.
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter...
Definition: ApiBase.php:125
$mResolvedRedirectTitles
Definition: ApiPageSet.php:70
processTitlesArray($titles)
Given an array of title strings, convert them into Title objects.
getCacheMode($params=null)
Get the cache mode for the data generated by this module.
static newFromTextThrow($text, $defaultNamespace=NS_MAIN)
Like Title::newFromText(), but throws MalformedTitleException when the title is invalid, rather than returning null.
Definition: Title.php:307
int $mDefaultNamespace
Definition: ApiPageSet.php:81
executeInternal($isDryRun)
Populate the PageSet from the request parameters.
Definition: ApiPageSet.php:147
getMissingPageIDs()
Page IDs that were not found in the database.
Definition: ApiPageSet.php:433
getInterwikiTitles()
Get a list of interwiki titles - maps a title to its interwiki prefix.
Definition: ApiPageSet.php:551
$from
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
setRedirectMergePolicy($callable)
Controls how generator data about a redirect source is merged into the generator data for the redirec...
$mRequestedPageFields
Definition: ApiPageSet.php:79
linkcache txt The LinkCache class maintains a list of article titles and the information about whether or not the article exists in the database This is used to mark up links when displaying a page If the same link appears more than once on any page then it only has to be looked up once In most cases link lookups are done in batches with the LinkBatch class or the equivalent in so the link cache is mostly useful for short snippets of parsed and for links in the navigation areas of the skin The link cache was formerly used to track links used in a document for the purposes of updating the link tables This application is now deprecated To create a you can use the following $titles
Definition: linkcache.txt:17
getRedirectTargets()
Get the targets of the pending redirects from the database.
getInterwikiTitlesAsResult($result=null, $iwUrl=false)
Get a list of interwiki titles - maps a title to its interwiki prefix as result.
Definition: ApiPageSet.php:563
getAllowedParams($flags=0)
getNormalizedTitles()
Get a list of title normalizations - maps a title to its normalized version.
Definition: ApiPageSet.php:489
const PARAM_ISMULTI
(boolean) Accept multiple pipe-separated values for this parameter (e.g.
Definition: ApiBase.php:53
array $mInvalidTitles
[fake_page_id] => array( 'title' => $title, 'invalidreason' => $reason )
Definition: ApiPageSet.php:62
__construct(ApiBase $dbSource, $flags=0, $defaultNamespace=NS_MAIN)
Definition: ApiPageSet.php:116
dieUsage($description, $errorCode, $httpRespCode=0, $extradata=null)
Throw a UsageException, which will (if uncaught) call the main module's error handler and die with an...
Definition: ApiBase.php:1526
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the local content language as $wgContLang
Definition: design.txt:56
This abstract class implements many basic API functions, and is the base of all API classes...
Definition: ApiBase.php:39
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:500
isResolvingRedirects()
Check whether this PageSet is resolving redirects.
Definition: ApiPageSet.php:240
getRevisionCount()
Returns the number of revisions (requested with revids= parameter).
Definition: ApiPageSet.php:687
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:832
static dieDebug($method, $message)
Internal code errors should be reported with this method.
Definition: ApiBase.php:2230
const DISABLE_GENERATORS
Constructor flag: The new instance of ApiPageSet will ignore the 'generator=' parameter.
Definition: ApiPageSet.php:46
Title[] $mPendingRedirectIDs
Definition: ApiPageSet.php:69
static getPositiveIntegers($array)
Returns the input array of integers with all values < 0 removed.
static array $languagesWithVariants
languages supporting variants
const OVERRIDE
Override existing value in addValue(), setValue(), and similar functions.
Definition: ApiResult.php:39
static addTitleInfo(&$arr, $title, $prefix= '')
Add information (title and namespace) about a Title object to a result array.
execute()
Populate the PageSet from the request parameters.
Definition: ApiPageSet.php:138
getUser()
Get the User object.
static & makeTitle($ns, $title, $fragment= '', $interwiki= '')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:524
getDeletedRevisionIDs()
Get the list of revision IDs that were associated with deleted titles.
Definition: ApiPageSet.php:643
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached $page
Definition: hooks.txt:2342
getCustomField($fieldName)
Get the value of a custom field previously requested through requestField()
Definition: ApiPageSet.php:284
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:314