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