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
60
64
65 private ?ChangesListResult $queryResult = null;
66
68 private $mainQueryHookRegistered = false;
70 private $mainQueryHookCalled = false;
71
80 public function __construct(
81 $name,
82 $restriction,
87 ) {
88 parent::__construct( $name, $restriction );
89
90 $this->userIdentityUtils = $userIdentityUtils;
91 $this->tempUserConfig = $tempUserConfig;
92 $this->recentChangeFactory = $recentChangeFactory;
93 $this->changesListQueryFactory = $changesListQueryFactory;
94 $this->filterGroups = new ChangesListFilterGroupContainer();
95 }
96
107 private function getBaseFilterGroupDefinitions() {
108 return [
109 [
110 'name' => 'registration',
111 'title' => 'rcfilters-filtergroup-registration',
112 'class' => ChangesListBooleanFilterGroup::class,
113 'filters' => [
114 [
115 'name' => 'hideliu',
116 // rcshowhideliu-show, rcshowhideliu-hide,
117 // wlshowhideliu
118 'showHideSuffix' => 'showhideliu',
119 'default' => false,
120 'action' => [ 'exclude', 'named' ],
121 'isReplacedInStructuredUi' => true,
122 ],
123 [
124 'name' => 'hideanons',
125 // rcshowhideanons-show, rcshowhideanons-hide,
126 // wlshowhideanons
127 'showHideSuffix' => 'showhideanons',
128 'default' => false,
129 'action' => [ 'require', 'named' ],
130 'isReplacedInStructuredUi' => true,
131 ]
132 ],
133 ],
134
135 [
136 'name' => 'userExpLevel',
137 'title' => 'rcfilters-filtergroup-user-experience-level',
138 'class' => ChangesListStringOptionsFilterGroup::class,
139 'isFullCoverage' => true,
140 'filters' => [
141 [
142 'name' => 'unregistered',
143 'requireConfig' => [ 'isRegistrationRequiredToEdit' => false ],
144 'label' => 'rcfilters-filter-user-experience-level-unregistered-label',
145 'description' => $this->tempUserConfig->isKnown() ?
146 'rcfilters-filter-user-experience-level-unregistered-description-temp' :
147 'rcfilters-filter-user-experience-level-unregistered-description',
148 'cssClassSuffix' => 'user-unregistered',
149 'action' => [ 'require', 'experience', 'unregistered' ],
150 ],
151 [
152 'name' => 'registered',
153 'requireConfig' => [ 'isRegistrationRequiredToEdit' => false ],
154 'label' => 'rcfilters-filter-user-experience-level-registered-label',
155 'description' => 'rcfilters-filter-user-experience-level-registered-description',
156 'cssClassSuffix' => 'user-registered',
157 'action' => [ 'require', 'experience', 'registered' ],
158 'subsets' => [ 'newcomer', 'learner', 'experienced' ],
159 ],
160 [
161 'name' => 'newcomer',
162 'label' => 'rcfilters-filter-user-experience-level-newcomer-label',
163 'description' => 'rcfilters-filter-user-experience-level-newcomer-description',
164 'cssClassSuffix' => 'user-newcomer',
165 'action' => [ 'require', 'experience', 'newcomer' ],
166 ],
167 [
168 'name' => 'learner',
169 'label' => 'rcfilters-filter-user-experience-level-learner-label',
170 'description' => 'rcfilters-filter-user-experience-level-learner-description',
171 'cssClassSuffix' => 'user-learner',
172 'action' => [ 'require', 'experience', 'learner' ],
173 ],
174 [
175 'name' => 'experienced',
176 'label' => 'rcfilters-filter-user-experience-level-experienced-label',
177 'description' => 'rcfilters-filter-user-experience-level-experienced-description',
178 'cssClassSuffix' => 'user-experienced',
179 'action' => [ 'require', 'experience', 'experienced' ],
180 ]
181 ],
183 ],
184
185 [
186 'name' => 'authorship',
187 'title' => 'rcfilters-filtergroup-authorship',
188 'class' => ChangesListBooleanFilterGroup::class,
189 'filters' => [
190 [
191 'name' => 'hidemyself',
192 'label' => 'rcfilters-filter-editsbyself-label',
193 'description' => 'rcfilters-filter-editsbyself-description',
194 // rcshowhidemine-show, rcshowhidemine-hide,
195 // wlshowhidemine
196 'showHideSuffix' => 'showhidemine',
197 'default' => false,
198 'action' => [ 'exclude', 'user', $this->getUser() ],
199 'highlight' => [ 'require', 'user', $this->getUser() ],
200 'cssClassSuffix' => 'self',
201 ],
202 [
203 'name' => 'hidebyothers',
204 'label' => 'rcfilters-filter-editsbyother-label',
205 'description' => 'rcfilters-filter-editsbyother-description',
206 'default' => false,
207 'action' => [ 'require', 'user', $this->getUser() ],
208 'highlight' => [ 'exclude', 'user', $this->getUser() ],
209 'cssClassSuffix' => 'others',
210 ]
211 ]
212 ],
213
214 [
215 'name' => 'automated',
216 'title' => 'rcfilters-filtergroup-automated',
217 'class' => ChangesListBooleanFilterGroup::class,
218 'filters' => [
219 [
220 'name' => 'hidebots',
221 'label' => 'rcfilters-filter-bots-label',
222 'description' => 'rcfilters-filter-bots-description',
223 // rcshowhidebots-show, rcshowhidebots-hide,
224 // wlshowhidebots
225 'showHideSuffix' => 'showhidebots',
226 'default' => false,
227 'action' => [ 'exclude', 'bot' ],
228 'highlight' => [ 'require', 'bot' ],
229 'cssClassSuffix' => 'bot',
230 ],
231 [
232 'name' => 'hidehumans',
233 'label' => 'rcfilters-filter-humans-label',
234 'description' => 'rcfilters-filter-humans-description',
235 'default' => false,
236 'action' => [ 'require', 'bot' ],
237 'highlight' => [ 'exclude', 'bot' ],
238 'cssClassSuffix' => 'human',
239 ]
240 ]
241 ],
242
243 // significance (conditional)
244
245 [
246 'name' => 'significance',
247 'title' => 'rcfilters-filtergroup-significance',
248 'class' => ChangesListBooleanFilterGroup::class,
249 'priority' => -6,
250 'filters' => [
251 [
252 'name' => 'hideminor',
253 'label' => 'rcfilters-filter-minor-label',
254 'description' => 'rcfilters-filter-minor-description',
255 // rcshowhideminor-show, rcshowhideminor-hide,
256 // wlshowhideminor
257 'showHideSuffix' => 'showhideminor',
258 'default' => false,
259 'action' => [ 'exclude', 'minor' ],
260 'highlight' => [ 'require', 'minor' ],
261 'cssClassSuffix' => 'minor',
262 'conflictOptions' => [
263 'globalKey' => 'rcfilters-hideminor-conflicts-typeofchange-global',
264 'forwardKey' => 'rcfilters-hideminor-conflicts-typeofchange',
265 'backwardKey' => 'rcfilters-typeofchange-conflicts-hideminor',
266 ],
267 'conflictsWith' => [
268 'changeType' => [
269 'hidecategorization' => [],
270 'hidelog' => [],
271 'hidenewuserlog' => [],
272 'hidenewpages' => []
273 ],
274 ],
275 ],
276 [
277 'name' => 'hidemajor',
278 'label' => 'rcfilters-filter-major-label',
279 'description' => 'rcfilters-filter-major-description',
280 'default' => false,
281 'action' => [ 'require', 'minor' ],
282 'highlight' => [ 'exclude', 'minor' ],
283 'cssClassSuffix' => 'major',
284 ]
285 ]
286 ],
287
288 [
289 'name' => 'lastRevision',
290 'title' => 'rcfilters-filtergroup-lastrevision',
291 'class' => ChangesListBooleanFilterGroup::class,
292 'priority' => -7,
293 'filters' => [
294 [
295 'name' => 'hidelastrevision',
296 'label' => 'rcfilters-filter-lastrevision-label',
297 'description' => 'rcfilters-filter-lastrevision-description',
298 'default' => false,
299 'action' => [
300 [ 'require', 'revisionType', 'old' ],
301 [ 'require', 'revisionType', 'none' ],
302 ],
303 'highlight' => [ 'require', 'revisionType', 'latest' ],
304 'cssClassSuffix' => 'last',
305 ],
306 [
307 'name' => 'hidepreviousrevisions',
308 'label' => 'rcfilters-filter-previousrevision-label',
309 'description' => 'rcfilters-filter-previousrevision-description',
310 'default' => false,
311 'action' => [
312 [ 'require', 'revisionType', 'latest' ],
313 [ 'require', 'revisionType', 'none' ],
314 ],
315 'highlight' => [ 'require', 'revisionType', 'old' ],
316 'cssClassSuffix' => 'previous',
317 ]
318 ]
319 ],
320
321 // With extensions, there can be change types that will not be hidden by any of these.
322 [
323 'name' => 'changeType',
324 'title' => 'rcfilters-filtergroup-changetype',
325 'class' => ChangesListBooleanFilterGroup::class,
326 'priority' => -8,
327 'filters' => [
328 [
329 'name' => 'hidepageedits',
330 'label' => 'rcfilters-filter-pageedits-label',
331 'description' => 'rcfilters-filter-pageedits-description',
332 'default' => false,
333 'priority' => -2,
334 'action' => [ 'exclude', 'source', RecentChange::SRC_EDIT ],
335 'highlight' => [ 'require', 'source', RecentChange::SRC_EDIT ],
336 'cssClassSuffix' => 'src-mw-edit',
337 ],
338 [
339 'name' => 'hidenewpages',
340 'label' => 'rcfilters-filter-newpages-label',
341 'description' => 'rcfilters-filter-newpages-description',
342 'default' => false,
343 'priority' => -3,
344 'action' => [ 'exclude', 'source', RecentChange::SRC_NEW ],
345 'highlight' => [ 'require', 'source', RecentChange::SRC_NEW ],
346 'cssClassSuffix' => 'src-mw-new',
347 ],
348 [
349 'name' => 'hidecategorization',
350 'label' => 'rcfilters-filter-categorization-label',
351 'description' => 'rcfilters-filter-categorization-description',
352 // rcshowhidecategorization-show, rcshowhidecategorization-hide.
353 // wlshowhidecategorization
354 'showHideSuffix' => 'showhidecategorization',
355 'default' => false,
356 'priority' => -4,
357 'requireConfig' => [ 'RCWatchCategoryMembership' => true ],
358 'action' => [ 'exclude', 'source', RecentChange::SRC_CATEGORIZE ],
359 'highlight' => [ 'require', 'source', RecentChange::SRC_CATEGORIZE ],
360 'cssClassSuffix' => 'src-mw-categorize',
361 'conflictOptions' => [
362 'globalKey' => 'rcfilters-hidecategorization-conflicts-reviewstatus-global',
363 'forwardKey' => 'rcfilters-hidecategorization-conflicts-reviewstatus',
364 'backwardKey' => 'rcfilters-reviewstatus-conflicts-reviewstatus',
365 ],
366 'conflictsWith' => [
367 'reviewStatus' => [
368 'unpatrolled' => [],
369 'manual' => [],
370 ],
371 ],
372 ],
373 [
374 'name' => 'hidelog',
375 'label' => 'rcfilters-filter-logactions-label',
376 'description' => 'rcfilters-filter-logactions-description',
377 'default' => false,
378 'priority' => -5,
379 'action' => [ 'exclude', 'source', RecentChange::SRC_LOG ],
380 'highlight' => [ 'require', 'source', RecentChange::SRC_LOG ],
381 'cssClassSuffix' => 'src-mw-log',
382 ],
383 [
384 'name' => 'hidenewuserlog',
385 'label' => 'rcfilters-filter-accountcreations-label',
386 'description' => 'rcfilters-filter-accountcreations-description',
387 'default' => false,
388 'priority' => -6,
389 'action' => [ 'exclude', 'logType', 'newusers' ],
390 'highlight' => [ 'require', 'logType', 'newusers' ],
391 'cssClassSuffix' => 'src-mw-newuserlog',
392 ],
393 ],
394 ],
395
396 [
397 'name' => 'legacyReviewStatus',
398 'title' => 'rcfilters-filtergroup-reviewstatus',
399 'class' => ChangesListBooleanFilterGroup::class,
400 'requireConfig' => [ 'useRCPatrol' => true ],
401 'filters' => [
402 [
403 'name' => 'hidepatrolled',
404 // rcshowhidepatr-show, rcshowhidepatr-hide
405 // wlshowhidepatr
406 'showHideSuffix' => 'showhidepatr',
407 'default' => false,
408 'action' => [ 'require', 'patrolled', RecentChange::PRC_UNPATROLLED ],
409 'isReplacedInStructuredUi' => true,
410 ],
411 [
412 'name' => 'hideunpatrolled',
413 'default' => false,
414 'action' => [ 'exclude', 'patrolled', RecentChange::PRC_UNPATROLLED ],
415 'isReplacedInStructuredUi' => true,
416 ],
417 ],
418 ],
419
420 [
421 'name' => 'reviewStatus',
422 'title' => 'rcfilters-filtergroup-reviewstatus',
423 'class' => ChangesListStringOptionsFilterGroup::class,
424 'isFullCoverage' => true,
425 'priority' => -5,
426 'requireConfig' => [ 'useRCPatrol' => true ],
427 'filters' => [
428 [
429 'name' => 'unpatrolled',
430 'label' => 'rcfilters-filter-reviewstatus-unpatrolled-label',
431 'description' => 'rcfilters-filter-reviewstatus-unpatrolled-description',
432 'cssClassSuffix' => 'reviewstatus-unpatrolled',
433 'action' => [ 'require', 'patrolled', RecentChange::PRC_UNPATROLLED ],
434 ],
435 [
436 'name' => 'manual',
437 'label' => 'rcfilters-filter-reviewstatus-manual-label',
438 'description' => 'rcfilters-filter-reviewstatus-manual-description',
439 'cssClassSuffix' => 'reviewstatus-manual',
440 'action' => [ 'require', 'patrolled', RecentChange::PRC_PATROLLED ],
441 ],
442 [
443 'name' => 'auto',
444 'label' => 'rcfilters-filter-reviewstatus-auto-label',
445 'description' => 'rcfilters-filter-reviewstatus-auto-description',
446 'cssClassSuffix' => 'reviewstatus-auto',
447 'action' => [ 'require', 'patrolled', RecentChange::PRC_AUTOPATROLLED ],
448 ],
449 ],
451 ],
452 ];
453 }
454
461 protected function getExtraFilterGroupDefinitions(): array {
462 return [];
463 }
464
468 public function execute( $subpage ) {
469 $this->rcSubpage = $subpage;
470
471 if ( $this->considerActionsForDefaultSavedQuery( $subpage ) ) {
472 // Don't bother rendering the page if we'll be performing a redirect (T330100).
473 return;
474 }
475
476 // Enable OOUI and module for the clock icon.
477 if ( $this->getConfig()->get( MainConfigNames::WatchlistExpiry ) && !$this->including() ) {
478 $this->getOutput()->enableOOUI();
479 $this->getOutput()->addModules( 'mediawiki.special.changeslist.watchlistexpiry' );
480 }
481
482 $opts = $this->getOptions();
483 try {
484 $result = $this->getQueryResult();
485 $rows = $result->getResultWrapper();
486
487 // Used by Structured UI app to get results without MW chrome
488 if ( $this->getRequest()->getRawVal( 'action' ) === 'render' ) {
489 $this->getOutput()->setArticleBodyOnly( true );
490 }
491
492 // Used by "live update" and "view newest" to check
493 // if there's new changes with minimal data transfer
494 if ( $this->getRequest()->getBool( 'peek' ) ) {
495 $code = $rows->numRows() > 0 ? 200 : 204;
496 $this->getOutput()->setStatusCode( $code );
497
498 if ( $this->getUser()->isAnon() !==
499 $this->getRequest()->getFuzzyBool( 'isAnon' )
500 ) {
501 $this->getOutput()->setStatusCode( 205 );
502 }
503
504 return;
505 }
506
507 $services = MediaWikiServices::getInstance();
508 $logFormatterFactory = $services->getLogFormatterFactory();
509 $linkBatchFactory = $services->getLinkBatchFactory();
510 $batch = $linkBatchFactory->newLinkBatch();
511 $userNames = [];
512 foreach ( $rows as $row ) {
513 $batch->addUser( new UserIdentityValue( $row->rc_user ?? 0, $row->rc_user_text ) );
514 $userNames[] = $row->rc_user_text;
515 $batch->add( $row->rc_namespace, $row->rc_title );
516 if ( $row->rc_source === RecentChange::SRC_LOG ) {
517 $formatter = $logFormatterFactory->newFromRow( $row );
518 foreach ( $formatter->getPreloadTitles() as $title ) {
519 $batch->addObj( $title );
520 if ( $title->inNamespace( NS_USER ) || $title->inNamespace( NS_USER_TALK ) ) {
521 $userNames[] = $title->getText();
522 }
523 }
524 }
525 }
526 $batch->execute();
527 foreach ( UserArray::newFromNames( $userNames ) as $_ ) {
528 // Trigger UserEditTracker::setCachedUserEditCount via User::loadFromRow
529 // Preloads edit count for User::getExperienceLevel() and Linker::userToolLinks()
530 }
531
532 $this->setHeaders();
533 $this->outputHeader();
534 $this->addModules();
535 $this->webOutput( $rows, $opts );
536 } catch ( DBQueryTimeoutError $timeoutException ) {
537 MWExceptionHandler::logException( $timeoutException );
538
539 $this->setHeaders();
540 $this->outputHeader();
541 $this->addModules();
542
543 $this->getOutput()->setStatusCode( 500 );
544 $this->webOutputHeader( 0, $opts );
545 $this->outputTimeout();
546 }
547
548 $this->includeRcFiltersApp();
549 }
550
558 public function setTempUserConfig( TempUserConfig $tempUserConfig ) {
559 $this->tempUserConfig = $tempUserConfig;
560 $this->changesListQueryFactory->setTempUserConfig( $tempUserConfig );
561 }
562
571 protected function considerActionsForDefaultSavedQuery( $subpage ) {
572 if ( !$this->isStructuredFilterUiEnabled() || $this->including() ) {
573 return false;
574 }
575
576 $knownParams = $this->getRequest()->getValues(
577 ...array_keys( $this->getOptions()->getAllValues() )
578 );
579
580 // HACK: Temporarily until we can properly define "sticky" filters and parameters,
581 // we need to exclude several parameters we know should not be counted towards preventing
582 // the loading of defaults.
583 $excludedParams = [ 'limit' => '', 'days' => '', 'enhanced' => '', 'from' => '' ];
584 $knownParams = array_diff_key( $knownParams, $excludedParams );
585
586 if (
587 // If there are NO known parameters in the URL request
588 // (that are not excluded) then we need to check into loading
589 // the default saved query
590 count( $knownParams ) === 0
591 ) {
593 ->getUserOptionsLookup()
594 ->getOption( $this->getUser(), $this->getSavedQueriesPreferenceName() );
595
596 // Get the saved queries data and parse it
597 $savedQueries = $prefJson ? FormatJson::decode( $prefJson, true ) : false;
598
599 if ( $savedQueries && isset( $savedQueries[ 'default' ] ) ) {
600 // Only load queries that are 'version' 2, since those
601 // have parameter representation
602 if ( isset( $savedQueries[ 'version' ] ) && $savedQueries[ 'version' ] === '2' ) {
603 $savedQueryDefaultID = $savedQueries[ 'default' ];
604 $defaultQuery = $savedQueries[ 'queries' ][ $savedQueryDefaultID ][ 'data' ];
605
606 // Build the entire parameter list
607 $query = array_merge(
608 $defaultQuery[ 'params' ],
609 $defaultQuery[ 'highlights' ],
610 [
611 'urlversion' => '2',
612 ]
613 );
614 // Add to the query any parameters that we may have ignored before
615 // but are still valid and requested in the URL
616 $query = array_merge( $this->getRequest()->getQueryValues(), $query );
617 unset( $query[ 'title' ] );
618 $this->getOutput()->redirect( $this->getPageTitle( $subpage )->getCanonicalURL( $query ) );
619
620 // Signal that we only need to redirect to the full URL
621 // and can skip rendering the actual page (T330100).
622 return true;
623 } else {
624 // There's a default, but the version is not 2, and the server can't
625 // actually recognize the query itself. This happens if it is before
626 // the conversion, so we need to tell the UI to reload saved query as
627 // it does the conversion to version 2
628 $this->getOutput()->addJsConfigVars(
629 'wgStructuredChangeFiltersDefaultSavedQueryExists',
630 true
631 );
632
633 // Add the class that tells the frontend it is still loading
634 // another query
635 $this->getOutput()->addBodyClasses( 'mw-rcfilters-ui-loading' );
636 }
637 }
638 }
639
640 return false;
641 }
642
647 protected function getLinkDays() {
648 $linkDays = $this->getConfig()->get( MainConfigNames::RCLinkDays );
649 $filterByAge = $this->getConfig()->get( MainConfigNames::RCFilterByAge );
650 $maxAge = $this->getConfig()->get( MainConfigNames::RCMaxAge );
651 if ( $filterByAge ) {
652 // Trim it to only links which are within $wgRCMaxAge.
653 // Note that we allow one link higher than the max for things like
654 // "age 56 days" being accessible through the "60 days" link.
655 sort( $linkDays );
656
657 $maxAgeDays = $maxAge / ( 3600 * 24 );
658 foreach ( $linkDays as $i => $days ) {
659 if ( $days >= $maxAgeDays ) {
660 array_splice( $linkDays, $i + 1 );
661 break;
662 }
663 }
664 }
665
666 return $linkDays;
667 }
668
675 protected function includeRcFiltersApp() {
676 $out = $this->getOutput();
677 if ( $this->isStructuredFilterUiEnabled() && !$this->including() ) {
678 $jsData = $this->filterGroups->getJsData();
679 $messages = [];
680 foreach ( $jsData['messageKeys'] as $key ) {
681 $messages[$key] = $this->msg( $key )->plain();
682 }
683
684 $out->addBodyClasses( 'mw-rcfilters-enabled' );
685 $collapsed = MediaWikiServices::getInstance()->getUserOptionsLookup()
686 ->getBoolOption( $this->getUser(), $this->getCollapsedPreferenceName() );
687 if ( $collapsed ) {
688 $out->addBodyClasses( 'mw-rcfilters-collapsed' );
689 }
690
691 // These config and message exports should be moved into a ResourceLoader data module (T201574)
692 $out->addJsConfigVars( 'wgStructuredChangeFilters', $jsData['groups'] );
693 $out->addJsConfigVars( 'wgStructuredChangeFiltersMessages', $messages );
694 $out->addJsConfigVars( 'wgStructuredChangeFiltersCollapsedState', $collapsed );
695
696 $out->addJsConfigVars(
697 'StructuredChangeFiltersDisplayConfig',
698 [
699 'maxDays' => // Translate to days
700 (int)$this->getConfig()->get( MainConfigNames::RCMaxAge ) / ( 24 * 3600 ),
701 'limitArray' => $this->getConfig()->get( MainConfigNames::RCLinkLimits ),
702 'limitDefault' => $this->getDefaultLimit(),
703 'daysArray' => $this->getLinkDays(),
704 'daysDefault' => $this->getDefaultDays(),
705 ]
706 );
707
708 $out->addJsConfigVars(
709 'wgStructuredChangeFiltersSavedQueriesPreferenceName',
710 $this->getSavedQueriesPreferenceName()
711 );
712 $out->addJsConfigVars(
713 'wgStructuredChangeFiltersLimitPreferenceName',
714 $this->getLimitPreferenceName()
715 );
716 $out->addJsConfigVars(
717 'wgStructuredChangeFiltersDaysPreferenceName',
718 $this->getDefaultDaysPreferenceName()
719 );
720 $out->addJsConfigVars(
721 'wgStructuredChangeFiltersCollapsedPreferenceName',
722 $this->getCollapsedPreferenceName()
723 );
724 } else {
725 $out->addBodyClasses( 'mw-rcfilters-disabled' );
726 }
727 }
728
737 public static function getRcFiltersConfigSummary( RL\Context $context ) {
738 $lang = MediaWikiServices::getInstance()->getLanguageFactory()
739 ->getLanguage( $context->getLanguage() );
740 return [
741 // Reduce version computation by avoiding Message parsing
742 'RCFiltersChangeTags' => ChangeTags::getChangeTagListSummary( $context, $lang ),
743 'StructuredChangeFiltersEditWatchlistUrl' =>
744 SpecialPage::getTitleFor( 'EditWatchlist' )->getLocalURL()
745 ];
746 }
747
755 public static function getRcFiltersConfigVars( RL\Context $context ) {
756 $lang = MediaWikiServices::getInstance()->getLanguageFactory()
757 ->getLanguage( $context->getLanguage() );
758 return [
759 'RCFiltersChangeTags' => ChangeTags::getChangeTagList( $context, $lang ),
760 'StructuredChangeFiltersEditWatchlistUrl' =>
761 SpecialPage::getTitleFor( 'EditWatchlist' )->getLocalURL()
762 ];
763 }
764
768 protected function outputNoResults() {
769 $this->getOutput()->addHTML(
770 Html::rawElement(
771 'div',
772 [ 'class' => 'mw-changeslist-empty' ],
773 $this->msg( 'recentchanges-noresult' )->parse()
774 )
775 );
776 }
777
781 protected function outputTimeout() {
782 $this->getOutput()->addHTML(
783 '<div class="mw-changeslist-empty mw-changeslist-timeout">' .
784 $this->msg( 'recentchanges-timeout' )->parse() .
785 '</div>'
786 );
787 }
788
794 public function getRows() {
795 return $this->getQueryResult()->getResultWrapper();
796 }
797
803 protected function getQueryResult(): ChangesListResult {
804 if ( !$this->queryResult ) {
805 $opts = $this->getOptions();
806 $query = $this->buildQuery( $opts );
807 $this->modifyQuery( $query, $opts );
808 $this->queryResult = $query->fetchResult();
809
810 if ( $this->mainQueryHookRegistered && !$this->mainQueryHookCalled ) {
811 // When an empty result set is forced, ChangesListQuery doesn't run
812 // the hook, but some extensions need us to run it anyway to register
813 // form options.
814 // FIXME: risky to pass empty arrays here, and inefficient to
815 // call this hook when most of what it does is not needed.
816 // We need to deprecate it.
817 $tables = $fields = $conds = $options = $joins = [];
818 $this->runMainQueryHook( $tables, $fields, $conds, $options,
819 $joins, $opts );
820 }
821 }
822 return $this->queryResult;
823 }
824
832 protected function newRecentChangeFromRow( $row ) {
833 $rc = $this->recentChangeFactory->newRecentChangeFromRow( $row );
834 $rc->setHighlights( $this->getQueryResult()->getHighlightsFromRow( $row ) );
835 return $rc;
836 }
837
843 public function getOptions() {
844 if ( $this->rcOptions === null ) {
845 $this->rcOptions = $this->setup( $this->rcSubpage );
846 }
847
848 return $this->rcOptions;
849 }
850
858 private function getBaseFilterFactoryConfig() {
859 return [
860 'showHidePrefix' => '',
861 'isRegistrationRequiredToEdit' => !MediaWikiServices::getInstance()
862 ->getPermissionManager()
863 ->isEveryoneAllowed( "edit" ),
864 'useRCPatrol' => !$this->including() && $this->getUser()->useRCPatrol(),
865 'RCWatchCategoryMembership' =>
866 $this->getConfig()->get( MainConfigNames::RCWatchCategoryMembership ),
867 ];
868 }
869
875 protected function getExtraFilterFactoryConfig(): array {
876 return [];
877 }
878
885 protected function getFilterDefaultOverrides(): array {
886 return [];
887 }
888
891 $this->getExtraFilterFactoryConfig() + $this->getBaseFilterFactoryConfig()
892 );
893 }
894
899 protected function registerFilters() {
900 $filterFactory = $this->getFilterFactory();
901 $filterFactory->registerFiltersFromDefinitions(
902 $this->filterGroups,
903 $this->getBaseFilterGroupDefinitions()
904 );
905 $filterFactory->registerFiltersFromDefinitions(
906 $this->filterGroups,
907 $this->getExtraFilterGroupDefinitions()
908 );
909 $this->getHookRunner()->onChangesListSpecialPageStructuredFilters( $this );
910 $this->filterGroups->setDefaults( $this->getFilterDefaultOverrides() );
911 }
912
923 protected function registerFiltersFromDefinitions( array $definition ) {
924 $this->getFilterFactory()->registerFiltersFromDefinitions( $this->filterGroups, $definition );
925 }
926
935 public function setup( $parameters ) {
936 $this->registerFilters();
937
938 $opts = $this->getDefaultOptions();
939
940 $opts = $this->fetchOptionsFromRequest( $opts );
941
942 // Give precedence to subpage syntax
943 if ( $parameters !== null ) {
944 $this->parseParameters( $parameters, $opts );
945 }
946
947 $this->validateOptions( $opts );
948
949 return $opts;
950 }
951
961 public function getDefaultOptions() {
962 $opts = new FormOptions();
963 $structuredUI = $this->isStructuredFilterUiEnabled();
964 // If urlversion=2 is set, ignore the filter defaults and set them all to false/empty
965 $useDefaults = $this->getRequest()->getInt( 'urlversion' ) !== 2;
966
967 $this->filterGroups->addOptions( $opts, $useDefaults, $structuredUI );
968
969 $opts->add( 'namespace', '', FormOptions::STRING );
970 $opts->add( 'subpageof', '', FormOptions::STRING );
971 // TODO: Rename this option to 'invertnamespaces'?
972 $opts->add( 'invert', false );
973 $opts->add( 'associated', false );
974 $opts->add( 'urlversion', 1 );
975 $opts->add( 'tagfilter', '' );
976 $opts->add( 'inverttags', false );
977
978 $opts->add( 'days', $this->getDefaultDays(), FormOptions::FLOAT );
979 $opts->add( 'limit', $this->getDefaultLimit(), FormOptions::INT );
980
981 $opts->add( 'from', '' );
982
983 return $opts;
984 }
985
989 public function registerFilterGroup( ChangesListFilterGroup $group ) {
990 $this->filterGroups->registerGroup( $group );
991 }
992
1002 public function getFilterGroup( $groupName ) {
1003 return $this->filterGroups->getGroup( $groupName );
1004 }
1005
1014 protected function getStructuredFilterJsData() {
1015 return $this->filterGroups->getJsData();
1016 }
1017
1026 protected function fetchOptionsFromRequest( $opts ) {
1027 $opts->fetchValuesFromRequest( $this->getRequest() );
1028
1029 return $opts;
1030 }
1031
1040 public function parseParameters( $par, FormOptions $opts ) {
1041 $params = $this->filterGroups->getSubpageParams();
1042
1043 $bits = preg_split( '/\s*,\s*/', trim( $par ) );
1044 foreach ( $bits as $bit ) {
1045 $m = [];
1046 if ( ( $params[$bit] ?? '' ) === 'bool' ) {
1047 // hidefoo => hidefoo=true
1048 $opts[$bit] = true;
1049 } elseif ( ( $params["hide$bit"] ?? '' ) === 'bool' ) {
1050 // foo => hidefoo=false
1051 $opts["hide$bit"] = false;
1052 } elseif ( preg_match( '/^(.*)=(.*)$/', $bit, $m ) ) {
1053 if ( ( $params[$m[1]] ?? '' ) === 'string' ) {
1054 $opts[$m[1]] = $m[2];
1055 }
1056 }
1057 }
1058 }
1059
1063 public function validateOptions( FormOptions $opts ) {
1064 $isContradictory = $this->fixContradictoryOptions( $opts );
1065 $isReplaced = $this->replaceOldOptions( $opts );
1066
1067 if ( $isContradictory || $isReplaced ) {
1068 $query = wfArrayToCgi( $this->convertParamsForLink( $opts->getChangedValues() ) );
1069 $this->getOutput()->redirect( $this->getPageTitle()->getCanonicalURL( $query ) );
1070 }
1071
1072 $opts->validateIntBounds( 'limit', 0, 5000 );
1073 $opts->validateBounds( 'days', 0,
1074 $this->getConfig()->get( MainConfigNames::RCMaxAge ) / ( 3600 * 24 ) );
1075 }
1076
1083 private function fixContradictoryOptions( FormOptions $opts ) {
1084 $fixed = $this->fixBackwardsCompatibilityOptions( $opts );
1085 $fixed = $this->filterGroups->fixContradictoryOptions( $opts ) || $fixed;
1086
1087 // Namespace conflicts with subpageof
1088 if ( $opts['namespace'] !== '' && $opts['subpageof'] !== '' ) {
1089 $opts['namespace'] = '';
1090 $fixed = true;
1091 }
1092
1093 return $fixed;
1094 }
1095
1105 private function fixBackwardsCompatibilityOptions( FormOptions $opts ) {
1106 if ( $opts['hideanons'] && $opts['hideliu'] ) {
1107 $opts->reset( 'hideanons' );
1108 if ( !$opts['hidebots'] ) {
1109 $opts->reset( 'hideliu' );
1110 $opts['hidehumans'] = 1;
1111 }
1112
1113 return true;
1114 }
1115
1116 return false;
1117 }
1118
1125 public function replaceOldOptions( FormOptions $opts ) {
1126 if ( !$this->isStructuredFilterUiEnabled() ) {
1127 return false;
1128 }
1129
1130 $changed = false;
1131
1132 // At this point 'hideanons' and 'hideliu' cannot be both true,
1133 // because fixBackwardsCompatibilityOptions resets (at least) 'hideanons' in such case
1134 if ( $opts[ 'hideanons' ] ) {
1135 $opts->reset( 'hideanons' );
1136 $opts[ 'userExpLevel' ] = 'registered';
1137 $changed = true;
1138 }
1139
1140 if ( $opts[ 'hideliu' ] ) {
1141 $opts->reset( 'hideliu' );
1142 $opts[ 'userExpLevel' ] = 'unregistered';
1143 $changed = true;
1144 }
1145
1146 if ( $this->filterGroups->hasGroup( 'legacyReviewStatus' ) ) {
1147 if ( $opts[ 'hidepatrolled' ] ) {
1148 $opts->reset( 'hidepatrolled' );
1149 $opts[ 'reviewStatus' ] = 'unpatrolled';
1150 $changed = true;
1151 }
1152
1153 if ( $opts[ 'hideunpatrolled' ] ) {
1154 $opts->reset( 'hideunpatrolled' );
1155 $opts[ 'reviewStatus' ] = implode(
1156 ChangesListStringOptionsFilterGroup::SEPARATOR,
1157 [ 'manual', 'auto' ]
1158 );
1159 $changed = true;
1160 }
1161 }
1162
1163 return $changed;
1164 }
1165
1174 protected function convertParamsForLink( $params ) {
1175 foreach ( $params as &$value ) {
1176 if ( $value === false ) {
1177 $value = '0';
1178 }
1179 }
1180 unset( $value );
1181 return $params;
1182 }
1183
1191 protected function buildQuery( FormOptions $opts ) {
1192 $dbr = $this->getDB();
1193 $isStructuredUI = $this->isStructuredFilterUiEnabled();
1194
1195 $query = $this->changesListQueryFactory->newQuery()
1196 ->recentChangeFields()
1197 ->watchlistUser( $this->getUser() )
1198 ->audience( $this->getAuthority() )
1199 ->excludeDeletedLogAction()
1200 ->limit( $opts['limit'] )
1201 ->maxExecutionTime( $this->getConfig()->get(
1202 MainConfigNames::MaxExecutionTimeForExpensiveQueries ) )
1203 ->caller( static::class . '::buildQuery' );
1204
1205 // Main query hook
1206 $this->addMainQueryHook( $query, $opts );
1207
1208 // Old filter groups interface
1209 $query->legacyMutator(
1210 function (
1211 &$tables,
1212 &$fields,
1213 &$conds,
1214 &$query_options,
1215 &$join_conds,
1216 ) use ( $dbr, $opts, $isStructuredUI ) {
1217 $this->filterGroups->modifyLegacyQuery(
1218 $dbr,
1219 $this,
1220 $tables,
1221 $fields,
1222 $conds,
1223 $query_options,
1224 $join_conds,
1225 $opts,
1226 $isStructuredUI
1227 );
1228 }
1229 );
1230
1231 // New filter groups interface
1232 $this->filterGroups->modifyChangesListQuery( $query, $opts, $isStructuredUI );
1233
1234 // Namespace filtering
1235 if ( $opts[ 'namespace' ] !== '' ) {
1236 $namespaces = explode( ';', $opts[ 'namespace' ] );
1237
1238 $namespaces = $this->expandSymbolicNamespaceFilters( $namespaces );
1239
1240 $namespaceInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
1241 $namespaces = array_filter( $namespaces, $namespaceInfo->exists( ... ) );
1242
1243 if ( $namespaces !== [] ) {
1244 // Namespaces are just ints, use them as int when acting with the database
1245 $namespaces = array_map( 'intval', $namespaces );
1246
1247 if ( $opts[ 'associated' ] ) {
1248 $associatedNamespaces = array_map(
1249 $namespaceInfo->getAssociated( ... ),
1250 array_filter( $namespaces, $namespaceInfo->hasTalkNamespace( ... ) )
1251 );
1252 $namespaces = array_unique( array_merge( $namespaces, $associatedNamespaces ) );
1253 }
1254
1255 if ( $opts['invert'] ) {
1256 $query->excludeNamespaces( $namespaces );
1257 } else {
1258 $query->requireNamespaces( $namespaces );
1259 }
1260 }
1261 }
1262
1263 // Filtering for subpages of a given set of pages
1264 if ( $opts['subpageof'] !== '' ) {
1265 $titleParser = MediaWikiServices::getInstance()->getTitleParser();
1266 $basePages = explode( '|', $opts['subpageof'] );
1267 foreach ( $basePages as $basePageText ) {
1268 // Strip any trailing slash
1269 $basePageText = rtrim( $basePageText, '/' );
1270 try {
1271 $basePage = $titleParser->parseTitle( $basePageText );
1272 } catch ( MalformedTitleException ) {
1273 // Ignore invalid titles
1274 continue;
1275 }
1276 $query->requireSubpageOf( $basePage );
1277 }
1278 }
1279
1280 // Change tags
1281 if ( $this->getConfig()->get( MainConfigNames::UseTagFilter ) ) {
1282 $tagFilter = $opts['tagfilter'] !== '' ? explode( '|', $opts['tagfilter'] ) : [];
1283 if ( $opts['inverttags'] ) {
1284 $query->excludeChangeTags( $tagFilter );
1285 } else {
1286 $query->requireChangeTags( $tagFilter );
1287 }
1288 }
1289 $query->addChangeTagSummaryField();
1290
1291 // Calculate cutoff
1292 $cutoff_unixtime = ConvertibleTimestamp::time() - $opts['days'] * 3600 * 24;
1293 $cutoff = $dbr->timestamp( $cutoff_unixtime );
1294
1295 $fromValid = preg_match( '/^[0-9]{14}$/', $opts['from'] );
1296 if ( $fromValid && $opts['from'] > wfTimestamp( TS::MW, $cutoff ) ) {
1297 $cutoff = $dbr->timestamp( $opts['from'] );
1298 } else {
1299 $opts->reset( 'from' );
1300 }
1301
1302 $query->minTimestamp( $cutoff );
1303
1304 // Feature flag
1305 if ( $this->getRequest()->getBool( 'enable_partitioning' ) ) {
1306 $query->enablePartitioning();
1307 }
1308 return $query;
1309 }
1310
1317 protected function modifyQuery( ChangesListQuery $query, FormOptions $opts ) {
1318 }
1319
1329 protected function runMainQueryHook( &$tables, &$fields, &$conds,
1330 &$query_options, &$join_conds, $opts
1331 ) {
1332 return $this->getHookRunner()->onChangesListSpecialPageQuery(
1333 $this->getName(), $tables, $fields, $conds, $query_options, $join_conds, $opts );
1334 }
1335
1340 protected function addMainQueryHook( $query, $opts ) {
1341 if ( $this->getHookContainer()->isRegistered( 'ChangesListSpecialPageQuery' ) ) {
1342 $this->mainQueryHookRegistered = true;
1343 $query->legacyMutator(
1344 function ( &$tables, &$fields, &$conds, &$query_options, &$join_conds )
1345 use ( $opts ) {
1346 $this->mainQueryHookCalled = true;
1347 return $this->runMainQueryHook( $tables, $fields, $conds,
1348 $query_options, $join_conds, $opts );
1349 }
1350 );
1351 }
1352 }
1353
1357 protected function getDB(): IReadableDatabase {
1358 return MediaWikiServices::getInstance()->getConnectionProvider()->getReplicaDatabase();
1359 }
1360
1367 private function webOutputHeader( $rowCount, $opts ) {
1368 if ( !$this->including() ) {
1369 $this->outputFeedLinks();
1370 $this->doHeader( $opts, $rowCount );
1371 }
1372 }
1373
1380 public function webOutput( $rows, $opts ) {
1381 $this->webOutputHeader( $rows->numRows(), $opts );
1382
1383 $this->outputChangesList( $rows, $opts );
1384 }
1385
1386 public function outputFeedLinks() {
1387 // nothing by default
1388 }
1389
1396 abstract public function outputChangesList( $rows, $opts );
1397
1404 public function doHeader( $opts, $numRows ) {
1405 $this->setTopText( $opts );
1406
1407 // @todo Lots of stuff should be done here.
1408
1409 $this->setBottomText( $opts );
1410 }
1411
1417 public function setTopText( FormOptions $opts ) {
1418 // nothing by default
1419 }
1420
1426 public function setBottomText( FormOptions $opts ) {
1427 // nothing by default
1428 }
1429
1439 public function getExtraOptions( $opts ) {
1440 return [];
1441 }
1442
1448 public function makeLegend() {
1449 $context = $this->getContext();
1450 $user = $context->getUser();
1451 # The legend showing what the letters and stuff mean
1452 $legend = Html::openElement( 'dl' ) . "\n";
1453 # Iterates through them and gets the messages for both letter and tooltip
1454 $legendItems = $context->getConfig()->get( MainConfigNames::RecentChangesFlags );
1455 if ( !( $user->useRCPatrol() || $user->useNPPatrol() ) ) {
1456 unset( $legendItems['unpatrolled'] );
1457 }
1458 foreach ( $legendItems as $key => $item ) { # generate items of the legend
1459 $label = $item['legend'] ?? $item['title'];
1460 $letter = $item['letter'];
1461 $cssClass = $item['class'] ?? $key;
1462
1463 $legend .= Html::element( 'dt',
1464 [ 'class' => $cssClass ], $context->msg( $letter )->text()
1465 ) . "\n" .
1466 Html::rawElement( 'dd',
1467 [ 'class' => Sanitizer::escapeClass( 'mw-changeslist-legend-' . $key ) ],
1468 $context->msg( $label )->parse()
1469 ) . "\n";
1470 }
1471 # (+-123)
1472 $legend .= Html::rawElement( 'dt',
1473 [ 'class' => 'mw-plusminus-pos' ],
1474 $context->msg( 'recentchanges-legend-plusminus' )->parse()
1475 ) . "\n";
1476 $legend .= Html::element(
1477 'dd',
1478 [ 'class' => 'mw-changeslist-legend-plusminus' ],
1479 $context->msg( 'recentchanges-label-plusminus' )->text()
1480 ) . "\n";
1481 // Watchlist expiry clock icon.
1482 if ( $context->getConfig()->get( MainConfigNames::WatchlistExpiry ) && !$this->including() ) {
1483 $widget = new IconWidget( [
1484 'icon' => 'clock',
1485 'classes' => [ 'mw-changesList-watchlistExpiry' ],
1486 ] );
1487 // Link the image to its label for assistive technologies.
1488 $watchlistLabelId = 'mw-changeslist-watchlistExpiry-label';
1489 $widget->getIconElement()->setAttributes( [
1490 'role' => 'img',
1491 'aria-labelledby' => $watchlistLabelId,
1492 ] );
1493 $legend .= Html::rawElement(
1494 'dt',
1495 [ 'class' => 'mw-changeslist-legend-watchlistexpiry' ],
1496 $widget->toString()
1497 );
1498 $legend .= Html::element(
1499 'dd',
1500 [ 'class' => 'mw-changeslist-legend-watchlistexpiry', 'id' => $watchlistLabelId ],
1501 $context->msg( 'recentchanges-legend-watchlistexpiry' )->text()
1502 );
1503 }
1504 $legend .= Html::closeElement( 'dl' ) . "\n";
1505
1506 $legendHeading = $this->isStructuredFilterUiEnabled() ?
1507 $context->msg( 'rcfilters-legend-heading' )->parse() :
1508 $context->msg( 'recentchanges-legend-heading' )->parse();
1509
1510 # Collapsible
1511 $collapsedState = $this->getRequest()->getCookie( 'changeslist-state' );
1512
1513 $legend = Html::rawElement( 'details', [
1514 'class' => 'mw-changeslist-legend',
1515 'open' => $collapsedState !== 'collapsed' ? 'open' : null,
1516 ],
1517 Html::rawElement( 'summary', [], $legendHeading ) .
1518 $legend
1519 );
1520
1521 return $legend;
1522 }
1523
1527 protected function addModules() {
1528 $out = $this->getOutput();
1529 // Styles and behavior for the legend box (see makeLegend())
1530 $out->addModuleStyles( [
1531 'mediawiki.interface.helpers.styles',
1532 'mediawiki.special.changeslist.legend',
1533 'mediawiki.special.changeslist',
1534 ] );
1535 $out->addModules( 'mediawiki.special.changeslist.legend.js' );
1536
1537 if ( $this->isStructuredFilterUiEnabled() && !$this->including() ) {
1538 $out->addModules( 'mediawiki.rcfilters.filters.ui' );
1539 $out->addModuleStyles( 'mediawiki.rcfilters.filters.base.styles' );
1540 }
1541 }
1542
1544 protected function getGroupName() {
1545 return 'changes';
1546 }
1547
1554 if ( $this->getRequest()->getBool( 'rcfilters' ) ) {
1555 return true;
1556 }
1557
1558 return static::checkStructuredFilterUiEnabled( $this->getUser() );
1559 }
1560
1568 public static function checkStructuredFilterUiEnabled( UserIdentity $user ) {
1569 return !MediaWikiServices::getInstance()
1570 ->getUserOptionsLookup()
1571 ->getOption( $user, 'rcenhancedfilters-disable' );
1572 }
1573
1581 public function getDefaultLimit() {
1582 return MediaWikiServices::getInstance()
1583 ->getUserOptionsLookup()
1584 ->getIntOption( $this->getUser(), $this->getLimitPreferenceName() );
1585 }
1586
1595 public function getDefaultDays() {
1596 return floatval( MediaWikiServices::getInstance()
1597 ->getUserOptionsLookup()
1598 ->getOption( $this->getUser(), $this->getDefaultDaysPreferenceName() ) );
1599 }
1600
1607 abstract protected function getLimitPreferenceName(): string;
1608
1615 abstract protected function getSavedQueriesPreferenceName(): string;
1616
1623 abstract protected function getDefaultDaysPreferenceName(): string;
1624
1631 abstract protected function getCollapsedPreferenceName(): string;
1632
1637 private function expandSymbolicNamespaceFilters( array $namespaces ) {
1638 $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
1639 $symbolicFilters = [
1640 'all-contents' => $nsInfo->getSubjectNamespaces(),
1641 'all-discussions' => $nsInfo->getTalkNamespaces(),
1642 ];
1643 $additionalNamespaces = [];
1644 foreach ( $symbolicFilters as $name => $values ) {
1645 if ( in_array( $name, $namespaces ) ) {
1646 $additionalNamespaces = array_merge( $additionalNamespaces, $values );
1647 }
1648 }
1649 $namespaces = array_diff( $namespaces, array_keys( $symbolicFilters ) );
1650 $namespaces = array_merge( $namespaces, $additionalNamespaces );
1651 return array_unique( $namespaces );
1652 }
1653}
1654
1656class_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:68
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:43
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.
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.
__construct( $name, $restriction, UserIdentityUtils $userIdentityUtils, TempUserConfig $tempUserConfig, RecentChangeFactory $recentChangeFactory, ChangesListQueryFactory $changesListQueryFactory,)
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'=> false, '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, 250, 300,], '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, 'DjvuUseBoxedCommand'=> false, 'DjvuDump'=> null, 'DjvuRenderer'=> null, 'DjvuTxt'=> null, 'DjvuPostProcessor'=> 'pnmtojpeg', 'DjvuOutputExtension'=> 'jpg', 'EmergencyContact'=> false, 'PasswordSender'=> false, 'NoReplyAddress'=> false, 'EnableEmail'=> true, 'EnableUserEmail'=> true, 'EnableSpecialMute'=> false, 'EnableUserEmailMuteList'=> false, 'UserEmailUseReplyTo'=> true, 'PasswordReminderResendTime'=> 24, 'NewPasswordExpiry'=> 604800, 'UserEmailConfirmationTokenExpiry'=> 604800, 'UserEmailConfirmationUseHTML'=> false, 'PasswordExpirationDays'=> false, 'PasswordExpireGrace'=> 604800, 'SMTP'=> false, 'AdditionalMailParams'=> null, 'AllowHTMLEmail'=> false, 'EnotifFromEditor'=> false, 'EmailAuthentication'=> true, '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, 'ImageLinksSchemaMigrationStage'=> 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'=> '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,],], 'parsoid-pcache'=>['default'=>['minCpuTime'=> 0,],], 'postproc-pcache'=>['default'=>['minCpuTime'=> 9223372036854775807,],], 'postproc-parsoid-pcache'=>['default'=>['minCpuTime'=> 9223372036854775807,],],], 'ChronologyProtectorSecret'=> '', 'ParserCacheExpireTime'=> 86400, 'ParserCacheAsyncExpireTime'=> 60, 'ParserCacheAsyncRefreshJobs'=> true, 'OldRevisionParserCacheExpireTime'=> 3600, 'ObjectCacheSessionExpiry'=> 3600, 'PHPSessionHandling'=> 'warn', 'SuspiciousIpExpiry'=> false, 'SessionPbkdf2Iterations'=> 10001, 'UseSessionCookieJwt'=> false, 'MemCachedServers'=>['127.0.0.1:11211',], 'MemCachedPersistent'=> false, 'MemCachedTimeout'=> 500000, 'UseLocalMessageCache'=> false, 'AdaptiveMessageCache'=> false, 'LocalisationCacheConf'=>['class'=> '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, ], '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' => [ ], '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, 'pagelang' => true, ], 'editprotected' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => true, 'editprotected' => true, ], 'editmycssjs' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => true, 'editmyusercss' => true, 'editmyuserjson' => true, 'editmyuserjs' => true, ], 'editmyoptions' => [ 'editmyoptions' => true, 'editmyuserjson' => true, ], 'editinterface' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => true, 'editinterface' => true, 'edituserjson' => true, 'editsitejson' => true, ], 'editsiteconfig' => [ 'edit' => true, 'minoredit' => true, 'applychangetags' => true, 'changetags' => true, 'editcontentmodel' => 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, '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, '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, '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, '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, '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' => [ ], 'RCEngines' => [ 'redis' => 'MediaWiki\\RCFeed\\RedisPubSubFeedEngine', 'udp' => 'MediaWiki\\RCFeed\\UDPRCFeedEngine', ], '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, '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, 'UsePostprocCache' => false, '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', ], 'UserEmailConfirmationUseHTML' => 'boolean', 'SMTP' => [ 'boolean', 'object', ], 'EnotifFromEditor' => 'boolean', 'EnotifRevealEditorAddress' => 'boolean', 'UsersNotifiedOnAllChanges' => 'object', 'DBmwschema' => [ 'string', 'null', ], 'SharedTables' => 'array', 'DBservers' => [ 'boolean', 'array', ], 'LBFactoryConf' => 'object', 'LocalDatabases' => 'array', 'VirtualDomainsMapping' => 'object', 'FileSchemaMigrationStage' => 'integer', 'ImageLinksSchemaMigrationStage' => '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', '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', ], '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', 'RCEngines' => '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', ], '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', 'UsePostprocCache' => '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', ], 'msg' => [ 'type' => 'string', 'description' => 'a message key', ], ], 'required' => [ 'url', ], ], ], '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.