MediaWiki master
ChangesListSpecialPage.php
Go to the documentation of this file.
1<?php
8
35use OOUI\IconWidget;
36use stdClass;
40use Wikimedia\Timestamp\ConvertibleTimestamp;
41use Wikimedia\Timestamp\TimestampFormat as TS;
42
51abstract class ChangesListSpecialPage extends SpecialPage {
52
54 protected $rcSubpage;
55
57 protected $rcOptions;
58
60
61 private ?ChangesListResult $queryResult = null;
62
64 private $mainQueryHookRegistered = false;
66 private $mainQueryHookCalled = false;
67
75 public function __construct(
76 $name,
77 protected readonly UserIdentityUtils $userIdentityUtils,
78 protected TempUserConfig $tempUserConfig,
79 protected readonly RecentChangeFactory $recentChangeFactory,
80 protected readonly ChangesListQueryFactory $changesListQueryFactory,
81 ) {
82 parent::__construct( $name );
83
84 $this->filterGroups = new ChangesListFilterGroupContainer();
85 }
86
97 private function getBaseFilterGroupDefinitions() {
98 return [
99 [
100 'name' => 'registration',
101 'title' => 'rcfilters-filtergroup-registration',
102 'class' => ChangesListBooleanFilterGroup::class,
103 'filters' => [
104 [
105 'name' => 'hideliu',
106 // rcshowhideliu-show, rcshowhideliu-hide,
107 // wlshowhideliu
108 'showHideSuffix' => 'showhideliu',
109 'default' => false,
110 'action' => [ 'exclude', 'named' ],
111 'isReplacedInStructuredUi' => true,
112 ],
113 [
114 'name' => 'hideanons',
115 // rcshowhideanons-show, rcshowhideanons-hide,
116 // wlshowhideanons
117 'showHideSuffix' => 'showhideanons',
118 'default' => false,
119 'action' => [ 'require', 'named' ],
120 'isReplacedInStructuredUi' => true,
121 ]
122 ],
123 ],
124
125 [
126 'name' => 'userExpLevel',
127 'title' => 'rcfilters-filtergroup-user-experience-level',
128 'class' => ChangesListStringOptionsFilterGroup::class,
129 'isFullCoverage' => true,
130 'filters' => [
131 [
132 'name' => 'unregistered',
133 'requireConfig' => [ 'isRegistrationRequiredToEdit' => false ],
134 'label' => 'rcfilters-filter-user-experience-level-unregistered-label',
135 'description' => $this->tempUserConfig->isKnown() ?
136 'rcfilters-filter-user-experience-level-unregistered-description-temp' :
137 'rcfilters-filter-user-experience-level-unregistered-description',
138 'cssClassSuffix' => 'user-unregistered',
139 'action' => [ 'require', 'experience', 'unregistered' ],
140 ],
141 [
142 'name' => 'registered',
143 'requireConfig' => [ 'isRegistrationRequiredToEdit' => false ],
144 'label' => 'rcfilters-filter-user-experience-level-registered-label',
145 'description' => 'rcfilters-filter-user-experience-level-registered-description',
146 'cssClassSuffix' => 'user-registered',
147 'action' => [ 'require', 'experience', 'registered' ],
148 'subsets' => [ 'newcomer', 'learner', 'experienced' ],
149 ],
150 [
151 'name' => 'newcomer',
152 'label' => 'rcfilters-filter-user-experience-level-newcomer-label',
153 'description' => 'rcfilters-filter-user-experience-level-newcomer-description',
154 'cssClassSuffix' => 'user-newcomer',
155 'action' => [ 'require', 'experience', 'newcomer' ],
156 ],
157 [
158 'name' => 'learner',
159 'label' => 'rcfilters-filter-user-experience-level-learner-label',
160 'description' => 'rcfilters-filter-user-experience-level-learner-description',
161 'cssClassSuffix' => 'user-learner',
162 'action' => [ 'require', 'experience', 'learner' ],
163 ],
164 [
165 'name' => 'experienced',
166 'label' => 'rcfilters-filter-user-experience-level-experienced-label',
167 'description' => 'rcfilters-filter-user-experience-level-experienced-description',
168 'cssClassSuffix' => 'user-experienced',
169 'action' => [ 'require', 'experience', 'experienced' ],
170 ]
171 ],
173 ],
174
175 [
176 'name' => 'authorship',
177 'title' => 'rcfilters-filtergroup-authorship',
178 'class' => ChangesListBooleanFilterGroup::class,
179 'filters' => [
180 [
181 'name' => 'hidemyself',
182 'label' => 'rcfilters-filter-editsbyself-label',
183 'description' => 'rcfilters-filter-editsbyself-description',
184 // rcshowhidemine-show, rcshowhidemine-hide,
185 // wlshowhidemine
186 'showHideSuffix' => 'showhidemine',
187 'default' => false,
188 'action' => [ 'exclude', 'user', $this->getUser() ],
189 'highlight' => [ 'require', 'user', $this->getUser() ],
190 'cssClassSuffix' => 'self',
191 ],
192 [
193 'name' => 'hidebyothers',
194 'label' => 'rcfilters-filter-editsbyother-label',
195 'description' => 'rcfilters-filter-editsbyother-description',
196 'default' => false,
197 'action' => [ 'require', 'user', $this->getUser() ],
198 'highlight' => [ 'exclude', 'user', $this->getUser() ],
199 'cssClassSuffix' => 'others',
200 ]
201 ]
202 ],
203
204 [
205 'name' => 'automated',
206 'title' => 'rcfilters-filtergroup-automated',
207 'class' => ChangesListBooleanFilterGroup::class,
208 'filters' => [
209 [
210 'name' => 'hidebots',
211 'label' => 'rcfilters-filter-bots-label',
212 'description' => 'rcfilters-filter-bots-description',
213 // rcshowhidebots-show, rcshowhidebots-hide,
214 // wlshowhidebots
215 'showHideSuffix' => 'showhidebots',
216 'default' => false,
217 'action' => [ 'exclude', 'bot' ],
218 'highlight' => [ 'require', 'bot' ],
219 'cssClassSuffix' => 'bot',
220 ],
221 [
222 'name' => 'hidehumans',
223 'label' => 'rcfilters-filter-humans-label',
224 'description' => 'rcfilters-filter-humans-description',
225 'default' => false,
226 'action' => [ 'require', 'bot' ],
227 'highlight' => [ 'exclude', 'bot' ],
228 'cssClassSuffix' => 'human',
229 ]
230 ]
231 ],
232
233 // significance (conditional)
234
235 [
236 'name' => 'significance',
237 'title' => 'rcfilters-filtergroup-significance',
238 'class' => ChangesListBooleanFilterGroup::class,
239 'priority' => -6,
240 'filters' => [
241 [
242 'name' => 'hideminor',
243 'label' => 'rcfilters-filter-minor-label',
244 'description' => 'rcfilters-filter-minor-description',
245 // rcshowhideminor-show, rcshowhideminor-hide,
246 // wlshowhideminor
247 'showHideSuffix' => 'showhideminor',
248 'default' => false,
249 'action' => [ 'exclude', 'minor' ],
250 'highlight' => [ 'require', 'minor' ],
251 'cssClassSuffix' => 'minor',
252 'conflictOptions' => [
253 'globalKey' => 'rcfilters-hideminor-conflicts-typeofchange-global',
254 'forwardKey' => 'rcfilters-hideminor-conflicts-typeofchange',
255 'backwardKey' => 'rcfilters-typeofchange-conflicts-hideminor',
256 ],
257 'conflictsWith' => [
258 'changeType' => [
259 'hidecategorization' => [],
260 'hidelog' => [],
261 'hidenewuserlog' => [],
262 'hidenewpages' => []
263 ],
264 ],
265 ],
266 [
267 'name' => 'hidemajor',
268 'label' => 'rcfilters-filter-major-label',
269 'description' => 'rcfilters-filter-major-description',
270 'default' => false,
271 'action' => [ 'require', 'minor' ],
272 'highlight' => [ 'exclude', 'minor' ],
273 'cssClassSuffix' => 'major',
274 ]
275 ]
276 ],
277
278 [
279 'name' => 'lastRevision',
280 'title' => 'rcfilters-filtergroup-lastrevision',
281 'class' => ChangesListBooleanFilterGroup::class,
282 'priority' => -7,
283 'filters' => [
284 [
285 'name' => 'hidelastrevision',
286 'label' => 'rcfilters-filter-lastrevision-label',
287 'description' => 'rcfilters-filter-lastrevision-description',
288 'default' => false,
289 'action' => [
290 [ 'require', 'revisionType', 'old' ],
291 [ 'require', 'revisionType', 'none' ],
292 ],
293 'highlight' => [ 'require', 'revisionType', 'latest' ],
294 'cssClassSuffix' => 'last',
295 ],
296 [
297 'name' => 'hidepreviousrevisions',
298 'label' => 'rcfilters-filter-previousrevision-label',
299 'description' => 'rcfilters-filter-previousrevision-description',
300 'default' => false,
301 'action' => [
302 [ 'require', 'revisionType', 'latest' ],
303 [ 'require', 'revisionType', 'none' ],
304 ],
305 'highlight' => [ 'require', 'revisionType', 'old' ],
306 'cssClassSuffix' => 'previous',
307 ]
308 ]
309 ],
310
311 // With extensions, there can be change types that will not be hidden by any of these.
312 [
313 'name' => 'changeType',
314 'title' => 'rcfilters-filtergroup-changetype',
315 'class' => ChangesListBooleanFilterGroup::class,
316 'priority' => -8,
317 'filters' => [
318 [
319 'name' => 'hidepageedits',
320 'label' => 'rcfilters-filter-pageedits-label',
321 'description' => 'rcfilters-filter-pageedits-description',
322 'default' => false,
323 'priority' => -2,
324 'action' => [ 'exclude', 'source', RecentChange::SRC_EDIT ],
325 'highlight' => [ 'require', 'source', RecentChange::SRC_EDIT ],
326 'cssClassSuffix' => 'src-mw-edit',
327 ],
328 [
329 'name' => 'hidenewpages',
330 'label' => 'rcfilters-filter-newpages-label',
331 'description' => 'rcfilters-filter-newpages-description',
332 'default' => false,
333 'priority' => -3,
334 'action' => [ 'exclude', 'source', RecentChange::SRC_NEW ],
335 'highlight' => [ 'require', 'source', RecentChange::SRC_NEW ],
336 'cssClassSuffix' => 'src-mw-new',
337 ],
338 [
339 'name' => 'hidecategorization',
340 'label' => 'rcfilters-filter-categorization-label',
341 'description' => 'rcfilters-filter-categorization-description',
342 // rcshowhidecategorization-show, rcshowhidecategorization-hide.
343 // wlshowhidecategorization
344 'showHideSuffix' => 'showhidecategorization',
345 'default' => false,
346 'priority' => -4,
347 'requireConfig' => [ 'RCWatchCategoryMembership' => true ],
348 'action' => [ 'exclude', 'source', RecentChange::SRC_CATEGORIZE ],
349 'highlight' => [ 'require', 'source', RecentChange::SRC_CATEGORIZE ],
350 'cssClassSuffix' => 'src-mw-categorize',
351 'conflictOptions' => [
352 'globalKey' => 'rcfilters-hidecategorization-conflicts-reviewstatus-global',
353 'forwardKey' => 'rcfilters-hidecategorization-conflicts-reviewstatus',
354 'backwardKey' => 'rcfilters-reviewstatus-conflicts-reviewstatus',
355 ],
356 'conflictsWith' => [
357 'reviewStatus' => [
358 'unpatrolled' => [],
359 'manual' => [],
360 ],
361 ],
362 ],
363 [
364 'name' => 'hidelog',
365 'label' => 'rcfilters-filter-logactions-label',
366 'description' => 'rcfilters-filter-logactions-description',
367 'default' => false,
368 'priority' => -5,
369 'action' => [ 'exclude', 'source', RecentChange::SRC_LOG ],
370 'highlight' => [ 'require', 'source', RecentChange::SRC_LOG ],
371 'cssClassSuffix' => 'src-mw-log',
372 ],
373 [
374 'name' => 'hidenewuserlog',
375 'label' => 'rcfilters-filter-accountcreations-label',
376 'description' => 'rcfilters-filter-accountcreations-description',
377 'default' => false,
378 'priority' => -6,
379 'action' => [ 'exclude', 'logType', 'newusers' ],
380 'highlight' => [ 'require', 'logType', 'newusers' ],
381 'cssClassSuffix' => 'src-mw-newuserlog',
382 ],
383 ],
384 ],
385
386 [
387 'name' => 'legacyReviewStatus',
388 'title' => 'rcfilters-filtergroup-reviewstatus',
389 'class' => ChangesListBooleanFilterGroup::class,
390 'requireConfig' => [ 'useRCPatrol' => true ],
391 'filters' => [
392 [
393 'name' => 'hidepatrolled',
394 // rcshowhidepatr-show, rcshowhidepatr-hide
395 // wlshowhidepatr
396 'showHideSuffix' => 'showhidepatr',
397 'default' => false,
398 'action' => [ 'require', 'patrolled', RecentChange::PRC_UNPATROLLED ],
399 'isReplacedInStructuredUi' => true,
400 ],
401 [
402 'name' => 'hideunpatrolled',
403 'default' => false,
404 'action' => [ 'exclude', 'patrolled', RecentChange::PRC_UNPATROLLED ],
405 'isReplacedInStructuredUi' => true,
406 ],
407 ],
408 ],
409
410 [
411 'name' => 'reviewStatus',
412 'title' => 'rcfilters-filtergroup-reviewstatus',
413 'class' => ChangesListStringOptionsFilterGroup::class,
414 'isFullCoverage' => true,
415 'priority' => -5,
416 'requireConfig' => [ 'useRCPatrol' => true ],
417 'filters' => [
418 [
419 'name' => 'unpatrolled',
420 'label' => 'rcfilters-filter-reviewstatus-unpatrolled-label',
421 'description' => 'rcfilters-filter-reviewstatus-unpatrolled-description',
422 'cssClassSuffix' => 'reviewstatus-unpatrolled',
423 'action' => [ 'require', 'patrolled', RecentChange::PRC_UNPATROLLED ],
424 ],
425 [
426 'name' => 'manual',
427 'label' => 'rcfilters-filter-reviewstatus-manual-label',
428 'description' => 'rcfilters-filter-reviewstatus-manual-description',
429 'cssClassSuffix' => 'reviewstatus-manual',
430 'action' => [ 'require', 'patrolled', RecentChange::PRC_PATROLLED ],
431 ],
432 [
433 'name' => 'auto',
434 'label' => 'rcfilters-filter-reviewstatus-auto-label',
435 'description' => 'rcfilters-filter-reviewstatus-auto-description',
436 'cssClassSuffix' => 'reviewstatus-auto',
437 'action' => [ 'require', 'patrolled', RecentChange::PRC_AUTOPATROLLED ],
438 ],
439 ],
441 ],
442 ];
443 }
444
451 protected function getExtraFilterGroupDefinitions(): array {
452 return [];
453 }
454
458 public function execute( $subpage ) {
459 $this->rcSubpage = $subpage;
460
461 if ( $this->considerActionsForDefaultSavedQuery( $subpage ) ) {
462 // Don't bother rendering the page if we'll be performing a redirect (T330100).
463 return;
464 }
465
466 // Enable OOUI and module for the clock icon.
467 if ( $this->getConfig()->get( MainConfigNames::WatchlistExpiry ) && !$this->including() ) {
468 $this->getOutput()->enableOOUI();
469 $this->getOutput()->addModules( 'mediawiki.special.changeslist.watchlistexpiry' );
470 }
471
472 $opts = $this->getOptions();
473 try {
474 $result = $this->getQueryResult();
475 $rows = $result->getResultWrapper();
476
477 // Used by Structured UI app to get results without MW chrome
478 if ( $this->getRequest()->getRawVal( 'action' ) === 'render' ) {
479 $this->getOutput()->setArticleBodyOnly( true );
480 }
481
482 // Used by "live update" and "view newest" to check
483 // if there's new changes with minimal data transfer
484 if ( $this->getRequest()->getBool( 'peek' ) ) {
485 $code = $rows->numRows() > 0 ? 200 : 204;
486 $this->getOutput()->setStatusCode( $code );
487
488 if ( $this->getUser()->isAnon() !==
489 $this->getRequest()->getFuzzyBool( 'isAnon' )
490 ) {
491 $this->getOutput()->setStatusCode( 205 );
492 }
493
494 return;
495 }
496
497 $services = MediaWikiServices::getInstance();
498 $logFormatterFactory = $services->getLogFormatterFactory();
499 $linkBatchFactory = $services->getLinkBatchFactory();
500 $batch = $linkBatchFactory->newLinkBatch();
501 $userNames = [];
502 foreach ( $rows as $row ) {
503 $batch->addUser( new UserIdentityValue( $row->rc_user ?? 0, $row->rc_user_text ) );
504 $userNames[] = $row->rc_user_text;
505 $batch->add( $row->rc_namespace, $row->rc_title );
506 if ( $row->rc_source === RecentChange::SRC_LOG ) {
507 $formatter = $logFormatterFactory->newFromRow( $row );
508 foreach ( $formatter->getPreloadTitles() as $title ) {
509 $batch->addObj( $title );
510 if ( $title->inNamespace( NS_USER ) || $title->inNamespace( NS_USER_TALK ) ) {
511 $userNames[] = $title->getText();
512 }
513 }
514 }
515 }
516 $batch->execute();
517 foreach ( UserArray::newFromNames( $userNames ) as $_ ) {
518 // Trigger UserEditTracker::setCachedUserEditCount via User::loadFromRow
519 // Preloads edit count for User::getExperienceLevel() and Linker::userToolLinks()
520 }
521
522 $this->setHeaders();
523 $this->outputHeader();
524 $this->addModules();
525 $this->webOutput( $rows, $opts );
526 } catch ( DBQueryTimeoutError $timeoutException ) {
527 MWExceptionHandler::logException( $timeoutException );
528
529 $this->setHeaders();
530 $this->outputHeader();
531 $this->addModules();
532
533 $this->getOutput()->setStatusCode( 500 );
534 $this->webOutputHeader( 0, $opts );
535 $this->outputTimeout();
536 }
537
538 $this->includeRcFiltersApp();
539 }
540
548 public function setTempUserConfig( TempUserConfig $tempUserConfig ) {
549 $this->tempUserConfig = $tempUserConfig;
550 $this->changesListQueryFactory->setTempUserConfig( $tempUserConfig );
551 }
552
561 protected function considerActionsForDefaultSavedQuery( $subpage ) {
562 if ( !$this->isStructuredFilterUiEnabled() || $this->including() ) {
563 return false;
564 }
565
566 $knownParams = $this->getRequest()->getValues(
567 ...array_keys( $this->getOptions()->getAllValues() )
568 );
569
570 // HACK: Temporarily until we can properly define "sticky" filters and parameters,
571 // we need to exclude several parameters we know should not be counted towards preventing
572 // the loading of defaults.
573 $excludedParams = [ 'limit' => '', 'days' => '', 'enhanced' => '', 'from' => '' ];
574 $knownParams = array_diff_key( $knownParams, $excludedParams );
575
576 if (
577 // If there are NO known parameters in the URL request
578 // (that are not excluded) then we need to check into loading
579 // the default saved query
580 count( $knownParams ) === 0
581 ) {
583 ->getUserOptionsLookup()
584 ->getOption( $this->getUser(), $this->getSavedQueriesPreferenceName() );
585
586 // Get the saved queries data and parse it
587 $savedQueries = $prefJson ? FormatJson::decode( $prefJson, true ) : false;
588
589 if ( $savedQueries && isset( $savedQueries[ 'default' ] ) ) {
590 // Only load queries that are 'version' 2, since those
591 // have parameter representation
592 if ( isset( $savedQueries[ 'version' ] ) && $savedQueries[ 'version' ] === '2' ) {
593 $savedQueryDefaultID = $savedQueries[ 'default' ];
594 $defaultQuery = $savedQueries[ 'queries' ][ $savedQueryDefaultID ][ 'data' ];
595
596 // Build the entire parameter list
597 $query = array_merge(
598 $defaultQuery[ 'params' ],
599 $defaultQuery[ 'highlights' ],
600 [
601 'urlversion' => '2',
602 ]
603 );
604 // Add to the query any parameters that we may have ignored before
605 // but are still valid and requested in the URL
606 $query = array_merge( $this->getRequest()->getQueryValues(), $query );
607 unset( $query[ 'title' ] );
608 $this->getOutput()->redirect( $this->getPageTitle( $subpage )->getCanonicalURL( $query ) );
609
610 // Signal that we only need to redirect to the full URL
611 // and can skip rendering the actual page (T330100).
612 return true;
613 } else {
614 // There's a default, but the version is not 2, and the server can't
615 // actually recognize the query itself. This happens if it is before
616 // the conversion, so we need to tell the UI to reload saved query as
617 // it does the conversion to version 2
618 $this->getOutput()->addJsConfigVars(
619 'wgStructuredChangeFiltersDefaultSavedQueryExists',
620 true
621 );
622
623 // Add the class that tells the frontend it is still loading
624 // another query
625 $this->getOutput()->addBodyClasses( 'mw-rcfilters-ui-loading' );
626 }
627 }
628 }
629
630 return false;
631 }
632
637 protected function getLinkDays() {
638 $linkDays = $this->getConfig()->get( MainConfigNames::RCLinkDays );
639 $filterByAge = $this->getConfig()->get( MainConfigNames::RCFilterByAge );
640 $maxAge = $this->getConfig()->get( MainConfigNames::RCMaxAge );
641 if ( $filterByAge ) {
642 // Trim it to only links which are within $wgRCMaxAge.
643 // Note that we allow one link higher than the max for things like
644 // "age 56 days" being accessible through the "60 days" link.
645 sort( $linkDays );
646
647 $maxAgeDays = $maxAge / ( 3600 * 24 );
648 foreach ( $linkDays as $i => $days ) {
649 if ( $days >= $maxAgeDays ) {
650 array_splice( $linkDays, $i + 1 );
651 break;
652 }
653 }
654 }
655
656 return $linkDays;
657 }
658
665 protected function includeRcFiltersApp() {
666 $out = $this->getOutput();
667 if ( $this->isStructuredFilterUiEnabled() && !$this->including() ) {
668 $jsData = $this->filterGroups->getJsData();
669 $messages = [];
670 foreach ( $jsData['messageKeys'] as $key ) {
671 $messages[$key] = $this->msg( $key )->plain();
672 }
673
674 $out->addBodyClasses( 'mw-rcfilters-enabled' );
675 $collapsed = MediaWikiServices::getInstance()->getUserOptionsLookup()
676 ->getBoolOption( $this->getUser(), $this->getCollapsedPreferenceName() );
677 if ( $collapsed ) {
678 $out->addBodyClasses( 'mw-rcfilters-collapsed' );
679 }
680
681 // These config and message exports should be moved into a ResourceLoader data module (T201574)
682 $out->addJsConfigVars( 'wgStructuredChangeFilters', $jsData['groups'] );
683 $out->addJsConfigVars( 'wgStructuredChangeFiltersMessages', $messages );
684 $out->addJsConfigVars( 'wgStructuredChangeFiltersCollapsedState', $collapsed );
685 $restrictedTags = $this->getViewableRestrictedChangeTags();
686 if ( $restrictedTags ) {
687 $out->addJsConfigVars( 'wgStructuredChangeFiltersRestrictedTags', $restrictedTags );
688 }
689
690 $out->addJsConfigVars(
691 'StructuredChangeFiltersDisplayConfig',
692 [
693 'maxDays' => // Translate to days
694 (int)$this->getConfig()->get( MainConfigNames::RCMaxAge ) / ( 24 * 3600 ),
695 'limitArray' => $this->getConfig()->get( MainConfigNames::RCLinkLimits ),
696 'limitDefault' => $this->getDefaultLimit(),
697 'daysArray' => $this->getLinkDays(),
698 'daysDefault' => $this->getDefaultDays(),
699 ]
700 );
701
702 $out->addJsConfigVars(
703 'wgStructuredChangeFiltersSavedQueriesPreferenceName',
704 $this->getSavedQueriesPreferenceName()
705 );
706 $out->addJsConfigVars(
707 'wgStructuredChangeFiltersLimitPreferenceName',
708 $this->getLimitPreferenceName()
709 );
710 $out->addJsConfigVars(
711 'wgStructuredChangeFiltersDaysPreferenceName',
712 $this->getDefaultDaysPreferenceName()
713 );
714 $out->addJsConfigVars(
715 'wgStructuredChangeFiltersCollapsedPreferenceName',
716 $this->getCollapsedPreferenceName()
717 );
718 } else {
719 $out->addBodyClasses( 'mw-rcfilters-disabled' );
720 }
721 }
722
728 private function getViewableRestrictedChangeTags(): array {
729 $services = MediaWikiServices::getInstance();
730 $changeTagsFormatter = $services->getChangeTagsFormatter();
731 $changeTagsStore = $services->getChangeTagsStore();
732
733 // First check if the user can see any restricted tags using the less expensive ::getChangeTagListSummary
734 $changeTagsSummary = $changeTagsFormatter->getChangeTagListSummary(
735 $this->getContext(),
736 $this->getAuthority()
737 );
738 $restrictedTagNames = array_fill_keys(
739 array_filter(
740 array_column( $changeTagsSummary, 'name' ),
741 static fn ( string $tagName ) => $changeTagsStore->isRestrictedTag( $tagName )
742 ),
743 true
744 );
745 if ( !$restrictedTagNames ) {
746 return [];
747 }
748
749 // Now call the more expensive ::getChangeTagList to get the list for the frontend
750 return array_values( array_filter(
751 $changeTagsFormatter->getChangeTagList( $this->getContext(), $this->getAuthority() ),
752 static fn ( array $tagInfo ) => isset( $restrictedTagNames[$tagInfo['name']] )
753 ) );
754 }
755
762 public static function getRcFiltersConfigSummary( RL\Context $context ): array {
763 $services = MediaWikiServices::getInstance();
764 return [
765 // Reduce version computation by avoiding Message parsing
766 'RCFiltersChangeTags' => $services->getChangeTagsFormatter()->getChangeTagListSummary(
767 $context,
768 self::getAuthorityForPublicChangeTags()
769 ),
770 'StructuredChangeFiltersEditWatchlistUrl' =>
771 SpecialPage::getTitleFor( 'EditWatchlist' )->getLocalURL()
772 ];
773 }
774
782 public static function getRcFiltersConfigVars( RL\Context $context ): array {
783 $services = MediaWikiServices::getInstance();
784 return [
785 'RCFiltersChangeTags' => $services->getChangeTagsFormatter()->getChangeTagList(
786 $context,
787 self::getAuthorityForPublicChangeTags()
788 ),
789 'StructuredChangeFiltersEditWatchlistUrl' =>
790 SpecialPage::getTitleFor( 'EditWatchlist' )->getLocalURL()
791 ];
792 }
793
798 private static function getAuthorityForPublicChangeTags(): Authority {
799 return new SimpleAuthority( UserIdentityValue::newAnonymous( '127.0.0.1' ), [] );
800 }
801
805 protected function outputNoResults() {
806 $this->getOutput()->addHTML(
807 Html::rawElement(
808 'div',
809 [ 'class' => 'mw-changeslist-empty' ],
810 $this->msg( 'recentchanges-noresult' )->parse()
811 )
812 );
813 }
814
818 protected function outputTimeout() {
819 $this->getOutput()->addHTML(
820 '<div class="mw-changeslist-empty mw-changeslist-timeout">' .
821 $this->msg( 'recentchanges-timeout' )->parse() .
822 '</div>'
823 );
824 }
825
831 public function getRows() {
832 return $this->getQueryResult()->getResultWrapper();
833 }
834
840 protected function getQueryResult(): ChangesListResult {
841 if ( !$this->queryResult ) {
842 $opts = $this->getOptions();
843 $query = $this->buildQuery( $opts );
844 $this->modifyQuery( $query, $opts );
845 $this->queryResult = $query->fetchResult();
846
847 if ( $this->mainQueryHookRegistered && !$this->mainQueryHookCalled ) {
848 // When an empty result set is forced, ChangesListQuery doesn't run
849 // the hook, but some extensions need us to run it anyway to register
850 // form options.
851 // FIXME: risky to pass empty arrays here, and inefficient to
852 // call this hook when most of what it does is not needed.
853 // We need to deprecate it.
854 $tables = $fields = $conds = $options = $joins = [];
855 $this->runMainQueryHook( $tables, $fields, $conds, $options,
856 $joins, $opts );
857 }
858 }
859 return $this->queryResult;
860 }
861
869 protected function newRecentChangeFromRow( $row ) {
870 $rc = $this->recentChangeFactory->newRecentChangeFromRow( $row );
871 $rc->setHighlights( $this->getQueryResult()->getHighlightsFromRow( $row ) );
872 return $rc;
873 }
874
880 public function getOptions() {
881 if ( $this->rcOptions === null ) {
882 $this->rcOptions = $this->setup( $this->rcSubpage );
883 }
884
885 return $this->rcOptions;
886 }
887
895 private function getBaseFilterFactoryConfig() {
896 return [
897 'showHidePrefix' => '',
898 'isRegistrationRequiredToEdit' => !MediaWikiServices::getInstance()
899 ->getPermissionManager()
900 ->isEveryoneAllowed( "edit" ),
901 'useRCPatrol' => !$this->including() && $this->getUser()->useRCPatrol(),
902 'RCWatchCategoryMembership' =>
903 $this->getConfig()->get( MainConfigNames::RCWatchCategoryMembership ),
904 ];
905 }
906
912 protected function getExtraFilterFactoryConfig(): array {
913 return [];
914 }
915
922 protected function getFilterDefaultOverrides(): array {
923 return [];
924 }
925
928 $this->getExtraFilterFactoryConfig() + $this->getBaseFilterFactoryConfig()
929 );
930 }
931
936 protected function registerFilters() {
937 $filterFactory = $this->getFilterFactory();
938 $filterFactory->registerFiltersFromDefinitions(
939 $this->filterGroups,
940 $this->getBaseFilterGroupDefinitions()
941 );
942 $filterFactory->registerFiltersFromDefinitions(
943 $this->filterGroups,
944 $this->getExtraFilterGroupDefinitions()
945 );
946 $this->getHookRunner()->onChangesListSpecialPageStructuredFilters( $this );
947 $this->filterGroups->setDefaults( $this->getFilterDefaultOverrides() );
948 }
949
960 protected function registerFiltersFromDefinitions( array $definition ) {
961 $this->getFilterFactory()->registerFiltersFromDefinitions( $this->filterGroups, $definition );
962 }
963
972 public function setup( $parameters ) {
973 $this->registerFilters();
974
975 $opts = $this->getDefaultOptions();
976
977 $opts = $this->fetchOptionsFromRequest( $opts );
978
979 // Give precedence to subpage syntax
980 if ( $parameters !== null ) {
981 $this->parseParameters( $parameters, $opts );
982 }
983
984 $this->validateOptions( $opts );
985
986 return $opts;
987 }
988
998 public function getDefaultOptions() {
999 $opts = new FormOptions();
1000 $structuredUI = $this->isStructuredFilterUiEnabled();
1001 // If urlversion=2 is set, ignore the filter defaults and set them all to false/empty
1002 $useDefaults = $this->getRequest()->getInt( 'urlversion' ) !== 2;
1003
1004 $this->filterGroups->addOptions( $opts, $useDefaults, $structuredUI );
1005
1006 $opts->add( 'namespace', '', FormOptions::STRING );
1007 $opts->add( 'subpageof', '', FormOptions::STRING );
1008 // TODO: Rename this option to 'invertnamespaces'?
1009 $opts->add( 'invert', false );
1010 $opts->add( 'associated', false );
1011 $opts->add( 'urlversion', 1 );
1012 $opts->add( 'tagfilter', '' );
1013 $opts->add( 'inverttags', false );
1014
1015 $opts->add( 'days', $this->getDefaultDays(), FormOptions::FLOAT );
1016 $opts->add( 'limit', $this->getDefaultLimit(), FormOptions::INT );
1017
1018 $opts->add( 'from', '' );
1019
1020 return $opts;
1021 }
1022
1027 $this->filterGroups->registerGroup( $group );
1028 }
1029
1039 public function getFilterGroup( $groupName ) {
1040 return $this->filterGroups->getGroup( $groupName );
1041 }
1042
1051 protected function getStructuredFilterJsData() {
1052 return $this->filterGroups->getJsData();
1053 }
1054
1063 protected function fetchOptionsFromRequest( $opts ) {
1064 $opts->fetchValuesFromRequest( $this->getRequest() );
1065
1066 return $opts;
1067 }
1068
1077 public function parseParameters( $par, FormOptions $opts ) {
1078 $params = $this->filterGroups->getSubpageParams();
1079
1080 $bits = preg_split( '/\s*,\s*/', trim( $par ) );
1081 foreach ( $bits as $bit ) {
1082 $m = [];
1083 if ( ( $params[$bit] ?? '' ) === 'bool' ) {
1084 // hidefoo => hidefoo=true
1085 $opts[$bit] = true;
1086 } elseif ( ( $params["hide$bit"] ?? '' ) === 'bool' ) {
1087 // foo => hidefoo=false
1088 $opts["hide$bit"] = false;
1089 } elseif ( preg_match( '/^(.*)=(.*)$/', $bit, $m ) ) {
1090 if ( ( $params[$m[1]] ?? '' ) === 'string' ) {
1091 $opts[$m[1]] = $m[2];
1092 }
1093 }
1094 }
1095 }
1096
1100 public function validateOptions( FormOptions $opts ) {
1101 $isContradictory = $this->fixContradictoryOptions( $opts );
1102 $isReplaced = $this->replaceOldOptions( $opts );
1103
1104 if ( $isContradictory || $isReplaced ) {
1105 $query = wfArrayToCgi( $this->convertParamsForLink( $opts->getChangedValues() ) );
1106 $this->getOutput()->redirect( $this->getPageTitle()->getCanonicalURL( $query ) );
1107 }
1108
1109 $opts->validateIntBounds( 'limit', 0, 5000 );
1110 $opts->validateBounds( 'days', 0,
1111 $this->getConfig()->get( MainConfigNames::RCMaxAge ) / ( 3600 * 24 ) );
1112 }
1113
1120 private function fixContradictoryOptions( FormOptions $opts ) {
1121 $fixed = $this->fixBackwardsCompatibilityOptions( $opts );
1122 $fixed = $this->filterGroups->fixContradictoryOptions( $opts ) || $fixed;
1123
1124 // Namespace conflicts with subpageof
1125 if ( $opts['namespace'] !== '' && $opts['subpageof'] !== '' ) {
1126 $opts['namespace'] = '';
1127 $fixed = true;
1128 }
1129
1130 return $fixed;
1131 }
1132
1142 private function fixBackwardsCompatibilityOptions( FormOptions $opts ) {
1143 if ( $opts['hideanons'] && $opts['hideliu'] ) {
1144 $opts->reset( 'hideanons' );
1145 if ( !$opts['hidebots'] ) {
1146 $opts->reset( 'hideliu' );
1147 $opts['hidehumans'] = 1;
1148 }
1149
1150 return true;
1151 }
1152
1153 return false;
1154 }
1155
1162 public function replaceOldOptions( FormOptions $opts ) {
1163 if ( !$this->isStructuredFilterUiEnabled() ) {
1164 return false;
1165 }
1166
1167 $changed = false;
1168
1169 // At this point 'hideanons' and 'hideliu' cannot be both true,
1170 // because fixBackwardsCompatibilityOptions resets (at least) 'hideanons' in such case
1171 if ( $opts[ 'hideanons' ] ) {
1172 $opts->reset( 'hideanons' );
1173 $opts[ 'userExpLevel' ] = 'registered';
1174 $changed = true;
1175 }
1176
1177 if ( $opts[ 'hideliu' ] ) {
1178 $opts->reset( 'hideliu' );
1179 $opts[ 'userExpLevel' ] = 'unregistered';
1180 $changed = true;
1181 }
1182
1183 if ( $this->filterGroups->hasGroup( 'legacyReviewStatus' ) ) {
1184 if ( $opts[ 'hidepatrolled' ] ) {
1185 $opts->reset( 'hidepatrolled' );
1186 $opts[ 'reviewStatus' ] = 'unpatrolled';
1187 $changed = true;
1188 }
1189
1190 if ( $opts[ 'hideunpatrolled' ] ) {
1191 $opts->reset( 'hideunpatrolled' );
1192 $opts[ 'reviewStatus' ] = implode(
1193 ChangesListStringOptionsFilterGroup::SEPARATOR,
1194 [ 'manual', 'auto' ]
1195 );
1196 $changed = true;
1197 }
1198 }
1199
1200 return $changed;
1201 }
1202
1211 protected function convertParamsForLink( $params ) {
1212 foreach ( $params as &$value ) {
1213 if ( $value === false ) {
1214 $value = '0';
1215 }
1216 }
1217 unset( $value );
1218 return $params;
1219 }
1220
1228 protected function buildQuery( FormOptions $opts ) {
1229 $dbr = $this->getDB();
1230 $isStructuredUI = $this->isStructuredFilterUiEnabled();
1231
1232 $query = $this->changesListQueryFactory->newQuery()
1233 ->recentChangeFields()
1234 ->watchlistUser( $this->getUser() )
1235 ->audience( $this->getAuthority() )
1236 ->excludeDeletedLogAction()
1237 ->limit( $opts['limit'] )
1238 ->maxExecutionTime( $this->getConfig()->get(
1239 MainConfigNames::MaxExecutionTimeForExpensiveQueries ) )
1240 ->caller( static::class . '::buildQuery' );
1241
1242 // Main query hook
1243 $this->addMainQueryHook( $query, $opts );
1244
1245 // Old filter groups interface
1246 $query->legacyMutator(
1247 function (
1248 &$tables,
1249 &$fields,
1250 &$conds,
1251 &$query_options,
1252 &$join_conds,
1253 ) use ( $dbr, $opts, $isStructuredUI ) {
1254 $this->filterGroups->modifyLegacyQuery(
1255 $dbr,
1256 $this,
1257 $tables,
1258 $fields,
1259 $conds,
1260 $query_options,
1261 $join_conds,
1262 $opts,
1263 $isStructuredUI
1264 );
1265 }
1266 );
1267
1268 // New filter groups interface
1269 $this->filterGroups->modifyChangesListQuery( $query, $opts, $isStructuredUI );
1270
1271 // Namespace filtering
1272 if ( $opts[ 'namespace' ] !== '' ) {
1273 $namespaces = explode( ';', $opts[ 'namespace' ] );
1274 $namespaces = $this->expandSymbolicNamespaceFilters( $namespaces );
1275 if ( $namespaces !== [] ) {
1276 if ( $opts[ 'associated' ] ) {
1277 $namespaceInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
1278 $associatedNamespaces = array_map(
1279 $namespaceInfo->getAssociated( ... ),
1280 array_filter( $namespaces, $namespaceInfo->hasTalkNamespace( ... ) )
1281 );
1282 $namespaces = array_unique( array_merge( $namespaces, $associatedNamespaces ) );
1283 }
1284
1285 if ( $opts['invert'] ) {
1286 $query->excludeNamespaces( $namespaces );
1287 } else {
1288 $query->requireNamespaces( $namespaces );
1289 }
1290 }
1291 }
1292
1293 // Filtering for subpages of a given set of pages
1294 if ( $opts['subpageof'] !== '' ) {
1295 $titleParser = MediaWikiServices::getInstance()->getTitleParser();
1296 $basePages = explode( '|', $opts['subpageof'] );
1297 foreach ( $basePages as $basePageText ) {
1298 // Strip any trailing slash
1299 $basePageText = rtrim( $basePageText, '/' );
1300 try {
1301 $basePage = $titleParser->parseTitle( $basePageText );
1302 } catch ( MalformedTitleException ) {
1303 // Ignore invalid titles
1304 continue;
1305 }
1306 $query->requireSubpageOf( $basePage );
1307 }
1308 }
1309
1310 // Change tags
1311 if ( $this->getConfig()->get( MainConfigNames::UseTagFilter ) ) {
1312 $tagFilter = $opts['tagfilter'] !== '' ? explode( '|', $opts['tagfilter'] ) : [];
1313 if ( $opts['inverttags'] ) {
1314 $query->excludeChangeTags( $tagFilter );
1315 } else {
1316 $query->requireChangeTags( $tagFilter );
1317 }
1318 }
1319 $query->addChangeTagSummaryField();
1320
1321 // Calculate cutoff
1322 $cutoff_unixtime = ConvertibleTimestamp::time() - $opts['days'] * 3600 * 24;
1323 $cutoff = $dbr->timestamp( $cutoff_unixtime );
1324
1325 $fromValid = preg_match( '/^[0-9]{14}$/', $opts['from'] );
1326 if ( $fromValid && $opts['from'] > wfTimestamp( TS::MW, $cutoff ) ) {
1327 $cutoff = $dbr->timestamp( $opts['from'] );
1328 } else {
1329 $opts->reset( 'from' );
1330 }
1331
1332 $query->minTimestamp( $cutoff );
1333
1334 // Feature flag
1335 if ( $this->getRequest()->getBool( 'enable_partitioning' ) ) {
1336 $query->enablePartitioning();
1337 }
1338 return $query;
1339 }
1340
1347 protected function modifyQuery( ChangesListQuery $query, FormOptions $opts ) {
1348 }
1349
1359 protected function runMainQueryHook( &$tables, &$fields, &$conds,
1360 &$query_options, &$join_conds, $opts
1361 ) {
1362 return $this->getHookRunner()->onChangesListSpecialPageQuery(
1363 $this->getName(), $tables, $fields, $conds, $query_options, $join_conds, $opts );
1364 }
1365
1370 protected function addMainQueryHook( $query, $opts ) {
1371 if ( $this->getHookContainer()->isRegistered( 'ChangesListSpecialPageQuery' ) ) {
1372 $this->mainQueryHookRegistered = true;
1373 $query->legacyMutator(
1374 function ( &$tables, &$fields, &$conds, &$query_options, &$join_conds )
1375 use ( $opts ) {
1376 $this->mainQueryHookCalled = true;
1377 return $this->runMainQueryHook( $tables, $fields, $conds,
1378 $query_options, $join_conds, $opts );
1379 }
1380 );
1381 }
1382 }
1383
1387 protected function getDB(): IReadableDatabase {
1388 return MediaWikiServices::getInstance()->getConnectionProvider()->getReplicaDatabase();
1389 }
1390
1397 private function webOutputHeader( $rowCount, $opts ) {
1398 if ( !$this->including() ) {
1399 $this->outputFeedLinks();
1400 $this->doHeader( $opts, $rowCount );
1401 }
1402 }
1403
1410 public function webOutput( $rows, $opts ) {
1411 $this->webOutputHeader( $rows->numRows(), $opts );
1412
1413 $this->outputChangesList( $rows, $opts );
1414 }
1415
1416 public function outputFeedLinks() {
1417 // nothing by default
1418 }
1419
1426 abstract public function outputChangesList( $rows, $opts );
1427
1434 public function doHeader( $opts, $numRows ) {
1435 $this->setTopText( $opts );
1436
1437 // @todo Lots of stuff should be done here.
1438
1439 $this->setBottomText( $opts );
1440 }
1441
1447 public function setTopText( FormOptions $opts ) {
1448 // nothing by default
1449 }
1450
1456 public function setBottomText( FormOptions $opts ) {
1457 // nothing by default
1458 }
1459
1469 public function getExtraOptions( $opts ) {
1470 return [];
1471 }
1472
1478 public function makeLegend() {
1479 $context = $this->getContext();
1480 $user = $context->getUser();
1481 # The legend showing what the letters and stuff mean
1482 $legend = Html::openElement( 'dl' ) . "\n";
1483 # Iterates through them and gets the messages for both letter and tooltip
1484 $legendItems = $context->getConfig()->get( MainConfigNames::RecentChangesFlags );
1485 if ( !( $user->useRCPatrol() || $user->useNPPatrol() ) ) {
1486 unset( $legendItems['unpatrolled'] );
1487 }
1488 foreach ( $legendItems as $key => $item ) { # generate items of the legend
1489 $label = $item['legend'] ?? $item['title'];
1490 $letter = $item['letter'];
1491 $cssClass = $item['class'] ?? $key;
1492
1493 $legend .= Html::element( 'dt',
1494 [ 'class' => $cssClass ], $context->msg( $letter )->text()
1495 ) . "\n" .
1496 Html::rawElement( 'dd',
1497 [ 'class' => Sanitizer::escapeClass( 'mw-changeslist-legend-' . $key ) ],
1498 $context->msg( $label )->parse()
1499 ) . "\n";
1500 }
1501 # (+-123)
1502 $legend .= Html::rawElement( 'dt',
1503 [ 'class' => 'mw-plusminus-pos' ],
1504 $context->msg( 'recentchanges-legend-plusminus' )->parse()
1505 ) . "\n";
1506 $legend .= Html::element(
1507 'dd',
1508 [ 'class' => 'mw-changeslist-legend-plusminus' ],
1509 $context->msg( 'recentchanges-label-plusminus' )->text()
1510 ) . "\n";
1511 // Watchlist expiry clock icon.
1512 if ( $context->getConfig()->get( MainConfigNames::WatchlistExpiry ) && !$this->including() ) {
1513 $widget = new IconWidget( [
1514 'icon' => 'clock',
1515 'classes' => [ 'mw-changesList-watchlistExpiry' ],
1516 ] );
1517 // Link the image to its label for assistive technologies.
1518 $watchlistLabelId = 'mw-changeslist-watchlistExpiry-label';
1519 $widget->getIconElement()->setAttributes( [
1520 'role' => 'img',
1521 'aria-labelledby' => $watchlistLabelId,
1522 ] );
1523 $legend .= Html::rawElement(
1524 'dt',
1525 [ 'class' => 'mw-changeslist-legend-watchlistexpiry' ],
1526 $widget->toString()
1527 );
1528 $legend .= Html::element(
1529 'dd',
1530 [ 'class' => 'mw-changeslist-legend-watchlistexpiry', 'id' => $watchlistLabelId ],
1531 $context->msg( 'recentchanges-legend-watchlistexpiry' )->text()
1532 );
1533 }
1534 $legend .= Html::closeElement( 'dl' ) . "\n";
1535
1536 $legendHeading = $this->isStructuredFilterUiEnabled() ?
1537 $context->msg( 'rcfilters-legend-heading' )->parse() :
1538 $context->msg( 'recentchanges-legend-heading' )->parse();
1539
1540 # Collapsible
1541 $collapsedState = $this->getRequest()->getCookie( 'changeslist-state' );
1542
1543 $legend = Html::rawElement( 'details', [
1544 'class' => 'mw-changeslist-legend',
1545 'open' => $collapsedState !== 'collapsed' ? 'open' : null,
1546 ],
1547 Html::rawElement( 'summary', [], $legendHeading ) .
1548 $legend
1549 );
1550
1551 return $legend;
1552 }
1553
1557 protected function addModules() {
1558 $out = $this->getOutput();
1559 // Styles and behavior for the legend box (see makeLegend())
1560 $out->addModuleStyles( [
1561 'mediawiki.interface.helpers.styles',
1562 'mediawiki.special.changeslist.legend',
1563 'mediawiki.special.changeslist',
1564 ] );
1565 $out->addModules( 'mediawiki.special.changeslist.legend.js' );
1566
1567 if ( $this->isStructuredFilterUiEnabled() && !$this->including() ) {
1568 $out->addModules( 'mediawiki.rcfilters.filters.ui' );
1569 $out->addModuleStyles( 'mediawiki.rcfilters.filters.base.styles' );
1570 }
1571 }
1572
1574 protected function getGroupName() {
1575 return 'changes';
1576 }
1577
1584 if ( $this->getRequest()->getBool( 'rcfilters' ) ) {
1585 return true;
1586 }
1587
1588 return static::checkStructuredFilterUiEnabled( $this->getUser() );
1589 }
1590
1598 public static function checkStructuredFilterUiEnabled( UserIdentity $user ) {
1599 return !MediaWikiServices::getInstance()
1600 ->getUserOptionsLookup()
1601 ->getOption( $user, 'rcenhancedfilters-disable' );
1602 }
1603
1611 public function getDefaultLimit() {
1612 return MediaWikiServices::getInstance()
1613 ->getUserOptionsLookup()
1614 ->getIntOption( $this->getUser(), $this->getLimitPreferenceName() );
1615 }
1616
1625 public function getDefaultDays() {
1626 return floatval( MediaWikiServices::getInstance()
1627 ->getUserOptionsLookup()
1628 ->getOption( $this->getUser(), $this->getDefaultDaysPreferenceName() ) );
1629 }
1630
1637 abstract protected function getLimitPreferenceName(): string;
1638
1645 abstract protected function getSavedQueriesPreferenceName(): string;
1646
1653 abstract protected function getDefaultDaysPreferenceName(): string;
1654
1661 abstract protected function getCollapsedPreferenceName(): string;
1662
1667 private function expandSymbolicNamespaceFilters( array $inputs ): array {
1668 $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
1669 $namespaces = [];
1670 foreach ( $inputs as $input ) {
1671 if ( $input === 'all-contents' ) {
1672 array_push( $namespaces, ...$nsInfo->getSubjectNamespaces() );
1673 } elseif ( $input === 'all-discussions' ) {
1674 array_push( $namespaces, ...$nsInfo->getTalkNamespaces() );
1675 } elseif ( is_numeric( $input ) && $nsInfo->exists( (int)$input ) ) {
1676 $namespaces[] = (int)$input;
1677 }
1678 }
1679 return array_unique( $namespaces );
1680 }
1681}
1682
1683// @codeCoverageIgnoreStart
1685class_alias( ChangesListSpecialPage::class, 'ChangesListSpecialPage' );
1686// @codeCoverageIgnoreEnd
const NS_USER
Definition Defines.php:53
const NS_USER_TALK
Definition Defines.php:54
wfTimestamp( $outputtype=TS::UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:71
Handler class for MWExceptions.
Helper class to keep track of options when mixing links and form elements.
getChangedValues()
Return options modified as an array ( name => value )
validateIntBounds( $name, $min, $max)
validateBounds( $name, $min, $max)
Constrain a numeric value for a given option to a given range.
reset( $name)
Delete the option value.
This class is a collection of static functions that serve two purposes:
Definition Html.php:44
JSON formatter wrapper class.
A class containing constants representing the names of configuration variables.
const RCMaxAge
Name constant for the RCMaxAge setting, for use with Config::get()
const WatchlistExpiry
Name constant for the WatchlistExpiry setting, for use with Config::get()
const RCFilterByAge
Name constant for the RCFilterByAge setting, for use with Config::get()
const RCLinkLimits
Name constant for the RCLinkLimits setting, for use with Config::get()
const RCLinkDays
Name constant for the RCLinkDays setting, for use with Config::get()
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
HTML sanitizer for MediaWiki.
Definition Sanitizer.php:34
Represents an authority that has a specific set of permissions which are specified explicitly.
If the group is active, any unchecked filters will translate to hide parameters in the URL.
Represents a filter group (used on ChangesListSpecialPage and descendants)
Use via MediaWikiServices::getChangesListQueryFactory.
Build and execute a query on the recentchanges table with optional joins and conditions.
const NONE
Signifies that no options in the group are selected, meaning the group has no effect.
Utility class for creating and reading rows in the recentchanges table.
Special page which uses a ChangesList to show query results.
getDB()
Which database to use for read queries.
getDefaultOptions()
Get a FormOptions object containing the default options.
getFilterDefaultOverrides()
Subclasses may override this to provide an array of filter group defaults, overriding the defaults in...
getExtraFilterFactoryConfig()
Subclasses may override this to add configuration to the filter factory.
getSavedQueriesPreferenceName()
Preference name for saved queries.
parseParameters( $par, FormOptions $opts)
Process $par and put options found in $opts.
setTempUserConfig(TempUserConfig $tempUserConfig)
Set the temp user config.
outputNoResults()
Add the "no results" message to the output.
doHeader( $opts, $numRows)
Set the text to be displayed above the changes.
newRecentChangeFromRow( $row)
Create a RecentChange object from a row, injecting highlights from the current ChangesListQuery.
considerActionsForDefaultSavedQuery( $subpage)
Check whether or not the page should load defaults, and if so, whether a default saved query is relev...
makeLegend()
Return the legend displayed within the fieldset.
__construct( $name, protected readonly UserIdentityUtils $userIdentityUtils, protected TempUserConfig $tempUserConfig, protected readonly RecentChangeFactory $recentChangeFactory, protected readonly ChangesListQueryFactory $changesListQueryFactory,)
getRows()
Get the database result for this special page instance.
buildQuery(FormOptions $opts)
Sets appropriate tables, fields, conditions, etc.
outputChangesList( $rows, $opts)
Build and output the actual changes list.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
getFilterGroup( $groupName)
Gets a specified ChangesListFilterGroup by name.
getExtraOptions( $opts)
Get options to be displayed in a form.
runMainQueryHook(&$tables, &$fields, &$conds, &$query_options, &$join_conds, $opts)
fetchOptionsFromRequest( $opts)
Fetch values for a FormOptions object from the WebRequest associated with this instance.
modifyQuery(ChangesListQuery $query, FormOptions $opts)
Allow subclasses to modify the main query.
static getRcFiltersConfigVars(RL\Context $context)
Get config vars to export with the mediawiki.rcfilters.filters.ui module.
isStructuredFilterUiEnabled()
Check whether the structured filter UI is enabled.
getLimitPreferenceName()
Getting the preference name for 'limit'.
setup( $parameters)
Register all the filters, including legacy hook-driven ones.
setTopText(FormOptions $opts)
Send the text to be displayed before the options.
includeRcFiltersApp()
Include the modules and configuration for the RCFilters app.
getDefaultLimit()
Get the default value of the number of changes to display when loading the result set.
getDefaultDays()
Get the default value of the number of days to display when loading the result set.
registerFilters()
Register all filters and their groups (including those from hooks), plus handle conflicts and default...
replaceOldOptions(FormOptions $opts)
Replace old options with their structured UI equivalents.
convertParamsForLink( $params)
Convert parameters values from true/false to 1/0 so they are not omitted by wfArrayToCgi() T38524.
getExtraFilterGroupDefinitions()
This may be overridden by subclasses to add more filter groups.
getOptions()
Get the current FormOptions for this request.
getStructuredFilterJsData()
Gets structured filter information needed by JS.
getDefaultDaysPreferenceName()
Preference name for 'days'.
getQueryResult()
Perform and cache the main query.
getCollapsedPreferenceName()
Preference name for collapsing the active filter display.
static getRcFiltersConfigSummary(RL\Context $context)
Get essential data about self::getRcFiltersConfigVars() for change detection.
webOutput( $rows, $opts)
Send output to the OutputPage object, only called if not used feeds.
validateOptions(FormOptions $opts)
Validate a FormOptions object generated by getDefaultOptions() with values already populated.
registerFiltersFromDefinitions(array $definition)
Register filters from a definition object.
setBottomText(FormOptions $opts)
Send the text to be displayed after the options.
registerFilterGroup(ChangesListFilterGroup $group)
Register a structured changes list filter group.
outputTimeout()
Add the "timeout" message to the output.
static checkStructuredFilterUiEnabled(UserIdentity $user)
Static method to check whether StructuredFilter UI is enabled for the given user.
Parent class for all special pages.
getUser()
Shortcut to get the User executing this instance.
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
Class to walk into a list of User objects.
Definition UserArray.php:19
Convenience functions for interpreting UserIdentity objects using additional services or config.
Value object representing a user's identity.
Error thrown when a query times out.
return[ 'config-schema-inverse'=>['default'=>['ConfigRegistry'=>['main'=> 'MediaWiki\\Config\\GlobalVarConfig::newInstance',], 'Sitename'=> 'MediaWiki', 'Server'=> false, 'CanonicalServer'=> false, 'ServerName'=> false, 'AssumeProxiesUseDefaultProtocolPorts'=> true, 'HttpsPort'=> 443, 'ForceHTTPS'=> false, 'ScriptPath'=> '/wiki', 'UsePathInfo'=> null, 'Script'=> false, 'LoadScript'=> false, 'RestPath'=> false, 'StylePath'=> false, 'LocalStylePath'=> false, 'ExtensionAssetsPath'=> false, 'ExtensionDirectory'=> null, 'StyleDirectory'=> null, 'ArticlePath'=> false, 'UploadPath'=> false, 'ImgAuthPath'=> false, 'ThumbPath'=> false, 'UploadDirectory'=> false, 'FileCacheDirectory'=> false, 'Logo'=> false, 'Logos'=> false, 'Favicon'=> '/favicon.ico', 'AppleTouchIcon'=> false, 'ReferrerPolicy'=> false, 'TmpDirectory'=> false, 'UploadBaseUrl'=> '', 'UploadStashScalerBaseUrl'=> false, 'ActionPaths'=>[], 'MainPageIsDomainRoot'=> false, 'EnableUploads'=> false, 'UploadStashMaxAge'=> 21600, 'EnableAsyncUploads'=> false, 'EnableAsyncUploadsByURL'=> false, 'EnableChunkedUploads'=> false, 'UploadMaintenance'=> false, 'IllegalFileChars'=> ':\\/\\\\', 'DeletedDirectory'=> false, 'ImgAuthDetails'=> false, 'ImgAuthUrlPathMap'=>[], 'LocalFileRepo'=>['class'=> 'MediaWiki\\FileRepo\\LocalRepo', 'name'=> 'local', 'directory'=> null, 'scriptDirUrl'=> null, 'favicon'=> null, 'url'=> null, 'hashLevels'=> null, 'thumbScriptUrl'=> null, 'transformVia404'=> null, 'deletedDir'=> null, 'deletedHashLevels'=> null, 'updateCompatibleMetadata'=> null, 'reserializeMetadata'=> null,], 'ForeignFileRepos'=>[], 'UseInstantCommons'=> false, 'UseSharedUploads'=> false, 'SharedUploadDirectory'=> null, 'SharedUploadPath'=> null, 'HashedSharedUploadDirectory'=> true, 'RepositoryBaseUrl'=> 'https:'FetchCommonsDescriptions'=> false, 'SharedUploadDBname'=> false, 'SharedUploadDBprefix'=> '', 'SharedUploadDBschema'=> null, 'CacheSharedUploads'=> true, 'ForeignUploadTargets'=>['local',], 'UploadDialog'=>['fields'=>['description'=> true, 'date'=> false, 'categories'=> false,], 'licensemessages'=>['local'=> 'generic-local', 'foreign'=> 'generic-foreign',], 'comment'=>['local'=> '', 'foreign'=> '',], 'format'=>['filepage'=> ' $DESCRIPTION', 'description'=> ' $TEXT', 'ownwork'=> '', 'license'=> '', 'uncategorized'=> '',],], 'FileBackends'=>[], 'LockManagers'=>[], 'DefaultLockManager'=> null, 'ShowEXIF'=> null, 'UpdateCompatibleMetadata'=> false, 'AllowCopyUploads'=> false, 'CopyUploadsDomains'=>[], 'CopyUploadsFromSpecialUpload'=> false, 'CopyUploadProxy'=> false, 'CopyUploadTimeout'=> false, 'CopyUploadAllowOnWikiDomainConfig'=> false, 'MaxUploadSize'=> 104857600, 'MinUploadChunkSize'=> 1024, 'UploadNavigationUrl'=> false, 'UploadMissingFileUrl'=> false, 'ThumbnailScriptPath'=> false, 'SharedThumbnailScriptPath'=> false, 'HashedUploadDirectory'=> true, 'CSPUploadEntryPoint'=> true, 'FileExtensions'=>['png', 'gif', 'jpg', 'jpeg', 'webp',], 'ProhibitedFileExtensions'=>['html', 'htm', 'js', 'jsb', 'mhtml', 'mht', 'xhtml', 'xht', 'php', 'phtml', 'php3', 'php4', 'php5', 'phps', 'phar', 'shtml', 'jhtml', 'pl', 'py', 'cgi', 'exe', 'scr', 'dll', 'msi', 'vbs', 'bat', 'com', 'pif', 'cmd', 'vxd', 'cpl', 'xml',], 'MimeTypeExclusions'=>['text/html', 'application/javascript', 'text/javascript', 'text/x-javascript', 'application/x-shellscript', 'application/x-php', 'text/x-php', 'text/x-python', 'text/x-perl', 'text/x-bash', 'text/x-sh', 'text/x-csh', 'text/scriptlet', 'application/x-msdownload', 'application/x-msmetafile', 'application/java', 'application/xml', 'text/xml',], 'CheckFileExtensions'=> true, 'StrictFileExtensions'=> true, 'DisableUploadScriptChecks'=> false, 'UploadSizeWarning'=> false, 'TrustedMediaFormats'=>['BITMAP', 'AUDIO', 'VIDEO', 'image/svg+xml', 'application/pdf',], 'MediaHandlers'=>[], 'NativeImageLazyLoading'=> true, 'ParserTestMediaHandlers'=>['image/jpeg'=> 'MockBitmapHandler', 'image/png'=> 'MockBitmapHandler', 'image/gif'=> 'MockBitmapHandler', 'image/tiff'=> 'MockBitmapHandler', 'image/webp'=> 'MockBitmapHandler', 'image/x-ms-bmp'=> 'MockBitmapHandler', 'image/x-bmp'=> 'MockBitmapHandler', 'image/x-xcf'=> 'MockBitmapHandler', 'image/svg+xml'=> 'MockSvgHandler', 'image/vnd.djvu'=> 'MockDjVuHandler',], 'UseImageResize'=> true, 'UseImageMagick'=> false, 'ImageMagickConvertCommand'=> '/usr/bin/convert', 'MaxInterlacingAreas'=>[], 'SharpenParameter'=> '0x0.4', 'SharpenReductionThreshold'=> 0.85, 'ImageMagickTempDir'=> false, 'CustomConvertCommand'=> false, 'JpegTran'=> '/usr/bin/jpegtran', 'JpegPixelFormat'=> 'yuv420', 'JpegQuality'=> 80, 'Exiv2Command'=> '/usr/bin/exiv2', 'Exiftool'=> '/usr/bin/exiftool', 'SVGConverters'=>['ImageMagick'=> ' $path/convert -background "#ffffff00" -thumbnail $widthx$height\\! $input PNG:$output', 'inkscape'=> ' $path/inkscape -w $width -o $output $input', 'batik'=> 'java -Djava.awt.headless=true -jar $path/batik-rasterizer.jar -w $width -d $output $input', 'rsvg'=> ' $path/rsvg-convert -w $width -h $height -l $lang -o $output $input', 'ImagickExt'=>['SvgHandler::rasterizeImagickExt',],], 'SVGConverter'=> 'ImageMagick', 'SVGConverterPath'=> '', 'SVGMaxSize'=> 5120, 'SVGMetadataCutoff'=> 5242880, 'SVGNativeRendering'=> true, 'SVGNativeRenderingSizeLimit'=> 51200, 'MediaInTargetLanguage'=> true, 'MaxImageArea'=> 12500000, 'MaxAnimatedGifArea'=> 12500000, 'MaxAnimatedWebPArea'=> 12500000, 'WebPThumbnailType'=>['webp', 'image/webp',], 'TiffThumbnailType'=>[], 'ThumbnailEpoch'=> '20030516000000', 'AttemptFailureEpoch'=> 1, 'IgnoreImageErrors'=> false, 'GenerateThumbnailOnParse'=> true, 'ShowArchiveThumbnails'=> true, 'EnableAutoRotation'=> null, 'Antivirus'=> null, 'AntivirusSetup'=>['clamav'=>['command'=> 'clamscan --no-summary ', 'codemap'=>[0=> 0, 1=> 1, 52=> -1, ' *'=> false,], 'messagepattern'=> '/.*?:(.*)/sim',],], 'AntivirusRequired'=> true, 'VerifyMimeType'=> true, 'MimeTypeFile'=> 'internal', 'MimeInfoFile'=> 'internal', 'MimeDetectorCommand'=> null, 'TrivialMimeDetection'=> false, 'XMLMimeTypes'=>['http:'svg'=> 'image/svg+xml', 'http:'http:'html'=> 'text/html',], 'ImageLimits'=>[[320, 240,], [640, 480,], [800, 600,], [1024, 768,], [1280, 1024,], [2560, 2048,],], 'ThumbLimits'=>[120, 150, 180, 200, 220, 250, 300, 400,], 'ThumbnailNamespaces'=>[6,], 'ThumbnailSteps'=> null, 'ThumbnailBuckets'=> null, 'ThumbnailMinimumBucketDistance'=> 50, 'UploadThumbnailRenderMap'=>[], 'UploadThumbnailRenderMethod'=> 'jobqueue', 'UploadThumbnailRenderHttpCustomHost'=> false, 'UploadThumbnailRenderHttpCustomDomain'=> false, 'UseTinyRGBForJPGThumbnails'=> false, 'GalleryOptions'=>[], 'ThumbUpright'=> 0.75, 'DirectoryMode'=> 511, 'ResponsiveImages'=> true, 'ImagePreconnect'=> false, 'TrackMediaRequestProvenance'=> false, 'DjvuUseBoxedCommand'=> false, 'DjvuDump'=> null, 'DjvuRenderer'=> null, 'DjvuTxt'=> null, 'DjvuPostProcessor'=> 'pnmtojpeg', 'DjvuOutputExtension'=> 'jpg', 'EmergencyContact'=> false, 'PasswordSender'=> false, 'NoReplyAddress'=> false, 'EnableEmail'=> true, 'EnableUserEmail'=> true, 'UserEmailUseReplyTo'=> true, 'PasswordReminderResendTime'=> 24, 'NewPasswordExpiry'=> 604800, 'UserEmailConfirmationTokenExpiry'=> 604800, 'PasswordExpirationDays'=> false, 'PasswordExpireGrace'=> 604800, 'SMTP'=> false, 'AdditionalMailParams'=> null, 'AllowHTMLEmail'=> false, 'EnotifFromEditor'=> false, 'EmailAuthentication'=> true, 'EmailConfirmationBanner'=> false, 'EnotifWatchlist'=> false, 'EnotifUserTalk'=> false, 'EnotifRevealEditorAddress'=> false, 'EnotifMinorEdits'=> true, 'EnotifUseRealName'=> false, 'UsersNotifiedOnAllChanges'=>[], 'DBname'=> 'my_wiki', 'DBmwschema'=> null, 'DBprefix'=> '', 'DBserver'=> 'localhost', 'DBport'=> 5432, 'DBuser'=> 'wikiuser', 'DBpassword'=> '', 'DBtype'=> 'mysql', 'DBssl'=> false, 'DBcompress'=> false, 'DBStrictWarnings'=> false, 'DBadminuser'=> null, 'DBadminpassword'=> null, 'SearchType'=> null, 'SearchTypeAlternatives'=> null, 'DBTableOptions'=> 'ENGINE=InnoDB, DEFAULT CHARSET=binary', 'SQLMode'=> '', 'SQLiteDataDir'=> '', 'SharedDB'=> null, 'SharedPrefix'=> false, 'SharedTables'=>['user', 'user_properties', 'user_autocreate_serial',], 'SharedSchema'=> false, 'DBservers'=> false, 'LBFactoryConf'=>['class'=> 'Wikimedia\\Rdbms\\LBFactorySimple',], 'DataCenterUpdateStickTTL'=> 10, 'DBerrorLog'=> false, 'DBerrorLogTZ'=> false, 'LocalDatabases'=>[], 'DatabaseReplicaLagWarning'=> 10, 'DatabaseReplicaLagCritical'=> 30, 'MaxExecutionTimeForExpensiveQueries'=> 0, 'VirtualDomainsMapping'=>[], 'RemoteVirtualDomainsMapping'=>[], 'FileSchemaMigrationStage'=> 3, 'ExternalLinksDomainGaps'=>[], 'ContentHandlers'=>['wikitext'=>['class'=> 'MediaWiki\\Content\\WikitextContentHandler', 'services'=>['TitleFactory', 'ParserFactory', 'GlobalIdGenerator', 'LanguageNameUtils', 'LinkRenderer', 'MagicWordFactory', 'ParsoidParserFactory',],], 'javascript'=>['class'=> 'MediaWiki\\Content\\JavaScriptContentHandler', 'services'=>['MainConfig', 'ParserFactory', 'UserOptionsLookup', 'CodeHighlighter',],], 'json'=>['class'=> 'MediaWiki\\Content\\JsonContentHandler', 'services'=>['ParsoidParserFactory', 'TitleFactory',],], 'css'=>['class'=> 'MediaWiki\\Content\\CssContentHandler', 'services'=>['MainConfig', 'ParserFactory', 'UserOptionsLookup', 'CodeHighlighter',],], 'vue'=>['class'=> 'MediaWiki\\Content\\VueContentHandler', 'services'=>['MainConfig', 'ParserFactory', 'CodeHighlighter',],], 'text'=> 'MediaWiki\\Content\\TextContentHandler', 'unknown'=> 'MediaWiki\\Content\\FallbackContentHandler',], 'NamespaceContentModels'=>[], 'TextModelsToParse'=>['wikitext', 'javascript', 'css',], 'CompressRevisions'=> false, 'ExternalStores'=>[], 'ExternalServers'=>[], 'DefaultExternalStore'=> false, 'RevisionCacheExpiry'=> 604800, 'PageLanguageUseDB'=> false, 'DiffEngine'=> null, 'ExternalDiffEngine'=> false, 'Wikidiff2Options'=>[], 'RequestTimeLimit'=> null, 'TransactionalTimeLimit'=> 120, 'CriticalSectionTimeLimit'=> 180.0, 'MiserMode'=> false, 'DisableQueryPages'=> false, 'QueryCacheLimit'=> 1000, 'WantedPagesThreshold'=> 1, 'AllowSlowParserFunctions'=> false, 'AllowSchemaUpdates'=> true, 'MaxArticleSize'=> 2048, 'MemoryLimit'=> '50M', 'PoolCounterConf'=> null, 'PoolCountClientConf'=>['servers'=>['127.0.0.1',], 'timeout'=> 0.1,], 'MaxUserDBWriteDuration'=> false, 'MaxJobDBWriteDuration'=> false, 'LinkHolderBatchSize'=> 1000, 'MaximumMovedPages'=> 100, 'ForceDeferredUpdatesPreSend'=> false, 'MultiShardSiteStats'=> false, 'CacheDirectory'=> false, 'MainCacheType'=> 0, 'MessageCacheType'=> -1, 'ParserCacheType'=> -1, 'SessionCacheType'=> -1, 'AnonSessionCacheType'=> false, 'LanguageConverterCacheType'=> -1, 'ObjectCaches'=>[0=>['class'=> 'Wikimedia\\ObjectCache\\EmptyBagOStuff', 'reportDupes'=> false,], 1=>['class'=> 'MediaWiki\\ObjectCache\\SqlBagOStuff', 'loggroup'=> 'SQLBagOStuff',], 'memcached-php'=>['class'=> 'Wikimedia\\ObjectCache\\MemcachedPhpBagOStuff', 'loggroup'=> 'memcached',], 'memcached-pecl'=>['class'=> 'Wikimedia\\ObjectCache\\MemcachedPeclBagOStuff', 'loggroup'=> 'memcached',], 'hash'=>['class'=> 'Wikimedia\\ObjectCache\\HashBagOStuff', 'reportDupes'=> false,], 'apc'=>['class'=> 'Wikimedia\\ObjectCache\\APCUBagOStuff', 'reportDupes'=> false,], 'apcu'=>['class'=> 'Wikimedia\\ObjectCache\\APCUBagOStuff', 'reportDupes'=> false,],], 'WANObjectCache'=>[], 'MicroStashType'=> -1, 'MainStash'=> 1, 'ParsoidCacheConfig'=>['StashType'=> null, 'StashDuration'=> 86400, 'WarmParsoidParserCache'=> false,], 'ParsoidSelectiveUpdateSampleRate'=> 0, 'SplitParsoidParserCache'=> true, 'ParserCacheFilterConfig'=>['pcache'=>['default'=>['minCpuTime'=> 0,],], 'postproc-pcache'=>['default'=>['minCpuTime'=> 9223372036854775807,],], 'parsoid-pcache'=>['default'=>['minCpuTime'=> 0,],], 'postproc-parsoid-pcache'=>['default'=>['minCpuTime'=> 0,],],], 'ChronologyProtectorSecret'=> '', 'ParserCacheExpireTime'=> 86400, 'ParserCacheAsyncExpireTime'=> 60, 'ParserCacheAsyncRefreshJobs'=> true, 'OldRevisionParserCacheExpireTime'=> 3600, 'ObjectCacheSessionExpiry'=> 3600, 'SuspiciousIpExpiry'=> false, 'SessionPbkdf2Iterations'=> 10001, 'UseSessionCookieJwt'=> false, 'JwtSessionCookieIssuer'=> null, 'MemCachedServers'=>['127.0.0.1:11211',], 'MemCachedPersistent'=> false, 'MemCachedTimeout'=> 500000, 'UseLocalMessageCache'=> false, 'AdaptiveMessageCache'=> false, 'LocalisationCacheConf'=>['class'=> 'MediaWiki\\Language\\LocalisationCache', 'store'=> 'detect', 'storeClass'=> false, 'storeDirectory'=> false, 'storeServer'=>[], 'forceRecache'=> false, 'manualRecache'=> false,], 'CachePages'=> true, 'CacheEpoch'=> '20030516000000', 'GitInfoCacheDirectory'=> false, 'UseFileCache'=> false, 'FileCacheDepth'=> 2, 'RenderHashAppend'=> '', 'EnableSidebarCache'=> false, 'SidebarCacheExpiry'=> 86400, 'UseGzip'=> false, 'InvalidateCacheOnLocalSettingsChange'=> true, 'ExtensionInfoMTime'=> false, 'EnableRemoteBagOStuffTests'=> false, 'UseCdn'=> false, 'VaryOnXFP'=> false, 'InternalServer'=> false, 'CdnMaxAge'=> 18000, 'CdnMaxageLagged'=> 30, 'CdnMaxageStale'=> 10, 'CdnReboundPurgeDelay'=> 0, 'CdnMaxageSubstitute'=> 60, 'ForcedRawSMaxage'=> 300, 'CdnServers'=>[], 'CdnServersNoPurge'=>[], 'HTCPRouting'=>[], 'HTCPMulticastTTL'=> 1, 'UsePrivateIPs'=> false, 'CdnMatchParameterOrder'=> true, 'LanguageCode'=> 'en', 'GrammarForms'=>[], 'InterwikiMagic'=> true, 'HideInterlanguageLinks'=> false, 'ExtraInterlanguageLinkPrefixes'=>[], 'InterlanguageLinkCodeMap'=>[], 'ExtraLanguageNames'=>[], 'ExtraLanguageCodes'=>['bh'=> 'bho', 'no'=> 'nb', 'simple'=> 'en',], 'DummyLanguageCodes'=>[], 'AllUnicodeFixes'=> false, 'LegacyEncoding'=> false, 'AmericanDates'=> false, 'TranslateNumerals'=> true, 'UseDatabaseMessages'=> true, 'MaxMsgCacheEntrySize'=> 10000, 'DisableLangConversion'=> false, 'DisableTitleConversion'=> false, 'DefaultLanguageVariant'=> false, 'UsePigLatinVariant'=> false, 'DisabledVariants'=>[], 'VariantArticlePath'=> false, 'UseXssLanguage'=> false, 'LoginLanguageSelector'=> false, 'ForceUIMsgAsContentMsg'=>[], 'RawHtmlMessages'=>[], 'Localtimezone'=> null, 'LocalTZoffset'=> null, 'OverrideUcfirstCharacters'=>[], 'MimeType'=> 'text/html', 'Html5Version'=> null, 'EditSubmitButtonLabelPublish'=> false, 'XhtmlNamespaces'=>[], 'SiteNotice'=> '', 'BrowserFormatDetection'=> 'telephone=no', 'SkinMetaTags'=>[], 'DefaultSkin'=> 'vector-2022', 'FallbackSkin'=> 'fallback', 'SkipSkins'=>[], 'DisableOutputCompression'=> false, 'FragmentMode'=>['html5', 'legacy',], 'ExternalInterwikiFragmentMode'=> 'legacy', 'FooterIcons'=>['copyright'=>['copyright'=>[],], 'poweredby'=>['mediawiki'=>['src'=> null, 'url'=> 'https:'alt'=> 'Powered by MediaWiki', 'lang'=> 'en',],],], 'EnableSectionShare'=> false, 'UseCombinedLoginLink'=> false, 'Edititis'=> false, 'Send404Code'=> true, 'ShowRollbackEditCount'=> 10, 'EnableCanonicalServerLink'=> false, 'InterwikiLogoOverride'=>[], 'ResourceModules'=>[], 'ResourceModuleSkinStyles'=>[], 'ResourceLoaderSources'=>[], 'ResourceBasePath'=> null, 'ResourceLoaderMaxage'=>[], 'ResourceLoaderDebug'=> false, 'ResourceLoaderMaxQueryLength'=> false, 'ResourceLoaderValidateJS'=> true, 'ResourceLoaderEnableJSProfiler'=> false, 'ResourceLoaderStorageEnabled'=> true, 'ResourceLoaderStorageVersion'=> 1, 'ResourceLoaderEnableSourceMapLinks'=> true, 'AllowSiteCSSOnRestrictedPages'=> false, 'VueDevelopmentMode'=> false, 'CodexDevelopmentDir'=> null, 'MetaNamespace'=> false, 'MetaNamespaceTalk'=> false, 'CanonicalNamespaceNames'=>[-2=> 'Media', -1=> 'Special', 0=> '', 1=> 'Talk', 2=> 'User', 3=> 'User_talk', 4=> 'Project', 5=> 'Project_talk', 6=> 'File', 7=> 'File_talk', 8=> 'MediaWiki', 9=> 'MediaWiki_talk', 10=> 'Template', 11=> 'Template_talk', 12=> 'Help', 13=> 'Help_talk', 14=> 'Category', 15=> 'Category_talk',], 'ExtraNamespaces'=>[], 'ExtraGenderNamespaces'=>[], 'NamespaceAliases'=>[], 'LegalTitleChars'=> ' %!"$&\'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+', 'CapitalLinks' => true, 'CapitalLinkOverrides' => [ ], 'NamespacesWithSubpages' => [ 1 => true, 2 => true, 3 => true, 4 => true, 5 => true, 7 => true, 8 => true, 9 => true, 10 => true, 11 => true, 12 => true, 13 => true, 15 => true, ], 'NamespacesWithoutAutoSummaries' => [ ], 'ContentNamespaces' => [ 0, ], 'ShortPagesNamespaceExclusions' => [ ], 'ExtraSignatureNamespaces' => [ ], 'InvalidRedirectTargets' => [ 'Filepath', 'Mypage', 'Mytalk', 'Redirect', 'Mylog', ], 'DisableHardRedirects' => false, 'FixDoubleRedirects' => false, 'LocalInterwikis' => [ ], 'InterwikiExpiry' => 10800, 'InterwikiCache' => false, 'InterwikiScopes' => 3, 'InterwikiFallbackSite' => 'wiki', 'RedirectSources' => false, 'SiteTypes' => [ 'mediawiki' => 'MediaWiki\\Site\\MediaWikiSite', ], 'MaxTocLevel' => 999, 'MaxPPNodeCount' => 1000000, 'MaxTemplateDepth' => 100, 'MaxPPExpandDepth' => 100, 'UrlProtocols' => [ 'bitcoin:', 'ftp: 'ftps: 'geo:', 'git: 'gopher: 'http: 'https: 'irc: 'ircs: 'magnet:', 'mailto:', 'matrix:', 'mms: 'news:', 'nntp: 'redis: 'sftp: 'sip:', 'sips:', 'sms:', 'ssh: 'svn: 'tel:', 'telnet: 'urn:', 'wikipedia: 'worldwind: 'xmpp:', ' ], 'CleanSignatures' => true, 'AllowExternalImages' => false, 'AllowExternalImagesFrom' => '', 'EnableImageWhitelist' => false, 'TidyConfig' => [ ], 'ParsoidSettings' => [ 'useSelser' => true, ], 'ParsoidExperimentalParserFunctionOutput' => false, 'RawHtml' => false, 'ExternalLinkTarget' => false, 'NoFollowLinks' => true, 'NoFollowNsExceptions' => [ ], 'NoFollowDomainExceptions' => [ 'mediawiki.org', ], 'RegisterInternalExternals' => false, 'ExternalLinksIgnoreDomains' => [ ], 'AllowDisplayTitle' => true, 'RestrictDisplayTitle' => true, 'ExpensiveParserFunctionLimit' => 100, 'PreprocessorCacheThreshold' => 1000, 'EnableScaryTranscluding' => false, 'TranscludeCacheExpiry' => 3600, 'EnableMagicLinks' => [ 'ISBN' => false, 'PMID' => false, 'RFC' => false, ], 'ParserEnableUserLanguage' => false, 'ArticleCountMethod' => 'link', 'ActiveUserDays' => 30, 'LearnerEdits' => 10, 'LearnerMemberSince' => 4, 'ExperiencedUserEdits' => 500, 'ExperiencedUserMemberSince' => 30, 'ManualRevertSearchRadius' => 15, 'RevertedTagMaxDepth' => 15, 'CentralIdLookupProviders' => [ 'local' => [ 'class' => 'MediaWiki\\User\\CentralId\\LocalIdLookup', 'services' => [ 'MainConfig', 'DBLoadBalancerFactory', 'HideUserUtils', ], ], ], 'CentralIdLookupProvider' => 'local', 'UserRegistrationProviders' => [ 'local' => [ 'class' => 'MediaWiki\\User\\Registration\\LocalUserRegistrationProvider', 'services' => [ 'ConnectionProvider', ], ], ], 'PasswordPolicy' => [ 'policies' => [ 'bureaucrat' => [ 'MinimalPasswordLength' => 10, 'MinimumPasswordLengthToLogin' => 1, ], 'sysop' => [ 'MinimalPasswordLength' => 10, 'MinimumPasswordLengthToLogin' => 1, ], 'interface-admin' => [ 'MinimalPasswordLength' => 10, 'MinimumPasswordLengthToLogin' => 1, ], 'bot' => [ 'MinimalPasswordLength' => 10, 'MinimumPasswordLengthToLogin' => 1, ], 'default' => [ 'MinimalPasswordLength' => [ 'value' => 8, 'suggestChangeOnLogin' => true, ], 'PasswordCannotBeSubstringInUsername' => [ 'value' => true, 'suggestChangeOnLogin' => true, ], 'PasswordCannotMatchDefaults' => [ 'value' => true, 'suggestChangeOnLogin' => true, ], 'MaximalPasswordLength' => [ 'value' => 4096, 'suggestChangeOnLogin' => true, ], 'PasswordNotInCommonList' => [ 'value' => true, 'suggestChangeOnLogin' => true, ], ], ], 'checks' => [ 'MinimalPasswordLength' => [ 'MediaWiki\\Password\\PasswordPolicyChecks', 'checkMinimalPasswordLength', ], 'MinimumPasswordLengthToLogin' => [ 'MediaWiki\\Password\\PasswordPolicyChecks', 'checkMinimumPasswordLengthToLogin', ], 'PasswordCannotBeSubstringInUsername' => [ 'MediaWiki\\Password\\PasswordPolicyChecks', 'checkPasswordCannotBeSubstringInUsername', ], 'PasswordCannotMatchDefaults' => [ 'MediaWiki\\Password\\PasswordPolicyChecks', 'checkPasswordCannotMatchDefaults', ], 'MaximalPasswordLength' => [ 'MediaWiki\\Password\\PasswordPolicyChecks', 'checkMaximalPasswordLength', ], 'PasswordNotInCommonList' => [ 'MediaWiki\\Password\\PasswordPolicyChecks', 'checkPasswordNotInCommonList', ], ], ], 'AuthManagerConfig' => null, 'AuthManagerAutoConfig' => [ 'preauth' => [ 'MediaWiki\\Auth\\ThrottlePreAuthenticationProvider' => [ 'class' => 'MediaWiki\\Auth\\ThrottlePreAuthenticationProvider', 'sort' => 0, ], 'MediaWiki\\Auth\\PreviouslyRenamedAccountPreAuthenticationProvider' => [ 'class' => 'MediaWiki\\Auth\\PreviouslyRenamedAccountPreAuthenticationProvider', 'services' => [ 'ConnectionProvider', 'UserFactory', ], 'sort' => 0, ], ], 'primaryauth' => [ 'MediaWiki\\Auth\\TemporaryPasswordPrimaryAuthenticationProvider' => [ 'class' => 'MediaWiki\\Auth\\TemporaryPasswordPrimaryAuthenticationProvider', 'services' => [ 'DBLoadBalancerFactory', 'UserOptionsLookup', ], 'args' => [ [ 'authoritative' => false, ], ], 'sort' => 0, ], 'MediaWiki\\Auth\\LocalPasswordPrimaryAuthenticationProvider' => [ 'class' => 'MediaWiki\\Auth\\LocalPasswordPrimaryAuthenticationProvider', 'services' => [ 'DBLoadBalancerFactory', ], 'args' => [ [ 'authoritative' => true, ], ], 'sort' => 100, ], ], 'secondaryauth' => [ 'MediaWiki\\Auth\\CheckBlocksSecondaryAuthenticationProvider' => [ 'class' => 'MediaWiki\\Auth\\CheckBlocksSecondaryAuthenticationProvider', 'sort' => 0, ], 'MediaWiki\\Auth\\ResetPasswordSecondaryAuthenticationProvider' => [ 'class' => 'MediaWiki\\Auth\\ResetPasswordSecondaryAuthenticationProvider', 'sort' => 100, ], 'MediaWiki\\Auth\\EmailNotificationSecondaryAuthenticationProvider' => [ 'class' => 'MediaWiki\\Auth\\EmailNotificationSecondaryAuthenticationProvider', 'services' => [ 'DBLoadBalancerFactory', ], 'sort' => 200, ], ], ], 'RememberMe' => 'choose', 'ReauthenticateTime' => [ 'default' => 3600, ], 'ChangeCredentialsBlacklist' => [ 'MediaWiki\\Auth\\TemporaryPasswordAuthenticationRequest', ], 'RemoveCredentialsBlacklist' => [ 'MediaWiki\\Auth\\PasswordAuthenticationRequest', ], 'InvalidPasswordReset' => true, 'PasswordDefault' => 'pbkdf2', 'PasswordConfig' => [ 'A' => [ 'class' => 'MediaWiki\\Password\\MWOldPassword', ], 'B' => [ 'class' => 'MediaWiki\\Password\\MWSaltedPassword', ], 'pbkdf2-legacyA' => [ 'class' => 'MediaWiki\\Password\\LayeredParameterizedPassword', 'types' => [ 'A', 'pbkdf2', ], ], 'pbkdf2-legacyB' => [ 'class' => 'MediaWiki\\Password\\LayeredParameterizedPassword', 'types' => [ 'B', 'pbkdf2', ], ], 'bcrypt' => [ 'class' => 'MediaWiki\\Password\\BcryptPassword', 'cost' => 9, ], 'pbkdf2' => [ 'class' => 'MediaWiki\\Password\\Pbkdf2PasswordUsingOpenSSL', 'algo' => 'sha512', 'cost' => '30000', 'length' => '64', ], 'argon2' => [ 'class' => 'MediaWiki\\Password\\Argon2Password', 'algo' => 'auto', ], ], 'PasswordResetRoutes' => [ 'username' => true, 'email' => true, ], 'MaxSigChars' => 255, 'SignatureValidation' => 'warning', 'SignatureAllowedLintErrors' => [ 'obsolete-tag', ], 'MaxNameChars' => 255, 'ReservedUsernames' => [ 'MediaWiki default', 'Conversion script', 'Maintenance script', 'Template namespace initialisation script', 'ScriptImporter', 'Delete page script', 'Move page script', 'Command line script', 'Unknown user', 'msg:double-redirect-fixer', 'msg:usermessage-editor', 'msg:proxyblocker', 'msg:sorbs', 'msg:spambot_username', 'msg:autochange-username', ], 'DefaultUserOptions' => [ 'ccmeonemails' => 0, 'date' => 'default', 'diffonly' => 0, 'diff-type' => 'table', 'disablemail' => 0, 'editfont' => 'monospace', 'editondblclick' => 0, 'editrecovery' => 0, 'editsectiononrightclick' => 0, 'email-allow-new-users' => 1, 'enotifminoredits' => 0, 'enotifrevealaddr' => 0, 'enotifusertalkpages' => 1, 'enotifwatchlistpages' => 1, 'extendwatchlist' => 1, 'fancysig' => 0, 'forceeditsummary' => 0, 'forcesafemode' => 0, 'gender' => 'unknown', 'hidecategorization' => 1, 'hideminor' => 0, 'hidepatrolled' => 0, 'imagesize' => 2, 'minordefault' => 0, 'newpageshidepatrolled' => 0, 'nickname' => '', 'norollbackdiff' => 0, 'prefershttps' => 1, 'previewonfirst' => 0, 'previewontop' => 1, 'pst-cssjs' => 1, 'rcdays' => 7, 'rcenhancedfilters-disable' => 0, 'rclimit' => 50, 'requireemail' => 0, 'search-match-redirect' => true, 'search-special-page' => 'Search', 'search-thumbnail-extra-namespaces' => true, 'searchlimit' => 20, 'showhiddencats' => 0, 'shownumberswatching' => 1, 'showrollbackconfirmation' => 0, 'skin' => false, 'skin-responsive' => 1, 'thumbsize' => 5, 'underline' => 2, 'useeditwarning' => 1, 'uselivepreview' => 0, 'usenewrc' => 1, 'watchcreations' => 1, 'watchcreations-expiry' => 'infinite', 'watchdefault' => 1, 'watchdefault-expiry' => 'infinite', 'watchdeletion' => 0, 'watchlistdays' => 7, 'watchlisthideanons' => 0, 'watchlisthidebots' => 0, 'watchlisthidecategorization' => 1, 'watchlisthideliu' => 0, 'watchlisthideminor' => 0, 'watchlisthideown' => 0, 'watchlisthidepatrolled' => 0, 'watchlistreloadautomatically' => 0, 'watchlistunwatchlinks' => 0, 'watchmoves' => 0, 'watchrollback' => 0, 'watchuploads' => 1, 'watchrollback-expiry' => 'infinite', 'watchstar-expiry' => 'infinite', 'wlenhancedfilters-disable' => 0, 'wllimit' => 250, ], 'ConditionalUserOptions' => [ ], 'HiddenPrefs' => [ ], 'UserJsPrefLimit' => 100, 'InvalidUsernameCharacters' => '@:>=', 'UserrightsInterwikiDelimiter' => '@', 'SecureLogin' => false, 'AuthenticationTokenVersion' => null, 'SessionProviders' => [ 'MediaWiki\\Session\\CookieSessionProvider' => [ 'class' => 'MediaWiki\\Session\\CookieSessionProvider', 'args' => [ [ 'priority' => 30, ], ], 'services' => [ 'JwtCodec', 'UrlUtils', ], ], 'MediaWiki\\Session\\BotPasswordSessionProvider' => [ 'class' => 'MediaWiki\\Session\\BotPasswordSessionProvider', 'args' => [ [ 'priority' => 75, ], ], 'services' => [ 'GrantsInfo', ], ], ], 'AutoCreateTempUser' => [ 'known' => false, 'enabled' => false, 'actions' => [ 'edit', ], 'genPattern' => '~$1', 'matchPattern' => null, 'reservedPattern' => '~$1', 'serialProvider' => [ 'type' => 'local', 'useYear' => true, ], 'serialMapping' => [ 'type' => 'readable-numeric', ], 'expireAfterDays' => 90, 'notifyBeforeExpirationDays' => 10, ], 'AutoblockExemptions' => [ ], 'AutoblockExpiry' => 86400, 'BlockAllowsUTEdit' => true, 'BlockCIDRLimit' => [ 'IPv4' => 16, 'IPv6' => 19, ], 'BlockDisablesLogin' => false, 'EnableMultiBlocks' => false, 'WhitelistRead' => false, 'WhitelistReadRegexp' => false, 'EmailConfirmToEdit' => false, 'HideIdentifiableRedirects' => true, 'GroupPermissions' => [ '*' => [ 'createaccount' => true, 'autocreateaccount' => true, 'read' => true, 'edit' => true, 'createpage' => true, 'createtalk' => true, 'viewmyprivateinfo' => true, 'editmyprivateinfo' => true, 'editmyoptions' => true, ], 'user' => [ 'move' => true, 'move-subpages' => true, 'move-rootuserpages' => true, 'move-categorypages' => true, 'movefile' => true, 'read' => true, 'edit' => true, 'createpage' => true, 'createtalk' => true, 'upload' => true, 'reupload' => true, 'reupload-shared' => true, 'minoredit' => true, 'editmyusercss' => true, 'editmyuserjson' => true, 'editmyuserjs' => true, 'editmyuserjsredirect' => true, 'sendemail' => true, 'applychangetags' => true, 'changetags' => true, 'viewmywatchlist' => true, 'editmywatchlist' => true, 'createwithcontentmodel' => true, 'logout' => true, ], 'autoconfirmed' => [ 'autoconfirmed' => true, 'editsemiprotected' => true, ], 'bot' => [ 'bot' => true, 'autoconfirmed' => true, 'editsemiprotected' => true, 'nominornewtalk' => true, 'autopatrol' => true, 'suppressredirect' => true, 'apihighlimits' => true, ], 'sysop' => [ 'block' => true, 'createaccount' => true, 'createpreviouslyrenamedaccount' => true, 'delete' => true, 'bigdelete' => true, 'deletedhistory' => true, 'deletedtext' => true, 'undelete' => true, 'editcontentmodel' => true, 'editinterface' => true, 'editsitejson' => true, 'edituserjson' => true, 'import' => true, 'importupload' => true, 'move' => true, 'move-subpages' => true, 'move-rootuserpages' => true, 'move-categorypages' => true, 'patrol' => true, 'autopatrol' => true, 'protect' => true, 'editprotected' => true, 'rollback' => true, 'upload' => true, 'reupload' => true, 'reupload-shared' => true, 'unwatchedpages' => true, 'autoconfirmed' => true, 'editsemiprotected' => true, 'ipblock-exempt' => true, 'blockemail' => true, 'markbotedits' => true, 'apihighlimits' => true, 'browsearchive' => true, 'noratelimit' => true, 'movefile' => true, 'unblockself' => true, 'suppressredirect' => true, 'mergehistory' => true, 'managechangetags' => true, 'deletechangetags' => true, ], 'interface-admin' => [ 'editinterface' => true, 'editsitecss' => true, 'editsitejson' => true, 'editsitejs' => true, 'editusercss' => true, 'edituserjson' => true, 'edituserjs' => true, ], 'bureaucrat' => [ 'userrights' => true, 'noratelimit' => true, 'renameuser' => true, ], 'suppress' => [ 'hideuser' => true, 'suppressrevision' => true, 'viewsuppressed' => true, 'suppressionlog' => true, 'deleterevision' => true, 'deletelogentry' => true, ], ], 'PrivilegedGroups' => [ 'bureaucrat', 'interface-admin', 'suppress', 'sysop', ], 'RevokePermissions' => [ ], 'GroupInheritsPermissions' => [ ], 'ImplicitGroups' => [ '*', 'user', 'autoconfirmed', ], 'GroupsAddToSelf' => [ ], 'GroupsRemoveFromSelf' => [ ], 'RestrictedGroups' => [ ], 'UserRequirementsPrivateConditions' => [ ], 'RestrictionTypes' => [ 'create', 'edit', 'move', 'upload', ], 'RestrictionLevels' => [ '', 'autoconfirmed', 'sysop', ], 'CascadingRestrictionLevels' => [ 'sysop', ], 'SemiprotectedRestrictionLevels' => [ 'autoconfirmed', ], 'NamespaceProtection' => [ ], 'RestrictUserPageEditing' => false, 'NonincludableNamespaces' => [ ], 'AutoConfirmAge' => 0, 'AutoConfirmCount' => 0, 'Autopromote' => [ 'autoconfirmed' => [ '&', [ 1, null, ], [ 2, null, ], ], ], 'AutopromoteOnce' => [ 'onEdit' => [ ], ], 'AutopromoteOnceLogInRC' => true, 'AutopromoteOnceRCExcludedGroups' => [ ], 'AddGroups' => [ ], 'RemoveGroups' => [ ], 'AvailableRights' => [ ], 'ImplicitRights' => [ ], 'DeleteRevisionsLimit' => 0, 'DeleteRevisionsBatchSize' => 1000, 'HideUserContribLimit' => 1000, 'AccountCreationThrottle' => [ [ 'count' => 0, 'seconds' => 86400, ], ], 'TempAccountCreationThrottle' => [ [ 'count' => 1, 'seconds' => 600, ], [ 'count' => 6, 'seconds' => 86400, ], ], 'TempAccountNameAcquisitionThrottle' => [ [ 'count' => 60, 'seconds' => 86400, ], ], 'SpamRegex' => [ ], 'SummarySpamRegex' => [ ], 'EnableDnsBlacklist' => false, 'DnsBlacklistUrls' => [ ], 'ProxyList' => [ ], 'ProxyWhitelist' => [ ], 'SoftBlockRanges' => [ ], 'ApplyIpBlocksToXff' => false, 'RateLimits' => [ 'edit' => [ 'ip' => [ 8, 60, ], 'newbie' => [ 8, 60, ], 'user' => [ 90, 60, ], ], 'move' => [ 'newbie' => [ 2, 120, ], 'user' => [ 8, 60, ], ], 'upload' => [ 'ip' => [ 8, 60, ], 'newbie' => [ 8, 60, ], ], 'rollback' => [ 'user' => [ 10, 60, ], 'newbie' => [ 5, 120, ], ], 'mailpassword' => [ 'ip' => [ 5, 3600, ], ], 'sendemail' => [ 'ip' => [ 5, 86400, ], 'newbie' => [ 5, 86400, ], 'user' => [ 20, 86400, ], ], 'changeemail' => [ 'ip-all' => [ 10, 3600, ], 'user' => [ 4, 86400, ], ], 'confirmemail' => [ 'ip-all' => [ 10, 3600, ], 'user' => [ 4, 86400, ], ], 'purge' => [ 'ip' => [ 30, 60, ], 'user' => [ 30, 60, ], ], 'linkpurge' => [ 'ip' => [ 30, 60, ], 'user' => [ 30, 60, ], ], 'renderfile' => [ 'ip' => [ 700, 30, ], 'user' => [ 700, 30, ], ], 'renderfile-nonstandard' => [ 'ip' => [ 70, 30, ], 'user' => [ 70, 30, ], ], 'stashedit' => [ 'ip' => [ 30, 60, ], 'newbie' => [ 30, 60, ], ], 'stashbasehtml' => [ 'ip' => [ 5, 60, ], 'newbie' => [ 5, 60, ], ], 'changetags' => [ 'ip' => [ 8, 60, ], 'newbie' => [ 8, 60, ], ], 'editcontentmodel' => [ 'newbie' => [ 2, 120, ], 'user' => [ 8, 60, ], ], ], 'RateLimitsExcludedIPs' => [ ], 'PutIPinRC' => true, 'QueryPageDefaultLimit' => 50, 'ExternalQuerySources' => [ ], 'PasswordAttemptThrottle' => [ [ 'count' => 5, 'seconds' => 300, ], [ 'count' => 150, 'seconds' => 172800, ], ], 'GrantPermissions' => [ 'basic' => [ 'autocreateaccount' => true, 'autoconfirmed' => true, 'autopatrol' => true, 'editsemiprotected' => true, 'ipblock-exempt' => true, 'nominornewtalk' => true, 'patrolmarks' => true, 'read' => true, 'unwatchedpages' => true, ], 'highvolume' => [ 'bot' => true, 'apihighlimits' => true, 'noratelimit' => true, 'markbotedits' => true, ], 'import' => [ 'import' => true, 'importupload' => true, ], 'editpage' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => true, 'createwithcontentmodel' => true, 'pagelang' => true, ], 'editprotected' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => true, 'createwithcontentmodel' => true, 'editprotected' => true, ], 'editmycssjs' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => true, 'createwithcontentmodel' => true, 'editmyusercss' => true, 'editmyuserjson' => true, 'editmyuserjs' => true, ], 'editmyoptions' => [ 'editmyoptions' => true, 'editmyuserjson' => true, ], 'editinterface' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => true, 'createwithcontentmodel' => true, 'editinterface' => true, 'edituserjson' => true, 'editsitejson' => true, ], 'editsiteconfig' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => true, 'createwithcontentmodel' => true, 'editinterface' => true, 'edituserjson' => true, 'editsitejson' => true, 'editusercss' => true, 'edituserjs' => true, 'editsitecss' => true, 'editsitejs' => true, ], 'createeditmovepage' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => true, 'createwithcontentmodel' => true, 'createpage' => true, 'createtalk' => true, 'delete-redirect' => true, 'move' => true, 'move-rootuserpages' => true, 'move-subpages' => true, 'move-categorypages' => true, 'suppressredirect' => true, ], 'uploadfile' => [ 'upload' => true, 'reupload-own' => true, ], 'uploadeditmovefile' => [ 'upload' => true, 'reupload-own' => true, 'reupload' => true, 'reupload-shared' => true, 'upload_by_url' => true, 'movefile' => true, 'suppressredirect' => true, ], 'patrol' => [ 'patrol' => true, ], 'rollback' => [ 'rollback' => true, ], 'blockusers' => [ 'block' => true, 'blockemail' => true, ], 'viewdeleted' => [ 'browsearchive' => true, 'deletedhistory' => true, 'deletedtext' => true, ], 'viewrestrictedlogs' => [ 'suppressionlog' => true, ], 'delete' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => true, 'createwithcontentmodel' => true, 'browsearchive' => true, 'deletedhistory' => true, 'deletedtext' => true, 'delete' => true, 'bigdelete' => true, 'deletelogentry' => true, 'deleterevision' => true, 'undelete' => true, ], 'oversight' => [ 'suppressrevision' => true, 'viewsuppressed' => true, ], 'protect' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => true, 'createwithcontentmodel' => true, 'editprotected' => true, 'protect' => true, ], 'viewmywatchlist' => [ 'viewmywatchlist' => true, ], 'editmywatchlist' => [ 'editmywatchlist' => true, ], 'sendemail' => [ 'sendemail' => true, ], 'createaccount' => [ 'createaccount' => true, ], 'privateinfo' => [ 'viewmyprivateinfo' => true, ], 'mergehistory' => [ 'mergehistory' => true, ], 'managesessions' => [ 'logout' => true, ], ], 'GrantPermissionGroups' => [ 'basic' => 'hidden', 'editpage' => 'page-interaction', 'createeditmovepage' => 'page-interaction', 'editprotected' => 'page-interaction', 'patrol' => 'page-interaction', 'uploadfile' => 'file-interaction', 'uploadeditmovefile' => 'file-interaction', 'sendemail' => 'email', 'viewmywatchlist' => 'watchlist-interaction', 'editmywatchlist' => 'watchlist-interaction', 'editmycssjs' => 'customization', 'editmyoptions' => 'customization', 'editinterface' => 'administration', 'editsiteconfig' => 'administration', 'rollback' => 'administration', 'blockusers' => 'administration', 'delete' => 'administration', 'viewdeleted' => 'administration', 'viewrestrictedlogs' => 'administration', 'protect' => 'administration', 'oversight' => 'administration', 'createaccount' => 'administration', 'mergehistory' => 'administration', 'import' => 'administration', 'highvolume' => 'high-volume', 'privateinfo' => 'private-information', 'managesessions' => 'private-information', ], 'GrantRiskGroups' => [ 'basic' => 'low', 'editpage' => 'low', 'createeditmovepage' => 'low', 'editprotected' => 'vandalism', 'patrol' => 'low', 'uploadfile' => 'low', 'uploadeditmovefile' => 'low', 'sendemail' => 'security', 'viewmywatchlist' => 'low', 'editmywatchlist' => 'low', 'editmycssjs' => 'security', 'editmyoptions' => 'security', 'editinterface' => 'vandalism', 'editsiteconfig' => 'security', 'rollback' => 'low', 'blockusers' => 'vandalism', 'delete' => 'vandalism', 'viewdeleted' => 'vandalism', 'viewrestrictedlogs' => 'security', 'protect' => 'vandalism', 'oversight' => 'security', 'createaccount' => 'low', 'mergehistory' => 'vandalism', 'import' => 'security', 'highvolume' => 'low', 'privateinfo' => 'low', 'managesessions' => 'low', ], 'EnableBotPasswords' => true, 'BotPasswordsCluster' => false, 'BotPasswordsDatabase' => false, 'BotPasswordsLimit' => 100, 'SecretKey' => false, 'JwtPrivateKey' => false, 'JwtPublicKey' => false, 'AllowUserJs' => false, 'ReauthenticateForActions' => [ 'edituserjs' => 'edituserjscss', 'editusercss' => 'edituserjscss', 'editsitejs' => 'editsitejscss', 'editsitecss' => 'editsitejscss', ], 'AllowUserCss' => false, 'AllowUserCssPrefs' => true, 'UseSiteJs' => true, 'UseSiteCss' => true, 'BreakFrames' => false, 'EditPageFrameOptions' => 'DENY', 'ApiFrameOptions' => 'DENY', 'CSPHeader' => false, 'CSPReportOnlyHeader' => false, 'CSPUseReportURIDirective' => false, 'CSPFalsePositiveUrls' => [ 'https: 'https: 'https: 'https: 'https: 'https: 'https: 'https: 'https: 'https: 'https: 'https: 'https: 'https: 'chrome-extension' => true, ], 'AllowCrossOrigin' => false, 'RestAllowCrossOriginCookieAuth' => false, 'SessionSecret' => false, 'CookieExpiration' => 2592000, 'ExtendedLoginCookieExpiration' => 15552000, 'SessionCookieJwtExpiration' => 14400, 'CookieDomain' => '', 'CookiePath' => '/', 'CookieSecure' => 'detect', 'CookiePrefix' => false, 'CookieHttpOnly' => true, 'CookieSameSite' => null, 'CacheVaryCookies' => [ ], 'SessionName' => false, 'CookieSetOnAutoblock' => true, 'CookieSetOnIpBlock' => true, 'DebugLogFile' => '', 'DebugLogPrefix' => '', 'DebugRedirects' => false, 'DebugRawPage' => false, 'DebugComments' => false, 'DebugDumpSql' => false, 'TrxProfilerLimits' => [ 'GET' => [ 'masterConns' => 0, 'writes' => 0, 'readQueryTime' => 5, 'readQueryRows' => 10000, ], 'POST' => [ 'readQueryTime' => 5, 'writeQueryTime' => 1, 'readQueryRows' => 100000, 'maxAffected' => 1000, ], 'POST-nonwrite' => [ 'writes' => 0, 'readQueryTime' => 5, 'readQueryRows' => 10000, ], 'PostSend-GET' => [ 'readQueryTime' => 5, 'writeQueryTime' => 1, 'readQueryRows' => 10000, 'maxAffected' => 1000, 'masterConns' => 0, 'writes' => 0, ], 'PostSend-POST' => [ 'readQueryTime' => 5, 'writeQueryTime' => 1, 'readQueryRows' => 100000, 'maxAffected' => 1000, ], 'JobRunner' => [ 'readQueryTime' => 30, 'writeQueryTime' => 5, 'readQueryRows' => 100000, 'maxAffected' => 500, ], 'Maintenance' => [ 'writeQueryTime' => 5, 'maxAffected' => 1000, ], ], 'DebugLogGroups' => [ ], 'MWLoggerDefaultSpi' => [ 'class' => 'MediaWiki\\Logger\\LegacySpi', ], 'ShowDebug' => false, 'SpecialVersionShowHooks' => false, 'ShowExceptionDetails' => false, 'LogExceptionBacktrace' => true, 'PropagateErrors' => true, 'ShowHostnames' => false, 'OverrideHostname' => false, 'DevelopmentWarnings' => false, 'DeprecationReleaseLimit' => false, 'Profiler' => [ ], 'StatsdServer' => false, 'StatsdMetricPrefix' => 'MediaWiki', 'StatsTarget' => null, 'StatsFormat' => null, 'StatsPrefix' => 'mediawiki', 'OpenTelemetryConfig' => null, 'PageInfoTransclusionLimit' => 50, 'EnableJavaScriptTest' => false, 'DebugToolbar' => false, 'ApiClientErrorSampleRate' => 1.0, 'DisableTextSearch' => false, 'AdvancedSearchHighlighting' => false, 'SearchHighlightBoundaries' => '[\\p{Z}\\p{P}\\p{C}]', 'OpenSearchTemplates' => [ 'application/x-suggestions+json' => false, 'application/x-suggestions+xml' => false, ], 'OpenSearchDefaultLimit' => 10, 'OpenSearchDescriptionLength' => 100, 'SearchSuggestCacheExpiry' => 1200, 'DisableSearchUpdate' => false, 'NamespacesToBeSearchedDefault' => [ true, ], 'DisableInternalSearch' => false, 'SearchForwardUrl' => null, 'SitemapNamespaces' => false, 'SitemapNamespacesPriorities' => false, 'SitemapApiConfig' => [ ], 'SpecialSearchFormOptions' => [ ], 'SearchMatchRedirectPreference' => false, 'SearchRunSuggestedQuery' => true, 'Diff3' => '/usr/bin/diff3', 'Diff' => '/usr/bin/diff', 'PreviewOnOpenNamespaces' => [ 14 => true, ], 'UniversalEditButton' => true, 'UseAutomaticEditSummaries' => true, 'CommandLineDarkBg' => false, 'ReadOnly' => null, 'ReadOnlyWatchedItemStore' => false, 'ReadOnlyFile' => false, 'UpgradeKey' => false, 'GitBin' => '/usr/bin/git', 'GitRepositoryViewers' => [ 'https: 'ssh: 'https: 'git@github\\.com:(.*?)(\\.git)?' => 'https: ], 'InstallerInitialPages' => [ [ 'titlemsg' => 'mainpage', 'text' => '{{subst:int:mainpagetext}}{{subst:int:mainpagedocfooter}}', ], ], 'RCMaxAge' => 7776000, 'WatchersMaxAge' => 15552000, 'UnwatchedPageSecret' => 1, 'RCFilterByAge' => false, 'RCLinkLimits' => [ 50, 100, 250, 500, ], 'RCLinkDays' => [ 1, 3, 7, 14, 30, ], 'RCFeeds' => [ ], 'RCWatchCategoryMembership' => false, 'UseRCPatrol' => true, 'StructuredChangeFiltersLiveUpdatePollingRate' => 3, 'UseNPPatrol' => true, 'UseFilePatrol' => true, 'Feed' => true, 'FeedLimit' => 50, 'FeedCacheTimeout' => 60, 'FeedDiffCutoff' => 32768, 'OverrideSiteFeed' => [ ], 'FeedClasses' => [ 'rss' => 'MediaWiki\\Feed\\RSSFeed', 'atom' => 'MediaWiki\\Feed\\AtomFeed', ], 'AdvertisedFeedTypes' => [ 'atom', ], 'RCShowWatchingUsers' => false, 'RCShowChangedSize' => true, 'RCChangedSizeThreshold' => 500, 'ShowUpdatedMarker' => true, 'DisableAnonTalk' => false, 'UseTagFilter' => true, 'SoftwareTags' => [ 'mw-contentmodelchange' => true, 'mw-new-redirect' => true, 'mw-removed-redirect' => true, 'mw-changed-redirect-target' => true, 'mw-blank' => true, 'mw-replace' => true, 'mw-recreated' => true, 'mw-rollback' => true, 'mw-undo' => true, 'mw-manual-revert' => true, 'mw-reverted' => true, 'mw-server-side-upload' => true, 'mw-ipblock-appeal' => true, 'mw-edited-other-users-js' => true, 'mw-edited-other-users-css' => true, ], 'RestrictedTagViewRights' => [ ], 'UnwatchedPageThreshold' => false, 'RecentChangesFlags' => [ 'newpage' => [ 'letter' => 'newpageletter', 'title' => 'recentchanges-label-newpage', 'legend' => 'recentchanges-legend-newpage', 'grouping' => 'any', ], 'minor' => [ 'letter' => 'minoreditletter', 'title' => 'recentchanges-label-minor', 'legend' => 'recentchanges-legend-minor', 'class' => 'minoredit', 'grouping' => 'all', ], 'bot' => [ 'letter' => 'boteditletter', 'title' => 'recentchanges-label-bot', 'legend' => 'recentchanges-legend-bot', 'class' => 'botedit', 'grouping' => 'all', ], 'unpatrolled' => [ 'letter' => 'unpatrolledletter', 'title' => 'recentchanges-label-unpatrolled', 'legend' => 'recentchanges-legend-unpatrolled', 'grouping' => 'any', ], ], 'WatchlistExpiry' => false, 'EnableWatchstarPopover' => false, 'EnableWatchlistLabels' => false, 'WatchlistLabelsMaxPerUser' => 100, 'WatchlistPurgeRate' => 0.1, 'WatchlistExpiryMaxDuration' => '1 year', 'EnableChangesListQueryPartitioning' => false, 'RightsPage' => null, 'RightsUrl' => null, 'RightsText' => null, 'RightsIcon' => null, 'UseCopyrightUpload' => false, 'MaxCredits' => 0, 'ShowCreditsIfMax' => true, 'ImportSources' => [ ], 'ImportTargetNamespace' => null, 'ExportAllowHistory' => true, 'ExportMaxHistory' => 0, 'ExportAllowListContributors' => false, 'ExportMaxLinkDepth' => 0, 'ExportFromNamespaces' => false, 'ExportAllowAll' => false, 'ExportPagelistLimit' => 5000, 'XmlDumpSchemaVersion' => '0.11', 'WikiFarmSettingsDirectory' => null, 'WikiFarmSettingsExtension' => 'yaml', 'ExtensionFunctions' => [ ], 'ExtensionMessagesFiles' => [ ], 'MessagesDirs' => [ ], 'TranslationAliasesDirs' => [ ], 'ExtensionEntryPointListFiles' => [ ], 'EnableParserLimitReporting' => true, 'ValidSkinNames' => [ ], 'SpecialPages' => [ ], 'ExtensionCredits' => [ ], 'Hooks' => [ ], 'ServiceWiringFiles' => [ ], 'JobClasses' => [ 'deletePage' => 'MediaWiki\\Page\\DeletePageJob', 'refreshLinks' => 'MediaWiki\\JobQueue\\Jobs\\RefreshLinksJob', 'deleteLinks' => 'MediaWiki\\Page\\DeleteLinksJob', 'htmlCacheUpdate' => 'MediaWiki\\JobQueue\\Jobs\\HTMLCacheUpdateJob', 'sendMail' => [ 'class' => 'MediaWiki\\Mail\\EmaillingJob', 'services' => [ 'Emailer', ], ], 'enotifNotify' => [ 'class' => 'MediaWiki\\RecentChanges\\RecentChangeNotifyJob', 'services' => [ 'RecentChangeLookup', ], ], 'fixDoubleRedirect' => [ 'class' => 'MediaWiki\\JobQueue\\Jobs\\DoubleRedirectJob', 'services' => [ 'RevisionLookup', 'MagicWordFactory', 'WikiPageFactory', ], 'needsPage' => true, ], 'AssembleUploadChunks' => 'MediaWiki\\JobQueue\\Jobs\\AssembleUploadChunksJob', 'PublishStashedFile' => 'MediaWiki\\JobQueue\\Jobs\\PublishStashedFileJob', 'ThumbnailRender' => 'MediaWiki\\JobQueue\\Jobs\\ThumbnailRenderJob', 'UploadFromUrl' => 'MediaWiki\\JobQueue\\Jobs\\UploadFromUrlJob', 'recentChangesUpdate' => 'MediaWiki\\RecentChanges\\RecentChangesUpdateJob', 'refreshLinksPrioritized' => 'MediaWiki\\JobQueue\\Jobs\\RefreshLinksJob', 'refreshLinksDynamic' => 'MediaWiki\\JobQueue\\Jobs\\RefreshLinksJob', 'activityUpdateJob' => 'MediaWiki\\Watchlist\\ActivityUpdateJob', 'categoryMembershipChange' => [ 'class' => 'MediaWiki\\RecentChanges\\CategoryMembershipChangeJob', 'services' => [ 'RecentChangeFactory', ], ], 'CategoryCountUpdateJob' => [ 'class' => 'MediaWiki\\JobQueue\\Jobs\\CategoryCountUpdateJob', 'services' => [ 'ConnectionProvider', 'NamespaceInfo', ], ], 'clearUserWatchlist' => 'MediaWiki\\Watchlist\\ClearUserWatchlistJob', 'watchlistExpiry' => 'MediaWiki\\Watchlist\\WatchlistExpiryJob', 'cdnPurge' => 'MediaWiki\\JobQueue\\Jobs\\CdnPurgeJob', 'userGroupExpiry' => 'MediaWiki\\User\\UserGroupExpiryJob', 'clearWatchlistNotifications' => 'MediaWiki\\Watchlist\\ClearWatchlistNotificationsJob', 'userOptionsUpdate' => 'MediaWiki\\User\\Options\\UserOptionsUpdateJob', 'revertedTagUpdate' => 'MediaWiki\\JobQueue\\Jobs\\RevertedTagUpdateJob', 'null' => 'MediaWiki\\JobQueue\\Jobs\\NullJob', 'userEditCountInit' => 'MediaWiki\\User\\UserEditCountInitJob', 'parsoidCachePrewarm' => [ 'class' => 'MediaWiki\\JobQueue\\Jobs\\ParsoidCachePrewarmJob', 'services' => [ 'ParserOutputAccess', 'PageStore', 'RevisionLookup', 'ParsoidSiteConfig', ], 'needsPage' => false, ], 'renameUserTable' => [ 'class' => 'MediaWiki\\RenameUser\\Job\\RenameUserTableJob', 'services' => [ 'MainConfig', 'DBLoadBalancerFactory', ], ], 'renameUserDerived' => [ 'class' => 'MediaWiki\\RenameUser\\Job\\RenameUserDerivedJob', 'services' => [ 'RenameUserFactory', 'UserFactory', ], ], 'renameUser' => [ 'class' => 'MediaWiki\\RenameUser\\Job\\RenameUserTableJob', 'services' => [ 'MainConfig', 'DBLoadBalancerFactory', ], ], ], 'JobTypesExcludedFromDefaultQueue' => [ 'AssembleUploadChunks', 'PublishStashedFile', 'UploadFromUrl', ], 'JobBackoffThrottling' => [ ], 'JobTypeConf' => [ 'default' => [ 'class' => 'MediaWiki\\JobQueue\\JobQueueDB', 'order' => 'random', 'claimTTL' => 3600, ], ], 'JobQueueIncludeInMaxLagFactor' => false, 'SpecialPageCacheUpdates' => [ 'Statistics' => [ 'MediaWiki\\Deferred\\SiteStatsUpdate', 'cacheUpdate', ], ], 'PagePropLinkInvalidations' => [ 'hiddencat' => 'categorylinks', ], 'CategoryMagicGallery' => true, 'CategoryPagingLimit' => 200, 'CategoryCollation' => 'uppercase', 'TempCategoryCollations' => [ ], 'SortedCategories' => false, 'TrackingCategories' => [ ], 'LogTypes' => [ '', 'block', 'protect', 'rights', 'delete', 'upload', 'move', 'import', 'interwiki', 'patrol', 'merge', 'suppress', 'tag', 'managetags', 'contentmodel', 'renameuser', ], 'LogRestrictions' => [ 'suppress' => 'suppressionlog', ], 'FilterLogTypes' => [ 'patrol' => true, 'tag' => true, 'newusers' => false, ], 'LogNames' => [ '' => 'all-logs-page', 'block' => 'blocklogpage', 'protect' => 'protectlogpage', 'rights' => 'rightslog', 'delete' => 'dellogpage', 'upload' => 'uploadlogpage', 'move' => 'movelogpage', 'import' => 'importlogpage', 'patrol' => 'patrol-log-page', 'merge' => 'mergelog', 'suppress' => 'suppressionlog', ], 'LogHeaders' => [ '' => 'alllogstext', 'block' => 'blocklogtext', 'delete' => 'dellogpagetext', 'import' => 'importlogpagetext', 'merge' => 'mergelogpagetext', 'move' => 'movelogpagetext', 'patrol' => 'patrol-log-header', 'protect' => 'protectlogtext', 'rights' => 'rightslogtext', 'suppress' => 'suppressionlogtext', 'upload' => 'uploadlogpagetext', ], 'LogActions' => [ ], 'LogActionsHandlers' => [ 'block/block' => [ 'class' => 'MediaWiki\\Logging\\BlockLogFormatter', 'services' => [ 'TitleParser', 'NamespaceInfo', ], ], 'block/reblock' => [ 'class' => 'MediaWiki\\Logging\\BlockLogFormatter', 'services' => [ 'TitleParser', 'NamespaceInfo', ], ], 'block/unblock' => [ 'class' => 'MediaWiki\\Logging\\BlockLogFormatter', 'services' => [ 'TitleParser', 'NamespaceInfo', ], ], 'contentmodel/change' => 'MediaWiki\\Logging\\ContentModelLogFormatter', 'contentmodel/new' => 'MediaWiki\\Logging\\ContentModelLogFormatter', 'delete/delete' => 'MediaWiki\\Logging\\DeleteLogFormatter', 'delete/delete_redir' => 'MediaWiki\\Logging\\DeleteLogFormatter', 'delete/delete_redir2' => 'MediaWiki\\Logging\\DeleteLogFormatter', 'delete/event' => 'MediaWiki\\Logging\\DeleteLogFormatter', 'delete/restore' => 'MediaWiki\\Logging\\DeleteLogFormatter', 'delete/revision' => 'MediaWiki\\Logging\\DeleteLogFormatter', 'import/interwiki' => 'MediaWiki\\Logging\\ImportLogFormatter', 'import/upload' => 'MediaWiki\\Logging\\ImportLogFormatter', 'interwiki/iw_add' => 'MediaWiki\\Logging\\InterwikiLogFormatter', 'interwiki/iw_delete' => 'MediaWiki\\Logging\\InterwikiLogFormatter', 'interwiki/iw_edit' => 'MediaWiki\\Logging\\InterwikiLogFormatter', 'managetags/activate' => 'MediaWiki\\Logging\\LogFormatter', 'managetags/create' => 'MediaWiki\\Logging\\LogFormatter', 'managetags/deactivate' => 'MediaWiki\\Logging\\LogFormatter', 'managetags/delete' => 'MediaWiki\\Logging\\LogFormatter', 'merge/merge' => [ 'class' => 'MediaWiki\\Logging\\MergeLogFormatter', 'services' => [ 'TitleParser', ], ], 'merge/merge-into' => [ 'class' => 'MediaWiki\\Logging\\MergeLogFormatter', 'services' => [ 'TitleParser', ], ], 'move/move' => [ 'class' => 'MediaWiki\\Logging\\MoveLogFormatter', 'services' => [ 'TitleParser', ], ], 'move/move_redir' => [ 'class' => 'MediaWiki\\Logging\\MoveLogFormatter', 'services' => [ 'TitleParser', ], ], 'patrol/patrol' => 'MediaWiki\\Logging\\PatrolLogFormatter', 'patrol/autopatrol' => 'MediaWiki\\Logging\\PatrolLogFormatter', 'protect/modify' => [ 'class' => 'MediaWiki\\Logging\\ProtectLogFormatter', 'services' => [ 'TitleParser', ], ], 'protect/move_prot' => [ 'class' => 'MediaWiki\\Logging\\ProtectLogFormatter', 'services' => [ 'TitleParser', ], ], 'protect/protect' => [ 'class' => 'MediaWiki\\Logging\\ProtectLogFormatter', 'services' => [ 'TitleParser', ], ], 'protect/unprotect' => [ 'class' => 'MediaWiki\\Logging\\ProtectLogFormatter', 'services' => [ 'TitleParser', ], ], 'renameuser/renameuser' => [ 'class' => 'MediaWiki\\Logging\\RenameuserLogFormatter', 'services' => [ 'TitleParser', ], ], 'rights/autopromote' => 'MediaWiki\\Logging\\RightsLogFormatter', 'rights/rights' => 'MediaWiki\\Logging\\RightsLogFormatter', 'suppress/block' => [ 'class' => 'MediaWiki\\Logging\\BlockLogFormatter', 'services' => [ 'TitleParser', 'NamespaceInfo', ], ], 'suppress/delete' => 'MediaWiki\\Logging\\DeleteLogFormatter', 'suppress/event' => 'MediaWiki\\Logging\\DeleteLogFormatter', 'suppress/reblock' => [ 'class' => 'MediaWiki\\Logging\\BlockLogFormatter', 'services' => [ 'TitleParser', 'NamespaceInfo', ], ], 'suppress/revision' => 'MediaWiki\\Logging\\DeleteLogFormatter', 'tag/update' => 'MediaWiki\\Logging\\TagLogFormatter', 'upload/overwrite' => 'MediaWiki\\Logging\\UploadLogFormatter', 'upload/revert' => 'MediaWiki\\Logging\\UploadLogFormatter', 'upload/upload' => 'MediaWiki\\Logging\\UploadLogFormatter', ], 'ActionFilteredLogs' => [ 'block' => [ 'block' => [ 'block', ], 'reblock' => [ 'reblock', ], 'unblock' => [ 'unblock', ], ], 'contentmodel' => [ 'change' => [ 'change', ], 'new' => [ 'new', ], ], 'delete' => [ 'delete' => [ 'delete', ], 'delete_redir' => [ 'delete_redir', 'delete_redir2', ], 'restore' => [ 'restore', ], 'event' => [ 'event', ], 'revision' => [ 'revision', ], ], 'import' => [ 'interwiki' => [ 'interwiki', ], 'upload' => [ 'upload', ], ], 'managetags' => [ 'create' => [ 'create', ], 'delete' => [ 'delete', ], 'activate' => [ 'activate', ], 'deactivate' => [ 'deactivate', ], ], 'move' => [ 'move' => [ 'move', ], 'move_redir' => [ 'move_redir', ], ], 'newusers' => [ 'create' => [ 'create', 'newusers', ], 'create2' => [ 'create2', ], 'autocreate' => [ 'autocreate', ], 'byemail' => [ 'byemail', ], ], 'protect' => [ 'protect' => [ 'protect', ], 'modify' => [ 'modify', ], 'unprotect' => [ 'unprotect', ], 'move_prot' => [ 'move_prot', ], ], 'rights' => [ 'rights' => [ 'rights', ], 'autopromote' => [ 'autopromote', ], ], 'suppress' => [ 'event' => [ 'event', ], 'revision' => [ 'revision', ], 'delete' => [ 'delete', ], 'block' => [ 'block', ], 'reblock' => [ 'reblock', ], ], 'upload' => [ 'upload' => [ 'upload', ], 'overwrite' => [ 'overwrite', ], 'revert' => [ 'revert', ], ], ], 'NewUserLog' => true, 'PageCreationLog' => true, 'AllowSpecialInclusion' => true, 'DisableQueryPageUpdate' => false, 'CountCategorizedImagesAsUsed' => false, 'MaxRedirectLinksRetrieved' => 500, 'RangeContributionsCIDRLimit' => [ 'IPv4' => 16, 'IPv6' => 32, ], 'Actions' => [ ], 'DefaultRobotPolicy' => 'index,follow', 'NamespaceRobotPolicies' => [ ], 'ArticleRobotPolicies' => [ ], 'ExemptFromUserRobotsControl' => null, 'DebugAPI' => false, 'APIModules' => [ ], 'APIFormatModules' => [ ], 'APIMetaModules' => [ ], 'APIPropModules' => [ ], 'APIListModules' => [ ], 'APIMaxDBRows' => 5000, 'APIMaxResultSize' => 8388608, 'APIMaxUncachedDiffs' => 1, 'APIMaxLagThreshold' => 7, 'APICacheHelpTimeout' => 3600, 'APIUselessQueryPages' => [ 'MIMEsearch', 'LinkSearch', ], 'AjaxLicensePreview' => true, 'CrossSiteAJAXdomains' => [ ], 'CrossSiteAJAXdomainExceptions' => [ ], 'AllowedCorsHeaders' => [ 'Accept', 'Accept-Language', 'Content-Language', 'Content-Type', 'Accept-Encoding', 'DNT', 'Origin', 'User-Agent', 'Api-User-Agent', 'Promise-Non-Write-API-Action', 'Access-Control-Max-Age', 'Authorization', ], 'RestAPIAdditionalRouteFiles' => [ ], 'RestLocalModuleTestBaseUrl' => null, 'RestModuleOverrides' => [ ], 'RestExternalModules' => [ ], 'RestTermsOfServiceUrl' => null, 'MaxShellMemory' => 307200, 'MaxShellFileSize' => 102400, 'MaxShellTime' => 180, 'MaxShellWallClockTime' => 180, 'ShellCgroup' => false, 'PhpCli' => '/usr/bin/php', 'ShellRestrictionMethod' => 'autodetect', 'ShellboxUrls' => [ 'default' => null, ], 'ShellboxSecretKey' => null, 'ShellboxShell' => '/bin/sh', 'HTTPTimeout' => 25, 'HTTPConnectTimeout' => 5.0, 'HTTPMaxTimeout' => 0, 'HTTPMaxConnectTimeout' => 0, 'HTTPImportTimeout' => 25, 'HTTPUserAgentContact' => false, 'AsyncHTTPTimeout' => 25, 'HTTPProxy' => '', 'LocalVirtualHosts' => [ ], 'LocalHTTPProxy' => false, 'AllowExternalReqID' => false, 'GenerateReqIDFormat' => 'rand24', 'JobRunRate' => 1, 'RunJobsAsync' => false, 'UpdateRowsPerJob' => 300, 'UpdateRowsPerQuery' => 100, 'RedirectOnLogin' => null, 'EventRelayerConfig' => [ 'default' => [ 'class' => 'Wikimedia\\EventRelayer\\EventRelayerNull', ], ], 'Pingback' => false, 'OriginTrials' => [ ], 'ReportToExpiry' => 86400, 'ReportToEndpoints' => [ ], 'FeaturePolicyReportOnly' => [ ], 'SkinsPreferred' => [ 'vector-2022', 'vector', ], 'SpecialContributeSkinsEnabled' => [ ], 'SpecialContributeNewPageTarget' => null, 'EnableEditRecovery' => false, 'EditRecoveryExpiry' => 2592000, 'UseCodexSpecialBlock' => false, 'ShowLogoutConfirmation' => false, 'EnableProtectionIndicators' => true, 'OutputPipelineStages' => [ ], 'FeatureShutdown' => [ ], 'CloneArticleParserOutput' => true, 'UseLeximorph' => false, 'UsePostprocCacheLegacy' => false, 'UsePostprocCacheParsoid' => true, 'ParserOptionsLogUnsafeSampleRate' => 0, 'ReturnExperimentalPFragmentTypes' => [ ], 'UseParsoidLinksUpdate' => null, 'UseParsoidMessages' => true, ], 'type' => [ 'ConfigRegistry' => 'object', 'AssumeProxiesUseDefaultProtocolPorts' => 'boolean', 'ForceHTTPS' => 'boolean', 'ExtensionDirectory' => [ 'string', 'null', ], 'StyleDirectory' => [ 'string', 'null', ], 'UploadDirectory' => [ 'string', 'boolean', 'null', ], 'Logos' => [ 'object', 'boolean', ], 'ReferrerPolicy' => [ 'array', 'string', 'boolean', ], 'ActionPaths' => 'object', 'MainPageIsDomainRoot' => 'boolean', 'ImgAuthUrlPathMap' => 'object', 'LocalFileRepo' => 'object', 'ForeignFileRepos' => 'array', 'UseSharedUploads' => 'boolean', 'SharedUploadDirectory' => [ 'string', 'null', ], 'SharedUploadPath' => [ 'string', 'null', ], 'HashedSharedUploadDirectory' => 'boolean', 'FetchCommonsDescriptions' => 'boolean', 'SharedUploadDBname' => [ 'boolean', 'string', ], 'SharedUploadDBprefix' => 'string', 'SharedUploadDBschema' => [ 'string', 'null', ], 'CacheSharedUploads' => 'boolean', 'ForeignUploadTargets' => 'array', 'UploadDialog' => 'object', 'FileBackends' => 'object', 'LockManagers' => 'array', 'DefaultLockManager' => [ 'string', 'null', ], 'CopyUploadsDomains' => 'array', 'CopyUploadTimeout' => [ 'boolean', 'integer', ], 'SharedThumbnailScriptPath' => [ 'string', 'boolean', ], 'HashedUploadDirectory' => 'boolean', 'CSPUploadEntryPoint' => 'boolean', 'FileExtensions' => 'array', 'ProhibitedFileExtensions' => 'array', 'MimeTypeExclusions' => 'array', 'TrustedMediaFormats' => 'array', 'MediaHandlers' => 'object', 'NativeImageLazyLoading' => 'boolean', 'ParserTestMediaHandlers' => 'object', 'MaxInterlacingAreas' => 'object', 'SVGConverters' => 'object', 'SVGNativeRendering' => [ 'string', 'boolean', ], 'MaxImageArea' => [ 'string', 'integer', 'boolean', ], 'WebPThumbnailType' => 'array', 'TiffThumbnailType' => 'array', 'GenerateThumbnailOnParse' => 'boolean', 'EnableAutoRotation' => [ 'boolean', 'null', ], 'Antivirus' => [ 'string', 'null', ], 'AntivirusSetup' => 'object', 'MimeDetectorCommand' => [ 'string', 'null', ], 'XMLMimeTypes' => 'object', 'ImageLimits' => 'array', 'ThumbLimits' => 'array', 'ThumbnailNamespaces' => 'array', 'ThumbnailSteps' => [ 'array', 'null', ], 'ThumbnailBuckets' => [ 'array', 'null', ], 'UploadThumbnailRenderMap' => 'object', 'GalleryOptions' => 'object', 'DjvuDump' => [ 'string', 'null', ], 'DjvuRenderer' => [ 'string', 'null', ], 'DjvuTxt' => [ 'string', 'null', ], 'DjvuPostProcessor' => [ 'string', 'null', ], 'SMTP' => [ 'boolean', 'object', ], 'EnotifFromEditor' => 'boolean', 'EmailConfirmationBanner' => 'boolean', 'EnotifRevealEditorAddress' => 'boolean', 'UsersNotifiedOnAllChanges' => 'object', 'DBmwschema' => [ 'string', 'null', ], 'SharedTables' => 'array', 'DBservers' => [ 'boolean', 'array', ], 'LBFactoryConf' => 'object', 'LocalDatabases' => 'array', 'VirtualDomainsMapping' => 'object', 'RemoteVirtualDomainsMapping' => 'object', 'FileSchemaMigrationStage' => 'integer', 'ExternalLinksDomainGaps' => 'object', 'ContentHandlers' => 'object', 'NamespaceContentModels' => 'object', 'TextModelsToParse' => 'array', 'ExternalStores' => 'array', 'ExternalServers' => 'object', 'DefaultExternalStore' => [ 'array', 'boolean', ], 'RevisionCacheExpiry' => 'integer', 'PageLanguageUseDB' => 'boolean', 'DiffEngine' => [ 'string', 'null', ], 'ExternalDiffEngine' => [ 'string', 'boolean', ], 'Wikidiff2Options' => 'object', 'RequestTimeLimit' => [ 'integer', 'null', ], 'CriticalSectionTimeLimit' => 'number', 'PoolCounterConf' => [ 'object', 'null', ], 'PoolCountClientConf' => 'object', 'MaxUserDBWriteDuration' => [ 'integer', 'boolean', ], 'MaxJobDBWriteDuration' => [ 'integer', 'boolean', ], 'MultiShardSiteStats' => 'boolean', 'ObjectCaches' => 'object', 'WANObjectCache' => 'object', 'MicroStashType' => [ 'string', 'integer', ], 'ParsoidCacheConfig' => 'object', 'ParsoidSelectiveUpdateSampleRate' => 'integer', 'SplitParsoidParserCache' => 'boolean', 'ParserCacheFilterConfig' => 'object', 'ChronologyProtectorSecret' => 'string', 'SuspiciousIpExpiry' => [ 'integer', 'boolean', ], 'MemCachedServers' => 'array', 'LocalisationCacheConf' => 'object', 'ExtensionInfoMTime' => [ 'integer', 'boolean', ], 'CdnServers' => 'object', 'CdnServersNoPurge' => 'object', 'HTCPRouting' => 'object', 'GrammarForms' => 'object', 'ExtraInterlanguageLinkPrefixes' => 'array', 'InterlanguageLinkCodeMap' => 'object', 'ExtraLanguageNames' => 'object', 'ExtraLanguageCodes' => 'object', 'DummyLanguageCodes' => 'object', 'DisabledVariants' => 'object', 'ForceUIMsgAsContentMsg' => 'object', 'RawHtmlMessages' => 'array', 'OverrideUcfirstCharacters' => 'object', 'XhtmlNamespaces' => 'object', 'BrowserFormatDetection' => 'string', 'SkinMetaTags' => 'object', 'SkipSkins' => 'object', 'FragmentMode' => 'array', 'FooterIcons' => 'object', 'InterwikiLogoOverride' => 'array', 'ResourceModules' => 'object', 'ResourceModuleSkinStyles' => 'object', 'ResourceLoaderSources' => 'object', 'ResourceLoaderMaxage' => 'object', 'ResourceLoaderMaxQueryLength' => [ 'integer', 'boolean', ], 'CanonicalNamespaceNames' => 'object', 'ExtraNamespaces' => 'object', 'ExtraGenderNamespaces' => 'object', 'NamespaceAliases' => 'object', 'CapitalLinkOverrides' => 'object', 'NamespacesWithSubpages' => 'object', 'NamespacesWithoutAutoSummaries' => 'array', 'ContentNamespaces' => 'array', 'ShortPagesNamespaceExclusions' => 'array', 'ExtraSignatureNamespaces' => 'array', 'InvalidRedirectTargets' => 'array', 'LocalInterwikis' => 'array', 'InterwikiCache' => [ 'boolean', 'object', ], 'SiteTypes' => 'object', 'UrlProtocols' => 'array', 'TidyConfig' => 'object', 'ParsoidSettings' => 'object', 'ParsoidExperimentalParserFunctionOutput' => 'boolean', 'NoFollowNsExceptions' => 'array', 'NoFollowDomainExceptions' => 'array', 'ExternalLinksIgnoreDomains' => 'array', 'EnableMagicLinks' => 'object', 'ManualRevertSearchRadius' => 'integer', 'RevertedTagMaxDepth' => 'integer', 'CentralIdLookupProviders' => 'object', 'CentralIdLookupProvider' => 'string', 'UserRegistrationProviders' => 'object', 'PasswordPolicy' => 'object', 'AuthManagerConfig' => [ 'object', 'null', ], 'AuthManagerAutoConfig' => 'object', 'RememberMe' => 'string', 'ReauthenticateTime' => 'object', 'ChangeCredentialsBlacklist' => 'array', 'RemoveCredentialsBlacklist' => 'array', 'PasswordConfig' => 'object', 'PasswordResetRoutes' => 'object', 'SignatureAllowedLintErrors' => 'array', 'ReservedUsernames' => 'array', 'DefaultUserOptions' => 'object', 'ConditionalUserOptions' => 'object', 'HiddenPrefs' => 'array', 'UserJsPrefLimit' => 'integer', 'AuthenticationTokenVersion' => [ 'string', 'null', ], 'SessionProviders' => 'object', 'AutoCreateTempUser' => 'object', 'AutoblockExemptions' => 'array', 'BlockCIDRLimit' => 'object', 'EnableMultiBlocks' => 'boolean', 'GroupPermissions' => 'object', 'PrivilegedGroups' => 'array', 'RevokePermissions' => 'object', 'GroupInheritsPermissions' => 'object', 'ImplicitGroups' => 'array', 'GroupsAddToSelf' => 'object', 'GroupsRemoveFromSelf' => 'object', 'RestrictedGroups' => 'object', 'UserRequirementsPrivateConditions' => 'array', 'RestrictionTypes' => 'array', 'RestrictionLevels' => 'array', 'CascadingRestrictionLevels' => 'array', 'SemiprotectedRestrictionLevels' => 'array', 'NamespaceProtection' => 'object', 'RestrictUserPageEditing' => 'boolean', 'NonincludableNamespaces' => 'object', 'Autopromote' => 'object', 'AutopromoteOnce' => 'object', 'AutopromoteOnceRCExcludedGroups' => 'array', 'AddGroups' => 'object', 'RemoveGroups' => 'object', 'AvailableRights' => 'array', 'ImplicitRights' => 'array', 'AccountCreationThrottle' => [ 'integer', 'array', ], 'TempAccountCreationThrottle' => 'array', 'TempAccountNameAcquisitionThrottle' => 'array', 'SpamRegex' => 'array', 'SummarySpamRegex' => 'array', 'DnsBlacklistUrls' => 'array', 'ProxyList' => [ 'string', 'array', ], 'ProxyWhitelist' => 'array', 'SoftBlockRanges' => 'array', 'RateLimits' => 'object', 'RateLimitsExcludedIPs' => 'array', 'ExternalQuerySources' => 'object', 'PasswordAttemptThrottle' => 'array', 'GrantPermissions' => 'object', 'GrantPermissionGroups' => 'object', 'GrantRiskGroups' => 'object', 'EnableBotPasswords' => 'boolean', 'BotPasswordsCluster' => [ 'string', 'boolean', ], 'BotPasswordsDatabase' => [ 'string', 'boolean', ], 'BotPasswordsLimit' => 'integer', 'ReauthenticateForActions' => 'object', 'CSPHeader' => [ 'boolean', 'object', ], 'CSPReportOnlyHeader' => [ 'boolean', 'object', ], 'CSPUseReportURIDirective' => [ 'boolean', 'object', ], 'CSPFalsePositiveUrls' => 'object', 'AllowCrossOrigin' => 'boolean', 'RestAllowCrossOriginCookieAuth' => 'boolean', 'CookieSameSite' => [ 'string', 'null', ], 'CacheVaryCookies' => 'array', 'TrxProfilerLimits' => 'object', 'DebugLogGroups' => 'object', 'MWLoggerDefaultSpi' => 'object', 'Profiler' => 'object', 'StatsTarget' => [ 'string', 'null', ], 'StatsFormat' => [ 'string', 'null', ], 'StatsPrefix' => 'string', 'OpenTelemetryConfig' => [ 'object', 'null', ], 'OpenSearchTemplates' => 'object', 'NamespacesToBeSearchedDefault' => 'object', 'SitemapNamespaces' => [ 'boolean', 'array', ], 'SitemapNamespacesPriorities' => [ 'boolean', 'object', ], 'SitemapApiConfig' => 'object', 'SpecialSearchFormOptions' => 'object', 'SearchMatchRedirectPreference' => 'boolean', 'SearchRunSuggestedQuery' => 'boolean', 'PreviewOnOpenNamespaces' => 'object', 'ReadOnlyWatchedItemStore' => 'boolean', 'GitRepositoryViewers' => 'object', 'InstallerInitialPages' => 'array', 'RCLinkLimits' => 'array', 'RCLinkDays' => 'array', 'RCFeeds' => 'object', 'OverrideSiteFeed' => 'object', 'FeedClasses' => 'object', 'AdvertisedFeedTypes' => 'array', 'SoftwareTags' => 'object', 'RestrictedTagViewRights' => 'object', 'RecentChangesFlags' => 'object', 'WatchlistExpiry' => 'boolean', 'EnableWatchstarPopover' => 'boolean', 'EnableWatchlistLabels' => 'boolean', 'WatchlistLabelsMaxPerUser' => 'integer', 'WatchlistPurgeRate' => 'number', 'WatchlistExpiryMaxDuration' => [ 'string', 'null', ], 'EnableChangesListQueryPartitioning' => 'boolean', 'ImportSources' => 'object', 'ExtensionFunctions' => 'array', 'ExtensionMessagesFiles' => 'object', 'MessagesDirs' => 'object', 'TranslationAliasesDirs' => 'object', 'ExtensionEntryPointListFiles' => 'object', 'ValidSkinNames' => 'object', 'SpecialPages' => 'object', 'ExtensionCredits' => 'object', 'Hooks' => 'object', 'ServiceWiringFiles' => 'array', 'JobClasses' => 'object', 'JobTypesExcludedFromDefaultQueue' => 'array', 'JobBackoffThrottling' => 'object', 'JobTypeConf' => 'object', 'SpecialPageCacheUpdates' => 'object', 'PagePropLinkInvalidations' => 'object', 'TempCategoryCollations' => 'array', 'SortedCategories' => 'boolean', 'TrackingCategories' => 'array', 'LogTypes' => 'array', 'LogRestrictions' => 'object', 'FilterLogTypes' => 'object', 'LogNames' => 'object', 'LogHeaders' => 'object', 'LogActions' => 'object', 'LogActionsHandlers' => 'object', 'ActionFilteredLogs' => 'object', 'RangeContributionsCIDRLimit' => 'object', 'Actions' => 'object', 'NamespaceRobotPolicies' => 'object', 'ArticleRobotPolicies' => 'object', 'ExemptFromUserRobotsControl' => [ 'array', 'null', ], 'APIModules' => 'object', 'APIFormatModules' => 'object', 'APIMetaModules' => 'object', 'APIPropModules' => 'object', 'APIListModules' => 'object', 'APIUselessQueryPages' => 'array', 'CrossSiteAJAXdomains' => 'object', 'CrossSiteAJAXdomainExceptions' => 'object', 'AllowedCorsHeaders' => 'array', 'RestAPIAdditionalRouteFiles' => 'array', 'RestLocalModuleTestBaseUrl' => [ 'string', 'null', ], 'RestModuleOverrides' => 'object', 'RestExternalModules' => 'object', 'RestTermsOfServiceUrl' => [ 'string', 'null', ], 'ShellRestrictionMethod' => [ 'string', 'boolean', ], 'ShellboxUrls' => 'object', 'ShellboxSecretKey' => [ 'string', 'null', ], 'ShellboxShell' => [ 'string', 'null', ], 'HTTPTimeout' => 'number', 'HTTPConnectTimeout' => 'number', 'HTTPMaxTimeout' => 'number', 'HTTPMaxConnectTimeout' => 'number', 'HTTPUserAgentContact' => [ 'string', 'boolean', ], 'LocalVirtualHosts' => 'object', 'LocalHTTPProxy' => [ 'string', 'boolean', ], 'GenerateReqIDFormat' => 'string', 'EventRelayerConfig' => 'object', 'Pingback' => 'boolean', 'OriginTrials' => 'array', 'ReportToExpiry' => 'integer', 'ReportToEndpoints' => 'array', 'FeaturePolicyReportOnly' => 'array', 'SkinsPreferred' => 'array', 'SpecialContributeSkinsEnabled' => 'array', 'SpecialContributeNewPageTarget' => [ 'string', 'null', ], 'EnableEditRecovery' => 'boolean', 'EditRecoveryExpiry' => 'integer', 'UseCodexSpecialBlock' => 'boolean', 'ShowLogoutConfirmation' => 'boolean', 'EnableProtectionIndicators' => 'boolean', 'OutputPipelineStages' => 'object', 'FeatureShutdown' => 'array', 'CloneArticleParserOutput' => 'boolean', 'UseLeximorph' => 'boolean', 'UsePostprocCacheLegacy' => 'boolean', 'UsePostprocCacheParsoid' => 'boolean', 'ParserOptionsLogUnsafeSampleRate' => 'integer', 'ReturnExperimentalPFragmentTypes' => 'array', 'UseParsoidLinksUpdate' => [ 'boolean', 'null', ], 'UseParsoidMessages' => [ 'boolean', 'null', ], ], 'mergeStrategy' => [ 'WebPThumbnailType' => 'replace', 'TiffThumbnailType' => 'replace', 'LBFactoryConf' => 'replace', 'InterwikiCache' => 'replace', 'PasswordPolicy' => 'array_replace_recursive', 'AuthManagerAutoConfig' => 'array_plus_2d', 'GroupPermissions' => 'array_plus_2d', 'RevokePermissions' => 'array_plus_2d', 'AddGroups' => 'array_merge_recursive', 'RemoveGroups' => 'array_merge_recursive', 'RateLimits' => 'array_plus_2d', 'GrantPermissions' => 'array_plus_2d', 'MWLoggerDefaultSpi' => 'replace', 'Profiler' => 'replace', 'Hooks' => 'array_merge_recursive', 'RestModuleOverrides' => 'array_replace_recursive', 'RestExternalModules' => 'array_replace_recursive', ], 'dynamicDefault' => [ 'UsePathInfo' => [ 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultUsePathInfo', ], ], 'Script' => [ 'use' => [ 'ScriptPath', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultScript', ], ], 'LoadScript' => [ 'use' => [ 'ScriptPath', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultLoadScript', ], ], 'RestPath' => [ 'use' => [ 'ScriptPath', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultRestPath', ], ], 'StylePath' => [ 'use' => [ 'ResourceBasePath', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultStylePath', ], ], 'LocalStylePath' => [ 'use' => [ 'ScriptPath', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultLocalStylePath', ], ], 'ExtensionAssetsPath' => [ 'use' => [ 'ResourceBasePath', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultExtensionAssetsPath', ], ], 'ArticlePath' => [ 'use' => [ 'Script', 'UsePathInfo', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultArticlePath', ], ], 'UploadPath' => [ 'use' => [ 'ScriptPath', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultUploadPath', ], ], 'FileCacheDirectory' => [ 'use' => [ 'UploadDirectory', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultFileCacheDirectory', ], ], 'Logo' => [ 'use' => [ 'ResourceBasePath', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultLogo', ], ], 'DeletedDirectory' => [ 'use' => [ 'UploadDirectory', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultDeletedDirectory', ], ], 'ShowEXIF' => [ 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultShowEXIF', ], ], 'SharedPrefix' => [ 'use' => [ 'DBprefix', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultSharedPrefix', ], ], 'SharedSchema' => [ 'use' => [ 'DBmwschema', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultSharedSchema', ], ], 'DBerrorLogTZ' => [ 'use' => [ 'Localtimezone', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultDBerrorLogTZ', ], ], 'Localtimezone' => [ 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultLocaltimezone', ], ], 'LocalTZoffset' => [ 'use' => [ 'Localtimezone', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultLocalTZoffset', ], ], 'ResourceBasePath' => [ 'use' => [ 'ScriptPath', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultResourceBasePath', ], ], 'MetaNamespace' => [ 'use' => [ 'Sitename', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultMetaNamespace', ], ], 'CookieSecure' => [ 'use' => [ 'ForceHTTPS', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultCookieSecure', ], ], 'CookiePrefix' => [ 'use' => [ 'SharedDB', 'SharedPrefix', 'SharedTables', 'DBname', 'DBprefix', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultCookiePrefix', ], ], 'ReadOnlyFile' => [ 'use' => [ 'UploadDirectory', ], 'callback' => [ 'MediaWiki\\MainConfigSchema', 'getDefaultReadOnlyFile', ], ], ], ], 'config-schema' => [ 'UploadStashScalerBaseUrl' => [ 'deprecated' => 'since 1.36 Use thumbProxyUrl in $wgLocalFileRepo', ], 'IllegalFileChars' => [ 'deprecated' => 'since 1.41; no longer customizable', ], 'ThumbnailNamespaces' => [ 'items' => [ 'type' => 'integer', ], ], 'LocalDatabases' => [ 'items' => [ 'type' => 'string', ], ], 'ParserCacheFilterConfig' => [ 'additionalProperties' => [ 'type' => 'object', 'description' => 'A map of namespace IDs to filter definitions.', 'additionalProperties' => [ 'type' => 'object', 'description' => 'A map of filter names to values.', 'properties' => [ 'minCpuTime' => [ 'type' => 'number', ], ], ], ], ], 'RawHtmlMessages' => [ 'items' => [ 'type' => 'string', ], ], 'InterwikiLogoOverride' => [ 'items' => [ 'type' => 'string', ], ], 'LegalTitleChars' => [ 'deprecated' => 'since 1.41; use Extension:TitleBlacklist to customize', ], 'ReauthenticateTime' => [ 'additionalProperties' => [ 'type' => 'integer', ], ], 'ChangeCredentialsBlacklist' => [ 'items' => [ 'type' => 'string', ], ], 'RemoveCredentialsBlacklist' => [ 'items' => [ 'type' => 'string', ], ], 'GroupPermissions' => [ 'additionalProperties' => [ 'type' => 'object', 'additionalProperties' => [ 'type' => 'boolean', ], ], ], 'GroupInheritsPermissions' => [ 'additionalProperties' => [ 'type' => 'string', ], ], 'AvailableRights' => [ 'items' => [ 'type' => 'string', ], ], 'ImplicitRights' => [ 'items' => [ 'type' => 'string', ], ], 'SoftBlockRanges' => [ 'items' => [ 'type' => 'string', ], ], 'ExternalQuerySources' => [ 'additionalProperties' => [ 'type' => 'object', 'properties' => [ 'enabled' => [ 'type' => 'boolean', 'default' => false, ], 'url' => [ 'type' => 'string', 'format' => 'uri', ], 'timeout' => [ 'type' => 'integer', 'default' => 10, ], ], 'required' => [ 'enabled', 'url', ], 'additionalProperties' => false, ], ], 'GrantPermissions' => [ 'additionalProperties' => [ 'type' => 'object', 'additionalProperties' => [ 'type' => 'boolean', ], ], ], 'GrantPermissionGroups' => [ 'additionalProperties' => [ 'type' => 'string', ], ], 'SitemapNamespacesPriorities' => [ 'deprecated' => 'since 1.45 and ignored', ], 'SitemapApiConfig' => [ 'additionalProperties' => [ 'enabled' => [ 'type' => 'bool', ], 'sitemapsPerIndex' => [ 'type' => 'int', ], 'pagesPerSitemap' => [ 'type' => 'int', ], 'expiry' => [ 'type' => 'int', ], 'skipRedirects' => [ 'type' => 'bool', ], ], ], 'SoftwareTags' => [ 'additionalProperties' => [ 'type' => 'boolean', ], ], 'UseCopyrightUpload' => [ 'deprecated' => 'since 1.47 This feature is being removed.', ], 'JobBackoffThrottling' => [ 'additionalProperties' => [ 'type' => 'number', ], ], 'JobTypeConf' => [ 'additionalProperties' => [ 'type' => 'object', 'properties' => [ 'class' => [ 'type' => 'string', ], 'order' => [ 'type' => 'string', ], 'claimTTL' => [ 'type' => 'integer', ], ], ], ], 'TrackingCategories' => [ 'deprecated' => 'since 1.25 Extensions should now register tracking categories using the new extension registration system.', ], 'RangeContributionsCIDRLimit' => [ 'additionalProperties' => [ 'type' => 'integer', ], ], 'RestModuleOverrides' => [ 'additionalProperties' => [ 'type' => 'object', 'properties' => [ 'availability' => [ 'type' => 'string', ], ], 'required' => [ 'availability', ], ], ], 'RestExternalModules' => [ 'additionalProperties' => [ 'type' => 'object', 'properties' => [ 'info' => [ 'type' => 'object', 'properties' => [ 'version' => [ 'type' => 'string', ], 'title' => [ 'type' => 'string', ], 'x-i18n-title' => [ 'type' => 'string', ], 'description' => [ 'type' => 'string', ], 'x-i18n-description' => [ 'type' => 'string', ], ], 'required' => [ 'version', ], ], 'base' => [ 'type' => 'string', 'format' => 'uri', ], 'spec' => [ 'type' => 'string', 'format' => 'uri', ], ], 'required' => [ 'info', 'base', 'spec', ], ], ], 'ShellboxUrls' => [ 'additionalProperties' => [ 'type' => [ 'string', 'boolean', 'null', ], ], ], ], 'obsolete-config' => [ 'MangleFlashPolicy' => 'Since 1.39; no longer has any effect.', 'EnableOpenSearchSuggest' => 'Since 1.35, no longer used', 'AutoloadAttemptLowercase' => 'Since 1.40; no longer has any effect.', ],]
This interface represents the authority associated with the current execution context,...
Definition Authority.php:23
Interface for temporary user creation config and name matching.
Interface for objects representing user identity.
A database connection without write operations.
Result wrapper for grabbing data queried from an IDatabase object.