MediaWiki master
ChangesListSpecialPage.php
Go to the documentation of this file.
1<?php
8
34use OOUI\IconWidget;
35use stdClass;
39use Wikimedia\Timestamp\ConvertibleTimestamp;
40use Wikimedia\Timestamp\TimestampFormat as TS;
41
50abstract class ChangesListSpecialPage extends SpecialPage {
51
53 protected $rcSubpage;
54
56 protected $rcOptions;
57
59
60 private ?ChangesListResult $queryResult = null;
61
63 private $mainQueryHookRegistered = false;
65 private $mainQueryHookCalled = false;
66
74 public function __construct(
75 $name,
76 protected readonly UserIdentityUtils $userIdentityUtils,
77 protected TempUserConfig $tempUserConfig,
78 protected readonly RecentChangeFactory $recentChangeFactory,
79 protected readonly ChangesListQueryFactory $changesListQueryFactory,
80 ) {
81 parent::__construct( $name );
82
83 $this->filterGroups = new ChangesListFilterGroupContainer();
84 }
85
96 private function getBaseFilterGroupDefinitions() {
97 return [
98 [
99 'name' => 'registration',
100 'title' => 'rcfilters-filtergroup-registration',
101 'class' => ChangesListBooleanFilterGroup::class,
102 'filters' => [
103 [
104 'name' => 'hideliu',
105 // rcshowhideliu-show, rcshowhideliu-hide,
106 // wlshowhideliu
107 'showHideSuffix' => 'showhideliu',
108 'default' => false,
109 'action' => [ 'exclude', 'named' ],
110 'isReplacedInStructuredUi' => true,
111 ],
112 [
113 'name' => 'hideanons',
114 // rcshowhideanons-show, rcshowhideanons-hide,
115 // wlshowhideanons
116 'showHideSuffix' => 'showhideanons',
117 'default' => false,
118 'action' => [ 'require', 'named' ],
119 'isReplacedInStructuredUi' => true,
120 ]
121 ],
122 ],
123
124 [
125 'name' => 'userExpLevel',
126 'title' => 'rcfilters-filtergroup-user-experience-level',
127 'class' => ChangesListStringOptionsFilterGroup::class,
128 'isFullCoverage' => true,
129 'filters' => [
130 [
131 'name' => 'unregistered',
132 'requireConfig' => [ 'isRegistrationRequiredToEdit' => false ],
133 'label' => 'rcfilters-filter-user-experience-level-unregistered-label',
134 'description' => $this->tempUserConfig->isKnown() ?
135 'rcfilters-filter-user-experience-level-unregistered-description-temp' :
136 'rcfilters-filter-user-experience-level-unregistered-description',
137 'cssClassSuffix' => 'user-unregistered',
138 'action' => [ 'require', 'experience', 'unregistered' ],
139 ],
140 [
141 'name' => 'registered',
142 'requireConfig' => [ 'isRegistrationRequiredToEdit' => false ],
143 'label' => 'rcfilters-filter-user-experience-level-registered-label',
144 'description' => 'rcfilters-filter-user-experience-level-registered-description',
145 'cssClassSuffix' => 'user-registered',
146 'action' => [ 'require', 'experience', 'registered' ],
147 'subsets' => [ 'newcomer', 'learner', 'experienced' ],
148 ],
149 [
150 'name' => 'newcomer',
151 'label' => 'rcfilters-filter-user-experience-level-newcomer-label',
152 'description' => 'rcfilters-filter-user-experience-level-newcomer-description',
153 'cssClassSuffix' => 'user-newcomer',
154 'action' => [ 'require', 'experience', 'newcomer' ],
155 ],
156 [
157 'name' => 'learner',
158 'label' => 'rcfilters-filter-user-experience-level-learner-label',
159 'description' => 'rcfilters-filter-user-experience-level-learner-description',
160 'cssClassSuffix' => 'user-learner',
161 'action' => [ 'require', 'experience', 'learner' ],
162 ],
163 [
164 'name' => 'experienced',
165 'label' => 'rcfilters-filter-user-experience-level-experienced-label',
166 'description' => 'rcfilters-filter-user-experience-level-experienced-description',
167 'cssClassSuffix' => 'user-experienced',
168 'action' => [ 'require', 'experience', 'experienced' ],
169 ]
170 ],
172 ],
173
174 [
175 'name' => 'authorship',
176 'title' => 'rcfilters-filtergroup-authorship',
177 'class' => ChangesListBooleanFilterGroup::class,
178 'filters' => [
179 [
180 'name' => 'hidemyself',
181 'label' => 'rcfilters-filter-editsbyself-label',
182 'description' => 'rcfilters-filter-editsbyself-description',
183 // rcshowhidemine-show, rcshowhidemine-hide,
184 // wlshowhidemine
185 'showHideSuffix' => 'showhidemine',
186 'default' => false,
187 'action' => [ 'exclude', 'user', $this->getUser() ],
188 'highlight' => [ 'require', 'user', $this->getUser() ],
189 'cssClassSuffix' => 'self',
190 ],
191 [
192 'name' => 'hidebyothers',
193 'label' => 'rcfilters-filter-editsbyother-label',
194 'description' => 'rcfilters-filter-editsbyother-description',
195 'default' => false,
196 'action' => [ 'require', 'user', $this->getUser() ],
197 'highlight' => [ 'exclude', 'user', $this->getUser() ],
198 'cssClassSuffix' => 'others',
199 ]
200 ]
201 ],
202
203 [
204 'name' => 'automated',
205 'title' => 'rcfilters-filtergroup-automated',
206 'class' => ChangesListBooleanFilterGroup::class,
207 'filters' => [
208 [
209 'name' => 'hidebots',
210 'label' => 'rcfilters-filter-bots-label',
211 'description' => 'rcfilters-filter-bots-description',
212 // rcshowhidebots-show, rcshowhidebots-hide,
213 // wlshowhidebots
214 'showHideSuffix' => 'showhidebots',
215 'default' => false,
216 'action' => [ 'exclude', 'bot' ],
217 'highlight' => [ 'require', 'bot' ],
218 'cssClassSuffix' => 'bot',
219 ],
220 [
221 'name' => 'hidehumans',
222 'label' => 'rcfilters-filter-humans-label',
223 'description' => 'rcfilters-filter-humans-description',
224 'default' => false,
225 'action' => [ 'require', 'bot' ],
226 'highlight' => [ 'exclude', 'bot' ],
227 'cssClassSuffix' => 'human',
228 ]
229 ]
230 ],
231
232 // significance (conditional)
233
234 [
235 'name' => 'significance',
236 'title' => 'rcfilters-filtergroup-significance',
237 'class' => ChangesListBooleanFilterGroup::class,
238 'priority' => -6,
239 'filters' => [
240 [
241 'name' => 'hideminor',
242 'label' => 'rcfilters-filter-minor-label',
243 'description' => 'rcfilters-filter-minor-description',
244 // rcshowhideminor-show, rcshowhideminor-hide,
245 // wlshowhideminor
246 'showHideSuffix' => 'showhideminor',
247 'default' => false,
248 'action' => [ 'exclude', 'minor' ],
249 'highlight' => [ 'require', 'minor' ],
250 'cssClassSuffix' => 'minor',
251 'conflictOptions' => [
252 'globalKey' => 'rcfilters-hideminor-conflicts-typeofchange-global',
253 'forwardKey' => 'rcfilters-hideminor-conflicts-typeofchange',
254 'backwardKey' => 'rcfilters-typeofchange-conflicts-hideminor',
255 ],
256 'conflictsWith' => [
257 'changeType' => [
258 'hidecategorization' => [],
259 'hidelog' => [],
260 'hidenewuserlog' => [],
261 'hidenewpages' => []
262 ],
263 ],
264 ],
265 [
266 'name' => 'hidemajor',
267 'label' => 'rcfilters-filter-major-label',
268 'description' => 'rcfilters-filter-major-description',
269 'default' => false,
270 'action' => [ 'require', 'minor' ],
271 'highlight' => [ 'exclude', 'minor' ],
272 'cssClassSuffix' => 'major',
273 ]
274 ]
275 ],
276
277 [
278 'name' => 'lastRevision',
279 'title' => 'rcfilters-filtergroup-lastrevision',
280 'class' => ChangesListBooleanFilterGroup::class,
281 'priority' => -7,
282 'filters' => [
283 [
284 'name' => 'hidelastrevision',
285 'label' => 'rcfilters-filter-lastrevision-label',
286 'description' => 'rcfilters-filter-lastrevision-description',
287 'default' => false,
288 'action' => [
289 [ 'require', 'revisionType', 'old' ],
290 [ 'require', 'revisionType', 'none' ],
291 ],
292 'highlight' => [ 'require', 'revisionType', 'latest' ],
293 'cssClassSuffix' => 'last',
294 ],
295 [
296 'name' => 'hidepreviousrevisions',
297 'label' => 'rcfilters-filter-previousrevision-label',
298 'description' => 'rcfilters-filter-previousrevision-description',
299 'default' => false,
300 'action' => [
301 [ 'require', 'revisionType', 'latest' ],
302 [ 'require', 'revisionType', 'none' ],
303 ],
304 'highlight' => [ 'require', 'revisionType', 'old' ],
305 'cssClassSuffix' => 'previous',
306 ]
307 ]
308 ],
309
310 // With extensions, there can be change types that will not be hidden by any of these.
311 [
312 'name' => 'changeType',
313 'title' => 'rcfilters-filtergroup-changetype',
314 'class' => ChangesListBooleanFilterGroup::class,
315 'priority' => -8,
316 'filters' => [
317 [
318 'name' => 'hidepageedits',
319 'label' => 'rcfilters-filter-pageedits-label',
320 'description' => 'rcfilters-filter-pageedits-description',
321 'default' => false,
322 'priority' => -2,
323 'action' => [ 'exclude', 'source', RecentChange::SRC_EDIT ],
324 'highlight' => [ 'require', 'source', RecentChange::SRC_EDIT ],
325 'cssClassSuffix' => 'src-mw-edit',
326 ],
327 [
328 'name' => 'hidenewpages',
329 'label' => 'rcfilters-filter-newpages-label',
330 'description' => 'rcfilters-filter-newpages-description',
331 'default' => false,
332 'priority' => -3,
333 'action' => [ 'exclude', 'source', RecentChange::SRC_NEW ],
334 'highlight' => [ 'require', 'source', RecentChange::SRC_NEW ],
335 'cssClassSuffix' => 'src-mw-new',
336 ],
337 [
338 'name' => 'hidecategorization',
339 'label' => 'rcfilters-filter-categorization-label',
340 'description' => 'rcfilters-filter-categorization-description',
341 // rcshowhidecategorization-show, rcshowhidecategorization-hide.
342 // wlshowhidecategorization
343 'showHideSuffix' => 'showhidecategorization',
344 'default' => false,
345 'priority' => -4,
346 'requireConfig' => [ 'RCWatchCategoryMembership' => true ],
347 'action' => [ 'exclude', 'source', RecentChange::SRC_CATEGORIZE ],
348 'highlight' => [ 'require', 'source', RecentChange::SRC_CATEGORIZE ],
349 'cssClassSuffix' => 'src-mw-categorize',
350 'conflictOptions' => [
351 'globalKey' => 'rcfilters-hidecategorization-conflicts-reviewstatus-global',
352 'forwardKey' => 'rcfilters-hidecategorization-conflicts-reviewstatus',
353 'backwardKey' => 'rcfilters-reviewstatus-conflicts-reviewstatus',
354 ],
355 'conflictsWith' => [
356 'reviewStatus' => [
357 'unpatrolled' => [],
358 'manual' => [],
359 ],
360 ],
361 ],
362 [
363 'name' => 'hidelog',
364 'label' => 'rcfilters-filter-logactions-label',
365 'description' => 'rcfilters-filter-logactions-description',
366 'default' => false,
367 'priority' => -5,
368 'action' => [ 'exclude', 'source', RecentChange::SRC_LOG ],
369 'highlight' => [ 'require', 'source', RecentChange::SRC_LOG ],
370 'cssClassSuffix' => 'src-mw-log',
371 ],
372 [
373 'name' => 'hidenewuserlog',
374 'label' => 'rcfilters-filter-accountcreations-label',
375 'description' => 'rcfilters-filter-accountcreations-description',
376 'default' => false,
377 'priority' => -6,
378 'action' => [ 'exclude', 'logType', 'newusers' ],
379 'highlight' => [ 'require', 'logType', 'newusers' ],
380 'cssClassSuffix' => 'src-mw-newuserlog',
381 ],
382 ],
383 ],
384
385 [
386 'name' => 'legacyReviewStatus',
387 'title' => 'rcfilters-filtergroup-reviewstatus',
388 'class' => ChangesListBooleanFilterGroup::class,
389 'requireConfig' => [ 'useRCPatrol' => true ],
390 'filters' => [
391 [
392 'name' => 'hidepatrolled',
393 // rcshowhidepatr-show, rcshowhidepatr-hide
394 // wlshowhidepatr
395 'showHideSuffix' => 'showhidepatr',
396 'default' => false,
397 'action' => [ 'require', 'patrolled', RecentChange::PRC_UNPATROLLED ],
398 'isReplacedInStructuredUi' => true,
399 ],
400 [
401 'name' => 'hideunpatrolled',
402 'default' => false,
403 'action' => [ 'exclude', 'patrolled', RecentChange::PRC_UNPATROLLED ],
404 'isReplacedInStructuredUi' => true,
405 ],
406 ],
407 ],
408
409 [
410 'name' => 'reviewStatus',
411 'title' => 'rcfilters-filtergroup-reviewstatus',
412 'class' => ChangesListStringOptionsFilterGroup::class,
413 'isFullCoverage' => true,
414 'priority' => -5,
415 'requireConfig' => [ 'useRCPatrol' => true ],
416 'filters' => [
417 [
418 'name' => 'unpatrolled',
419 'label' => 'rcfilters-filter-reviewstatus-unpatrolled-label',
420 'description' => 'rcfilters-filter-reviewstatus-unpatrolled-description',
421 'cssClassSuffix' => 'reviewstatus-unpatrolled',
422 'action' => [ 'require', 'patrolled', RecentChange::PRC_UNPATROLLED ],
423 ],
424 [
425 'name' => 'manual',
426 'label' => 'rcfilters-filter-reviewstatus-manual-label',
427 'description' => 'rcfilters-filter-reviewstatus-manual-description',
428 'cssClassSuffix' => 'reviewstatus-manual',
429 'action' => [ 'require', 'patrolled', RecentChange::PRC_PATROLLED ],
430 ],
431 [
432 'name' => 'auto',
433 'label' => 'rcfilters-filter-reviewstatus-auto-label',
434 'description' => 'rcfilters-filter-reviewstatus-auto-description',
435 'cssClassSuffix' => 'reviewstatus-auto',
436 'action' => [ 'require', 'patrolled', RecentChange::PRC_AUTOPATROLLED ],
437 ],
438 ],
440 ],
441 ];
442 }
443
450 protected function getExtraFilterGroupDefinitions(): array {
451 return [];
452 }
453
457 public function execute( $subpage ) {
458 $this->rcSubpage = $subpage;
459
460 if ( $this->considerActionsForDefaultSavedQuery( $subpage ) ) {
461 // Don't bother rendering the page if we'll be performing a redirect (T330100).
462 return;
463 }
464
465 // Enable OOUI and module for the clock icon.
466 if ( $this->getConfig()->get( MainConfigNames::WatchlistExpiry ) && !$this->including() ) {
467 $this->getOutput()->enableOOUI();
468 $this->getOutput()->addModules( 'mediawiki.special.changeslist.watchlistexpiry' );
469 }
470
471 $opts = $this->getOptions();
472 try {
473 $result = $this->getQueryResult();
474 $rows = $result->getResultWrapper();
475
476 // Used by Structured UI app to get results without MW chrome
477 if ( $this->getRequest()->getRawVal( 'action' ) === 'render' ) {
478 $this->getOutput()->setArticleBodyOnly( true );
479 }
480
481 // Used by "live update" and "view newest" to check
482 // if there's new changes with minimal data transfer
483 if ( $this->getRequest()->getBool( 'peek' ) ) {
484 $code = $rows->numRows() > 0 ? 200 : 204;
485 $this->getOutput()->setStatusCode( $code );
486
487 if ( $this->getUser()->isAnon() !==
488 $this->getRequest()->getFuzzyBool( 'isAnon' )
489 ) {
490 $this->getOutput()->setStatusCode( 205 );
491 }
492
493 return;
494 }
495
496 $services = MediaWikiServices::getInstance();
497 $logFormatterFactory = $services->getLogFormatterFactory();
498 $linkBatchFactory = $services->getLinkBatchFactory();
499 $batch = $linkBatchFactory->newLinkBatch();
500 $userNames = [];
501 foreach ( $rows as $row ) {
502 $batch->addUser( new UserIdentityValue( $row->rc_user ?? 0, $row->rc_user_text ) );
503 $userNames[] = $row->rc_user_text;
504 $batch->add( $row->rc_namespace, $row->rc_title );
505 if ( $row->rc_source === RecentChange::SRC_LOG ) {
506 $formatter = $logFormatterFactory->newFromRow( $row );
507 foreach ( $formatter->getPreloadTitles() as $title ) {
508 $batch->addObj( $title );
509 if ( $title->inNamespace( NS_USER ) || $title->inNamespace( NS_USER_TALK ) ) {
510 $userNames[] = $title->getText();
511 }
512 }
513 }
514 }
515 $batch->execute();
516 foreach ( UserArray::newFromNames( $userNames ) as $_ ) {
517 // Trigger UserEditTracker::setCachedUserEditCount via User::loadFromRow
518 // Preloads edit count for User::getExperienceLevel() and Linker::userToolLinks()
519 }
520
521 $this->setHeaders();
522 $this->outputHeader();
523 $this->addModules();
524 $this->webOutput( $rows, $opts );
525 } catch ( DBQueryTimeoutError $timeoutException ) {
526 MWExceptionHandler::logException( $timeoutException );
527
528 $this->setHeaders();
529 $this->outputHeader();
530 $this->addModules();
531
532 $this->getOutput()->setStatusCode( 500 );
533 $this->webOutputHeader( 0, $opts );
534 $this->outputTimeout();
535 }
536
537 $this->includeRcFiltersApp();
538 }
539
547 public function setTempUserConfig( TempUserConfig $tempUserConfig ) {
548 $this->tempUserConfig = $tempUserConfig;
549 $this->changesListQueryFactory->setTempUserConfig( $tempUserConfig );
550 }
551
560 protected function considerActionsForDefaultSavedQuery( $subpage ) {
561 if ( !$this->isStructuredFilterUiEnabled() || $this->including() ) {
562 return false;
563 }
564
565 $knownParams = $this->getRequest()->getValues(
566 ...array_keys( $this->getOptions()->getAllValues() )
567 );
568
569 // HACK: Temporarily until we can properly define "sticky" filters and parameters,
570 // we need to exclude several parameters we know should not be counted towards preventing
571 // the loading of defaults.
572 $excludedParams = [ 'limit' => '', 'days' => '', 'enhanced' => '', 'from' => '' ];
573 $knownParams = array_diff_key( $knownParams, $excludedParams );
574
575 if (
576 // If there are NO known parameters in the URL request
577 // (that are not excluded) then we need to check into loading
578 // the default saved query
579 count( $knownParams ) === 0
580 ) {
582 ->getUserOptionsLookup()
583 ->getOption( $this->getUser(), $this->getSavedQueriesPreferenceName() );
584
585 // Get the saved queries data and parse it
586 $savedQueries = $prefJson ? FormatJson::decode( $prefJson, true ) : false;
587
588 if ( $savedQueries && isset( $savedQueries[ 'default' ] ) ) {
589 // Only load queries that are 'version' 2, since those
590 // have parameter representation
591 if ( isset( $savedQueries[ 'version' ] ) && $savedQueries[ 'version' ] === '2' ) {
592 $savedQueryDefaultID = $savedQueries[ 'default' ];
593 $defaultQuery = $savedQueries[ 'queries' ][ $savedQueryDefaultID ][ 'data' ];
594
595 // Build the entire parameter list
596 $query = array_merge(
597 $defaultQuery[ 'params' ],
598 $defaultQuery[ 'highlights' ],
599 [
600 'urlversion' => '2',
601 ]
602 );
603 // Add to the query any parameters that we may have ignored before
604 // but are still valid and requested in the URL
605 $query = array_merge( $this->getRequest()->getQueryValues(), $query );
606 unset( $query[ 'title' ] );
607 $this->getOutput()->redirect( $this->getPageTitle( $subpage )->getCanonicalURL( $query ) );
608
609 // Signal that we only need to redirect to the full URL
610 // and can skip rendering the actual page (T330100).
611 return true;
612 } else {
613 // There's a default, but the version is not 2, and the server can't
614 // actually recognize the query itself. This happens if it is before
615 // the conversion, so we need to tell the UI to reload saved query as
616 // it does the conversion to version 2
617 $this->getOutput()->addJsConfigVars(
618 'wgStructuredChangeFiltersDefaultSavedQueryExists',
619 true
620 );
621
622 // Add the class that tells the frontend it is still loading
623 // another query
624 $this->getOutput()->addBodyClasses( 'mw-rcfilters-ui-loading' );
625 }
626 }
627 }
628
629 return false;
630 }
631
636 protected function getLinkDays() {
637 $linkDays = $this->getConfig()->get( MainConfigNames::RCLinkDays );
638 $filterByAge = $this->getConfig()->get( MainConfigNames::RCFilterByAge );
639 $maxAge = $this->getConfig()->get( MainConfigNames::RCMaxAge );
640 if ( $filterByAge ) {
641 // Trim it to only links which are within $wgRCMaxAge.
642 // Note that we allow one link higher than the max for things like
643 // "age 56 days" being accessible through the "60 days" link.
644 sort( $linkDays );
645
646 $maxAgeDays = $maxAge / ( 3600 * 24 );
647 foreach ( $linkDays as $i => $days ) {
648 if ( $days >= $maxAgeDays ) {
649 array_splice( $linkDays, $i + 1 );
650 break;
651 }
652 }
653 }
654
655 return $linkDays;
656 }
657
664 protected function includeRcFiltersApp() {
665 $out = $this->getOutput();
666 if ( $this->isStructuredFilterUiEnabled() && !$this->including() ) {
667 $jsData = $this->filterGroups->getJsData();
668 $messages = [];
669 foreach ( $jsData['messageKeys'] as $key ) {
670 $messages[$key] = $this->msg( $key )->plain();
671 }
672
673 $out->addBodyClasses( 'mw-rcfilters-enabled' );
674 $collapsed = MediaWikiServices::getInstance()->getUserOptionsLookup()
675 ->getBoolOption( $this->getUser(), $this->getCollapsedPreferenceName() );
676 if ( $collapsed ) {
677 $out->addBodyClasses( 'mw-rcfilters-collapsed' );
678 }
679
680 // These config and message exports should be moved into a ResourceLoader data module (T201574)
681 $out->addJsConfigVars( 'wgStructuredChangeFilters', $jsData['groups'] );
682 $out->addJsConfigVars( 'wgStructuredChangeFiltersMessages', $messages );
683 $out->addJsConfigVars( 'wgStructuredChangeFiltersCollapsedState', $collapsed );
684
685 $out->addJsConfigVars(
686 'StructuredChangeFiltersDisplayConfig',
687 [
688 'maxDays' => // Translate to days
689 (int)$this->getConfig()->get( MainConfigNames::RCMaxAge ) / ( 24 * 3600 ),
690 'limitArray' => $this->getConfig()->get( MainConfigNames::RCLinkLimits ),
691 'limitDefault' => $this->getDefaultLimit(),
692 'daysArray' => $this->getLinkDays(),
693 'daysDefault' => $this->getDefaultDays(),
694 ]
695 );
696
697 $out->addJsConfigVars(
698 'wgStructuredChangeFiltersSavedQueriesPreferenceName',
699 $this->getSavedQueriesPreferenceName()
700 );
701 $out->addJsConfigVars(
702 'wgStructuredChangeFiltersLimitPreferenceName',
703 $this->getLimitPreferenceName()
704 );
705 $out->addJsConfigVars(
706 'wgStructuredChangeFiltersDaysPreferenceName',
707 $this->getDefaultDaysPreferenceName()
708 );
709 $out->addJsConfigVars(
710 'wgStructuredChangeFiltersCollapsedPreferenceName',
711 $this->getCollapsedPreferenceName()
712 );
713 } else {
714 $out->addBodyClasses( 'mw-rcfilters-disabled' );
715 }
716 }
717
726 public static function getRcFiltersConfigSummary( RL\Context $context ) {
727 $lang = MediaWikiServices::getInstance()->getLanguageFactory()
728 ->getLanguage( $context->getLanguage() );
729 return [
730 // Reduce version computation by avoiding Message parsing
731 'RCFiltersChangeTags' => ChangeTags::getChangeTagListSummary( $context, $lang ),
732 'StructuredChangeFiltersEditWatchlistUrl' =>
733 SpecialPage::getTitleFor( 'EditWatchlist' )->getLocalURL()
734 ];
735 }
736
744 public static function getRcFiltersConfigVars( RL\Context $context ) {
745 $lang = MediaWikiServices::getInstance()->getLanguageFactory()
746 ->getLanguage( $context->getLanguage() );
747 return [
748 'RCFiltersChangeTags' => ChangeTags::getChangeTagList( $context, $lang ),
749 'StructuredChangeFiltersEditWatchlistUrl' =>
750 SpecialPage::getTitleFor( 'EditWatchlist' )->getLocalURL()
751 ];
752 }
753
757 protected function outputNoResults() {
758 $this->getOutput()->addHTML(
759 Html::rawElement(
760 'div',
761 [ 'class' => 'mw-changeslist-empty' ],
762 $this->msg( 'recentchanges-noresult' )->parse()
763 )
764 );
765 }
766
770 protected function outputTimeout() {
771 $this->getOutput()->addHTML(
772 '<div class="mw-changeslist-empty mw-changeslist-timeout">' .
773 $this->msg( 'recentchanges-timeout' )->parse() .
774 '</div>'
775 );
776 }
777
783 public function getRows() {
784 return $this->getQueryResult()->getResultWrapper();
785 }
786
792 protected function getQueryResult(): ChangesListResult {
793 if ( !$this->queryResult ) {
794 $opts = $this->getOptions();
795 $query = $this->buildQuery( $opts );
796 $this->modifyQuery( $query, $opts );
797 $this->queryResult = $query->fetchResult();
798
799 if ( $this->mainQueryHookRegistered && !$this->mainQueryHookCalled ) {
800 // When an empty result set is forced, ChangesListQuery doesn't run
801 // the hook, but some extensions need us to run it anyway to register
802 // form options.
803 // FIXME: risky to pass empty arrays here, and inefficient to
804 // call this hook when most of what it does is not needed.
805 // We need to deprecate it.
806 $tables = $fields = $conds = $options = $joins = [];
807 $this->runMainQueryHook( $tables, $fields, $conds, $options,
808 $joins, $opts );
809 }
810 }
811 return $this->queryResult;
812 }
813
821 protected function newRecentChangeFromRow( $row ) {
822 $rc = $this->recentChangeFactory->newRecentChangeFromRow( $row );
823 $rc->setHighlights( $this->getQueryResult()->getHighlightsFromRow( $row ) );
824 return $rc;
825 }
826
832 public function getOptions() {
833 if ( $this->rcOptions === null ) {
834 $this->rcOptions = $this->setup( $this->rcSubpage );
835 }
836
837 return $this->rcOptions;
838 }
839
847 private function getBaseFilterFactoryConfig() {
848 return [
849 'showHidePrefix' => '',
850 'isRegistrationRequiredToEdit' => !MediaWikiServices::getInstance()
851 ->getPermissionManager()
852 ->isEveryoneAllowed( "edit" ),
853 'useRCPatrol' => !$this->including() && $this->getUser()->useRCPatrol(),
854 'RCWatchCategoryMembership' =>
855 $this->getConfig()->get( MainConfigNames::RCWatchCategoryMembership ),
856 ];
857 }
858
864 protected function getExtraFilterFactoryConfig(): array {
865 return [];
866 }
867
874 protected function getFilterDefaultOverrides(): array {
875 return [];
876 }
877
880 $this->getExtraFilterFactoryConfig() + $this->getBaseFilterFactoryConfig()
881 );
882 }
883
888 protected function registerFilters() {
889 $filterFactory = $this->getFilterFactory();
890 $filterFactory->registerFiltersFromDefinitions(
891 $this->filterGroups,
892 $this->getBaseFilterGroupDefinitions()
893 );
894 $filterFactory->registerFiltersFromDefinitions(
895 $this->filterGroups,
896 $this->getExtraFilterGroupDefinitions()
897 );
898 $this->getHookRunner()->onChangesListSpecialPageStructuredFilters( $this );
899 $this->filterGroups->setDefaults( $this->getFilterDefaultOverrides() );
900 }
901
912 protected function registerFiltersFromDefinitions( array $definition ) {
913 $this->getFilterFactory()->registerFiltersFromDefinitions( $this->filterGroups, $definition );
914 }
915
924 public function setup( $parameters ) {
925 $this->registerFilters();
926
927 $opts = $this->getDefaultOptions();
928
929 $opts = $this->fetchOptionsFromRequest( $opts );
930
931 // Give precedence to subpage syntax
932 if ( $parameters !== null ) {
933 $this->parseParameters( $parameters, $opts );
934 }
935
936 $this->validateOptions( $opts );
937
938 return $opts;
939 }
940
950 public function getDefaultOptions() {
951 $opts = new FormOptions();
952 $structuredUI = $this->isStructuredFilterUiEnabled();
953 // If urlversion=2 is set, ignore the filter defaults and set them all to false/empty
954 $useDefaults = $this->getRequest()->getInt( 'urlversion' ) !== 2;
955
956 $this->filterGroups->addOptions( $opts, $useDefaults, $structuredUI );
957
958 $opts->add( 'namespace', '', FormOptions::STRING );
959 $opts->add( 'subpageof', '', FormOptions::STRING );
960 // TODO: Rename this option to 'invertnamespaces'?
961 $opts->add( 'invert', false );
962 $opts->add( 'associated', false );
963 $opts->add( 'urlversion', 1 );
964 $opts->add( 'tagfilter', '' );
965 $opts->add( 'inverttags', false );
966
967 $opts->add( 'days', $this->getDefaultDays(), FormOptions::FLOAT );
968 $opts->add( 'limit', $this->getDefaultLimit(), FormOptions::INT );
969
970 $opts->add( 'from', '' );
971
972 return $opts;
973 }
974
978 public function registerFilterGroup( ChangesListFilterGroup $group ) {
979 $this->filterGroups->registerGroup( $group );
980 }
981
991 public function getFilterGroup( $groupName ) {
992 return $this->filterGroups->getGroup( $groupName );
993 }
994
1003 protected function getStructuredFilterJsData() {
1004 return $this->filterGroups->getJsData();
1005 }
1006
1015 protected function fetchOptionsFromRequest( $opts ) {
1016 $opts->fetchValuesFromRequest( $this->getRequest() );
1017
1018 return $opts;
1019 }
1020
1029 public function parseParameters( $par, FormOptions $opts ) {
1030 $params = $this->filterGroups->getSubpageParams();
1031
1032 $bits = preg_split( '/\s*,\s*/', trim( $par ) );
1033 foreach ( $bits as $bit ) {
1034 $m = [];
1035 if ( ( $params[$bit] ?? '' ) === 'bool' ) {
1036 // hidefoo => hidefoo=true
1037 $opts[$bit] = true;
1038 } elseif ( ( $params["hide$bit"] ?? '' ) === 'bool' ) {
1039 // foo => hidefoo=false
1040 $opts["hide$bit"] = false;
1041 } elseif ( preg_match( '/^(.*)=(.*)$/', $bit, $m ) ) {
1042 if ( ( $params[$m[1]] ?? '' ) === 'string' ) {
1043 $opts[$m[1]] = $m[2];
1044 }
1045 }
1046 }
1047 }
1048
1052 public function validateOptions( FormOptions $opts ) {
1053 $isContradictory = $this->fixContradictoryOptions( $opts );
1054 $isReplaced = $this->replaceOldOptions( $opts );
1055
1056 if ( $isContradictory || $isReplaced ) {
1057 $query = wfArrayToCgi( $this->convertParamsForLink( $opts->getChangedValues() ) );
1058 $this->getOutput()->redirect( $this->getPageTitle()->getCanonicalURL( $query ) );
1059 }
1060
1061 $opts->validateIntBounds( 'limit', 0, 5000 );
1062 $opts->validateBounds( 'days', 0,
1063 $this->getConfig()->get( MainConfigNames::RCMaxAge ) / ( 3600 * 24 ) );
1064 }
1065
1072 private function fixContradictoryOptions( FormOptions $opts ) {
1073 $fixed = $this->fixBackwardsCompatibilityOptions( $opts );
1074 $fixed = $this->filterGroups->fixContradictoryOptions( $opts ) || $fixed;
1075
1076 // Namespace conflicts with subpageof
1077 if ( $opts['namespace'] !== '' && $opts['subpageof'] !== '' ) {
1078 $opts['namespace'] = '';
1079 $fixed = true;
1080 }
1081
1082 return $fixed;
1083 }
1084
1094 private function fixBackwardsCompatibilityOptions( FormOptions $opts ) {
1095 if ( $opts['hideanons'] && $opts['hideliu'] ) {
1096 $opts->reset( 'hideanons' );
1097 if ( !$opts['hidebots'] ) {
1098 $opts->reset( 'hideliu' );
1099 $opts['hidehumans'] = 1;
1100 }
1101
1102 return true;
1103 }
1104
1105 return false;
1106 }
1107
1114 public function replaceOldOptions( FormOptions $opts ) {
1115 if ( !$this->isStructuredFilterUiEnabled() ) {
1116 return false;
1117 }
1118
1119 $changed = false;
1120
1121 // At this point 'hideanons' and 'hideliu' cannot be both true,
1122 // because fixBackwardsCompatibilityOptions resets (at least) 'hideanons' in such case
1123 if ( $opts[ 'hideanons' ] ) {
1124 $opts->reset( 'hideanons' );
1125 $opts[ 'userExpLevel' ] = 'registered';
1126 $changed = true;
1127 }
1128
1129 if ( $opts[ 'hideliu' ] ) {
1130 $opts->reset( 'hideliu' );
1131 $opts[ 'userExpLevel' ] = 'unregistered';
1132 $changed = true;
1133 }
1134
1135 if ( $this->filterGroups->hasGroup( 'legacyReviewStatus' ) ) {
1136 if ( $opts[ 'hidepatrolled' ] ) {
1137 $opts->reset( 'hidepatrolled' );
1138 $opts[ 'reviewStatus' ] = 'unpatrolled';
1139 $changed = true;
1140 }
1141
1142 if ( $opts[ 'hideunpatrolled' ] ) {
1143 $opts->reset( 'hideunpatrolled' );
1144 $opts[ 'reviewStatus' ] = implode(
1145 ChangesListStringOptionsFilterGroup::SEPARATOR,
1146 [ 'manual', 'auto' ]
1147 );
1148 $changed = true;
1149 }
1150 }
1151
1152 return $changed;
1153 }
1154
1163 protected function convertParamsForLink( $params ) {
1164 foreach ( $params as &$value ) {
1165 if ( $value === false ) {
1166 $value = '0';
1167 }
1168 }
1169 unset( $value );
1170 return $params;
1171 }
1172
1180 protected function buildQuery( FormOptions $opts ) {
1181 $dbr = $this->getDB();
1182 $isStructuredUI = $this->isStructuredFilterUiEnabled();
1183
1184 $query = $this->changesListQueryFactory->newQuery()
1185 ->recentChangeFields()
1186 ->watchlistUser( $this->getUser() )
1187 ->audience( $this->getAuthority() )
1188 ->excludeDeletedLogAction()
1189 ->limit( $opts['limit'] )
1190 ->maxExecutionTime( $this->getConfig()->get(
1191 MainConfigNames::MaxExecutionTimeForExpensiveQueries ) )
1192 ->caller( static::class . '::buildQuery' );
1193
1194 // Main query hook
1195 $this->addMainQueryHook( $query, $opts );
1196
1197 // Old filter groups interface
1198 $query->legacyMutator(
1199 function (
1200 &$tables,
1201 &$fields,
1202 &$conds,
1203 &$query_options,
1204 &$join_conds,
1205 ) use ( $dbr, $opts, $isStructuredUI ) {
1206 $this->filterGroups->modifyLegacyQuery(
1207 $dbr,
1208 $this,
1209 $tables,
1210 $fields,
1211 $conds,
1212 $query_options,
1213 $join_conds,
1214 $opts,
1215 $isStructuredUI
1216 );
1217 }
1218 );
1219
1220 // New filter groups interface
1221 $this->filterGroups->modifyChangesListQuery( $query, $opts, $isStructuredUI );
1222
1223 // Namespace filtering
1224 if ( $opts[ 'namespace' ] !== '' ) {
1225 $namespaces = explode( ';', $opts[ 'namespace' ] );
1226 $namespaces = $this->expandSymbolicNamespaceFilters( $namespaces );
1227 if ( $namespaces !== [] ) {
1228 if ( $opts[ 'associated' ] ) {
1229 $namespaceInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
1230 $associatedNamespaces = array_map(
1231 $namespaceInfo->getAssociated( ... ),
1232 array_filter( $namespaces, $namespaceInfo->hasTalkNamespace( ... ) )
1233 );
1234 $namespaces = array_unique( array_merge( $namespaces, $associatedNamespaces ) );
1235 }
1236
1237 if ( $opts['invert'] ) {
1238 $query->excludeNamespaces( $namespaces );
1239 } else {
1240 $query->requireNamespaces( $namespaces );
1241 }
1242 }
1243 }
1244
1245 // Filtering for subpages of a given set of pages
1246 if ( $opts['subpageof'] !== '' ) {
1247 $titleParser = MediaWikiServices::getInstance()->getTitleParser();
1248 $basePages = explode( '|', $opts['subpageof'] );
1249 foreach ( $basePages as $basePageText ) {
1250 // Strip any trailing slash
1251 $basePageText = rtrim( $basePageText, '/' );
1252 try {
1253 $basePage = $titleParser->parseTitle( $basePageText );
1254 } catch ( MalformedTitleException ) {
1255 // Ignore invalid titles
1256 continue;
1257 }
1258 $query->requireSubpageOf( $basePage );
1259 }
1260 }
1261
1262 // Change tags
1263 if ( $this->getConfig()->get( MainConfigNames::UseTagFilter ) ) {
1264 $tagFilter = $opts['tagfilter'] !== '' ? explode( '|', $opts['tagfilter'] ) : [];
1265 if ( $opts['inverttags'] ) {
1266 $query->excludeChangeTags( $tagFilter );
1267 } else {
1268 $query->requireChangeTags( $tagFilter );
1269 }
1270 }
1271 $query->addChangeTagSummaryField();
1272
1273 // Calculate cutoff
1274 $cutoff_unixtime = ConvertibleTimestamp::time() - $opts['days'] * 3600 * 24;
1275 $cutoff = $dbr->timestamp( $cutoff_unixtime );
1276
1277 $fromValid = preg_match( '/^[0-9]{14}$/', $opts['from'] );
1278 if ( $fromValid && $opts['from'] > wfTimestamp( TS::MW, $cutoff ) ) {
1279 $cutoff = $dbr->timestamp( $opts['from'] );
1280 } else {
1281 $opts->reset( 'from' );
1282 }
1283
1284 $query->minTimestamp( $cutoff );
1285
1286 // Feature flag
1287 if ( $this->getRequest()->getBool( 'enable_partitioning' ) ) {
1288 $query->enablePartitioning();
1289 }
1290 return $query;
1291 }
1292
1299 protected function modifyQuery( ChangesListQuery $query, FormOptions $opts ) {
1300 }
1301
1311 protected function runMainQueryHook( &$tables, &$fields, &$conds,
1312 &$query_options, &$join_conds, $opts
1313 ) {
1314 return $this->getHookRunner()->onChangesListSpecialPageQuery(
1315 $this->getName(), $tables, $fields, $conds, $query_options, $join_conds, $opts );
1316 }
1317
1322 protected function addMainQueryHook( $query, $opts ) {
1323 if ( $this->getHookContainer()->isRegistered( 'ChangesListSpecialPageQuery' ) ) {
1324 $this->mainQueryHookRegistered = true;
1325 $query->legacyMutator(
1326 function ( &$tables, &$fields, &$conds, &$query_options, &$join_conds )
1327 use ( $opts ) {
1328 $this->mainQueryHookCalled = true;
1329 return $this->runMainQueryHook( $tables, $fields, $conds,
1330 $query_options, $join_conds, $opts );
1331 }
1332 );
1333 }
1334 }
1335
1339 protected function getDB(): IReadableDatabase {
1340 return MediaWikiServices::getInstance()->getConnectionProvider()->getReplicaDatabase();
1341 }
1342
1349 private function webOutputHeader( $rowCount, $opts ) {
1350 if ( !$this->including() ) {
1351 $this->outputFeedLinks();
1352 $this->doHeader( $opts, $rowCount );
1353 }
1354 }
1355
1362 public function webOutput( $rows, $opts ) {
1363 $this->webOutputHeader( $rows->numRows(), $opts );
1364
1365 $this->outputChangesList( $rows, $opts );
1366 }
1367
1368 public function outputFeedLinks() {
1369 // nothing by default
1370 }
1371
1378 abstract public function outputChangesList( $rows, $opts );
1379
1386 public function doHeader( $opts, $numRows ) {
1387 $this->setTopText( $opts );
1388
1389 // @todo Lots of stuff should be done here.
1390
1391 $this->setBottomText( $opts );
1392 }
1393
1399 public function setTopText( FormOptions $opts ) {
1400 // nothing by default
1401 }
1402
1408 public function setBottomText( FormOptions $opts ) {
1409 // nothing by default
1410 }
1411
1421 public function getExtraOptions( $opts ) {
1422 return [];
1423 }
1424
1430 public function makeLegend() {
1431 $context = $this->getContext();
1432 $user = $context->getUser();
1433 # The legend showing what the letters and stuff mean
1434 $legend = Html::openElement( 'dl' ) . "\n";
1435 # Iterates through them and gets the messages for both letter and tooltip
1436 $legendItems = $context->getConfig()->get( MainConfigNames::RecentChangesFlags );
1437 if ( !( $user->useRCPatrol() || $user->useNPPatrol() ) ) {
1438 unset( $legendItems['unpatrolled'] );
1439 }
1440 foreach ( $legendItems as $key => $item ) { # generate items of the legend
1441 $label = $item['legend'] ?? $item['title'];
1442 $letter = $item['letter'];
1443 $cssClass = $item['class'] ?? $key;
1444
1445 $legend .= Html::element( 'dt',
1446 [ 'class' => $cssClass ], $context->msg( $letter )->text()
1447 ) . "\n" .
1448 Html::rawElement( 'dd',
1449 [ 'class' => Sanitizer::escapeClass( 'mw-changeslist-legend-' . $key ) ],
1450 $context->msg( $label )->parse()
1451 ) . "\n";
1452 }
1453 # (+-123)
1454 $legend .= Html::rawElement( 'dt',
1455 [ 'class' => 'mw-plusminus-pos' ],
1456 $context->msg( 'recentchanges-legend-plusminus' )->parse()
1457 ) . "\n";
1458 $legend .= Html::element(
1459 'dd',
1460 [ 'class' => 'mw-changeslist-legend-plusminus' ],
1461 $context->msg( 'recentchanges-label-plusminus' )->text()
1462 ) . "\n";
1463 // Watchlist expiry clock icon.
1464 if ( $context->getConfig()->get( MainConfigNames::WatchlistExpiry ) && !$this->including() ) {
1465 $widget = new IconWidget( [
1466 'icon' => 'clock',
1467 'classes' => [ 'mw-changesList-watchlistExpiry' ],
1468 ] );
1469 // Link the image to its label for assistive technologies.
1470 $watchlistLabelId = 'mw-changeslist-watchlistExpiry-label';
1471 $widget->getIconElement()->setAttributes( [
1472 'role' => 'img',
1473 'aria-labelledby' => $watchlistLabelId,
1474 ] );
1475 $legend .= Html::rawElement(
1476 'dt',
1477 [ 'class' => 'mw-changeslist-legend-watchlistexpiry' ],
1478 $widget->toString()
1479 );
1480 $legend .= Html::element(
1481 'dd',
1482 [ 'class' => 'mw-changeslist-legend-watchlistexpiry', 'id' => $watchlistLabelId ],
1483 $context->msg( 'recentchanges-legend-watchlistexpiry' )->text()
1484 );
1485 }
1486 $legend .= Html::closeElement( 'dl' ) . "\n";
1487
1488 $legendHeading = $this->isStructuredFilterUiEnabled() ?
1489 $context->msg( 'rcfilters-legend-heading' )->parse() :
1490 $context->msg( 'recentchanges-legend-heading' )->parse();
1491
1492 # Collapsible
1493 $collapsedState = $this->getRequest()->getCookie( 'changeslist-state' );
1494
1495 $legend = Html::rawElement( 'details', [
1496 'class' => 'mw-changeslist-legend',
1497 'open' => $collapsedState !== 'collapsed' ? 'open' : null,
1498 ],
1499 Html::rawElement( 'summary', [], $legendHeading ) .
1500 $legend
1501 );
1502
1503 return $legend;
1504 }
1505
1509 protected function addModules() {
1510 $out = $this->getOutput();
1511 // Styles and behavior for the legend box (see makeLegend())
1512 $out->addModuleStyles( [
1513 'mediawiki.interface.helpers.styles',
1514 'mediawiki.special.changeslist.legend',
1515 'mediawiki.special.changeslist',
1516 ] );
1517 $out->addModules( 'mediawiki.special.changeslist.legend.js' );
1518
1519 if ( $this->isStructuredFilterUiEnabled() && !$this->including() ) {
1520 $out->addModules( 'mediawiki.rcfilters.filters.ui' );
1521 $out->addModuleStyles( 'mediawiki.rcfilters.filters.base.styles' );
1522 }
1523 }
1524
1526 protected function getGroupName() {
1527 return 'changes';
1528 }
1529
1536 if ( $this->getRequest()->getBool( 'rcfilters' ) ) {
1537 return true;
1538 }
1539
1540 return static::checkStructuredFilterUiEnabled( $this->getUser() );
1541 }
1542
1550 public static function checkStructuredFilterUiEnabled( UserIdentity $user ) {
1551 return !MediaWikiServices::getInstance()
1552 ->getUserOptionsLookup()
1553 ->getOption( $user, 'rcenhancedfilters-disable' );
1554 }
1555
1563 public function getDefaultLimit() {
1564 return MediaWikiServices::getInstance()
1565 ->getUserOptionsLookup()
1566 ->getIntOption( $this->getUser(), $this->getLimitPreferenceName() );
1567 }
1568
1577 public function getDefaultDays() {
1578 return floatval( MediaWikiServices::getInstance()
1579 ->getUserOptionsLookup()
1580 ->getOption( $this->getUser(), $this->getDefaultDaysPreferenceName() ) );
1581 }
1582
1589 abstract protected function getLimitPreferenceName(): string;
1590
1597 abstract protected function getSavedQueriesPreferenceName(): string;
1598
1605 abstract protected function getDefaultDaysPreferenceName(): string;
1606
1613 abstract protected function getCollapsedPreferenceName(): string;
1614
1619 private function expandSymbolicNamespaceFilters( array $inputs ): array {
1620 $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
1621 $namespaces = [];
1622 foreach ( $inputs as $input ) {
1623 if ( $input === 'all-contents' ) {
1624 array_push( $namespaces, ...$nsInfo->getSubjectNamespaces() );
1625 } elseif ( $input === 'all-discussions' ) {
1626 array_push( $namespaces, ...$nsInfo->getTalkNamespaces() );
1627 } elseif ( is_numeric( $input ) && $nsInfo->exists( (int)$input ) ) {
1628 $namespaces[] = (int)$input;
1629 }
1630 }
1631 return array_unique( $namespaces );
1632 }
1633}
1634
1636class_alias( ChangesListSpecialPage::class, 'ChangesListSpecialPage' );
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:69
Recent changes tagging.
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:32
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)
Build and execute a query on the recentchanges table, optionally with 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 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.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
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, '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'=> '', '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'=>[], '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'=> false, '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 -o $output $input', 'ImagickExt'=>['SvgHandler::rasterizeImagickExt',],], 'SVGConverter'=> 'ImageMagick', 'SVGConverterPath'=> '', 'SVGMaxSize'=> 5120, 'SVGMetadataCutoff'=> 5242880, 'SVGNativeRendering'=> true, 'SVGNativeRenderingSizeLimit'=> 51200, 'MediaInTargetLanguage'=> true, 'MaxImageArea'=> 12500000, 'MaxAnimatedGifArea'=> 12500000, '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, 'ThumbnailStepsRatio'=> 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'=>[], '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',],], 'json'=>['class'=> 'MediaWiki\\Content\\JsonContentHandler', 'services'=>['ParsoidParserFactory', 'TitleFactory',],], 'css'=>['class'=> 'MediaWiki\\Content\\CssContentHandler', 'services'=>['MainConfig', 'ParserFactory', 'UserOptionsLookup',],], 'vue'=>['class'=> 'MediaWiki\\Content\\VueContentHandler', 'services'=>['MainConfig', 'ParserFactory',],], '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, '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, 'PHPSessionHandling'=> 'warn', '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',],],], '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, ], '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, 'UseLegacyMediaStyles' => 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, ], ], '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, ], 'AllowSecuritySensitiveOperationIfCannotReauthenticate' => [ 'default' => true, ], '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, '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, ], '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, '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' => [ ], '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, ], ], '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', 'editviewmywatchlist' => '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', ], 'GrantRiskGroups' => [ 'basic' => 'low', 'editpage' => 'low', 'createeditmovepage' => 'low', 'editprotected' => 'vandalism', 'patrol' => 'low', 'uploadfile' => 'low', 'uploadeditmovefile' => 'low', 'sendemail' => 'security', 'viewmywatchlist' => 'low', 'editviewmywatchlist' => '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', ], 'EnableBotPasswords' => true, 'BotPasswordsCluster' => false, 'BotPasswordsDatabase' => false, 'BotPasswordsLimit' => 100, 'SecretKey' => false, 'JwtPrivateKey' => false, 'JwtPublicKey' => false, 'AllowUserJs' => false, 'AllowUserCss' => false, 'AllowUserCssPrefs' => true, 'UseSiteJs' => true, 'UseSiteCss' => true, 'BreakFrames' => false, 'EditPageFrameOptions' => 'DENY', 'ApiFrameOptions' => 'DENY', 'CSPHeader' => false, 'CSPReportOnlyHeader' => 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, 'CachePrefix' => 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: ], '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, ], '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, '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\\JobQueue\\Jobs\\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', 'Access-Control-Max-Age', 'Authorization', ], 'RestAPIAdditionalRouteFiles' => [ ], 'RestSandboxSpecs' => [ ], '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, 'AsyncHTTPTimeout' => 25, 'HTTPProxy' => '', 'LocalVirtualHosts' => [ ], 'LocalHTTPProxy' => false, 'AllowExternalReqID' => false, 'GenerateReqIDFormat' => 'rand24', 'JobRunRate' => 1, 'RunJobsAsync' => false, 'UpdateRowsPerJob' => 300, 'UpdateRowsPerQuery' => 100, 'RedirectOnLogin' => null, 'VirtualRestConfig' => [ 'paths' => [ ], 'modules' => [ ], 'global' => [ 'timeout' => 360, 'forwardCookies' => false, 'HTTPProxy' => 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, ], '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', 'CacheSharedUploads' => 'boolean', 'ForeignUploadTargets' => 'array', 'UploadDialog' => 'object', 'FileBackends' => 'object', 'LockManagers' => 'array', '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', ], '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', ], 'ThumbnailStepsRatio' => [ 'number', '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', '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', 'ParserCacheFilterConfig' => 'object', 'ChronologyProtectorSecret' => 'string', 'PHPSessionHandling' => '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', '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', 'AllowSecuritySensitiveOperationIfCannotReauthenticate' => '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', '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', 'CSPHeader' => [ 'boolean', 'object', ], 'CSPReportOnlyHeader' => [ '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', 'RecentChangesFlags' => 'object', 'WatchlistExpiry' => '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', 'RestSandboxSpecs' => 'object', 'ShellRestrictionMethod' => [ 'string', 'boolean', ], 'ShellboxUrls' => 'object', 'ShellboxSecretKey' => [ 'string', 'null', ], 'ShellboxShell' => [ 'string', 'null', ], 'HTTPTimeout' => 'number', 'HTTPConnectTimeout' => 'number', 'HTTPMaxTimeout' => 'number', 'HTTPMaxConnectTimeout' => 'number', 'LocalVirtualHosts' => 'object', 'LocalHTTPProxy' => [ 'string', 'boolean', ], 'GenerateReqIDFormat' => 'string', 'VirtualRestConfig' => 'object', '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', ], 'mergeStrategy' => [ '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', 'VirtualRestConfig' => 'array_plus_2d', ], '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', ], ], ], ], ], 'PHPSessionHandling' => [ 'deprecated' => 'since 1.45 Integration with PHP session handling will be removed in the future', ], 'RawHtmlMessages' => [ 'items' => [ 'type' => 'string', ], ], 'InterwikiLogoOverride' => [ 'items' => [ 'type' => 'string', ], ], 'LegalTitleChars' => [ 'deprecated' => 'since 1.41; use Extension:TitleBlacklist to customize', ], 'ReauthenticateTime' => [ 'additionalProperties' => [ 'type' => 'integer', ], ], 'AllowSecuritySensitiveOperationIfCannotReauthenticate' => [ 'additionalProperties' => [ 'type' => 'boolean', ], ], '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', ], ], ], 'SoftwareTags' => [ 'additionalProperties' => [ 'type' => 'boolean', ], ], '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', ], ], 'RestSandboxSpecs' => [ 'additionalProperties' => [ 'type' => 'object', 'properties' => [ 'url' => [ 'type' => 'string', 'format' => 'url', ], 'name' => [ 'type' => 'string', ], 'file' => [ 'type' => 'string', ], 'msg' => [ 'type' => 'string', 'description' => 'a message key', ], ], ], ], '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.', ],]
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.