Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 196 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
LocalSettingsGenerator | |
0.00% |
0 / 196 |
|
0.00% |
0 / 8 |
2352 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 39 |
|
0.00% |
0 / 1 |
30 | |||
setGroupRights | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
escapePhpString | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
12 | |||
getText | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
30 | |||
generateExtEnableLine | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
20 | |||
writeFile | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
buildMemcachedServerList | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
12 | |||
getDefaultText | |
0.00% |
0 / 106 |
|
0.00% |
0 / 1 |
702 |
1 | <?php |
2 | /** |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | * http://www.gnu.org/copyleft/gpl.html |
17 | * |
18 | * @file |
19 | */ |
20 | |
21 | namespace MediaWiki\Installer; |
22 | |
23 | use InvalidArgumentException; |
24 | |
25 | /** |
26 | * Generate the LocalSettings.php file. |
27 | * |
28 | * @ingroup Installer |
29 | * @since 1.17 |
30 | */ |
31 | class LocalSettingsGenerator { |
32 | |
33 | protected $extensions = []; |
34 | protected $skins = []; |
35 | protected $values = []; |
36 | protected $groupPermissions = []; |
37 | protected $dbSettings = ''; |
38 | protected $IP; |
39 | |
40 | /** |
41 | * @var Installer |
42 | */ |
43 | protected $installer; |
44 | |
45 | /** |
46 | * @param Installer $installer |
47 | */ |
48 | public function __construct( Installer $installer ) { |
49 | $this->installer = $installer; |
50 | |
51 | $this->extensions = $installer->getVar( '_Extensions' ); |
52 | $this->skins = $installer->getVar( '_Skins' ); |
53 | $this->IP = $installer->getVar( 'IP' ); |
54 | |
55 | $db = $installer->getDBInstaller( $installer->getVar( 'wgDBtype' ) ); |
56 | |
57 | $confItems = array_merge( |
58 | [ |
59 | 'wgServer', 'wgScriptPath', |
60 | 'wgPasswordSender', 'wgImageMagickConvertCommand', |
61 | 'wgLanguageCode', 'wgLocaltimezone', 'wgEnableEmail', 'wgEnableUserEmail', |
62 | 'wgDiff3', 'wgEnotifUserTalk', 'wgEnotifWatchlist', 'wgEmailAuthentication', |
63 | 'wgDBtype', 'wgSecretKey', 'wgRightsUrl', 'wgSitename', 'wgRightsIcon', |
64 | 'wgRightsText', '_MainCacheType', 'wgEnableUploads', |
65 | '_MemCachedServers', 'wgDBserver', 'wgDBuser', |
66 | 'wgDBpassword', 'wgUseInstantCommons', 'wgUpgradeKey', 'wgDefaultSkin', |
67 | 'wgMetaNamespace', 'wgAuthenticationTokenVersion', 'wgPingback', |
68 | '_Logo1x', '_LogoTagline', '_LogoWordmark', '_LogoIcon', |
69 | '_LogoWordmarkWidth', '_LogoWordmarkHeight', |
70 | '_LogoTaglineWidth', '_LogoTaglineHeight', '_WithDevelopmentSettings' |
71 | ], |
72 | $db->getGlobalNames() |
73 | ); |
74 | |
75 | // The WebInstaller form field for "Logo" contains a literal "$wgResourceBasePath", |
76 | // and site admins are told in the help text that they can use $wgStylePath and $wgScriptPath |
77 | // within their input, such treat this as raw PHP for now. |
78 | $unescaped = [ 'wgRightsIcon', '_Caches', |
79 | '_Logo1x', '_LogoWordmark', '_LogoTagline', '_LogoIcon', |
80 | ]; |
81 | $boolItems = [ |
82 | 'wgEnableEmail', 'wgEnableUserEmail', 'wgEnotifUserTalk', |
83 | 'wgEnotifWatchlist', 'wgEmailAuthentication', 'wgEnableUploads', 'wgUseInstantCommons', |
84 | 'wgPingback', |
85 | ]; |
86 | |
87 | foreach ( $confItems as $c ) { |
88 | $val = $installer->getVar( $c ); |
89 | |
90 | if ( in_array( $c, $boolItems ) ) { |
91 | $val = wfBoolToStr( $val ); |
92 | } |
93 | |
94 | if ( !in_array( $c, $unescaped ) && $val !== null ) { |
95 | $val = self::escapePhpString( $val ); |
96 | } |
97 | |
98 | $this->values[$c] = $val; |
99 | } |
100 | |
101 | $this->dbSettings = $db->getLocalSettings(); |
102 | $this->values['wgEmergencyContact'] = $this->values['wgPasswordSender']; |
103 | } |
104 | |
105 | /** |
106 | * For $wgGroupPermissions, set a given ['group']['permission'] value. |
107 | * @param string $group Group name |
108 | * @param array $rightsArr An array of permissions, in the form of: |
109 | * [ 'right' => true, 'right2' => false ] |
110 | */ |
111 | public function setGroupRights( $group, $rightsArr ) { |
112 | $this->groupPermissions[$group] = $rightsArr; |
113 | } |
114 | |
115 | /** |
116 | * Returns the escaped version of a string of php code. |
117 | * |
118 | * @param string $string |
119 | * |
120 | * @return string|false |
121 | */ |
122 | public static function escapePhpString( $string ) { |
123 | if ( is_array( $string ) || is_object( $string ) ) { |
124 | return false; |
125 | } |
126 | |
127 | return strtr( |
128 | $string, |
129 | [ |
130 | "\n" => "\\n", |
131 | "\r" => "\\r", |
132 | "\t" => "\\t", |
133 | "\\" => "\\\\", |
134 | "\$" => "\\\$", |
135 | "\"" => "\\\"" |
136 | ] |
137 | ); |
138 | } |
139 | |
140 | /** |
141 | * Return the full text of the generated LocalSettings.php file, |
142 | * including the extensions and skins. |
143 | * |
144 | * @return string |
145 | */ |
146 | public function getText() { |
147 | $localSettings = $this->getDefaultText(); |
148 | |
149 | if ( count( $this->skins ) ) { |
150 | $localSettings .= " |
151 | # Enabled skins. |
152 | # The following skins were automatically enabled:\n"; |
153 | |
154 | foreach ( $this->skins as $skinName ) { |
155 | $localSettings .= $this->generateExtEnableLine( 'skins', $skinName ); |
156 | } |
157 | |
158 | $localSettings .= "\n"; |
159 | } |
160 | |
161 | if ( count( $this->extensions ) ) { |
162 | $localSettings .= " |
163 | # Enabled extensions. Most of the extensions are enabled by adding |
164 | # wfLoadExtension( 'ExtensionName' ); |
165 | # to LocalSettings.php. Check specific extension documentation for more details. |
166 | # The following extensions were automatically enabled:\n"; |
167 | |
168 | foreach ( $this->extensions as $extName ) { |
169 | $localSettings .= $this->generateExtEnableLine( 'extensions', $extName ); |
170 | } |
171 | |
172 | $localSettings .= "\n"; |
173 | } |
174 | |
175 | $localSettings .= " |
176 | # End of automatically generated settings. |
177 | # Add more configuration options below.\n\n"; |
178 | |
179 | return $localSettings; |
180 | } |
181 | |
182 | /** |
183 | * Generate the appropriate line to enable the given extension or skin |
184 | * |
185 | * @param string $dir Either "extensions" or "skins" |
186 | * @param string $name Name of extension/skin |
187 | * @throws InvalidArgumentException |
188 | * @return string |
189 | */ |
190 | private function generateExtEnableLine( $dir, $name ) { |
191 | if ( $dir === 'extensions' ) { |
192 | $jsonFile = 'extension.json'; |
193 | $function = 'wfLoadExtension'; |
194 | } elseif ( $dir === 'skins' ) { |
195 | $jsonFile = 'skin.json'; |
196 | $function = 'wfLoadSkin'; |
197 | } else { |
198 | throw new InvalidArgumentException( '$dir was not "extensions" or "skins"' ); |
199 | } |
200 | |
201 | $encName = self::escapePhpString( $name ); |
202 | |
203 | if ( file_exists( "{$this->IP}/$dir/$encName/$jsonFile" ) ) { |
204 | return "$function( '$encName' );\n"; |
205 | } else { |
206 | return "require_once \"\$IP/$dir/$encName/$encName.php\";\n"; |
207 | } |
208 | } |
209 | |
210 | /** |
211 | * Write the generated LocalSettings to a file |
212 | * |
213 | * @param string $fileName Full path to filename to write to |
214 | */ |
215 | public function writeFile( $fileName ) { |
216 | file_put_contents( $fileName, $this->getText() ); |
217 | } |
218 | |
219 | /** |
220 | * @return string |
221 | */ |
222 | protected function buildMemcachedServerList() { |
223 | $servers = $this->values['_MemCachedServers']; |
224 | |
225 | if ( !$servers ) { |
226 | return '[]'; |
227 | } else { |
228 | $ret = '[ '; |
229 | $servers = explode( ',', $servers ); |
230 | |
231 | foreach ( $servers as $srv ) { |
232 | $srv = trim( $srv ); |
233 | $ret .= "'$srv', "; |
234 | } |
235 | |
236 | return rtrim( $ret, ', ' ) . ' ]'; |
237 | } |
238 | } |
239 | |
240 | /** |
241 | * @return string |
242 | */ |
243 | protected function getDefaultText() { |
244 | if ( !$this->values['wgImageMagickConvertCommand'] ) { |
245 | $this->values['wgImageMagickConvertCommand'] = '/usr/bin/convert'; |
246 | $magic = '#'; |
247 | } else { |
248 | $magic = ''; |
249 | } |
250 | |
251 | $metaNamespace = ''; |
252 | if ( $this->values['wgMetaNamespace'] !== $this->values['wgSitename'] ) { |
253 | $metaNamespace = "\$wgMetaNamespace = '{$this->values['wgMetaNamespace']}';\n"; |
254 | } |
255 | |
256 | $groupRights = ''; |
257 | $noFollow = ''; |
258 | if ( $this->groupPermissions ) { |
259 | $groupRights .= "# The following permissions were set based on your choice in the installer\n"; |
260 | foreach ( $this->groupPermissions as $group => $rightArr ) { |
261 | $group = self::escapePhpString( $group ); |
262 | foreach ( $rightArr as $right => $perm ) { |
263 | $right = self::escapePhpString( $right ); |
264 | $groupRights .= "\$wgGroupPermissions['$group']['$right'] = " . |
265 | wfBoolToStr( $perm ) . ";\n"; |
266 | } |
267 | } |
268 | $groupRights .= "\n"; |
269 | |
270 | if ( ( isset( $this->groupPermissions['*']['edit'] ) && |
271 | $this->groupPermissions['*']['edit'] === false ) |
272 | && ( isset( $this->groupPermissions['*']['createaccount'] ) && |
273 | $this->groupPermissions['*']['createaccount'] === false ) |
274 | && ( isset( $this->groupPermissions['*']['read'] ) && |
275 | $this->groupPermissions['*']['read'] !== false ) |
276 | ) { |
277 | $noFollow = "# Set \$wgNoFollowLinks to true if you open up your wiki to editing by\n" |
278 | . "# the general public and wish to apply nofollow to external links as a\n" |
279 | . "# deterrent to spammers. Nofollow is not a comprehensive anti-spam solution\n" |
280 | . "# and open wikis will generally require other anti-spam measures; for more\n" |
281 | . "# information, see https://www.mediawiki.org/wiki/Manual:Combating_spam\n" |
282 | . "\$wgNoFollowLinks = false;\n\n"; |
283 | } |
284 | } |
285 | |
286 | $serverSetting = ""; |
287 | if ( array_key_exists( 'wgServer', $this->values ) && $this->values['wgServer'] !== null ) { |
288 | $serverSetting = "\n## The protocol and server name to use in fully-qualified URLs\n"; |
289 | $serverSetting .= "\$wgServer = '{$this->values['wgServer']}';"; |
290 | } |
291 | |
292 | switch ( $this->values['_MainCacheType'] ) { |
293 | case 'anything': |
294 | case 'db': |
295 | case 'memcached': |
296 | case 'accel': |
297 | $cacheType = 'CACHE_' . strtoupper( $this->values['_MainCacheType'] ); |
298 | break; |
299 | case 'none': |
300 | default: |
301 | $cacheType = 'CACHE_NONE'; |
302 | } |
303 | |
304 | $mcservers = $this->buildMemcachedServerList(); |
305 | if ( file_exists( dirname( __DIR__ ) . '/PlatformSettings.php' ) ) { |
306 | $platformSettings = "\n## Include platform/distribution defaults"; |
307 | $platformSettings .= "\nrequire_once \"\$IP/includes/PlatformSettings.php\";"; |
308 | } else { |
309 | $platformSettings = ''; |
310 | } |
311 | |
312 | $developmentSettings = ''; |
313 | if ( isset( $this->values['_WithDevelopmentSettings'] ) && $this->values['_WithDevelopmentSettings'] ) { |
314 | $developmentSettings = "\n## Include DevelopmentSettings.php"; |
315 | $developmentSettings .= "\nrequire_once \"\$IP/includes/DevelopmentSettings.php\";"; |
316 | } |
317 | |
318 | $this->values['taglineConfig'] = $this->values['_LogoTagline'] ? "\n\t'tagline' => [ |
319 | \"src\" => \"{$this->values['_LogoTagline']}\", |
320 | \"width\" => {$this->values['_LogoTaglineWidth']}, |
321 | \"height\" => {$this->values['_LogoTaglineHeight']} |
322 | ]," : ""; |
323 | |
324 | $this->values['wordmarkConfig'] = $this->values['_LogoWordmark'] ? "\n\t'wordmark' => [ |
325 | \"src\" => \"{$this->values['_LogoWordmark']}\", |
326 | \"width\" => {$this->values['_LogoWordmarkWidth']}, |
327 | \"height\" => {$this->values['_LogoWordmarkHeight']}, |
328 | ]," : ""; |
329 | |
330 | $this->values['sidebarLogo'] = $this->values['_Logo1x'] ?: $this->values['_LogoIcon']; |
331 | |
332 | $version = MW_VERSION; |
333 | return "<?php |
334 | # This file was automatically generated by the MediaWiki {$version} |
335 | # installer. If you make manual changes, please keep track in case you |
336 | # need to recreate them later. |
337 | # |
338 | # See includes/MainConfigSchema.php for all configurable settings |
339 | # and their default values, but don't forget to make changes in _this_ |
340 | # file, not there. |
341 | # |
342 | # Further documentation for configuration settings may be found at: |
343 | # https://www.mediawiki.org/wiki/Manual:Configuration_settings |
344 | |
345 | # Protect against web entry |
346 | if ( !defined( 'MEDIAWIKI' ) ) { |
347 | exit; |
348 | } |
349 | {$developmentSettings} |
350 | |
351 | {$platformSettings} |
352 | |
353 | ## Uncomment this to disable output compression |
354 | # \$wgDisableOutputCompression = true; |
355 | |
356 | \$wgSitename = '{$this->values['wgSitename']}'; |
357 | {$metaNamespace} |
358 | ## The URL base path to the directory containing the wiki; |
359 | ## defaults for all runtime URL paths are based off of this. |
360 | ## For more information on customizing the URLs |
361 | ## (like /w/index.php/Page_title to /wiki/Page_title) please see: |
362 | ## https://www.mediawiki.org/wiki/Manual:Short_URL |
363 | \$wgScriptPath = '{$this->values['wgScriptPath']}'; |
364 | {$serverSetting} |
365 | |
366 | ## The URL path to static resources (images, scripts, etc.) |
367 | \$wgResourceBasePath = \$wgScriptPath; |
368 | |
369 | ## The URL paths to the logo. Make sure you change this from the default, |
370 | ## or else you'll overwrite your logo when you upgrade! |
371 | \$wgLogos = [ |
372 | '1x' => \"{$this->values['sidebarLogo']}\",{$this->values['wordmarkConfig']}{$this->values['taglineConfig']} |
373 | 'icon' => \"{$this->values['_LogoIcon']}\", |
374 | ]; |
375 | |
376 | ## UPO means: this is also a user preference option |
377 | |
378 | \$wgEnableEmail = {$this->values['wgEnableEmail']}; |
379 | \$wgEnableUserEmail = {$this->values['wgEnableUserEmail']}; # UPO |
380 | |
381 | \$wgEmergencyContact = '{$this->values['wgEmergencyContact']}'; |
382 | \$wgPasswordSender = '{$this->values['wgPasswordSender']}'; |
383 | |
384 | \$wgEnotifUserTalk = {$this->values['wgEnotifUserTalk']}; # UPO |
385 | \$wgEnotifWatchlist = {$this->values['wgEnotifWatchlist']}; # UPO |
386 | \$wgEmailAuthentication = {$this->values['wgEmailAuthentication']}; |
387 | |
388 | ## Database settings |
389 | \$wgDBtype = '{$this->values['wgDBtype']}'; |
390 | \$wgDBserver = '{$this->values['wgDBserver']}'; |
391 | \$wgDBname = '{$this->values['wgDBname']}'; |
392 | \$wgDBuser = '{$this->values['wgDBuser']}'; |
393 | \$wgDBpassword = '{$this->values['wgDBpassword']}'; |
394 | |
395 | {$this->dbSettings} |
396 | |
397 | # Shared database table |
398 | # This has no effect unless \$wgSharedDB is also set. |
399 | \$wgSharedTables[] = \"actor\"; |
400 | |
401 | ## Shared memory settings |
402 | \$wgMainCacheType = $cacheType; |
403 | \$wgMemCachedServers = $mcservers; |
404 | |
405 | ## To enable image uploads, make sure the 'images' directory |
406 | ## is writable, then set this to true: |
407 | \$wgEnableUploads = {$this->values['wgEnableUploads']}; |
408 | {$magic}\$wgUseImageMagick = true; |
409 | {$magic}\$wgImageMagickConvertCommand = '{$this->values['wgImageMagickConvertCommand']}'; |
410 | |
411 | # InstantCommons allows wiki to use images from https://commons.wikimedia.org |
412 | \$wgUseInstantCommons = {$this->values['wgUseInstantCommons']}; |
413 | |
414 | # Periodically send a pingback to https://www.mediawiki.org/ with basic data |
415 | # about this MediaWiki instance. The Wikimedia Foundation shares this data |
416 | # with MediaWiki developers to help guide future development efforts. |
417 | \$wgPingback = {$this->values['wgPingback']}; |
418 | |
419 | # Site language code, should be one of the list in ./includes/languages/data/Names.php |
420 | \$wgLanguageCode = '{$this->values['wgLanguageCode']}'; |
421 | |
422 | # Time zone |
423 | \$wgLocaltimezone = '{$this->values['wgLocaltimezone']}'; |
424 | |
425 | ## Set \$wgCacheDirectory to a writable directory on the web server |
426 | ## to make your wiki go slightly faster. The directory should not |
427 | ## be publicly accessible from the web. |
428 | #\$wgCacheDirectory = \"\$IP/cache\"; |
429 | |
430 | \$wgSecretKey = '{$this->values['wgSecretKey']}'; |
431 | |
432 | # Changing this will log out all existing sessions. |
433 | \$wgAuthenticationTokenVersion = '{$this->values['wgAuthenticationTokenVersion']}'; |
434 | |
435 | # Site upgrade key. Must be set to a string (default provided) to turn on the |
436 | # web installer while LocalSettings.php is in place |
437 | \$wgUpgradeKey = '{$this->values['wgUpgradeKey']}'; |
438 | |
439 | ## For attaching licensing metadata to pages, and displaying an |
440 | ## appropriate copyright notice / icon. GNU Free Documentation |
441 | ## License and Creative Commons licenses are supported so far. |
442 | \$wgRightsPage = \"\"; # Set to the title of a wiki page that describes your license/copyright |
443 | \$wgRightsUrl = '{$this->values['wgRightsUrl']}'; |
444 | \$wgRightsText = '{$this->values['wgRightsText']}'; |
445 | \$wgRightsIcon = \"{$this->values['wgRightsIcon']}\"; |
446 | |
447 | # Path to the GNU diff3 utility. Used for conflict resolution. |
448 | \$wgDiff3 = '{$this->values['wgDiff3']}'; |
449 | |
450 | {$groupRights}{$noFollow}## Default skin: you can change the default skin. Use the internal symbolic |
451 | ## names, e.g. 'vector' or 'monobook': |
452 | \$wgDefaultSkin = '{$this->values['wgDefaultSkin']}'; |
453 | "; |
454 | } |
455 | } |