Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 218
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2/**
3 * This is included by Setup.php to adjust the values of globals before services are initialized.
4 * It's split into a separate file so it can be tested.
5 */
6
7use MediaWiki\MainConfigSchema;
8use MediaWiki\Title\NamespaceInfo;
9use Wikimedia\AtEase\AtEase;
10
11// For backwards compatibility, the value of wgLogos is copied to wgLogo.
12// This is because some extensions/skins may be using $config->get('Logo')
13// to access the value.
14if ( $wgLogos !== false && isset( $wgLogos['1x'] ) ) {
15    $wgLogo = $wgLogos['1x'];
16}
17
18// Back-compat
19if ( isset( $wgFileBlacklist ) ) {
20    $wgProhibitedFileExtensions = array_merge( $wgProhibitedFileExtensions, $wgFileBlacklist );
21} else {
22    $wgFileBlacklist = $wgProhibitedFileExtensions;
23}
24if ( isset( $wgMimeTypeBlacklist ) ) {
25    $wgMimeTypeExclusions = array_merge( $wgMimeTypeExclusions, $wgMimeTypeBlacklist );
26} else {
27    $wgMimeTypeBlacklist = $wgMimeTypeExclusions;
28}
29if ( isset( $wgEnableUserEmailBlacklist ) ) {
30    $wgEnableUserEmailMuteList = $wgEnableUserEmailBlacklist;
31} else {
32    $wgEnableUserEmailBlacklist = $wgEnableUserEmailMuteList;
33}
34if ( isset( $wgShortPagesNamespaceBlacklist ) ) {
35    $wgShortPagesNamespaceExclusions = $wgShortPagesNamespaceBlacklist;
36} else {
37    $wgShortPagesNamespaceBlacklist = $wgShortPagesNamespaceExclusions;
38}
39
40// Rate limits should have the same name as the corresponding permission
41if ( isset( $wgRateLimits['emailuser'] ) ) {
42    // If the deprecated field is set, use it.
43    // Note that we can't know whether the new field has been set explicitly, since it has a default value.
44    $wgSettings->warning(
45        'RateLimit: The "emailuser" limit is deprecated, use "sendemail" instead.'
46    );
47    $wgRateLimits['sendemail'] = $wgRateLimits['emailuser'];
48}
49
50// Rate limits should have the same name as the corresponding permission
51if ( isset( $wgRateLimits['changetag'] ) ) {
52    // If the deprecated field is set, use it.
53    // Note that we can't know whether the new field has been set explicitly, since it has a default value.
54    $wgSettings->warning(
55        'RateLimit: The "changetag" limit is deprecated, use "changetags" instead.'
56    );
57    $wgRateLimits['changetags'] = $wgRateLimits['changetag'];
58}
59
60// Prohibited file extensions shouldn't appear on the "allowed" list
61// @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal False positive
62$wgFileExtensions = array_values( array_diff( $wgFileExtensions, $wgProhibitedFileExtensions ) );
63
64// Fix path to icon images after they were moved in 1.24
65if ( $wgRightsIcon ) {
66    $wgRightsIcon = str_replace(
67        "{$wgStylePath}/common/images/",
68        "{$wgResourceBasePath}/resources/assets/licenses/",
69        $wgRightsIcon
70    );
71}
72
73if ( isset( $wgFooterIcons['copyright']['copyright'] )
74    && $wgFooterIcons['copyright']['copyright'] === []
75) {
76    if ( $wgRightsIcon || $wgRightsText ) {
77        $wgFooterIcons['copyright']['copyright'] = [
78            'url' => $wgRightsUrl,
79            'src' => $wgRightsIcon,
80            'alt' => $wgRightsText,
81        ];
82    }
83}
84
85if ( isset( $wgFooterIcons['poweredby'] )
86    && isset( $wgFooterIcons['poweredby']['mediawiki'] )
87    && $wgFooterIcons['poweredby']['mediawiki']['src'] === null
88) {
89    $wgFooterIcons['poweredby']['mediawiki']['src'] =
90        "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png";
91    $wgFooterIcons['poweredby']['mediawiki']['srcset'] =
92        "$wgResourceBasePath/resources/assets/poweredby_mediawiki_132x47.png 1.5x, " .
93        "$wgResourceBasePath/resources/assets/poweredby_mediawiki_176x62.png 2x";
94}
95
96// Unconditional protection for NS_MEDIAWIKI since otherwise it's too easy for a
97// sysadmin to set $wgNamespaceProtection incorrectly and leave the wiki insecure.
98//
99// Note that this is the definition of editinterface and it can be granted to
100// all users if desired.
101$wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface';
102
103// Initialise $wgLockManagers to include basic FS version
104$wgLockManagers[] = [
105    'name' => 'fsLockManager',
106    'class' => FSLockManager::class,
107    'lockDirectory' => "{$wgUploadDirectory}/lockdir",
108];
109$wgLockManagers[] = [
110    'name' => 'nullLockManager',
111    'class' => NullLockManager::class,
112];
113
114// Default parameters for the "<gallery>" tag.
115// See \MediaWiki\MainConfigSchema::GalleryOptions
116$wgGalleryOptions += [
117    'imagesPerRow' => 0,
118    'imageWidth' => 120,
119    'imageHeight' => 120,
120    'captionLength' => true,
121    'showBytes' => true,
122    'showDimensions' => true,
123    'mode' => 'traditional',
124];
125
126if ( isset( $wgLocalFileRepo['name'] ) && !isset( $wgLocalFileRepo['backend'] ) ) {
127    // Create a default FileBackend name.
128    // FileBackendGroup will register a default, if absent from $wgFileBackends.
129    $wgLocalFileRepo['backend'] = $wgLocalFileRepo['name'] . '-backend';
130}
131
132/**
133 * Shortcuts for $wgForeignFileRepos
134 */
135if ( $wgUseSharedUploads ) {
136    if ( $wgSharedUploadDBname ) {
137        $wgForeignFileRepos[] = [
138            'class' => ForeignDBRepo::class,
139            'name' => 'shared',
140            'directory' => $wgSharedUploadDirectory,
141            'url' => $wgSharedUploadPath,
142            'hashLevels' => $wgHashedSharedUploadDirectory ? 2 : 0,
143            'thumbScriptUrl' => $wgSharedThumbnailScriptPath,
144            'transformVia404' => !$wgGenerateThumbnailOnParse,
145            'dbType' => $wgDBtype,
146            'dbServer' => $wgDBserver,
147            'dbUser' => $wgDBuser,
148            'dbPassword' => $wgDBpassword,
149            'dbName' => $wgSharedUploadDBname,
150            'dbFlags' => ( $wgDebugDumpSql ? DBO_DEBUG : 0 ) | DBO_DEFAULT,
151            'tablePrefix' => $wgSharedUploadDBprefix,
152            'hasSharedCache' => $wgCacheSharedUploads,
153            'descBaseUrl' => $wgRepositoryBaseUrl,
154            'fetchDescription' => $wgFetchCommonsDescriptions,
155        ];
156    } else {
157        $wgForeignFileRepos[] = [
158            'class' => FileRepo::class,
159            'name' => 'shared',
160            'directory' => $wgSharedUploadDirectory,
161            'url' => $wgSharedUploadPath,
162            'hashLevels' => $wgHashedSharedUploadDirectory ? 2 : 0,
163            'thumbScriptUrl' => $wgSharedThumbnailScriptPath,
164            'transformVia404' => !$wgGenerateThumbnailOnParse,
165            'descBaseUrl' => $wgRepositoryBaseUrl,
166            'fetchDescription' => $wgFetchCommonsDescriptions,
167        ];
168    }
169}
170if ( $wgUseInstantCommons ) {
171    $wgForeignFileRepos[] = [
172        'class' => ForeignAPIRepo::class,
173        'name' => 'wikimediacommons',
174        'apibase' => 'https://commons.wikimedia.org/w/api.php',
175        'url' => 'https://upload.wikimedia.org/wikipedia/commons',
176        'thumbUrl' => 'https://upload.wikimedia.org/wikipedia/commons/thumb',
177        'hashLevels' => 2,
178        'transformVia404' => true,
179        'fetchDescription' => true,
180        'descriptionCacheExpiry' => 43200,
181        'apiThumbCacheExpiry' => 0,
182    ];
183}
184foreach ( $wgForeignFileRepos as &$repo ) {
185    if ( !isset( $repo['directory'] ) && $repo['class'] === ForeignAPIRepo::class ) {
186        $repo['directory'] = $wgUploadDirectory; // b/c
187    }
188    if ( !isset( $repo['backend'] ) ) {
189        $repo['backend'] = $repo['name'] . '-backend';
190    }
191}
192unset( $repo ); // no global pollution; destroy reference
193
194$rcMaxAgeDays = $wgRCMaxAge / ( 3600 * 24 );
195// Ensure that default user options are not invalid, since that breaks Special:Preferences
196$wgDefaultUserOptions['rcdays'] = min(
197    $wgDefaultUserOptions['rcdays'],
198    ceil( $rcMaxAgeDays )
199);
200$wgDefaultUserOptions['watchlistdays'] = min(
201    $wgDefaultUserOptions['watchlistdays'],
202    ceil( $rcMaxAgeDays )
203);
204unset( $rcMaxAgeDays );
205
206$wgCookiePrefix = strtr( $wgCookiePrefix, '=,; +."\'\\[', '__________' );
207
208if ( !$wgEnableEmail ) {
209    // Disable all other email settings automatically if $wgEnableEmail
210    // is set to false. - T65678
211    $wgAllowHTMLEmail = false;
212    $wgEmailAuthentication = false; // do not require auth if you're not sending email anyway
213    $wgEnableUserEmail = false;
214    $wgEnotifFromEditor = false;
215    $wgEnotifImpersonal = false;
216    $wgEnotifMaxRecips = 0;
217    $wgEnotifMinorEdits = false;
218    $wgEnotifRevealEditorAddress = false;
219    $wgEnotifUseRealName = false;
220    $wgEnotifUserTalk = false;
221    $wgEnotifWatchlist = false;
222    unset( $wgGroupPermissions['user']['sendemail'] );
223    $wgUserEmailUseReplyTo = false;
224    $wgUsersNotifiedOnAllChanges = [];
225}
226
227if ( !$wgLocaltimezone ) {
228    // NOTE: The automatic dynamic default only kicks in if $wgLocaltimezone is null,
229    //       but the installer writes $wgLocaltimezone into LocalSettings, and may
230    //       produce (or may have produced historically) an empty string for some
231    //       reason. To be compatible with existing LocalSettings.php files, we need
232    //       to gracefully handle the case of $wgLocaltimezone being the empty string.
233    //       See T305093#8063451.
234    $wgLocaltimezone = MainConfigSchema::getDefaultLocaltimezone();
235    $wgSettings->warning(
236        'The Localtimezone setting must a valid timezone string or null. '
237        . 'It must not be an empty string or false.'
238    );
239}
240
241// The part after the System| is ignored, but rest of MW fills it out as the local offset.
242$wgDefaultUserOptions['timecorrection'] = "System|$wgLocalTZoffset";
243
244/**
245 * Definitions of the NS_ constants are in Defines.php
246 * @internal
247 */
248$wgCanonicalNamespaceNames = NamespaceInfo::CANONICAL_NAMES;
249
250// Hard-deprecate setting $wgDummyLanguageCodes in LocalSettings.php
251if ( count( $wgDummyLanguageCodes ) !== 0 ) {
252    $wgSettings->warning(
253        'Do not add to DummyLanguageCodes directly, ' .
254        'add to ExtraLanguageCodes instead.'
255    );
256}
257// Merge in the legacy language codes, incorporating overrides from the config
258$wgDummyLanguageCodes += [
259    // Internal language codes of the private-use area which get mapped to
260    // themselves.
261    'qqq' => 'qqq', // Used for message documentation
262    'qqx' => 'qqx', // Used for viewing message keys
263] + $wgExtraLanguageCodes + LanguageCode::getDeprecatedCodeMapping();
264// Merge in (inverted) BCP 47 mappings
265foreach ( LanguageCode::getNonstandardLanguageCodeMapping() as $code => $bcp47 ) {
266    $bcp47 = strtolower( $bcp47 ); // force case-insensitivity
267    if ( !isset( $wgDummyLanguageCodes[$bcp47] ) ) {
268        $wgDummyLanguageCodes[$bcp47] = $wgDummyLanguageCodes[$code] ?? $code;
269    }
270}
271unset( $code ); // no global pollution; destroy reference
272unset( $bcp47 ); // no global pollution; destroy reference
273if ( $wgUseXssLanguage ) {
274    $wgDummyLanguageCodes['x-xss'] = 'x-xss'; // Used for testing
275}
276
277// Temporary backwards-compatibility reading of old replica lag settings as of MediaWiki 1.36,
278// to support sysadmins who fail to update their settings immediately:
279
280if ( isset( $wgSlaveLagWarning ) ) {
281    // If the old value is set to something other than the default, use it.
282    if ( $wgDatabaseReplicaLagWarning === 10 && $wgSlaveLagWarning !== 10 ) {
283        $wgDatabaseReplicaLagWarning = $wgSlaveLagWarning;
284        $wgSettings->warning( 'SlaveLagWarning is no longer supported, ' .
285            'use DatabaseReplicaLagWarning instead!' );
286    }
287} else {
288    // Backwards-compatibility for extensions that read this value.
289    $wgSlaveLagWarning = $wgDatabaseReplicaLagWarning;
290}
291
292if ( isset( $wgSlaveLagCritical ) ) {
293    // If the old value is set to something other than the default, use it.
294    if ( $wgDatabaseReplicaLagCritical === 30 && $wgSlaveLagCritical !== 30 ) {
295        $wgDatabaseReplicaLagCritical = $wgSlaveLagCritical;
296        $wgSettings->warning( 'SlaveLagCritical is no longer supported, ' .
297            'use DatabaseReplicaLagCritical instead!' );
298    }
299} else {
300    // Backwards-compatibility for extensions that read this value.
301    $wgSlaveLagCritical = $wgDatabaseReplicaLagCritical;
302}
303
304if ( $wgInvalidateCacheOnLocalSettingsChange && defined( 'MW_CONFIG_FILE' ) ) {
305    AtEase::suppressWarnings();
306    $wgCacheEpoch = max( $wgCacheEpoch, gmdate( 'YmdHis', filemtime( MW_CONFIG_FILE ) ) );
307    AtEase::restoreWarnings();
308}
309
310if ( $wgNewUserLog ) {
311    // Add new user log type
312    $wgLogTypes[] = 'newusers';
313    $wgLogNames['newusers'] = 'newuserlogpage';
314    $wgLogHeaders['newusers'] = 'newuserlogpagetext';
315    $wgLogActionsHandlers['newusers/newusers'] = NewUsersLogFormatter::class;
316    $wgLogActionsHandlers['newusers/create'] = NewUsersLogFormatter::class;
317    $wgLogActionsHandlers['newusers/create2'] = NewUsersLogFormatter::class;
318    $wgLogActionsHandlers['newusers/byemail'] = NewUsersLogFormatter::class;
319    $wgLogActionsHandlers['newusers/autocreate'] = NewUsersLogFormatter::class;
320}
321
322if ( $wgPageCreationLog ) {
323    // Add page creation log type
324    $wgLogTypes[] = 'create';
325    $wgLogActionsHandlers['create/create'] = LogFormatter::class;
326}
327
328if ( $wgPageLanguageUseDB ) {
329    $wgLogTypes[] = 'pagelang';
330    $wgLogActionsHandlers['pagelang/pagelang'] = [
331        'class' => PageLangLogFormatter::class,
332        'services' => [
333            'LanguageNameUtils',
334        ]
335    ];
336}
337
338if ( $wgPHPSessionHandling !== 'enable' &&
339    $wgPHPSessionHandling !== 'warn' &&
340    $wgPHPSessionHandling !== 'disable'
341) {
342    $wgPHPSessionHandling = 'warn';
343}
344if ( defined( 'MW_NO_SESSION' ) ) {
345    // If the entry point wants no session, force 'disable' here unless they
346    // specifically set it to the (undocumented) 'warn'.
347    $wgPHPSessionHandling = MW_NO_SESSION === 'warn' ? 'warn' : 'disable';
348}
349
350// Backwards compatibility with old bot passwords storage configs
351if ( !$wgVirtualDomainsMapping ) {
352    $wgVirtualDomainsMapping = [];
353}
354if ( $wgBotPasswordsCluster ) {
355    $wgVirtualDomainsMapping['virtual-botpasswords']['cluster'] = $wgBotPasswordsCluster;
356}
357
358if ( $wgBotPasswordsDatabase ) {
359    $wgVirtualDomainsMapping['virtual-botpasswords']['db'] = $wgBotPasswordsDatabase;
360}