MediaWiki master
CliInstaller.php
Go to the documentation of this file.
1<?php
2
24
34
41class CliInstaller extends Installer {
43 private $specifiedScriptPath = false;
44
45 private const OPTION_MAP = [
46 'dbtype' => 'wgDBtype',
47 'dbserver' => 'wgDBserver',
48 'dbname' => 'wgDBname',
49 'dbuser' => 'wgDBuser',
50 'dbpass' => 'wgDBpassword',
51 'dbprefix' => 'wgDBprefix',
52 'dbtableoptions' => 'wgDBTableOptions',
53 'dbport' => 'wgDBport',
54 'dbssl' => 'wgDBssl',
55 'dbschema' => 'wgDBmwschema',
56 'dbpath' => 'wgSQLiteDataDir',
57 'server' => 'wgServer',
58 'scriptpath' => 'wgScriptPath',
59 ];
60
67 public function __construct( $siteName, $admin = null, array $options = [] ) {
68 global $wgPasswordPolicy;
69
70 parent::__construct();
71
72 if ( isset( $options['scriptpath'] ) ) {
73 $this->specifiedScriptPath = true;
74 }
75
76 foreach ( self::OPTION_MAP as $opt => $global ) {
77 if ( isset( $options[$opt] ) ) {
78 $GLOBALS[$global] = $options[$opt];
79 $this->setVar( $global, $options[$opt] );
80 }
81 }
82
83 if ( isset( $options['lang'] ) ) {
85 $this->setVar( '_UserLang', $options['lang'] );
86 $wgLanguageCode = $options['lang'];
87 $this->setVar( 'wgLanguageCode', $wgLanguageCode );
88 $wgLang = MediaWikiServices::getInstance()->getLanguageFactory()
89 ->getLanguage( $options['lang'] );
90 RequestContext::getMain()->setLanguage( $wgLang );
91 }
92
93 $this->setVar( 'wgSitename', $siteName );
94
95 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
96 $metaNS = $contLang->ucfirst( str_replace( ' ', '_', $siteName ) );
97 if ( $metaNS == 'MediaWiki' ) {
98 $metaNS = 'Project';
99 }
100 $this->setVar( 'wgMetaNamespace', $metaNS );
101
102 if ( !isset( $options['installdbuser'] ) ) {
103 $this->setVar( '_InstallUser',
104 $this->getVar( 'wgDBuser' ) );
105 $this->setVar( '_InstallPassword',
106 $this->getVar( 'wgDBpassword' ) );
107 } else {
108 $this->setVar( '_InstallUser',
109 $options['installdbuser'] );
110 $this->setVar( '_InstallPassword',
111 $options['installdbpass'] ?? "" );
112
113 // Assume that if we're given the installer user, we'll create the account.
114 $this->setVar( '_CreateDBAccount', true );
115 }
116
117 if ( $admin ) {
118 $this->setVar( '_AdminName', $admin );
119 if ( isset( $options['pass'] ) ) {
120 $adminUser = User::newFromName( $admin );
121 if ( !$adminUser ) {
122 throw new InstallException( Status::newFatal( 'config-admin-name-invalid' ) );
123 }
124 $upp = new UserPasswordPolicy(
125 $wgPasswordPolicy['policies'],
126 $wgPasswordPolicy['checks']
127 );
128 $status = $upp->checkUserPasswordForGroups( $adminUser, $options['pass'],
129 [ 'bureaucrat', 'sysop', 'interface-admin' ] ); // per Installer::createSysop()
130 if ( !$status->isGood() ) {
131 throw new InstallException( Status::newFatal(
132 $status->getMessage( 'config-admin-error-password-invalid' ) ) );
133 }
134 $this->setVar( '_AdminPassword', $options['pass'] );
135 }
136 }
137
138 // Detect and inject any extension found
139 if ( isset( $options['extensions'] ) ) {
140 $status = $this->validateExtensions(
141 'extension', 'extensions', $options['extensions'] );
142 if ( !$status->isOK() ) {
143 throw new InstallException( $status );
144 }
145 $this->setVar( '_Extensions', $status->value );
146 } elseif ( isset( $options['with-extensions'] ) ) {
147 $status = $this->findExtensions();
148 if ( !$status->isOK() ) {
149 throw new InstallException( $status );
150 }
151 $this->setVar( '_Extensions', array_keys( $status->value ) );
152 }
153
154 // Set up the default skins
155 if ( isset( $options['skins'] ) ) {
156 $status = $this->validateExtensions( 'skin', 'skins', $options['skins'] );
157 if ( !$status->isOK() ) {
158 throw new InstallException( $status );
159 }
160 $skins = $status->value;
161 } else {
162 $status = $this->findExtensions( 'skins' );
163 if ( !$status->isOK() ) {
164 throw new InstallException( $status );
165 }
166 $skins = array_keys( $status->value );
167 }
168 $this->setVar( '_Skins', $skins );
169
170 if ( $skins ) {
171 $skinNames = array_map( 'strtolower', $skins );
172 $this->setVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) );
173 }
174
175 $this->setVar( '_WithDevelopmentSettings', isset( $options['with-developmentsettings'] ) );
176 }
177
183 private function validateExtensions( string $type, string $directory, $nameLists ): Status {
184 $extensions = [];
185 $status = new Status;
186 foreach ( (array)$nameLists as $nameList ) {
187 foreach ( explode( ',', $nameList ) as $name ) {
188 $name = trim( $name );
189 if ( $name === '' ) {
190 continue;
191 }
192 $extStatus = $this->getExtensionInfo( $type, $directory, $name );
193 if ( $extStatus->isOK() ) {
194 $extensions[] = $name;
195 } else {
196 $status->merge( $extStatus );
197 }
198 }
199 }
200 $extensions = array_unique( $extensions );
201 $status->value = $extensions;
202 return $status;
203 }
204
209 public function execute() {
210 // If APC is available, use that as the MainCacheType, instead of nothing.
211 // This is hacky and should be consolidated with WebInstallerOptions.
212 // This is here instead of in __construct(), because it should run after
213 // doEnvironmentChecks(), which populates '_Caches'.
214 if ( count( $this->getVar( '_Caches' ) ) ) {
215 // We detected a CACHE_ACCEL implementation, use it.
216 $this->setVar( '_MainCacheType', 'accel' );
217 }
218
220 if ( $vars ) {
221 $status = Status::newFatal( "config-localsettings-cli-upgrade" );
222 $this->showStatusMessage( $status );
223 return $status;
224 }
225
226 $status = $this->performInstallation(
227 [ $this, 'startStage' ],
228 [ $this, 'endStage' ]
229 );
230 if ( $status->isOK() ) {
231 return Status::newGood();
232 } else {
233 return $status;
234 }
235 }
236
242 public function writeConfigurationFile( $path ) {
244 $ls->writeFile( "$path/LocalSettings.php" );
245 }
246
250 public function startStage( $task ) {
251 // @phan-suppress-next-line SecurityCheck-XSS -- it's CLI
252 echo $this->formatMessage( $task->getDescriptionMessage() ) . '... ';
253 }
254
259 public function endStage( $task, $status ) {
260 $this->showStatusMessage( $status );
261 if ( $status->isOK() ) {
262 $this->showMessage( 'config-install-step-done' );
263 } else {
264 $this->showError( 'config-install-step-failed' );
265 }
266 }
267
268 public function showMessage( $msg, ...$params ) {
269 // @phan-suppress-next-line SecurityCheck-XSS
270 echo $this->getMessageText( $msg, $params ) . "\n";
271 flush();
272 }
273
274 public function showSuccess( $msg, ...$params ) {
275 // @phan-suppress-next-line SecurityCheck-XSS
276 echo $this->getMessageText( $msg, $params ) . "\n";
277 flush();
278 }
279
280 public function showWarning( $msg, ...$params ) {
281 // @phan-suppress-next-line SecurityCheck-XSS
282 echo $this->getMessageText( $msg, $params ) . "\n";
283 flush();
284 }
285
286 public function showError( $msg, ...$params ) {
287 // @phan-suppress-next-line SecurityCheck-XSS
288 echo "***{$this->getMessageText( $msg, $params )}***\n";
289 flush();
290 }
291
297 protected function getMessageText( $msg, $params ) {
298 return $this->formatMessage( wfMessage( $msg, $params ) );
299 }
300
305 protected function formatMessage( $message ) {
306 $text = $message->parse();
307 $text = preg_replace( '/<a href="(.*?)".*?>(.*?)<\/a>/', '$2 &lt;$1&gt;', $text );
308 return Sanitizer::stripAllTags( $text );
309 }
310
311 public function showStatusMessage( Status $status ) {
312 // Show errors at the end in CLI installer to make them easier to notice
313 foreach ( $status->getMessages( 'warning' ) as $msg ) {
314 $this->showMessage( $msg );
315 }
316 foreach ( $status->getMessages( 'error' ) as $msg ) {
317 $this->showMessage( $msg );
318 }
319 }
320
321 public function envCheckPath() {
322 if ( !$this->specifiedScriptPath ) {
323 $this->showMessage( 'config-no-cli-uri', $this->getVar( "wgScriptPath" ) );
324 }
325
326 return parent::envCheckPath();
327 }
328
329 protected function envGetDefaultServer() {
330 // Use a basic value if the user didn't pass in --server
331 return 'http://localhost';
332 }
333
334 public function dirIsExecutable( $dir, $url ) {
335 $this->showMessage( 'config-no-cli-uploads-check', $dir );
336
337 return false;
338 }
339}
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(!defined( 'MW_NO_SESSION') &&MW_ENTRY_POINT !=='cli' $wgLang
Definition Setup.php:563
Group all the pieces relevant to the context of a request into one instance.
Class for the core installer command line interface.
showStatusMessage(Status $status)
Show a message to the installing user by using a Status object.
envCheckPath()
Environment check to inform user which paths we've assumed.
showSuccess( $msg,... $params)
Display a success message.
writeConfigurationFile( $path)
Write LocalSettings.php to a given path.
envGetDefaultServer()
Helper function to be called from getDefaultSettings()
dirIsExecutable( $dir, $url)
Checks if scripts located in the given directory can be executed via the given URL.
showWarning( $msg,... $params)
Display a warning message.
showMessage( $msg,... $params)
Display a short neutral message.
showError( $msg,... $params)
Display an error message.
__construct( $siteName, $admin=null, array $options=[])
Exception thrown if an error occurs during installation.
static getLocalSettingsGenerator(Installer $installer)
Instantiates and returns an instance of LocalSettingsGenerator or its descendant classes.
Base installer class.
Definition Installer.php:84
setVar( $name, $value)
Set a MW configuration variable, or internal installer configuration variable.
findExtensions( $directory='extensions')
Find extensions or skins in a subdirectory of $IP.
getExtensionInfo( $type, $parentRelPath, $name)
getDefaultSkin(array $skinNames)
Returns a default value to be used for $wgDefaultSkin: normally the DefaultSkin from config-schema....
static getExistingLocalSettings()
Determine if LocalSettings.php exists.
getVar( $name, $default=null)
Get an MW configuration variable, or internal installer configuration variable.
Base class for installer tasks.
Definition Task.php:24
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition Message.php:157
HTML sanitizer for MediaWiki.
Definition Sanitizer.php:46
Check if a user's password complies with any password policies that apply to that user,...
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:54
User class for the MediaWiki software.
Definition User.php:123
getMessages(?string $type=null)
Returns a list of error messages, optionally only those of the given type.
$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.