MediaWiki  master
CliInstaller.php
Go to the documentation of this file.
1 <?php
26 
33 class CliInstaller extends Installer {
34  private $specifiedScriptPath = false;
35 
36  private $optionMap = [
37  'dbtype' => 'wgDBtype',
38  'dbserver' => 'wgDBserver',
39  'dbname' => 'wgDBname',
40  'dbuser' => 'wgDBuser',
41  'dbpass' => 'wgDBpassword',
42  'dbprefix' => 'wgDBprefix',
43  'dbtableoptions' => 'wgDBTableOptions',
44  'dbport' => 'wgDBport',
45  'dbschema' => 'wgDBmwschema',
46  'dbpath' => 'wgSQLiteDataDir',
47  'server' => 'wgServer',
48  'scriptpath' => 'wgScriptPath',
49  ];
50 
57  public function __construct( $siteName, $admin = null, array $options = [] ) {
58  global $wgPasswordPolicy;
59 
60  parent::__construct();
61 
62  if ( isset( $options['scriptpath'] ) ) {
63  $this->specifiedScriptPath = true;
64  }
65 
66  foreach ( $this->optionMap as $opt => $global ) {
67  if ( isset( $options[$opt] ) ) {
68  $GLOBALS[$global] = $options[$opt];
69  $this->setVar( $global, $options[$opt] );
70  }
71  }
72 
73  if ( isset( $options['lang'] ) ) {
74  global $wgLang, $wgLanguageCode;
75  $this->setVar( '_UserLang', $options['lang'] );
76  $wgLanguageCode = $options['lang'];
77  $this->setVar( 'wgLanguageCode', $wgLanguageCode );
78  $wgLang = MediaWikiServices::getInstance()->getLanguageFactory()
79  ->getLanguage( $options['lang'] );
80  RequestContext::getMain()->setLanguage( $wgLang );
81  }
82 
83  $this->setVar( 'wgSitename', $siteName );
84 
85  $contLang = MediaWikiServices::getInstance()->getContentLanguage();
86  $metaNS = $contLang->ucfirst( str_replace( ' ', '_', $siteName ) );
87  if ( $metaNS == 'MediaWiki' ) {
88  $metaNS = 'Project';
89  }
90  $this->setVar( 'wgMetaNamespace', $metaNS );
91 
92  if ( !isset( $options['installdbuser'] ) ) {
93  $this->setVar( '_InstallUser',
94  $this->getVar( 'wgDBuser' ) );
95  $this->setVar( '_InstallPassword',
96  $this->getVar( 'wgDBpassword' ) );
97  } else {
98  $this->setVar( '_InstallUser',
99  $options['installdbuser'] );
100  $this->setVar( '_InstallPassword',
101  $options['installdbpass'] ?? "" );
102 
103  // Assume that if we're given the installer user, we'll create the account.
104  $this->setVar( '_CreateDBAccount', true );
105  }
106 
107  if ( $admin ) {
108  $this->setVar( '_AdminName', $admin );
109  if ( isset( $options['pass'] ) ) {
110  $adminUser = User::newFromName( $admin );
111  if ( !$adminUser ) {
112  throw new InstallException( Status::newFatal( 'config-admin-name-invalid' ) );
113  }
114  $upp = new UserPasswordPolicy(
115  $wgPasswordPolicy['policies'],
116  $wgPasswordPolicy['checks']
117  );
118  $status = $upp->checkUserPasswordForGroups( $adminUser, $options['pass'],
119  [ 'bureaucrat', 'sysop', 'interface-admin' ] ); // per Installer::createSysop()
120  if ( !$status->isGood() ) {
122  $status->getMessage( 'config-admin-error-password-invalid' ) ) );
123  }
124  $this->setVar( '_AdminPassword', $options['pass'] );
125  }
126  }
127 
128  // Detect and inject any extension found
129  if ( isset( $options['extensions'] ) ) {
130  $status = $this->validateExtensions(
131  'extension', 'extensions', $options['extensions'] );
132  if ( !$status->isOK() ) {
133  throw new InstallException( $status );
134  }
135  $this->setVar( '_Extensions', $status->value );
136  } elseif ( isset( $options['with-extensions'] ) ) {
137  $status = $this->findExtensions();
138  if ( !$status->isOK() ) {
139  throw new InstallException( $status );
140  }
141  $this->setVar( '_Extensions', array_keys( $status->value ) );
142  }
143 
144  // Set up the default skins
145  if ( isset( $options['skins'] ) ) {
146  $status = $this->validateExtensions( 'skin', 'skins', $options['skins'] );
147  if ( !$status->isOK() ) {
148  throw new InstallException( $status );
149  }
150  $skins = $status->value;
151  } else {
152  $status = $this->findExtensions( 'skins' );
153  if ( !$status->isOK() ) {
154  throw new InstallException( $status );
155  }
156  $skins = array_keys( $status->value );
157  }
158  $this->setVar( '_Skins', $skins );
159 
160  if ( $skins ) {
161  $skinNames = array_map( 'strtolower', $skins );
162  $this->setVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) );
163  }
164  }
165 
166  private function validateExtensions( $type, $directory, $nameLists ) {
167  $extensions = [];
168  $status = new Status;
169  foreach ( (array)$nameLists as $nameList ) {
170  foreach ( explode( ',', $nameList ) as $name ) {
171  $name = trim( $name );
172  if ( $name === '' ) {
173  continue;
174  }
175  $extStatus = $this->getExtensionInfo( $type, $directory, $name );
176  if ( $extStatus->isOK() ) {
177  $extensions[] = $name;
178  } else {
179  $status->merge( $extStatus );
180  }
181  }
182  }
183  $extensions = array_unique( $extensions );
184  $status->value = $extensions;
185  return $status;
186  }
187 
192  public function execute() {
193  // If APC is available, use that as the MainCacheType, instead of nothing.
194  // This is hacky and should be consolidated with WebInstallerOptions.
195  // This is here instead of in __construct(), because it should run after
196  // doEnvironmentChecks(), which populates '_Caches'.
197  if ( count( $this->getVar( '_Caches' ) ) ) {
198  // We detected a CACHE_ACCEL implementation, use it.
199  $this->setVar( '_MainCacheType', 'accel' );
200  }
201 
203  if ( $vars ) {
204  $status = Status::newFatal( "config-localsettings-cli-upgrade" );
205  $this->showStatusMessage( $status );
206  return $status;
207  }
208 
209  $result = $this->performInstallation(
210  [ $this, 'startStage' ],
211  [ $this, 'endStage' ]
212  );
213  // PerformInstallation bails on a fatal, so make sure the last item
214  // completed before giving 'next.' Likewise, only provide back on failure
215  $lastStepStatus = end( $result );
216  if ( $lastStepStatus->isOK() ) {
217  return Status::newGood();
218  } else {
219  return $lastStepStatus;
220  }
221  }
222 
228  public function writeConfigurationFile( $path ) {
230  $ls->writeFile( "$path/LocalSettings.php" );
231  }
232 
233  public function startStage( $step ) {
234  // Messages: config-install-database, config-install-tables, config-install-interwiki,
235  // config-install-stats, config-install-keys, config-install-sysop, config-install-mainpage,
236  // config-install-extensions
237  $this->showMessage( "config-install-$step" );
238  }
239 
240  public function endStage( $step, $status ) {
241  $this->showStatusMessage( $status );
242  $this->showMessage( 'config-install-step-done' );
243  }
244 
245  public function showMessage( $msg, ...$params ) {
246  // @phan-suppress-next-line SecurityCheck-XSS
247  echo $this->getMessageText( $msg, $params ) . "\n";
248  flush();
249  }
250 
251  public function showError( $msg, ...$params ) {
252  // @phan-suppress-next-line SecurityCheck-XSS
253  echo "***{$this->getMessageText( $msg, $params )}***\n";
254  flush();
255  }
256 
263  protected function getMessageText( $msg, $params ) {
264  $text = wfMessage( $msg, $params )->parse();
265 
266  $text = preg_replace( '/<a href="(.*?)".*?>(.*?)<\/a>/', '$2 &lt;$1&gt;', $text );
267 
268  return Sanitizer::stripAllTags( $text );
269  }
270 
276  public function showHelpBox( $msg, ...$params ) {
277  }
278 
279  public function showStatusMessage( Status $status ) {
280  $warnings = array_merge( $status->getWarningsArray(),
281  $status->getErrorsArray() );
282 
283  if ( count( $warnings ) !== 0 ) {
284  foreach ( $warnings as $w ) {
285  $this->showMessage( ...$w );
286  }
287  }
288  }
289 
290  public function envCheckPath() {
291  if ( !$this->specifiedScriptPath ) {
292  $this->showMessage( 'config-no-cli-uri', $this->getVar( "wgScriptPath" ) );
293  }
294 
295  return parent::envCheckPath();
296  }
297 
298  protected function envGetDefaultServer() {
299  // Use a basic value if the user didn't pass in --server
300  return 'http://localhost';
301  }
302 
303  public function dirIsExecutable( $dir, $url ) {
304  $this->showMessage( 'config-no-cli-uploads-check', $dir );
305 
306  return false;
307  }
308 }
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(!defined( 'MW_NO_SESSION') &&! $wgCommandLineMode) $wgLang
Definition: Setup.php:485
Class for the core installer command line interface.
showMessage( $msg,... $params)
UI interface for displaying a short message The parameters are like parameters to wfMessage().
showHelpBox( $msg,... $params)
Dummy.
execute()
Main entry point.
__construct( $siteName, $admin=null, array $options=[])
getMessageText( $msg, $params)
showStatusMessage(Status $status)
Show a message to the installing user by using a Status object.
writeConfigurationFile( $path)
Write LocalSettings.php to a given path.
validateExtensions( $type, $directory, $nameLists)
dirIsExecutable( $dir, $url)
Checks if scripts located in the given directory can be executed via the given URL.
showError( $msg,... $params)
Same as showMessage(), but for displaying errors.
envGetDefaultServer()
Helper function to be called from envPrepServer()
envCheckPath()
Environment check to inform user which paths we've assumed.
startStage( $step)
endStage( $step, $status)
static getLocalSettingsGenerator(Installer $installer)
Instantiates and returns an instance of LocalSettingsGenerator or its descendant classes.
Base installer class.
Definition: Installer.php:57
getExtensionInfo( $type, $parentRelPath, $name)
Definition: Installer.php:1328
getDefaultSkin(array $skinNames)
Returns a default value to be used for $wgDefaultSkin: normally the DefaultSkin from config-schema....
Definition: Installer.php:1466
setVar( $name, $value)
Set a MW configuration variable, or internal installer configuration variable.
Definition: Installer.php:584
static getExistingLocalSettings()
Determine if LocalSettings.php exists.
Definition: Installer.php:649
performInstallation( $startCB, $endCB)
Actually perform the installation.
Definition: Installer.php:1678
getVar( $name, $default=null)
Get an MW configuration variable, or internal installer configuration variable.
Definition: Installer.php:598
findExtensions( $directory='extensions')
Find extensions or skins in a subdirectory of $IP.
Definition: Installer.php:1265
Exception thrown if an error occur which installation.
MediaWikiServices is the service locator for the application scope of MediaWiki.
static getMain()
Get the RequestContext object associated with the main request.
static stripAllTags( $html)
Take a fragment of (potentially invalid) HTML and return a version with any tags removed,...
Definition: Sanitizer.php:1711
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: Status.php:44
getErrorsArray()
Get the list of errors (but not warnings)
Definition: Status.php:356
getWarningsArray()
Get the list of warnings (but not errors)
Definition: Status.php:367
Check if a user's password complies with any password policies that apply to that user,...
static newFromName( $name, $validate='valid')
Definition: User.php:599
$wgLanguageCode
Config variable stub for the LanguageCode setting, for use by phpdoc and IDEs.
$wgPasswordPolicy
Config variable stub for the PasswordPolicy setting, for use by phpdoc and IDEs.