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