68 private bool $fld_protection =
false;
69 private bool $fld_talkid =
false;
70 private bool $fld_subjectid =
false;
71 private bool $fld_url =
false;
72 private bool $fld_readable =
false;
73 private bool $fld_watched =
false;
74 private bool $fld_watchers =
false;
75 private bool $fld_visitingwatchers =
false;
76 private bool $fld_notificationtimestamp =
false;
77 private bool $fld_preload =
false;
78 private bool $fld_preloadcontent =
false;
79 private bool $fld_editintro =
false;
80 private bool $fld_displaytitle =
false;
81 private bool $fld_varianttitles =
false;
87 private $fld_linkclasses =
false;
92 private $fld_associatedpage =
false;
105 private $pageIsRedir;
107 private $pageTouched;
111 private $protections;
112 private $restrictionTypes;
115 private $visitingwatchers;
116 private $notificationtimestamps;
119 private $displaytitles;
120 private $variantTitles;
126 private $watchlistExpiries;
132 private $linkClasses;
134 private $showZeroWatchers =
false;
136 private $countTestedActions = 0;
176 parent::__construct( $queryModule, $moduleName,
'in' );
178 $this->linkBatchFactory = $linkBatchFactory;
179 $this->namespaceInfo = $namespaceInfo;
180 $this->titleFactory = $titleFactory;
181 $this->titleFormatter = $titleFormatter;
182 $this->watchedItemStore = $watchedItemStore;
183 $this->restrictionStore = $restrictionStore;
184 $this->linksMigration = $linksMigration;
185 $this->tempUserCreator = $tempUserCreator;
186 $this->userFactory = $userFactory;
187 $this->introMessageBuilder = $introMessageBuilder;
188 $this->preloadedContentBuilder = $preloadedContentBuilder;
189 $this->revisionLookup = $revisionLookup;
190 $this->urlUtils = $urlUtils;
201 $pageSet->requestField(
'page_is_redirect' );
202 $pageSet->requestField(
'page_is_new' );
204 $pageSet->requestField(
'page_touched' );
205 $pageSet->requestField(
'page_latest' );
206 $pageSet->requestField(
'page_len' );
207 $pageSet->requestField(
'page_content_model' );
208 if ( $config->get( MainConfigNames::PageLanguageUseDB ) ) {
209 $pageSet->requestField(
'page_lang' );
215 if ( $this->params[
'prop'] !==
null ) {
216 $prop = array_fill_keys( $this->params[
'prop'],
true );
217 $this->fld_protection = isset( $prop[
'protection'] );
218 $this->fld_watched = isset( $prop[
'watched'] );
219 $this->fld_watchers = isset( $prop[
'watchers'] );
220 $this->fld_visitingwatchers = isset( $prop[
'visitingwatchers'] );
221 $this->fld_notificationtimestamp = isset( $prop[
'notificationtimestamp'] );
222 $this->fld_talkid = isset( $prop[
'talkid'] );
223 $this->fld_subjectid = isset( $prop[
'subjectid'] );
224 $this->fld_url = isset( $prop[
'url'] );
225 $this->fld_readable = isset( $prop[
'readable'] );
226 $this->fld_preload = isset( $prop[
'preload'] );
227 $this->fld_preloadcontent = isset( $prop[
'preloadcontent'] );
228 $this->fld_editintro = isset( $prop[
'editintro'] );
229 $this->fld_displaytitle = isset( $prop[
'displaytitle'] );
230 $this->fld_varianttitles = isset( $prop[
'varianttitles'] );
231 $this->fld_linkclasses = isset( $prop[
'linkclasses'] );
232 $this->fld_associatedpage = isset( $prop[
'associatedpage'] );
236 $this->titles = $pageSet->getGoodPages();
237 $this->missing = $pageSet->getMissingPages();
238 $this->everything = $this->titles + $this->missing;
242 ( $this->fld_preloadcontent || $this->fld_editintro ) &&
243 ( count( $this->everything ) > 1 || count( $this->
getPageSet()->getRevisionIDs() ) > 1 )
248 [
'apierror-info-singlepagerevision', $this->
getModulePrefix() ],
'invalidparammix'
252 uasort( $this->everything, [ Title::class,
'compare' ] );
253 if ( $this->params[
'continue'] !==
null ) {
257 $conttitle = $this->titleFactory->makeTitleSafe( $cont[0], $cont[1] );
259 foreach ( $this->everything as $pageid => $page ) {
260 if ( Title::compare( $page, $conttitle ) >= 0 ) {
263 unset( $this->titles[$pageid] );
264 unset( $this->missing[$pageid] );
265 unset( $this->everything[$pageid] );
270 $this->pageIsRedir = !$pageSet->isResolvingRedirects()
271 ? $pageSet->getCustomField(
'page_is_redirect' )
273 $this->pageIsNew = $pageSet->getCustomField(
'page_is_new' );
275 $this->pageTouched = $pageSet->getCustomField(
'page_touched' );
276 $this->pageLatest = $pageSet->getCustomField(
'page_latest' );
277 $this->pageLength = $pageSet->getCustomField(
'page_len' );
280 if ( $this->fld_protection ) {
281 $this->getProtectionInfo();
284 if ( $this->fld_watched || $this->fld_notificationtimestamp ) {
285 $this->getWatchedInfo();
288 if ( $this->fld_watchers ) {
289 $this->getWatcherInfo();
292 if ( $this->fld_visitingwatchers ) {
293 $this->getVisitingWatcherInfo();
297 if ( $this->fld_talkid || $this->fld_subjectid ) {
301 if ( $this->fld_displaytitle ) {
302 $this->getDisplayTitle();
305 if ( $this->fld_varianttitles ) {
306 $this->getVariantTitles();
309 if ( $this->fld_linkclasses ) {
310 $this->getLinkClasses( $this->params[
'linkcontext'] );
314 foreach ( $this->everything as $pageid => $page ) {
315 $pageInfo = $this->extractPageInfo( $pageid, $page );
316 $fit = $pageInfo !==
null && $result->addValue( [
319 ], $pageid, $pageInfo );
322 $page->getNamespace() .
'|' .
323 $this->titleFormatter->getText( $page ) );
335 private function extractPageInfo( $pageid, $page ) {
336 $title = $this->titleFactory->newFromPageIdentity( $page );
339 $pageExists = $pageid > 0;
340 $ns = $page->getNamespace();
341 $dbkey = $page->getDBkey();
343 $pageInfo[
'contentmodel'] = $title->getContentModel();
345 $pageLanguage = $title->getPageLanguage();
346 $pageInfo[
'pagelanguage'] = $pageLanguage->getCode();
347 $pageInfo[
'pagelanguagehtmlcode'] = $pageLanguage->getHtmlCode();
348 $pageInfo[
'pagelanguagedir'] = $pageLanguage->getDir();
351 $pageInfo[
'touched'] =
wfTimestamp( TS_ISO_8601, $this->pageTouched[$pageid] );
352 $pageInfo[
'lastrevid'] = (int)$this->pageLatest[$pageid];
353 $pageInfo[
'length'] = (int)$this->pageLength[$pageid];
355 if ( isset( $this->pageIsRedir[$pageid] ) && $this->pageIsRedir[$pageid] ) {
356 $pageInfo[
'redirect'] =
true;
358 if ( $this->pageIsNew[$pageid] ) {
359 $pageInfo[
'new'] =
true;
363 if ( $this->fld_protection ) {
364 $pageInfo[
'protection'] = [];
365 if ( isset( $this->protections[$ns][$dbkey] ) ) {
366 $pageInfo[
'protection'] =
367 $this->protections[$ns][$dbkey];
371 $pageInfo[
'restrictiontypes'] = [];
372 if ( isset( $this->restrictionTypes[$ns][$dbkey] ) ) {
373 $pageInfo[
'restrictiontypes'] =
374 $this->restrictionTypes[$ns][$dbkey];
379 if ( $this->fld_watched ) {
380 $pageInfo[
'watched'] =
false;
382 if ( isset( $this->watched[$ns][$dbkey] ) ) {
383 $pageInfo[
'watched'] = $this->watched[$ns][$dbkey];
386 if ( isset( $this->watchlistExpiries[$ns][$dbkey] ) ) {
387 $pageInfo[
'watchlistexpiry'] = $this->watchlistExpiries[$ns][$dbkey];
391 if ( $this->fld_watchers ) {
392 if ( $this->watchers !==
null && $this->watchers[$ns][$dbkey] !== 0 ) {
393 $pageInfo[
'watchers'] = $this->watchers[$ns][$dbkey];
394 } elseif ( $this->showZeroWatchers ) {
395 $pageInfo[
'watchers'] = 0;
399 if ( $this->fld_visitingwatchers ) {
400 if ( $this->visitingwatchers !==
null && $this->visitingwatchers[$ns][$dbkey] !== 0 ) {
401 $pageInfo[
'visitingwatchers'] = $this->visitingwatchers[$ns][$dbkey];
402 } elseif ( $this->showZeroWatchers ) {
403 $pageInfo[
'visitingwatchers'] = 0;
407 if ( $this->fld_notificationtimestamp ) {
408 $pageInfo[
'notificationtimestamp'] =
'';
409 if ( isset( $this->notificationtimestamps[$ns][$dbkey] ) ) {
410 $pageInfo[
'notificationtimestamp'] =
411 wfTimestamp( TS_ISO_8601, $this->notificationtimestamps[$ns][$dbkey] );
415 if ( $this->fld_talkid && isset( $this->talkids[$ns][$dbkey] ) ) {
416 $pageInfo[
'talkid'] = $this->talkids[$ns][$dbkey];
419 if ( $this->fld_subjectid && isset( $this->subjectids[$ns][$dbkey] ) ) {
420 $pageInfo[
'subjectid'] = $this->subjectids[$ns][$dbkey];
423 if ( $this->fld_associatedpage && $ns >=
NS_MAIN ) {
424 $pageInfo[
'associatedpage'] = $this->titleFormatter->getPrefixedText(
425 $this->namespaceInfo->getAssociatedPage( TitleValue::newFromPage( $page ) )
429 if ( $this->fld_url ) {
430 $pageInfo[
'fullurl'] = (string)$this->urlUtils->expand(
433 $pageInfo[
'editurl'] = (string)$this->urlUtils->expand(
436 $pageInfo[
'canonicalurl'] = (string)$this->urlUtils->expand(
440 if ( $this->fld_readable ) {
441 $pageInfo[
'readable'] = $this->
getAuthority()->definitelyCan(
'read', $page );
444 if ( $this->fld_preload ) {
446 $pageInfo[
'preload'] =
'';
450 $this->
getHookRunner()->onEditFormPreloadText( $text, $title );
452 $pageInfo[
'preload'] = $text;
456 if ( $this->fld_preloadcontent ) {
457 $newSection = $this->params[
'preloadnewsection'];
460 if ( !$pageExists || $newSection ) {
461 $content = $this->preloadedContentBuilder->getPreloadedContent(
462 $title->toPageIdentity(),
463 $this->getAuthority(),
464 $this->params[
'preloadcustom'],
465 $this->params[
'preloadparams'] ?? [],
466 $newSection ?
'new' : null
468 $defaultContent = $newSection ? null :
469 $this->preloadedContentBuilder->getDefaultContent( $title->toPageIdentity() );
470 $contentIsDefault = $defaultContent ? $content->equals( $defaultContent ) : $content->isEmpty();
473 $pageInfo[
'preloadcontent'][
'contentmodel'] = $content->getModel();
474 $pageInfo[
'preloadcontent'][
'contentformat'] = $content->getDefaultFormat();
479 $pageInfo[
'preloadisdefault'] = $contentIsDefault;
483 if ( $this->fld_editintro ) {
485 $localizerWithPage =
new class( $this, $page ) implements
MessageLocalizer {
497 public function msg( $key, ...$params ) {
498 return $this->base->msg( $key, ...$params )->page( $this->page );
503 'lessframes' => IntroMessageBuilder::LESS_FRAMES,
504 'moreframes' => IntroMessageBuilder::MORE_FRAMES,
507 $revId = array_key_first( $this->
getPageSet()->getLiveRevisionIDs() );
508 $revRecord = $revId ? $this->revisionLookup->getRevisionById( $revId ) :
null;
510 $messages = $this->introMessageBuilder->getIntroMessages(
511 $styleParamMap[ $this->params[
'editintrostyle'] ],
512 $this->params[
'editintroskip'] ?? [],
514 $title->toPageIdentity(),
516 $this->getAuthority(),
517 $this->params[
'editintrocustom'],
525 $pageInfo[
'editintro'] = $messages;
528 if ( $this->fld_displaytitle ) {
529 $pageInfo[
'displaytitle'] = $this->displaytitles[$pageid] ??
530 htmlspecialchars( $this->titleFormatter->getPrefixedText( $page ), ENT_NOQUOTES );
533 if ( $this->fld_varianttitles && isset( $this->variantTitles[$pageid] ) ) {
534 $pageInfo[
'varianttitles'] = $this->variantTitles[$pageid];
537 if ( $this->fld_linkclasses && isset( $this->linkClasses[$pageid] ) ) {
538 $pageInfo[
'linkclasses'] = $this->linkClasses[$pageid];
541 if ( $this->params[
'testactions'] ) {
543 if ( $this->countTestedActions >= $limit ) {
547 $detailLevel = $this->params[
'testactionsdetail'];
549 if ( $errorFormatter->getFormat() ===
'bc' ) {
551 $errorFormatter = $errorFormatter->newWithFormat(
'plaintext' );
554 $pageInfo[
'actions'] = [];
555 if ( $this->params[
'testactionsautocreate'] ) {
556 $pageInfo[
'wouldautocreate'] = [];
559 foreach ( $this->params[
'testactions'] as $action ) {
560 $this->countTestedActions++;
562 $shouldAutoCreate = $this->tempUserCreator->shouldAutoCreate( $this->
getUser(), $action );
564 if ( $shouldAutoCreate ) {
565 $authority = $this->userFactory->newTempPlaceholder();
570 if ( $detailLevel ===
'boolean' ) {
571 $pageInfo[
'actions'][$action] = $authority->authorizeRead( $action, $page );
574 if ( $detailLevel ===
'quick' ) {
575 $authority->probablyCan( $action, $page, $status );
577 $authority->definitelyCan( $action, $page, $status );
580 $pageInfo[
'actions'][$action] = $errorFormatter->arrayFromStatus( $status );
583 if ( $this->params[
'testactionsautocreate'] ) {
584 $pageInfo[
'wouldautocreate'][$action] = $shouldAutoCreate;
595 private function getProtectionInfo() {
596 $this->protections = [];
597 $db = $this->
getDB();
600 if ( count( $this->titles ) ) {
603 $this->
addFields( [
'pr_page',
'pr_type',
'pr_level',
604 'pr_expiry',
'pr_cascade' ] );
605 $this->
addWhereFld(
'pr_page', array_keys( $this->titles ) );
607 $res = $this->
select( __METHOD__ );
608 foreach ( $res as $row ) {
610 $page = $this->titles[$row->pr_page];
612 'type' => $row->pr_type,
613 'level' => $row->pr_level,
616 if ( $row->pr_cascade ) {
617 $a[
'cascade'] =
true;
624 if ( count( $this->missing ) ) {
626 $lb = $this->linkBatchFactory->newLinkBatch( $this->missing );
628 $this->
addFields( [
'pt_title',
'pt_namespace',
'pt_create_perm',
'pt_expiry' ] );
629 $this->
addWhere( $lb->constructSet(
'pt', $db ) );
630 $res = $this->
select( __METHOD__ );
631 foreach ( $res as $row ) {
632 $this->protections[$row->pt_namespace][$row->pt_title][] = [
634 'level' => $row->pt_create_perm,
642 $images = $others = [];
643 foreach ( $this->everything as $page ) {
644 if ( $page->getNamespace() ===
NS_FILE ) {
645 $images[] = $page->getDBkey();
650 $this->restrictionTypes[$page->getNamespace()][$page->getDBkey()] =
651 array_values( $this->restrictionStore->listApplicableRestrictionTypes( $page ) );
654 [ $blNamespace, $blTitle ] = $this->linksMigration->getTitleFields(
'templatelinks' );
655 $queryInfo = $this->linksMigration->getQueryInfo(
'templatelinks' );
657 if ( count( $others ) ) {
659 $lb = $this->linkBatchFactory->newLinkBatch( $others );
661 $this->
addTables( array_merge( [
'page_restrictions',
'page' ], $queryInfo[
'tables'] ) );
663 $this->
addOption(
'USE INDEX', [
'templatelinks' =>
'PRIMARY' ] );
664 $this->
addFields( [
'pr_type',
'pr_level',
'pr_expiry',
665 'page_title',
'page_namespace',
666 $blNamespace, $blTitle ] );
667 $this->
addWhere( $lb->constructSet(
'tl', $db ) );
668 $this->
addWhere(
'pr_page = page_id' );
669 $this->
addWhere(
'pr_page = tl_from' );
673 $res = $this->
select( __METHOD__ );
674 foreach ( $res as $row ) {
675 $this->protections[$row->$blNamespace][$row->$blTitle][] = [
676 'type' => $row->pr_type,
677 'level' => $row->pr_level,
679 'source' => $this->titleFormatter->formatTitle( $row->page_namespace, $row->page_title ),
684 if ( count( $images ) ) {
687 $this->
addTables( [
'page_restrictions',
'page',
'imagelinks' ] );
688 $this->
addFields( [
'pr_type',
'pr_level',
'pr_expiry',
689 'page_title',
'page_namespace',
'il_to' ] );
690 $this->
addWhere(
'pr_page = page_id' );
691 $this->
addWhere(
'pr_page = il_from' );
695 $res = $this->
select( __METHOD__ );
696 foreach ( $res as $row ) {
697 $this->protections[
NS_FILE][$row->il_to][] = [
698 'type' => $row->pr_type,
699 'level' => $row->pr_level,
701 'source' => $this->titleFormatter->formatTitle( $row->page_namespace, $row->page_title ),
711 private function getTSIDs() {
712 $getTitles = $this->talkids = $this->subjectids = [];
713 $nsInfo = $this->namespaceInfo;
716 foreach ( $this->everything as $page ) {
717 if ( $nsInfo->isTalk( $page->getNamespace() ) ) {
718 if ( $this->fld_subjectid ) {
719 $getTitles[] = $nsInfo->getSubjectPage( TitleValue::newFromPage( $page ) );
721 } elseif ( $this->fld_talkid ) {
722 $getTitles[] = $nsInfo->getTalkPage( TitleValue::newFromPage( $page ) );
725 if ( $getTitles === [] ) {
729 $db = $this->
getDB();
733 $lb = $this->linkBatchFactory->newLinkBatch( $getTitles );
736 $this->
addFields( [
'page_title',
'page_namespace',
'page_id' ] );
737 $this->
addWhere( $lb->constructSet(
'page', $db ) );
738 $res = $this->
select( __METHOD__ );
739 foreach ( $res as $row ) {
740 if ( $nsInfo->isTalk( $row->page_namespace ) ) {
741 $this->talkids[$nsInfo->getSubject( $row->page_namespace )][$row->page_title] =
742 (int)( $row->page_id );
744 $this->subjectids[$nsInfo->getTalk( $row->page_namespace )][$row->page_title] =
745 (int)( $row->page_id );
750 private function getDisplayTitle() {
751 $this->displaytitles = [];
753 $pageIds = array_keys( $this->titles );
755 if ( $pageIds === [] ) {
761 $this->
addFields( [
'pp_page',
'pp_value' ] );
763 $this->
addWhereFld(
'pp_propname',
'displaytitle' );
764 $res = $this->
select( __METHOD__ );
766 foreach ( $res as $row ) {
767 $this->displaytitles[$row->pp_page] = $row->pp_value;
778 private function getLinkClasses( ?
LinkTarget $context_title =
null ) {
779 if ( $this->titles === [] ) {
790 foreach ( $this->titles as $pageId => $page ) {
791 $pdbk = $this->titleFormatter->getPrefixedDBkey( $page );
792 $pagemap[$pageId] = $pdbk;
793 $classes[$pdbk] = isset( $this->pageIsRedir[$pageId] ) && $this->pageIsRedir[$pageId] ?
'mw-redirect' :
'';
796 $context_title = $this->titleFactory->newFromLinkTarget(
797 $context_title ?? $this->titleFactory->newMainPage()
800 $pagemap, $classes, $context_title
807 $this->linkClasses = [];
808 foreach ( $this->titles as $pageId => $page ) {
809 $pdbk = $this->titleFormatter->getPrefixedDBkey( $page );
810 $this->linkClasses[$pageId] = preg_split(
811 '/\s+/', $classes[$pdbk] ??
'', -1, PREG_SPLIT_NO_EMPTY
816 private function getVariantTitles() {
817 if ( $this->titles === [] ) {
820 $this->variantTitles = [];
821 foreach ( $this->titles as $pageId => $page ) {
822 $this->variantTitles[$pageId] = isset( $this->displaytitles[$pageId] )
823 ? $this->getAllVariants( $this->displaytitles[$pageId] )
824 : $this->getAllVariants( $this->titleFormatter->getText( $page ), $page->getNamespace() );
828 private function getAllVariants( $text, $ns =
NS_MAIN ) {
830 foreach ( $this->languageConverter->getVariants() as $variant ) {
831 $convertTitle = $this->languageConverter->autoConvert( $text, $variant );
833 $convertNs = $this->languageConverter->convertNamespace( $ns, $variant );
834 $convertTitle = $convertNs .
':' . $convertTitle;
836 $result[$variant] = $convertTitle;
845 private function getWatchedInfo() {
848 if ( !$user->isRegistered() || count( $this->everything ) == 0
849 || !$this->
getAuthority()->isAllowed(
'viewmywatchlist' )
855 $this->watchlistExpiries = [];
856 $this->notificationtimestamps = [];
859 $items = $this->watchedItemStore->loadWatchedItemsBatch( $user, $this->everything );
861 foreach ( $items as $item ) {
862 $nsId = $item->getTarget()->getNamespace();
863 $dbKey = $item->getTarget()->getDBkey();
865 if ( $this->fld_watched ) {
866 $this->watched[$nsId][$dbKey] =
true;
868 $expiry = $item->getExpiry( TS_ISO_8601 );
870 $this->watchlistExpiries[$nsId][$dbKey] = $expiry;
874 if ( $this->fld_notificationtimestamp ) {
875 $this->notificationtimestamps[$nsId][$dbKey] = $item->getNotificationTimestamp();
883 private function getWatcherInfo() {
884 if ( count( $this->everything ) == 0 ) {
888 $canUnwatchedpages = $this->
getAuthority()->isAllowed(
'unwatchedpages' );
889 $unwatchedPageThreshold =
890 $this->
getConfig()->get( MainConfigNames::UnwatchedPageThreshold );
891 if ( !$canUnwatchedpages && !is_int( $unwatchedPageThreshold ) ) {
895 $this->showZeroWatchers = $canUnwatchedpages;
898 if ( !$canUnwatchedpages ) {
899 $countOptions[
'minimumWatchers'] = $unwatchedPageThreshold;
902 $this->watchers = $this->watchedItemStore->countWatchersMultiple(
914 private function getVisitingWatcherInfo() {
916 $db = $this->
getDB();
918 $canUnwatchedpages = $this->
getAuthority()->isAllowed(
'unwatchedpages' );
919 $unwatchedPageThreshold = $config->get( MainConfigNames::UnwatchedPageThreshold );
920 if ( !$canUnwatchedpages && !is_int( $unwatchedPageThreshold ) ) {
924 $this->showZeroWatchers = $canUnwatchedpages;
926 $titlesWithThresholds = [];
927 if ( $this->titles ) {
928 $lb = $this->linkBatchFactory->newLinkBatch( $this->titles );
932 $this->
addTables( [
'page',
'revision' ] );
933 $this->
addFields( [
'page_namespace',
'page_title',
'rev_timestamp' ] );
935 'page_latest = rev_id',
936 $lb->constructSet(
'page', $db ),
938 $this->
addOption(
'GROUP BY', [
'page_namespace',
'page_title' ] );
939 $timestampRes = $this->
select( __METHOD__ );
941 $age = $config->get( MainConfigNames::WatchersMaxAge );
943 foreach ( $timestampRes as $row ) {
944 $revTimestamp =
wfTimestamp( TS_UNIX, (
int)$row->rev_timestamp );
945 $timestamps[$row->page_namespace][$row->page_title] = (int)$revTimestamp - $age;
947 $titlesWithThresholds = array_map(
948 static function (
PageReference $target ) use ( $timestamps ) {
957 if ( $this->missing ) {
958 $titlesWithThresholds = array_merge(
959 $titlesWithThresholds,
962 return [ $target, null ];
968 $this->visitingwatchers = $this->watchedItemStore->countVisitingWatchersMultiple(
969 $titlesWithThresholds,
970 !$canUnwatchedpages ? $unwatchedPageThreshold : null
986 if ( array_diff( (array)$params[
'prop'], $publicProps ) ) {
991 if (
$params[
'testactions'] ) {
1001 ParamValidator::PARAM_ISMULTI =>
true,
1002 ParamValidator::PARAM_TYPE => [
1005 'watched', #
private
1006 'watchers', #
private
1007 'visitingwatchers', #
private
1008 'notificationtimestamp', #
private
1012 'readable', #
private
1014 'preloadcontent', #
private: checks current user
's permissions
1015 'editintro
', # private: checks current user's permissions
1018 'linkclasses', #
private: stub length (and possibly hook colors)
1023 EnumDef::PARAM_DEPRECATED_VALUES => [
1029 ParamValidator::PARAM_TYPE =>
'title',
1030 ParamValidator::PARAM_DEFAULT => $this->titleFactory->newMainPage()->getPrefixedText(),
1031 TitleDef::PARAM_RETURN_OBJECT =>
true,
1034 ParamValidator::PARAM_TYPE =>
'string',
1035 ParamValidator::PARAM_ISMULTI =>
true,
1037 'testactionsdetail' => [
1038 ParamValidator::PARAM_TYPE => [
'boolean',
'full',
'quick' ],
1039 ParamValidator::PARAM_DEFAULT =>
'boolean',
1042 'testactionsautocreate' =>
false,
1043 'preloadcustom' => [
1046 ParamValidator::PARAM_TYPE =>
'string',
1049 'preloadparams' => [
1050 ParamValidator::PARAM_ISMULTI =>
true,
1053 'preloadnewsection' => [
1054 ParamValidator::PARAM_TYPE =>
'boolean',
1055 ParamValidator::PARAM_DEFAULT =>
false,
1058 'editintrostyle' => [
1059 ParamValidator::PARAM_TYPE => [
'lessframes',
'moreframes' ],
1060 ParamValidator::PARAM_DEFAULT =>
'moreframes',
1063 'editintroskip' => [
1064 ParamValidator::PARAM_TYPE =>
'string',
1065 ParamValidator::PARAM_ISMULTI =>
true,
1068 'editintrocustom' => [
1071 ParamValidator::PARAM_TYPE =>
'string',
1081 $title = Title::newMainPage()->getPrefixedText();
1082 $mp = rawurlencode( $title );
1085 "action=query&prop=info&titles={$mp}"
1086 =>
'apihelp-query+info-example-simple',
1087 "action=query&prop=info&inprop=protection&titles={$mp}"
1088 =>
'apihelp-query+info-example-protection',
1093 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Info';