MediaWiki REL1_28
ApiPageSet.php
Go to the documentation of this file.
1<?php
41class ApiPageSet extends ApiBase {
47
48 private $mDbSource;
49 private $mParams;
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 = [];
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';
84
92 private static function addValues( array &$result, $values, $flags = [], $name = null ) {
93 foreach ( $values as $val ) {
94 if ( $val instanceof Title ) {
95 $v = [];
97 } elseif ( $name !== null ) {
98 $v = [ $name => $val ];
99 } else {
100 $v = $val;
101 }
102 foreach ( $flags as $flag ) {
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 Hooks::run( 'APIQueryGeneratorAfterExecute', [ &$generator, &$this ] );
177 } else {
178 // Prevent warnings from being reported on these parameters
179 $main = $this->getMain();
180 foreach ( $generator->extractRequestParams() as $paramName => $param ) {
181 $main->markParamsUsed( $generator->encodeParamName( $paramName ) );
182 }
183 }
184
185 if ( !$isDryRun ) {
187 }
188 } else {
189 // Only one of the titles/pageids/revids is allowed at the same time
190 $dataSource = null;
191 if ( isset( $this->mParams['titles'] ) ) {
192 $dataSource = 'titles';
193 }
194 if ( isset( $this->mParams['pageids'] ) ) {
195 if ( isset( $dataSource ) ) {
196 $this->dieUsage( "Cannot use 'pageids' at the same time as '$dataSource'", 'multisource' );
197 }
198 $dataSource = 'pageids';
199 }
200 if ( isset( $this->mParams['revids'] ) ) {
201 if ( isset( $dataSource ) ) {
202 $this->dieUsage( "Cannot use 'revids' at the same time as '$dataSource'", 'multisource' );
203 }
204 $dataSource = 'revids';
205 }
206
207 if ( !$isDryRun ) {
208 // Populate page information with the original user input
209 switch ( $dataSource ) {
210 case 'titles':
211 $this->initFromTitles( $this->mParams['titles'] );
212 break;
213 case 'pageids':
214 $this->initFromPageIds( $this->mParams['pageids'] );
215 break;
216 case 'revids':
217 if ( $this->mResolveRedirects ) {
218 $this->setWarning( 'Redirect resolution cannot be used ' .
219 'together with the revids= parameter. Any redirects ' .
220 'the revids= point to have not been resolved.' );
221 }
222 $this->mResolveRedirects = false;
223 $this->initFromRevIDs( $this->mParams['revids'] );
224 break;
225 default:
226 // Do nothing - some queries do not need any of the data sources.
227 break;
228 }
229 }
230 }
231 }
232
237 public function isResolvingRedirects() {
239 }
240
249 public function getDataSource() {
250 if ( $this->mAllowGenerator && isset( $this->mParams['generator'] ) ) {
251 return 'generator';
252 }
253 if ( isset( $this->mParams['titles'] ) ) {
254 return 'titles';
255 }
256 if ( isset( $this->mParams['pageids'] ) ) {
257 return 'pageids';
258 }
259 if ( isset( $this->mParams['revids'] ) ) {
260 return 'revids';
261 }
262
263 return null;
264 }
265
271 public function requestField( $fieldName ) {
272 $this->mRequestedPageFields[$fieldName] = null;
273 }
274
281 public function getCustomField( $fieldName ) {
282 return $this->mRequestedPageFields[$fieldName];
283 }
284
291 public function getPageTableFields() {
292 // Ensure we get minimum required fields
293 // DON'T change this order
294 $pageFlds = [
295 'page_namespace' => null,
296 'page_title' => null,
297 'page_id' => null,
298 ];
299
300 if ( $this->mResolveRedirects ) {
301 $pageFlds['page_is_redirect'] = null;
302 }
303
304 if ( $this->getConfig()->get( 'ContentHandlerUseDB' ) ) {
305 $pageFlds['page_content_model'] = null;
306 }
307
308 if ( $this->getConfig()->get( 'PageLanguageUseDB' ) ) {
309 $pageFlds['page_lang'] = null;
310 }
311
312 foreach ( LinkCache::getSelectFields() as $field ) {
313 $pageFlds[$field] = null;
314 }
315
316 $pageFlds = array_merge( $pageFlds, $this->mRequestedPageFields );
317
318 return array_keys( $pageFlds );
319 }
320
327 public function getAllTitlesByNamespace() {
328 return $this->mAllPages;
329 }
330
335 public function getTitles() {
336 return $this->mTitles;
337 }
338
343 public function getTitleCount() {
344 return count( $this->mTitles );
345 }
346
351 public function getGoodTitlesByNamespace() {
352 return $this->mGoodPages;
353 }
354
359 public function getGoodTitles() {
360 return $this->mGoodTitles;
361 }
362
367 public function getGoodTitleCount() {
368 return count( $this->mGoodTitles );
369 }
370
376 public function getMissingTitlesByNamespace() {
378 }
379
385 public function getMissingTitles() {
387 }
388
396
401 public function getGoodAndMissingTitles() {
402 return $this->mGoodTitles + $this->mMissingTitles;
403 }
404
411 public function getInvalidTitles() {
412 wfDeprecated( __METHOD__, '1.26' );
413 return array_map( function ( $t ) {
414 return $t['title'];
416 }
417
423 public function getInvalidTitlesAndReasons() {
425 }
426
431 public function getMissingPageIDs() {
433 }
434
440 public function getRedirectTitles() {
442 }
443
451 public function getRedirectTitlesAsResult( $result = null ) {
452 $values = [];
453 foreach ( $this->getRedirectTitles() as $titleStrFrom => $titleTo ) {
454 $r = [
455 'from' => strval( $titleStrFrom ),
456 'to' => $titleTo->getPrefixedText(),
457 ];
458 if ( $titleTo->hasFragment() ) {
459 $r['tofragment'] = $titleTo->getFragment();
460 }
461 if ( $titleTo->isExternal() ) {
462 $r['tointerwiki'] = $titleTo->getInterwiki();
463 }
464 if ( isset( $this->mResolvedRedirectTitles[$titleStrFrom] ) ) {
465 $titleFrom = $this->mResolvedRedirectTitles[$titleStrFrom];
466 $ns = $titleFrom->getNamespace();
467 $dbkey = $titleFrom->getDBkey();
468 if ( isset( $this->mGeneratorData[$ns][$dbkey] ) ) {
469 $r = array_merge( $this->mGeneratorData[$ns][$dbkey], $r );
470 }
471 }
472
473 $values[] = $r;
474 }
475 if ( !empty( $values ) && $result ) {
476 ApiResult::setIndexedTagName( $values, 'r' );
477 }
478
479 return $values;
480 }
481
487 public function getNormalizedTitles() {
489 }
490
498 public function getNormalizedTitlesAsResult( $result = null ) {
500
501 $values = [];
502 foreach ( $this->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
503 $encode = ( $wgContLang->normalize( $rawTitleStr ) !== $rawTitleStr );
504 $values[] = [
505 'fromencoded' => $encode,
506 'from' => $encode ? rawurlencode( $rawTitleStr ) : $rawTitleStr,
507 'to' => $titleStr
508 ];
509 }
510 if ( !empty( $values ) && $result ) {
511 ApiResult::setIndexedTagName( $values, 'n' );
512 }
513
514 return $values;
515 }
516
522 public function getConvertedTitles() {
524 }
525
533 public function getConvertedTitlesAsResult( $result = null ) {
534 $values = [];
535 foreach ( $this->getConvertedTitles() as $rawTitleStr => $titleStr ) {
536 $values[] = [
537 'from' => $rawTitleStr,
538 'to' => $titleStr
539 ];
540 }
541 if ( !empty( $values ) && $result ) {
542 ApiResult::setIndexedTagName( $values, 'c' );
543 }
544
545 return $values;
546 }
547
553 public function getInterwikiTitles() {
555 }
556
565 public function getInterwikiTitlesAsResult( $result = null, $iwUrl = false ) {
566 $values = [];
567 foreach ( $this->getInterwikiTitles() as $rawTitleStr => $interwikiStr ) {
568 $item = [
569 'title' => $rawTitleStr,
570 'iw' => $interwikiStr,
571 ];
572 if ( $iwUrl ) {
573 $title = Title::newFromText( $rawTitleStr );
574 $item['url'] = $title->getFullURL( '', false, PROTO_CURRENT );
575 }
576 $values[] = $item;
577 }
578 if ( !empty( $values ) && $result ) {
579 ApiResult::setIndexedTagName( $values, 'i' );
580 }
581
582 return $values;
583 }
584
599 public function getInvalidTitlesAndRevisions( $invalidChecks = [ 'invalidTitles',
600 'special', 'missingIds', 'missingRevIds', 'missingTitles', 'interwikiTitles' ]
601 ) {
602 $result = [];
603 if ( in_array( 'invalidTitles', $invalidChecks ) ) {
604 self::addValues( $result, $this->getInvalidTitlesAndReasons(), [ 'invalid' ] );
605 }
606 if ( in_array( 'special', $invalidChecks ) ) {
607 $known = [];
608 $unknown = [];
609 foreach ( $this->getSpecialTitles() as $title ) {
610 if ( $title->isKnown() ) {
611 $known[] = $title;
612 } else {
613 $unknown[] = $title;
614 }
615 }
616 self::addValues( $result, $unknown, [ 'special', 'missing' ] );
617 self::addValues( $result, $known, [ 'special' ] );
618 }
619 if ( in_array( 'missingIds', $invalidChecks ) ) {
620 self::addValues( $result, $this->getMissingPageIDs(), [ 'missing' ], 'pageid' );
621 }
622 if ( in_array( 'missingRevIds', $invalidChecks ) ) {
623 self::addValues( $result, $this->getMissingRevisionIDs(), [ 'missing' ], 'revid' );
624 }
625 if ( in_array( 'missingTitles', $invalidChecks ) ) {
626 $known = [];
627 $unknown = [];
628 foreach ( $this->getMissingTitles() as $title ) {
629 if ( $title->isKnown() ) {
630 $known[] = $title;
631 } else {
632 $unknown[] = $title;
633 }
634 }
635 self::addValues( $result, $unknown, [ 'missing' ] );
636 self::addValues( $result, $known, [ 'missing', 'known' ] );
637 }
638 if ( in_array( 'interwikiTitles', $invalidChecks ) ) {
640 }
641
642 return $result;
643 }
644
649 public function getRevisionIDs() {
650 return $this->mGoodRevIDs;
651 }
652
657 public function getLiveRevisionIDs() {
658 return $this->mLiveRevIDs;
659 }
660
665 public function getDeletedRevisionIDs() {
667 }
668
673 public function getMissingRevisionIDs() {
675 }
676
683 public function getMissingRevisionIDsAsResult( $result = null ) {
684 $values = [];
685 foreach ( $this->getMissingRevisionIDs() as $revid ) {
686 $values[$revid] = [
687 'revid' => $revid
688 ];
689 }
690 if ( !empty( $values ) && $result ) {
691 ApiResult::setIndexedTagName( $values, 'rev' );
692 }
693
694 return $values;
695 }
696
701 public function getSpecialTitles() {
703 }
704
709 public function getRevisionCount() {
710 return count( $this->getRevisionIDs() );
711 }
712
717 public function populateFromTitles( $titles ) {
718 $this->initFromTitles( $titles );
719 }
720
725 public function populateFromPageIDs( $pageIDs ) {
726 $this->initFromPageIds( $pageIDs );
727 }
728
738 public function populateFromQueryResult( $db, $queryResult ) {
739 $this->initFromQueryResult( $queryResult );
740 }
741
746 public function populateFromRevisionIDs( $revIDs ) {
747 $this->initFromRevIDs( $revIDs );
748 }
749
754 public function processDbRow( $row ) {
755 // Store Title object in various data structures
756 $title = Title::newFromRow( $row );
757
758 LinkCache::singleton()->addGoodLinkObjFromRow( $title, $row );
759
760 $pageId = intval( $row->page_id );
761 $this->mAllPages[$row->page_namespace][$row->page_title] = $pageId;
762 $this->mTitles[] = $title;
763
764 if ( $this->mResolveRedirects && $row->page_is_redirect == '1' ) {
765 $this->mPendingRedirectIDs[$pageId] = $title;
766 } else {
767 $this->mGoodPages[$row->page_namespace][$row->page_title] = $pageId;
768 $this->mGoodAndMissingPages[$row->page_namespace][$row->page_title] = $pageId;
769 $this->mGoodTitles[$pageId] = $title;
770 }
771
772 foreach ( $this->mRequestedPageFields as $fieldName => &$fieldValues ) {
773 $fieldValues[$pageId] = $row->$fieldName;
774 }
775 }
776
793 private function initFromTitles( $titles ) {
794 // Get validated and normalized title objects
795 $linkBatch = $this->processTitlesArray( $titles );
796 if ( $linkBatch->isEmpty() ) {
797 return;
798 }
799
800 $db = $this->getDB();
801 $set = $linkBatch->constructSet( 'page', $db );
802
803 // Get pageIDs data from the `page` table
804 $res = $db->select( 'page', $this->getPageTableFields(), $set,
805 __METHOD__ );
806
807 // Hack: get the ns:titles stored in [ ns => [ titles ] ] format
808 $this->initFromQueryResult( $res, $linkBatch->data, true ); // process Titles
809
810 // Resolve any found redirects
812 }
813
818 private function initFromPageIds( $pageids ) {
819 if ( !$pageids ) {
820 return;
821 }
822
823 $pageids = array_map( 'intval', $pageids ); // paranoia
824 $remaining = array_flip( $pageids );
825
826 $pageids = self::getPositiveIntegers( $pageids );
827
828 $res = null;
829 if ( !empty( $pageids ) ) {
830 $set = [
831 'page_id' => $pageids
832 ];
833 $db = $this->getDB();
834
835 // Get pageIDs data from the `page` table
836 $res = $db->select( 'page', $this->getPageTableFields(), $set,
837 __METHOD__ );
838 }
839
840 $this->initFromQueryResult( $res, $remaining, false ); // process PageIDs
841
842 // Resolve any found redirects
844 }
845
856 private function initFromQueryResult( $res, &$remaining = null, $processTitles = null ) {
857 if ( !is_null( $remaining ) && is_null( $processTitles ) ) {
858 ApiBase::dieDebug( __METHOD__, 'Missing $processTitles parameter when $remaining is provided' );
859 }
860
861 $usernames = [];
862 if ( $res ) {
863 foreach ( $res as $row ) {
864 $pageId = intval( $row->page_id );
865
866 // Remove found page from the list of remaining items
867 if ( isset( $remaining ) ) {
868 if ( $processTitles ) {
869 unset( $remaining[$row->page_namespace][$row->page_title] );
870 } else {
871 unset( $remaining[$pageId] );
872 }
873 }
874
875 // Store any extra fields requested by modules
876 $this->processDbRow( $row );
877
878 // Need gender information
879 if ( MWNamespace::hasGenderDistinction( $row->page_namespace ) ) {
880 $usernames[] = $row->page_title;
881 }
882 }
883 }
884
885 if ( isset( $remaining ) ) {
886 // Any items left in the $remaining list are added as missing
887 if ( $processTitles ) {
888 // The remaining titles in $remaining are non-existent pages
889 $linkCache = LinkCache::singleton();
890 foreach ( $remaining as $ns => $dbkeys ) {
891 foreach ( array_keys( $dbkeys ) as $dbkey ) {
892 $title = Title::makeTitle( $ns, $dbkey );
893 $linkCache->addBadLinkObj( $title );
894 $this->mAllPages[$ns][$dbkey] = $this->mFakePageId;
895 $this->mMissingPages[$ns][$dbkey] = $this->mFakePageId;
896 $this->mGoodAndMissingPages[$ns][$dbkey] = $this->mFakePageId;
897 $this->mMissingTitles[$this->mFakePageId] = $title;
898 $this->mFakePageId--;
899 $this->mTitles[] = $title;
900
901 // need gender information
902 if ( MWNamespace::hasGenderDistinction( $ns ) ) {
903 $usernames[] = $dbkey;
904 }
905 }
906 }
907 } else {
908 // The remaining pageids do not exist
909 if ( !$this->mMissingPageIDs ) {
910 $this->mMissingPageIDs = array_keys( $remaining );
911 } else {
912 $this->mMissingPageIDs = array_merge( $this->mMissingPageIDs, array_keys( $remaining ) );
913 }
914 }
915 }
916
917 // Get gender information
918 $genderCache = GenderCache::singleton();
919 $genderCache->doQuery( $usernames, __METHOD__ );
920 }
921
927 private function initFromRevIDs( $revids ) {
928 if ( !$revids ) {
929 return;
930 }
931
932 $revids = array_map( 'intval', $revids ); // paranoia
933 $db = $this->getDB();
934 $pageids = [];
935 $remaining = array_flip( $revids );
936
937 $revids = self::getPositiveIntegers( $revids );
938
939 if ( !empty( $revids ) ) {
940 $tables = [ 'revision', 'page' ];
941 $fields = [ 'rev_id', 'rev_page' ];
942 $where = [ 'rev_id' => $revids, 'rev_page = page_id' ];
943
944 // Get pageIDs data from the `page` table
945 $res = $db->select( $tables, $fields, $where, __METHOD__ );
946 foreach ( $res as $row ) {
947 $revid = intval( $row->rev_id );
948 $pageid = intval( $row->rev_page );
949 $this->mGoodRevIDs[$revid] = $pageid;
950 $this->mLiveRevIDs[$revid] = $pageid;
951 $pageids[$pageid] = '';
952 unset( $remaining[$revid] );
953 }
954 }
955
956 $this->mMissingRevIDs = array_keys( $remaining );
957
958 // Populate all the page information
959 $this->initFromPageIds( array_keys( $pageids ) );
960
961 // If the user can see deleted revisions, pull out the corresponding
962 // titles from the archive table and include them too. We ignore
963 // ar_page_id because deleted revisions are tied by title, not page_id.
964 if ( !empty( $this->mMissingRevIDs ) && $this->getUser()->isAllowed( 'deletedhistory' ) ) {
965 $remaining = array_flip( $this->mMissingRevIDs );
966 $tables = [ 'archive' ];
967 $fields = [ 'ar_rev_id', 'ar_namespace', 'ar_title' ];
968 $where = [ 'ar_rev_id' => $this->mMissingRevIDs ];
969
970 $res = $db->select( $tables, $fields, $where, __METHOD__ );
971 $titles = [];
972 foreach ( $res as $row ) {
973 $revid = intval( $row->ar_rev_id );
974 $titles[$revid] = Title::makeTitle( $row->ar_namespace, $row->ar_title );
975 unset( $remaining[$revid] );
976 }
977
978 $this->initFromTitles( $titles );
979
980 foreach ( $titles as $revid => $title ) {
981 $ns = $title->getNamespace();
982 $dbkey = $title->getDBkey();
983
984 // Handle converted titles
985 if ( !isset( $this->mAllPages[$ns][$dbkey] ) &&
986 isset( $this->mConvertedTitles[$title->getPrefixedText()] )
987 ) {
988 $title = Title::newFromText( $this->mConvertedTitles[$title->getPrefixedText()] );
989 $ns = $title->getNamespace();
990 $dbkey = $title->getDBkey();
991 }
992
993 if ( isset( $this->mAllPages[$ns][$dbkey] ) ) {
994 $this->mGoodRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
995 $this->mDeletedRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
996 } else {
997 $remaining[$revid] = true;
998 }
999 }
1000
1001 $this->mMissingRevIDs = array_keys( $remaining );
1002 }
1003 }
1004
1010 private function resolvePendingRedirects() {
1011 if ( $this->mResolveRedirects ) {
1012 $db = $this->getDB();
1013 $pageFlds = $this->getPageTableFields();
1014
1015 // Repeat until all redirects have been resolved
1016 // The infinite loop is prevented by keeping all known pages in $this->mAllPages
1017 while ( $this->mPendingRedirectIDs ) {
1018 // Resolve redirects by querying the pagelinks table, and repeat the process
1019 // Create a new linkBatch object for the next pass
1020 $linkBatch = $this->getRedirectTargets();
1021
1022 if ( $linkBatch->isEmpty() ) {
1023 break;
1024 }
1025
1026 $set = $linkBatch->constructSet( 'page', $db );
1027 if ( $set === false ) {
1028 break;
1029 }
1030
1031 // Get pageIDs data from the `page` table
1032 $res = $db->select( 'page', $pageFlds, $set, __METHOD__ );
1033
1034 // Hack: get the ns:titles stored in [ns => array(titles)] format
1035 $this->initFromQueryResult( $res, $linkBatch->data, true );
1036 }
1037 }
1038 }
1039
1047 private function getRedirectTargets() {
1048 $lb = new LinkBatch();
1049 $db = $this->getDB();
1050
1051 $res = $db->select(
1052 'redirect',
1053 [
1054 'rd_from',
1055 'rd_namespace',
1056 'rd_fragment',
1057 'rd_interwiki',
1058 'rd_title'
1059 ], [ 'rd_from' => array_keys( $this->mPendingRedirectIDs ) ],
1060 __METHOD__
1061 );
1062 foreach ( $res as $row ) {
1063 $rdfrom = intval( $row->rd_from );
1064 $from = $this->mPendingRedirectIDs[$rdfrom]->getPrefixedText();
1065 $to = Title::makeTitle(
1066 $row->rd_namespace,
1067 $row->rd_title,
1068 $row->rd_fragment,
1069 $row->rd_interwiki
1070 );
1071 $this->mResolvedRedirectTitles[$from] = $this->mPendingRedirectIDs[$rdfrom];
1072 unset( $this->mPendingRedirectIDs[$rdfrom] );
1073 if ( $to->isExternal() ) {
1074 $this->mInterwikiTitles[$to->getPrefixedText()] = $to->getInterwiki();
1075 } elseif ( !isset( $this->mAllPages[$row->rd_namespace][$row->rd_title] ) ) {
1076 $lb->add( $row->rd_namespace, $row->rd_title );
1077 }
1078 $this->mRedirectTitles[$from] = $to;
1079 }
1080
1081 if ( $this->mPendingRedirectIDs ) {
1082 // We found pages that aren't in the redirect table
1083 // Add them
1084 foreach ( $this->mPendingRedirectIDs as $id => $title ) {
1086 $rt = $page->insertRedirect();
1087 if ( !$rt ) {
1088 // What the hell. Let's just ignore this
1089 continue;
1090 }
1091 $lb->addObj( $rt );
1092 $from = $title->getPrefixedText();
1093 $this->mResolvedRedirectTitles[$from] = $title;
1094 $this->mRedirectTitles[$from] = $rt;
1095 unset( $this->mPendingRedirectIDs[$id] );
1096 }
1097 }
1098
1099 return $lb;
1100 }
1101
1115 public function getCacheMode( $params = null ) {
1116 return $this->mCacheMode;
1117 }
1118
1128 private function processTitlesArray( $titles ) {
1129 $usernames = [];
1130 $linkBatch = new LinkBatch();
1131
1132 foreach ( $titles as $title ) {
1133 if ( is_string( $title ) ) {
1134 try {
1135 $titleObj = Title::newFromTextThrow( $title, $this->mDefaultNamespace );
1136 } catch ( MalformedTitleException $ex ) {
1137 // Handle invalid titles gracefully
1138 $this->mAllPages[0][$title] = $this->mFakePageId;
1139 $this->mInvalidTitles[$this->mFakePageId] = [
1140 'title' => $title,
1141 'invalidreason' => $ex->getMessage(),
1142 ];
1143 $this->mFakePageId--;
1144 continue; // There's nothing else we can do
1145 }
1146 } else {
1147 $titleObj = $title;
1148 }
1149 $unconvertedTitle = $titleObj->getPrefixedText();
1150 $titleWasConverted = false;
1151 if ( $titleObj->isExternal() ) {
1152 // This title is an interwiki link.
1153 $this->mInterwikiTitles[$unconvertedTitle] = $titleObj->getInterwiki();
1154 } else {
1155 // Variants checking
1157 if ( $this->mConvertTitles &&
1158 count( $wgContLang->getVariants() ) > 1 &&
1159 !$titleObj->exists()
1160 ) {
1161 // Language::findVariantLink will modify titleText and titleObj into
1162 // the canonical variant if possible
1163 $titleText = is_string( $title ) ? $title : $titleObj->getPrefixedText();
1164 $wgContLang->findVariantLink( $titleText, $titleObj );
1165 $titleWasConverted = $unconvertedTitle !== $titleObj->getPrefixedText();
1166 }
1167
1168 if ( $titleObj->getNamespace() < 0 ) {
1169 // Handle Special and Media pages
1170 $titleObj = $titleObj->fixSpecialName();
1171 $this->mSpecialTitles[$this->mFakePageId] = $titleObj;
1172 $this->mFakePageId--;
1173 } else {
1174 // Regular page
1175 $linkBatch->addObj( $titleObj );
1176 }
1177 }
1178
1179 // Make sure we remember the original title that was
1180 // given to us. This way the caller can correlate new
1181 // titles with the originally requested when e.g. the
1182 // namespace is localized or the capitalization is
1183 // different
1184 if ( $titleWasConverted ) {
1185 $this->mConvertedTitles[$unconvertedTitle] = $titleObj->getPrefixedText();
1186 // In this case the page can't be Special.
1187 if ( is_string( $title ) && $title !== $unconvertedTitle ) {
1188 $this->mNormalizedTitles[$title] = $unconvertedTitle;
1189 }
1190 } elseif ( is_string( $title ) && $title !== $titleObj->getPrefixedText() ) {
1191 $this->mNormalizedTitles[$title] = $titleObj->getPrefixedText();
1192 }
1193
1194 // Need gender information
1195 if ( MWNamespace::hasGenderDistinction( $titleObj->getNamespace() ) ) {
1196 $usernames[] = $titleObj->getText();
1197 }
1198 }
1199 // Get gender information
1200 $genderCache = GenderCache::singleton();
1201 $genderCache->doQuery( $usernames, __METHOD__ );
1202
1203 return $linkBatch;
1204 }
1205
1221 public function setGeneratorData( Title $title, array $data ) {
1222 $ns = $title->getNamespace();
1223 $dbkey = $title->getDBkey();
1224 $this->mGeneratorData[$ns][$dbkey] = $data;
1225 }
1226
1246 public function setRedirectMergePolicy( $callable ) {
1247 $this->mRedirectMergePolicy = $callable;
1248 }
1249
1270 public function populateGeneratorData( &$result, array $path = [] ) {
1271 if ( $result instanceof ApiResult ) {
1272 $data = $result->getResultData( $path );
1273 if ( $data === null ) {
1274 return true;
1275 }
1276 } else {
1277 $data = &$result;
1278 foreach ( $path as $key ) {
1279 if ( !isset( $data[$key] ) ) {
1280 // Path isn't in $result, so nothing to add, so everything
1281 // "fits"
1282 return true;
1283 }
1284 $data = &$data[$key];
1285 }
1286 }
1287 foreach ( $this->mGeneratorData as $ns => $dbkeys ) {
1288 if ( $ns === -1 ) {
1289 $pages = [];
1290 foreach ( $this->mSpecialTitles as $id => $title ) {
1291 $pages[$title->getDBkey()] = $id;
1292 }
1293 } else {
1294 if ( !isset( $this->mAllPages[$ns] ) ) {
1295 // No known titles in the whole namespace. Skip it.
1296 continue;
1297 }
1298 $pages = $this->mAllPages[$ns];
1299 }
1300 foreach ( $dbkeys as $dbkey => $genData ) {
1301 if ( !isset( $pages[$dbkey] ) ) {
1302 // Unknown title. Forget it.
1303 continue;
1304 }
1305 $pageId = $pages[$dbkey];
1306 if ( !isset( $data[$pageId] ) ) {
1307 // $pageId didn't make it into the result. Ignore it.
1308 continue;
1309 }
1310
1311 if ( $result instanceof ApiResult ) {
1312 $path2 = array_merge( $path, [ $pageId ] );
1313 foreach ( $genData as $key => $value ) {
1314 if ( !$result->addValue( $path2, $key, $value ) ) {
1315 return false;
1316 }
1317 }
1318 } else {
1319 $data[$pageId] = array_merge( $data[$pageId], $genData );
1320 }
1321 }
1322 }
1323
1324 // Merge data generated about redirect titles into the redirect destination
1325 if ( $this->mRedirectMergePolicy ) {
1326 foreach ( $this->mResolvedRedirectTitles as $titleFrom ) {
1327 $dest = $titleFrom;
1328 while ( isset( $this->mRedirectTitles[$dest->getPrefixedText()] ) ) {
1329 $dest = $this->mRedirectTitles[$dest->getPrefixedText()];
1330 }
1331 $fromNs = $titleFrom->getNamespace();
1332 $fromDBkey = $titleFrom->getDBkey();
1333 $toPageId = $dest->getArticleID();
1334 if ( isset( $data[$toPageId] ) &&
1335 isset( $this->mGeneratorData[$fromNs][$fromDBkey] )
1336 ) {
1337 // It is necesary to set both $data and add to $result, if an ApiResult,
1338 // to ensure multiple redirects to the same destination are all merged.
1339 $data[$toPageId] = call_user_func(
1340 $this->mRedirectMergePolicy,
1341 $data[$toPageId],
1342 $this->mGeneratorData[$fromNs][$fromDBkey]
1343 );
1344 if ( $result instanceof ApiResult ) {
1345 if ( !$result->addValue( $path, $toPageId, $data[$toPageId], ApiResult::OVERRIDE ) ) {
1346 return false;
1347 }
1348 }
1349 }
1350 }
1351 }
1352
1353 return true;
1354 }
1355
1360 protected function getDB() {
1361 return $this->mDbSource->getDB();
1362 }
1363
1370 private static function getPositiveIntegers( $array ) {
1371 // bug 25734 API: possible issue with revids validation
1372 // It seems with a load of revision rows, MySQL gets upset
1373 // Remove any < 0 integers, as they can't be valid
1374 foreach ( $array as $i => $int ) {
1375 if ( $int < 0 ) {
1376 unset( $array[$i] );
1377 }
1378 }
1379
1380 return $array;
1381 }
1382
1383 public function getAllowedParams( $flags = 0 ) {
1384 $result = [
1385 'titles' => [
1386 ApiBase::PARAM_ISMULTI => true,
1387 ApiBase::PARAM_HELP_MSG => 'api-pageset-param-titles',
1388 ],
1389 'pageids' => [
1390 ApiBase::PARAM_TYPE => 'integer',
1391 ApiBase::PARAM_ISMULTI => true,
1392 ApiBase::PARAM_HELP_MSG => 'api-pageset-param-pageids',
1393 ],
1394 'revids' => [
1395 ApiBase::PARAM_TYPE => 'integer',
1396 ApiBase::PARAM_ISMULTI => true,
1397 ApiBase::PARAM_HELP_MSG => 'api-pageset-param-revids',
1398 ],
1399 'generator' => [
1400 ApiBase::PARAM_TYPE => null,
1401 ApiBase::PARAM_HELP_MSG => 'api-pageset-param-generator',
1403 ],
1404 'redirects' => [
1405 ApiBase::PARAM_DFLT => false,
1406 ApiBase::PARAM_HELP_MSG => $this->mAllowGenerator
1407 ? 'api-pageset-param-redirects-generator'
1408 : 'api-pageset-param-redirects-nogenerator',
1409 ],
1410 'converttitles' => [
1411 ApiBase::PARAM_DFLT => false,
1413 'api-pageset-param-converttitles',
1415 function ( IContextSource $context ) {
1416 return $context->getLanguage()
1418 },
1419 $this
1420 )
1421 ],
1422 ],
1423 ];
1424
1425 if ( !$this->mAllowGenerator ) {
1426 unset( $result['generator'] );
1427 } elseif ( $flags & ApiBase::GET_VALUES_FOR_HELP ) {
1428 $result['generator'][ApiBase::PARAM_TYPE] = 'submodule';
1429 $result['generator'][ApiBase::PARAM_SUBMODULE_MAP] = $this->getGenerators();
1430 }
1431
1432 return $result;
1433 }
1434
1435 protected function handleParamNormalization( $paramName, $value, $rawValue ) {
1436 parent::handleParamNormalization( $paramName, $value, $rawValue );
1437
1438 if ( $paramName === 'titles' ) {
1439 // For the 'titles' parameter, we want to split it like ApiBase would
1440 // and add any changed titles to $this->mNormalizedTitles
1441 $value = $this->explodeMultiValue( $value, self::LIMIT_SML2 + 1 );
1442 $l = count( $value );
1443 $rawValue = $this->explodeMultiValue( $rawValue, $l );
1444 for ( $i = 0; $i < $l; $i++ ) {
1445 if ( $value[$i] !== $rawValue[$i] ) {
1446 $this->mNormalizedTitles[$rawValue[$i]] = $value[$i];
1447 }
1448 }
1449 }
1450 }
1451
1452 private static $generators = null;
1453
1458 private function getGenerators() {
1459 if ( self::$generators === null ) {
1461 if ( !( $query instanceof ApiQuery ) ) {
1462 // If the parent container of this pageset is not ApiQuery,
1463 // we must create it to get module manager
1464 $query = $this->getMain()->getModuleManager()->getModule( 'query' );
1465 }
1466 $gens = [];
1467 $prefix = $query->getModulePath() . '+';
1468 $mgr = $query->getModuleManager();
1469 foreach ( $mgr->getNamesWithClasses() as $name => $class ) {
1470 if ( is_subclass_of( $class, 'ApiQueryGeneratorBase' ) ) {
1471 $gens[$name] = $prefix . $name;
1472 }
1473 }
1474 ksort( $gens );
1475 self::$generators = $gens;
1476 }
1477
1478 return self::$generators;
1479 }
1480}
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:39
const PARAM_SUBMODULE_MAP
(string[]) When PARAM_TYPE is 'submodule', map parameter values to submodule paths.
Definition ApiBase.php:165
static dieDebug( $method, $message)
Internal code errors should be reported with this method.
Definition ApiBase.php:2295
getMain()
Get the main module.
Definition ApiBase.php:480
const PARAM_TYPE
(string|string[]) Either an array of allowed value strings, or a string type as described below.
Definition ApiBase.php:88
const PARAM_DFLT
(null|boolean|integer|string) Default value of the parameter.
Definition ApiBase.php:50
extractRequestParams( $parseLimit=true)
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:685
setWarning( $warning)
Set warning section for this module.
Definition ApiBase.php:1554
const PARAM_SUBMODULE_PARAM_PREFIX
(string) When PARAM_TYPE is 'submodule', used to indicate the 'g' prefix added by ApiQueryGeneratorBa...
Definition ApiBase.php:172
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition ApiBase.php:125
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
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:464
explodeMultiValue( $value, $limit)
Split a multi-valued parameter string, like explode()
Definition ApiBase.php:1207
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:1585
const PARAM_ISMULTI
(boolean) Accept multiple pipe-separated values for this parameter (e.g.
Definition ApiBase.php:53
This class contains a list of pages that the client has requested.
getGoodAndMissingTitlesByNamespace()
Returns an array [ns][dbkey] => page_id for all good and missing titles.
initFromPageIds( $pageids)
Does the same as initFromTitles(), but is based on page IDs instead.
populateFromRevisionIDs( $revIDs)
Populate this PageSet from a list of revision IDs.
getInterwikiTitlesAsResult( $result=null, $iwUrl=false)
Get a list of interwiki titles - maps a title to its interwiki prefix as result.
getCustomField( $fieldName)
Get the value of a custom field previously requested through requestField()
getNormalizedTitles()
Get a list of title normalizations - maps a title to its normalized version.
getGenerators()
Get an array of all available generators.
__construct(ApiBase $dbSource, $flags=0, $defaultNamespace=NS_MAIN)
getGoodTitlesByNamespace()
Returns an array [ns][dbkey] => page_id for all good titles.
getAllowedParams( $flags=0)
getRevisionIDs()
Get the list of valid revision IDs (requested with the revids= parameter)
getGoodAndMissingTitles()
Title objects for good and missing titles.
populateFromPageIDs( $pageIDs)
Populate this PageSet from a list of page IDs.
getRedirectTargets()
Get the targets of the pending redirects from the database.
getMissingTitlesByNamespace()
Returns an array [ns][dbkey] => fake_page_id for all missing titles.
static getPositiveIntegers( $array)
Returns the input array of integers with all values < 0 removed.
getMissingTitles()
Title objects that were NOT found in the database.
getDB()
Get the database connection (read-only)
static $generators
initFromRevIDs( $revids)
Does the same as initFromTitles(), but is based on revision IDs instead.
executeDryRun()
In case execute() is not called, call this method to mark all relevant parameters as used This preven...
getRedirectTitlesAsResult( $result=null)
Get a list of redirect resolutions - maps a title to its redirect target.
getPageTableFields()
Get the fields that have to be queried from the page table: the ones requested through requestField()...
getGoodTitleCount()
Returns the number of found unique pages (not revisions) in the set.
getRevisionCount()
Returns the number of revisions (requested with revids= parameter).
getAllTitlesByNamespace()
Returns an array [ns][dbkey] => page_id for all requested titles.
processDbRow( $row)
Extract all requested fields from the row received from the database.
processTitlesArray( $titles)
Given an array of title strings, convert them into Title objects.
static addValues(array &$result, $values, $flags=[], $name=null)
Add all items from $values into the result.
setRedirectMergePolicy( $callable)
Controls how generator data about a redirect source is merged into the generator data for the redirec...
handleParamNormalization( $paramName, $value, $rawValue)
Handle when a parameter was Unicode-normalized.
getNormalizedTitlesAsResult( $result=null)
Get a list of title normalizations - maps a title to its normalized version in the form of result arr...
getTitleCount()
Returns the number of unique pages (not revisions) in the set.
initFromTitles( $titles)
This method populates internal variables with page information based on the given array of title stri...
getInvalidTitlesAndReasons()
Titles that were deemed invalid by Title::newFromText() The array's index will be unique and negative...
array $mInvalidTitles
[fake_page_id] => [ 'title' => $title, 'invalidreason' => $reason ]
getSpecialTitles()
Get the list of titles with negative namespace.
Title[] $mPendingRedirectIDs
getTitles()
All Title objects provided.
int $mDefaultNamespace
executeInternal( $isDryRun)
Populate the PageSet from the request parameters.
resolvePendingRedirects()
Resolve any redirects in the result if redirect resolution was requested.
populateFromQueryResult( $db, $queryResult)
Populate this PageSet from a rowset returned from the database.
getMissingPageIDs()
Page IDs that were not found in the database.
requestField( $fieldName)
Request an additional field from the page table.
getInterwikiTitles()
Get a list of interwiki titles - maps a title to its interwiki prefix.
populateFromTitles( $titles)
Populate this PageSet from a list of Titles.
getMissingRevisionIDs()
Revision IDs that were not found in the database.
execute()
Populate the PageSet from the request parameters.
populateGeneratorData(&$result, array $path=[])
Populate the generator data for all titles in the result.
getConvertedTitlesAsResult( $result=null)
Get a list of title conversions - maps a title to its converted version as a result array.
getConvertedTitles()
Get a list of title conversions - maps a title to its converted version.
getInvalidTitles()
Titles that were deemed invalid by Title::newFromText() The array's index will be unique and negative...
getDataSource()
Return the parameter name that is the source of data for this PageSet.
getInvalidTitlesAndRevisions( $invalidChecks=[ 'invalidTitles', 'special', 'missingIds', 'missingRevIds', 'missingTitles', 'interwikiTitles'])
Get an array of invalid/special/missing titles.
getLiveRevisionIDs()
Get the list of non-deleted revision IDs (requested with the revids= parameter)
getCacheMode( $params=null)
Get the cache mode for the data generated by this module.
getGoodTitles()
Title objects that were found in the database.
$mResolvedRedirectTitles
callable null $mRedirectMergePolicy
isResolvingRedirects()
Check whether this PageSet is resolving redirects.
getRedirectTitles()
Get a list of redirect resolutions - maps a title to its redirect target, as an array of output-ready...
setGeneratorData(Title $title, array $data)
Set data for a title.
const DISABLE_GENERATORS
Constructor flag: The new instance of ApiPageSet will ignore the 'generator=' parameter.
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...
getMissingRevisionIDsAsResult( $result=null)
Revision IDs that were not found in the database as result array.
getDeletedRevisionIDs()
Get the list of revision IDs that were associated with deleted titles.
static addTitleInfo(&$arr, $title, $prefix='')
Add information (title and namespace) about a Title object to a result array.
This is the main query class.
Definition ApiQuery.php:38
This class represents the result of the API operations.
Definition ApiResult.php:33
const OVERRIDE
Override existing value in addValue(), setValue(), and similar functions.
Definition ApiResult.php:39
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
getUser()
Get the User object.
getConfig()
Get the Config object.
IContextSource $context
static array $languagesWithVariants
languages supporting variants
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition LinkBatch.php:32
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
Represents a title within MediaWiki.
Definition Title.php:36
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition WikiPage.php:115
$res
Definition database.txt:21
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:57
when a variable name is used in a it is silently declared as a new local masking the global
Definition design.txt:95
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
const PROTO_CURRENT
Definition Defines.php:226
const NS_MAIN
Definition Defines.php:56
the array() calling protocol came about after MediaWiki 1.4rc1.
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist & $tables
Definition hooks.txt:1028
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':DEPRECATED! Use HtmlPageLinkRendererBegin instead. 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:1937
namespace and then decline to actually register it file or subcat img or subcat $title
Definition hooks.txt:986
it s the revision text itself In either if gzip is the revision text is gzipped $flags
Definition hooks.txt:2710
Allows to change the fields on the form that will be generated $name
Definition hooks.txt:304
namespace are movable Hooks may change this value to override the return value of MWNamespace::isMovable(). 'NewDifferenceEngine' 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:2534
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:1595
$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:37
Interface for objects which can provide a MediaWiki context on request.
getLanguage()
Get the Language object.
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
$params