MediaWiki  master
LocalSettingsGenerator.php
Go to the documentation of this file.
1 <?php
31 
32  protected $extensions = [];
33  protected $skins = [];
34  protected $values = [];
35  protected $groupPermissions = [];
36  protected $dbSettings = '';
37  protected $IP;
38 
42  protected $installer;
43 
47  public function __construct( Installer $installer ) {
48  $this->installer = $installer;
49 
50  $this->extensions = $installer->getVar( '_Extensions' );
51  $this->skins = $installer->getVar( '_Skins' );
52  $this->IP = $installer->getVar( 'IP' );
53 
54  $db = $installer->getDBInstaller( $installer->getVar( 'wgDBtype' ) );
55 
56  $confItems = array_merge(
57  [
58  'wgServer', 'wgScriptPath',
59  'wgPasswordSender', 'wgImageMagickConvertCommand',
60  'wgLanguageCode', 'wgLocaltimezone', 'wgEnableEmail', 'wgEnableUserEmail',
61  'wgDiff3', 'wgEnotifUserTalk', 'wgEnotifWatchlist', 'wgEmailAuthentication',
62  'wgDBtype', 'wgSecretKey', 'wgRightsUrl', 'wgSitename', 'wgRightsIcon',
63  'wgRightsText', '_MainCacheType', 'wgEnableUploads',
64  '_MemCachedServers', 'wgDBserver', 'wgDBuser',
65  'wgDBpassword', 'wgUseInstantCommons', 'wgUpgradeKey', 'wgDefaultSkin',
66  'wgMetaNamespace', 'wgAuthenticationTokenVersion', 'wgPingback',
67  '_Logo1x', '_LogoTagline', '_LogoWordmark', '_LogoIcon',
68  '_LogoWordmarkWidth', '_LogoWordmarkHeight',
69  '_LogoTaglineWidth', '_LogoTaglineHeight'
70  ],
71  $db->getGlobalNames()
72  );
73 
74  // The WebInstaller form field for "Logo" contains a literal "$wgResourceBasePath",
75  // and site admins are told in the help text that they can use $wgStylePath and $wgScriptPath
76  // within their input, such treat this as raw PHP for now.
77  $unescaped = [ 'wgRightsIcon', '_Caches',
78  '_Logo1x', '_LogoWordmark', '_LogoTagline', '_LogoIcon',
79  ];
80  $boolItems = [
81  'wgEnableEmail', 'wgEnableUserEmail', 'wgEnotifUserTalk',
82  'wgEnotifWatchlist', 'wgEmailAuthentication', 'wgEnableUploads', 'wgUseInstantCommons',
83  'wgPingback',
84  ];
85 
86  foreach ( $confItems as $c ) {
87  $val = $installer->getVar( $c );
88 
89  if ( in_array( $c, $boolItems ) ) {
90  $val = wfBoolToStr( $val );
91  }
92 
93  if ( !in_array( $c, $unescaped ) && $val !== null ) {
94  $val = self::escapePhpString( $val );
95  }
96 
97  $this->values[$c] = $val;
98  }
99 
100  $this->dbSettings = $db->getLocalSettings();
101  $this->values['wgEmergencyContact'] = $this->values['wgPasswordSender'];
102  }
103 
110  public function setGroupRights( $group, $rightsArr ) {
111  $this->groupPermissions[$group] = $rightsArr;
112  }
113 
121  public static function escapePhpString( $string ) {
122  if ( is_array( $string ) || is_object( $string ) ) {
123  return false;
124  }
125 
126  return strtr(
127  $string,
128  [
129  "\n" => "\\n",
130  "\r" => "\\r",
131  "\t" => "\\t",
132  "\\" => "\\\\",
133  "\$" => "\\\$",
134  "\"" => "\\\""
135  ]
136  );
137  }
138 
145  public function getText() {
146  $localSettings = $this->getDefaultText();
147 
148  if ( count( $this->skins ) ) {
149  $localSettings .= "
150 # Enabled skins.
151 # The following skins were automatically enabled:\n";
152 
153  foreach ( $this->skins as $skinName ) {
154  $localSettings .= $this->generateExtEnableLine( 'skins', $skinName );
155  }
156 
157  $localSettings .= "\n";
158  }
159 
160  if ( count( $this->extensions ) ) {
161  $localSettings .= "
162 # Enabled extensions. Most of the extensions are enabled by adding
163 # wfLoadExtension( 'ExtensionName' );
164 # to LocalSettings.php. Check specific extension documentation for more details.
165 # The following extensions were automatically enabled:\n";
166 
167  foreach ( $this->extensions as $extName ) {
168  $localSettings .= $this->generateExtEnableLine( 'extensions', $extName );
169  }
170 
171  $localSettings .= "\n";
172  }
173 
174  $localSettings .= "
175 # End of automatically generated settings.
176 # Add more configuration options below.\n\n";
177 
178  return $localSettings;
179  }
180 
189  private function generateExtEnableLine( $dir, $name ) {
190  if ( $dir === 'extensions' ) {
191  $jsonFile = 'extension.json';
192  $function = 'wfLoadExtension';
193  } elseif ( $dir === 'skins' ) {
194  $jsonFile = 'skin.json';
195  $function = 'wfLoadSkin';
196  } else {
197  throw new InvalidArgumentException( '$dir was not "extensions" or "skins"' );
198  }
199 
200  $encName = self::escapePhpString( $name );
201 
202  if ( file_exists( "{$this->IP}/$dir/$encName/$jsonFile" ) ) {
203  return "$function( '$encName' );\n";
204  } else {
205  return "require_once \"\$IP/$dir/$encName/$encName.php\";\n";
206  }
207  }
208 
214  public function writeFile( $fileName ) {
215  file_put_contents( $fileName, $this->getText() );
216  }
217 
221  protected function buildMemcachedServerList() {
222  $servers = $this->values['_MemCachedServers'];
223 
224  if ( !$servers ) {
225  return '[]';
226  } else {
227  $ret = '[ ';
228  $servers = explode( ',', $servers );
229 
230  foreach ( $servers as $srv ) {
231  $srv = trim( $srv );
232  $ret .= "'$srv', ";
233  }
234 
235  return rtrim( $ret, ', ' ) . ' ]';
236  }
237  }
238 
242  protected function getDefaultText() {
243  if ( !$this->values['wgImageMagickConvertCommand'] ) {
244  $this->values['wgImageMagickConvertCommand'] = '/usr/bin/convert';
245  $magic = '#';
246  } else {
247  $magic = '';
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  if ( file_exists( dirname( __DIR__ ) . '/PlatformSettings.php' ) ) {
305  $platformSettings = "\n## Include platform/distribution defaults";
306  $platformSettings .= "\nrequire_once \"\$IP/includes/PlatformSettings.php\";";
307  } else {
308  $platformSettings = '';
309  }
310 
311  $this->values['taglineConfig'] = $this->values['_LogoTagline'] ? "'tagline' => [
312  \"src\" => \"{$this->values['_LogoTagline']}\",
313  \"width\" => {$this->values['_LogoTaglineWidth']},
314  \"height\" => {$this->values['_LogoTaglineHeight']}
315  ]," : "";
316 
317  $this->values['wordmarkConfig'] = $this->values['_LogoWordmark'] ? "'wordmark' => [
318  \"src\" => \"{$this->values['_LogoWordmark']}\",
319  \"width\" => {$this->values['_LogoWordmarkWidth']},
320  \"height\" => {$this->values['_LogoWordmarkHeight']},
321  ]," : "";
322 
323  $this->values['sidebarLogo'] = $this->values['_Logo1x'] ?: $this->values['_LogoIcon'];
324 
325  $version = MW_VERSION;
326  return "<?php
327 # This file was automatically generated by the MediaWiki {$version}
328 # installer. If you make manual changes, please keep track in case you
329 # need to recreate them later.
330 #
331 # See docs/Configuration.md for all configurable settings
332 # and their default values, but don't forget to make changes in _this_
333 # file, not there.
334 #
335 # Further documentation for configuration settings may be found at:
336 # https://www.mediawiki.org/wiki/Manual:Configuration_settings
337 
338 # Protect against web entry
339 if ( !defined( 'MEDIAWIKI' ) ) {
340  exit;
341 }
342 {$platformSettings}
343 
344 ## Uncomment this to disable output compression
345 # \$wgDisableOutputCompression = true;
346 
347 \$wgSitename = \"{$this->values['wgSitename']}\";
348 {$metaNamespace}
349 ## The URL base path to the directory containing the wiki;
350 ## defaults for all runtime URL paths are based off of this.
351 ## For more information on customizing the URLs
352 ## (like /w/index.php/Page_title to /wiki/Page_title) please see:
353 ## https://www.mediawiki.org/wiki/Manual:Short_URL
354 \$wgScriptPath = \"{$this->values['wgScriptPath']}\";
355 ${serverSetting}
356 
357 ## The URL path to static resources (images, scripts, etc.)
358 \$wgResourceBasePath = \$wgScriptPath;
359 
360 ## The URL paths to the logo. Make sure you change this from the default,
361 ## or else you'll overwrite your logo when you upgrade!
362 \$wgLogos = [
363  '1x' => \"{$this->values['sidebarLogo']}\",
364  {$this->values['wordmarkConfig']}
365  {$this->values['taglineConfig']}
366  'icon' => \"{$this->values['_LogoIcon']}\",
367 ];
368 
369 ## UPO means: this is also a user preference option
370 
371 \$wgEnableEmail = {$this->values['wgEnableEmail']};
372 \$wgEnableUserEmail = {$this->values['wgEnableUserEmail']}; # UPO
373 
374 \$wgEmergencyContact = \"{$this->values['wgEmergencyContact']}\";
375 \$wgPasswordSender = \"{$this->values['wgPasswordSender']}\";
376 
377 \$wgEnotifUserTalk = {$this->values['wgEnotifUserTalk']}; # UPO
378 \$wgEnotifWatchlist = {$this->values['wgEnotifWatchlist']}; # UPO
379 \$wgEmailAuthentication = {$this->values['wgEmailAuthentication']};
380 
381 ## Database settings
382 \$wgDBtype = \"{$this->values['wgDBtype']}\";
383 \$wgDBserver = \"{$this->values['wgDBserver']}\";
384 \$wgDBname = \"{$this->values['wgDBname']}\";
385 \$wgDBuser = \"{$this->values['wgDBuser']}\";
386 \$wgDBpassword = \"{$this->values['wgDBpassword']}\";
387 
388 {$this->dbSettings}
389 
390 # Shared database table
391 # This has no effect unless \$wgSharedDB is also set.
392 \$wgSharedTables[] = \"actor\";
393 
394 ## Shared memory settings
395 \$wgMainCacheType = $cacheType;
396 \$wgMemCachedServers = $mcservers;
397 
398 ## To enable image uploads, make sure the 'images' directory
399 ## is writable, then set this to true:
400 \$wgEnableUploads = {$this->values['wgEnableUploads']};
401 {$magic}\$wgUseImageMagick = true;
402 {$magic}\$wgImageMagickConvertCommand = \"{$this->values['wgImageMagickConvertCommand']}\";
403 
404 # InstantCommons allows wiki to use images from https://commons.wikimedia.org
405 \$wgUseInstantCommons = {$this->values['wgUseInstantCommons']};
406 
407 # Periodically send a pingback to https://www.mediawiki.org/ with basic data
408 # about this MediaWiki instance. The Wikimedia Foundation shares this data
409 # with MediaWiki developers to help guide future development efforts.
410 \$wgPingback = {$this->values['wgPingback']};
411 
412 # Site language code, should be one of the list in ./includes/languages/data/Names.php
413 \$wgLanguageCode = \"{$this->values['wgLanguageCode']}\";
414 
415 # Time zone
416 \$wgLocaltimezone = \"{$this->values['wgLocaltimezone']}\";
417 
418 ## Set \$wgCacheDirectory to a writable directory on the web server
419 ## to make your wiki go slightly faster. The directory should not
420 ## be publicly accessible from the web.
421 #\$wgCacheDirectory = \"\$IP/cache\";
422 
423 \$wgSecretKey = \"{$this->values['wgSecretKey']}\";
424 
425 # Changing this will log out all existing sessions.
426 \$wgAuthenticationTokenVersion = \"{$this->values['wgAuthenticationTokenVersion']}\";
427 
428 # Site upgrade key. Must be set to a string (default provided) to turn on the
429 # web installer while LocalSettings.php is in place
430 \$wgUpgradeKey = \"{$this->values['wgUpgradeKey']}\";
431 
432 ## For attaching licensing metadata to pages, and displaying an
433 ## appropriate copyright notice / icon. GNU Free Documentation
434 ## License and Creative Commons licenses are supported so far.
435 \$wgRightsPage = \"\"; # Set to the title of a wiki page that describes your license/copyright
436 \$wgRightsUrl = \"{$this->values['wgRightsUrl']}\";
437 \$wgRightsText = \"{$this->values['wgRightsText']}\";
438 \$wgRightsIcon = \"{$this->values['wgRightsIcon']}\";
439 
440 # Path to the GNU diff3 utility. Used for conflict resolution.
441 \$wgDiff3 = \"{$this->values['wgDiff3']}\";
442 
443 {$groupRights}{$noFollow}## Default skin: you can change the default skin. Use the internal symbolic
444 ## names, e.g. 'vector' or 'monobook':
445 \$wgDefaultSkin = \"{$this->values['wgDefaultSkin']}\";
446 ";
447  }
448 }
const MW_VERSION
The running version of MediaWiki.
Definition: Defines.php:36
wfBoolToStr( $value)
Convenience function converts boolean values into "true" or "false" (string) values.
Base installer class.
Definition: Installer.php:57
getDBInstaller( $type=false)
Get an instance of DatabaseInstaller for the specified DB type.
Definition: Installer.php:629
getVar( $name, $default=null)
Get an MW configuration variable, or internal installer configuration variable.
Definition: Installer.php:598
Class for generating LocalSettings.php file.
__construct(Installer $installer)
generateExtEnableLine( $dir, $name)
Generate the appropriate line to enable the given extension or skin.
setGroupRights( $group, $rightsArr)
For $wgGroupPermissions, set a given ['group']['permission'] value.
getText()
Return the full text of the generated LocalSettings.php file, including the extensions and skins.
writeFile( $fileName)
Write the generated LocalSettings to a file.
static escapePhpString( $string)
Returns the escaped version of a string of php code.