Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
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 | |
7 | use MediaWiki\MainConfigSchema; |
8 | use MediaWiki\Title\NamespaceInfo; |
9 | use 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. |
14 | if ( $wgLogos !== false && isset( $wgLogos['1x'] ) ) { |
15 | $wgLogo = $wgLogos['1x']; |
16 | } |
17 | |
18 | // Back-compat |
19 | if ( isset( $wgFileBlacklist ) ) { |
20 | $wgProhibitedFileExtensions = array_merge( $wgProhibitedFileExtensions, $wgFileBlacklist ); |
21 | } else { |
22 | $wgFileBlacklist = $wgProhibitedFileExtensions; |
23 | } |
24 | if ( isset( $wgMimeTypeBlacklist ) ) { |
25 | $wgMimeTypeExclusions = array_merge( $wgMimeTypeExclusions, $wgMimeTypeBlacklist ); |
26 | } else { |
27 | $wgMimeTypeBlacklist = $wgMimeTypeExclusions; |
28 | } |
29 | if ( isset( $wgEnableUserEmailBlacklist ) ) { |
30 | $wgEnableUserEmailMuteList = $wgEnableUserEmailBlacklist; |
31 | } else { |
32 | $wgEnableUserEmailBlacklist = $wgEnableUserEmailMuteList; |
33 | } |
34 | if ( isset( $wgShortPagesNamespaceBlacklist ) ) { |
35 | $wgShortPagesNamespaceExclusions = $wgShortPagesNamespaceBlacklist; |
36 | } else { |
37 | $wgShortPagesNamespaceBlacklist = $wgShortPagesNamespaceExclusions; |
38 | } |
39 | |
40 | // Rate limits should have the same name as the corresponding permission |
41 | if ( 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 |
51 | if ( 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 |
65 | if ( $wgRightsIcon ) { |
66 | $wgRightsIcon = str_replace( |
67 | "{$wgStylePath}/common/images/", |
68 | "{$wgResourceBasePath}/resources/assets/licenses/", |
69 | $wgRightsIcon |
70 | ); |
71 | } |
72 | |
73 | if ( 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 | |
85 | if ( 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 | |
126 | if ( 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 | */ |
135 | if ( $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 | } |
170 | if ( $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 | } |
184 | foreach ( $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 | } |
192 | unset( $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 | ); |
204 | unset( $rcMaxAgeDays ); |
205 | |
206 | $wgCookiePrefix = strtr( $wgCookiePrefix, '=,; +."\'\\[', '__________' ); |
207 | |
208 | if ( !$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 | |
227 | if ( !$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 |
251 | if ( 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 |
265 | foreach ( 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 | } |
271 | unset( $code ); // no global pollution; destroy reference |
272 | unset( $bcp47 ); // no global pollution; destroy reference |
273 | if ( $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 | |
280 | if ( 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 | |
292 | if ( 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 | |
304 | if ( $wgInvalidateCacheOnLocalSettingsChange && defined( 'MW_CONFIG_FILE' ) ) { |
305 | AtEase::suppressWarnings(); |
306 | $wgCacheEpoch = max( $wgCacheEpoch, gmdate( 'YmdHis', filemtime( MW_CONFIG_FILE ) ) ); |
307 | AtEase::restoreWarnings(); |
308 | } |
309 | |
310 | if ( $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 | |
322 | if ( $wgPageCreationLog ) { |
323 | // Add page creation log type |
324 | $wgLogTypes[] = 'create'; |
325 | $wgLogActionsHandlers['create/create'] = LogFormatter::class; |
326 | } |
327 | |
328 | if ( $wgPageLanguageUseDB ) { |
329 | $wgLogTypes[] = 'pagelang'; |
330 | $wgLogActionsHandlers['pagelang/pagelang'] = [ |
331 | 'class' => PageLangLogFormatter::class, |
332 | 'services' => [ |
333 | 'LanguageNameUtils', |
334 | ] |
335 | ]; |
336 | } |
337 | |
338 | if ( $wgPHPSessionHandling !== 'enable' && |
339 | $wgPHPSessionHandling !== 'warn' && |
340 | $wgPHPSessionHandling !== 'disable' |
341 | ) { |
342 | $wgPHPSessionHandling = 'warn'; |
343 | } |
344 | if ( 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 |
351 | if ( !$wgVirtualDomainsMapping ) { |
352 | $wgVirtualDomainsMapping = []; |
353 | } |
354 | if ( $wgBotPasswordsCluster ) { |
355 | $wgVirtualDomainsMapping['virtual-botpasswords']['cluster'] = $wgBotPasswordsCluster; |
356 | } |
357 | |
358 | if ( $wgBotPasswordsDatabase ) { |
359 | $wgVirtualDomainsMapping['virtual-botpasswords']['db'] = $wgBotPasswordsDatabase; |
360 | } |