MediaWiki master
CliInstaller.php
Go to the documentation of this file.
1<?php
2
10
20
27class CliInstaller extends Installer {
29 private $specifiedScriptPath = false;
30
31 private const OPTION_MAP = [
32 'dbtype' => 'wgDBtype',
33 'dbserver' => 'wgDBserver',
34 'dbname' => 'wgDBname',
35 'dbuser' => 'wgDBuser',
36 'dbpass' => 'wgDBpassword',
37 'dbprefix' => 'wgDBprefix',
38 'dbtableoptions' => 'wgDBTableOptions',
39 'dbport' => 'wgDBport',
40 'dbssl' => 'wgDBssl',
41 'dbschema' => 'wgDBmwschema',
42 'dbpath' => 'wgSQLiteDataDir',
43 'server' => 'wgServer',
44 'scriptpath' => 'wgScriptPath',
45 ];
46
53 public function __construct( $siteName, $admin = null, array $options = [] ) {
54 global $wgPasswordPolicy;
55
56 parent::__construct();
57
58 if ( isset( $options['scriptpath'] ) ) {
59 $this->specifiedScriptPath = true;
60 }
61
62 foreach ( self::OPTION_MAP as $opt => $global ) {
63 if ( isset( $options[$opt] ) ) {
64 $GLOBALS[$global] = $options[$opt];
65 $this->setVar( $global, $options[$opt] );
66 }
67 }
68
69 if ( isset( $options['lang'] ) ) {
71 $this->setVar( '_UserLang', $options['lang'] );
72 $wgLanguageCode = $options['lang'];
73 $this->setVar( 'wgLanguageCode', $wgLanguageCode );
74 $wgLang = MediaWikiServices::getInstance()->getLanguageFactory()
75 ->getLanguage( $options['lang'] );
76 RequestContext::getMain()->setLanguage( $wgLang );
77 }
78
79 $this->setVar( 'wgSitename', $siteName );
80
81 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
82 $metaNS = $contLang->ucfirst( str_replace( ' ', '_', $siteName ) );
83 if ( $metaNS == 'MediaWiki' ) {
84 $metaNS = 'Project';
85 }
86 $this->setVar( 'wgMetaNamespace', $metaNS );
87
88 if ( !isset( $options['installdbuser'] ) ) {
89 $this->setVar( '_InstallUser',
90 $this->getVar( 'wgDBuser' ) );
91 $this->setVar( '_InstallPassword',
92 $this->getVar( 'wgDBpassword' ) );
93 } else {
94 $this->setVar( '_InstallUser',
95 $options['installdbuser'] );
96 $this->setVar( '_InstallPassword',
97 $options['installdbpass'] ?? "" );
98
99 // Assume that if we're given the installer user, we'll create the account.
100 $this->setVar( '_CreateDBAccount', true );
101 }
102
103 if ( $admin ) {
104 $this->setVar( '_AdminName', $admin );
105 if ( isset( $options['pass'] ) ) {
106 $adminUser = User::newFromName( $admin );
107 if ( !$adminUser ) {
108 throw new InstallException( Status::newFatal( 'config-admin-name-invalid' ) );
109 }
110 $upp = new UserPasswordPolicy(
111 $wgPasswordPolicy['policies'],
112 $wgPasswordPolicy['checks']
113 );
114 $status = $upp->checkUserPasswordForGroups( $adminUser, $options['pass'],
115 [ 'bureaucrat', 'sysop', 'interface-admin' ] ); // per Installer::createSysop()
116 if ( !$status->isGood() ) {
117 throw new InstallException( Status::newFatal(
118 $status->getMessage( 'config-admin-error-password-invalid' ) ) );
119 }
120 $this->setVar( '_AdminPassword', $options['pass'] );
121 }
122 }
123
124 // Detect and inject any extension found
125 if ( isset( $options['extensions'] ) ) {
126 $status = $this->validateExtensions(
127 'extension', 'extensions', $options['extensions'] );
128 if ( !$status->isOK() ) {
129 throw new InstallException( $status );
130 }
131 $this->setVar( '_Extensions', $status->value );
132 } elseif ( isset( $options['with-extensions'] ) ) {
133 $status = $this->findExtensions();
134 if ( !$status->isOK() ) {
135 throw new InstallException( $status );
136 }
137 $this->setVar( '_Extensions', array_keys( $status->value ) );
138 }
139
140 // Set up the default skins
141 if ( isset( $options['skins'] ) ) {
142 $status = $this->validateExtensions( 'skin', 'skins', $options['skins'] );
143 if ( !$status->isOK() ) {
144 throw new InstallException( $status );
145 }
146 $skins = $status->value;
147 } else {
148 $status = $this->findExtensions( 'skins' );
149 if ( !$status->isOK() ) {
150 throw new InstallException( $status );
151 }
152 $skins = array_keys( $status->value );
153 }
154 $this->setVar( '_Skins', $skins );
155
156 if ( $skins ) {
157 $skinNames = array_map( 'strtolower', $skins );
158 $this->setVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) );
159 }
160
161 $this->setVar( '_WithDevelopmentSettings', isset( $options['with-developmentsettings'] ) );
162 }
163
169 private function validateExtensions( string $type, string $directory, $nameLists ): Status {
170 $extensions = [];
171 $status = new Status;
172 foreach ( (array)$nameLists as $nameList ) {
173 foreach ( explode( ',', $nameList ) as $name ) {
174 $name = trim( $name );
175 if ( $name === '' ) {
176 continue;
177 }
178 $extStatus = $this->getExtensionInfo( $type, $directory, $name );
179 if ( $extStatus->isOK() ) {
180 $extensions[] = $name;
181 } else {
182 $status->merge( $extStatus );
183 }
184 }
185 }
186 $extensions = array_unique( $extensions );
187 $status->value = $extensions;
188 return $status;
189 }
190
195 public function execute() {
196 // If APC is available, use that as the MainCacheType, instead of nothing.
197 // This is hacky and should be consolidated with WebInstallerOptions.
198 // This is here instead of in __construct(), because it should run after
199 // doEnvironmentChecks(), which populates '_Caches'.
200 if ( count( $this->getVar( '_Caches' ) ) ) {
201 // We detected a CACHE_ACCEL implementation, use it.
202 $this->setVar( '_MainCacheType', 'accel' );
203 }
204
206 if ( $vars ) {
207 $status = Status::newFatal( "config-localsettings-cli-upgrade" );
208 $this->showStatusMessage( $status );
209 return $status;
210 }
211
212 $status = $this->performInstallation(
213 $this->startStage( ... ),
214 $this->endStage( ... )
215 );
216 if ( $status->isOK() ) {
217 return Status::newGood();
218 } else {
219 return $status;
220 }
221 }
222
228 public function writeConfigurationFile( $path ) {
230 $ls->writeFile( "$path/LocalSettings.php" );
231 }
232
236 public function startStage( $task ) {
237 // @phan-suppress-next-line SecurityCheck-XSS -- it's CLI
238 echo $this->formatMessage( $task->getDescriptionMessage() ) . '... ';
239 }
240
245 public function endStage( $task, $status ) {
246 $this->showStatusMessage( $status );
247 if ( $status->isOK() ) {
248 $this->showMessage( 'config-install-step-done' );
249 } else {
250 $this->showError( 'config-install-step-failed' );
251 }
252 }
253
255 public function showMessage( $msg, ...$params ) {
256 // @phan-suppress-next-line SecurityCheck-XSS
257 echo $this->getMessageText( $msg, $params ) . "\n";
258 flush();
259 }
260
262 public function showSuccess( $msg, ...$params ) {
263 // @phan-suppress-next-line SecurityCheck-XSS
264 echo $this->getMessageText( $msg, $params ) . "\n";
265 flush();
266 }
267
269 public function showWarning( $msg, ...$params ) {
270 // @phan-suppress-next-line SecurityCheck-XSS
271 echo $this->getMessageText( $msg, $params ) . "\n";
272 flush();
273 }
274
276 public function showError( $msg, ...$params ) {
277 // @phan-suppress-next-line SecurityCheck-XSS
278 echo "***{$this->getMessageText( $msg, $params )}***\n";
279 flush();
280 }
281
287 protected function getMessageText( $msg, $params ) {
288 return $this->formatMessage( wfMessage( $msg, $params ) );
289 }
290
295 protected function formatMessage( $message ) {
296 $text = $message->parse();
297 $text = preg_replace( '/<a href="(.*?)".*?>(.*?)<\/a>/', '$2 &lt;$1&gt;', $text );
298 return Sanitizer::stripAllTags( $text );
299 }
300
301 public function showStatusMessage( Status $status ) {
302 // Show errors at the end in CLI installer to make them easier to notice
303 foreach ( $status->getMessages( 'warning' ) as $msg ) {
304 $this->showMessage( $msg );
305 }
306 foreach ( $status->getMessages( 'error' ) as $msg ) {
307 $this->showMessage( $msg );
308 }
309 }
310
312 public function envCheckPath() {
313 if ( !$this->specifiedScriptPath ) {
314 $this->showMessage( 'config-no-cli-uri', $this->getVar( "wgScriptPath" ) );
315 }
316
317 return parent::envCheckPath();
318 }
319
321 protected function envGetDefaultServer() {
322 // Use a basic value if the user didn't pass in --server
323 return 'http://localhost';
324 }
325
327 public function dirIsExecutable( $dir, $url ) {
328 $this->showMessage( 'config-no-cli-uploads-check', $dir );
329
330 return false;
331 }
332}
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(MW_ENTRY_POINT==='index') if(!defined( 'MW_NO_SESSION') &&MW_ENTRY_POINT !=='cli' $wgLang
Definition Setup.php:551
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.bool
showSuccess( $msg,... $params)
Display a success message.
writeConfigurationFile( $path)
Write LocalSettings.php to a given path.
envGetDefaultServer()
Helper function to be called from getDefaultSettings()string
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.Avoid error fatigue in the installer. Use this only if something the user ex...
__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:70
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:144
HTML sanitizer for MediaWiki.
Definition Sanitizer.php:32
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:44
User class for the MediaWiki software.
Definition User.php:110
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.