123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- <?php
- /**
- * Core installer command line interface.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Deployment
- */
- use MediaWiki\Installer\InstallException;
- use MediaWiki\MediaWikiServices;
- /**
- * Class for the core installer command line interface.
- *
- * @ingroup Deployment
- * @since 1.17
- */
- class CliInstaller extends Installer {
- private $specifiedScriptPath = false;
- private $optionMap = [
- 'dbtype' => 'wgDBtype',
- 'dbserver' => 'wgDBserver',
- 'dbname' => 'wgDBname',
- 'dbuser' => 'wgDBuser',
- 'dbpass' => 'wgDBpassword',
- 'dbprefix' => 'wgDBprefix',
- 'dbtableoptions' => 'wgDBTableOptions',
- 'dbport' => 'wgDBport',
- 'dbschema' => 'wgDBmwschema',
- 'dbpath' => 'wgSQLiteDataDir',
- 'server' => 'wgServer',
- 'scriptpath' => 'wgScriptPath',
- ];
- /**
- * @param string $siteName
- * @param string|null $admin
- * @param array $options
- * @throws InstallException
- */
- function __construct( $siteName, $admin = null, array $options = [] ) {
- global $wgContLang;
- parent::__construct();
- if ( isset( $options['scriptpath'] ) ) {
- $this->specifiedScriptPath = true;
- }
- foreach ( $this->optionMap as $opt => $global ) {
- if ( isset( $options[$opt] ) ) {
- $GLOBALS[$global] = $options[$opt];
- $this->setVar( $global, $options[$opt] );
- }
- }
- if ( isset( $options['lang'] ) ) {
- global $wgLang, $wgLanguageCode;
- $this->setVar( '_UserLang', $options['lang'] );
- $wgLanguageCode = $options['lang'];
- $this->setVar( 'wgLanguageCode', $wgLanguageCode );
- $wgContLang = MediaWikiServices::getInstance()->getContentLanguage();
- $wgLang = Language::factory( $options['lang'] );
- RequestContext::getMain()->setLanguage( $wgLang );
- }
- $this->setVar( 'wgSitename', $siteName );
- $metaNS = $wgContLang->ucfirst( str_replace( ' ', '_', $siteName ) );
- if ( $metaNS == 'MediaWiki' ) {
- $metaNS = 'Project';
- }
- $this->setVar( 'wgMetaNamespace', $metaNS );
- if ( $admin ) {
- $this->setVar( '_AdminName', $admin );
- }
- if ( !isset( $options['installdbuser'] ) ) {
- $this->setVar( '_InstallUser',
- $this->getVar( 'wgDBuser' ) );
- $this->setVar( '_InstallPassword',
- $this->getVar( 'wgDBpassword' ) );
- } else {
- $this->setVar( '_InstallUser',
- $options['installdbuser'] );
- $this->setVar( '_InstallPassword',
- $options['installdbpass'] ?? "" );
- // Assume that if we're given the installer user, we'll create the account.
- $this->setVar( '_CreateDBAccount', true );
- }
- if ( isset( $options['pass'] ) ) {
- $this->setVar( '_AdminPassword', $options['pass'] );
- }
- // Detect and inject any extension found
- if ( isset( $options['extensions'] ) ) {
- $status = $this->validateExtensions(
- 'extension', 'extensions', $options['extensions'] );
- if ( !$status->isOK() ) {
- throw new InstallException( $status );
- }
- $this->setVar( '_Extensions', $status->value );
- } elseif ( isset( $options['with-extensions'] ) ) {
- $status = $this->findExtensions();
- if ( !$status->isOK() ) {
- throw new InstallException( $status );
- }
- $this->setVar( '_Extensions', array_keys( $status->value ) );
- }
- // Set up the default skins
- if ( isset( $options['skins'] ) ) {
- $status = $this->validateExtensions( 'skin', 'skins', $options['skins'] );
- if ( !$status->isOK() ) {
- throw new InstallException( $status );
- }
- $skins = $status->value;
- } else {
- $status = $this->findExtensions( 'skins' );
- if ( !$status->isOK() ) {
- throw new InstallException( $status );
- }
- $skins = array_keys( $status->value );
- }
- $this->setVar( '_Skins', $skins );
- if ( $skins ) {
- $skinNames = array_map( 'strtolower', $skins );
- $this->setVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) );
- }
- }
- private function validateExtensions( $type, $directory, $nameLists ) {
- $extensions = [];
- $status = new Status;
- foreach ( (array)$nameLists as $nameList ) {
- foreach ( explode( ',', $nameList ) as $name ) {
- $name = trim( $name );
- if ( $name === '' ) {
- continue;
- }
- $extStatus = $this->getExtensionInfo( $type, $directory, $name );
- if ( $extStatus->isOK() ) {
- $extensions[] = $name;
- } else {
- $status->merge( $extStatus );
- }
- }
- }
- $extensions = array_unique( $extensions );
- $status->value = $extensions;
- return $status;
- }
- /**
- * Main entry point.
- */
- public function execute() {
- // If APC is available, use that as the MainCacheType, instead of nothing.
- // This is hacky and should be consolidated with WebInstallerOptions.
- // This is here instead of in __construct(), because it should run run after
- // doEnvironmentChecks(), which populates '_Caches'.
- if ( count( $this->getVar( '_Caches' ) ) ) {
- // We detected a CACHE_ACCEL implementation, use it.
- $this->setVar( '_MainCacheType', 'accel' );
- }
- $vars = Installer::getExistingLocalSettings();
- if ( $vars ) {
- $status = Status::newFatal( "config-localsettings-cli-upgrade" );
- $this->showStatusMessage( $status );
- return $status;
- }
- $result = $this->performInstallation(
- [ $this, 'startStage' ],
- [ $this, 'endStage' ]
- );
- // PerformInstallation bails on a fatal, so make sure the last item
- // completed before giving 'next.' Likewise, only provide back on failure
- $lastStepStatus = end( $result );
- if ( $lastStepStatus->isOK() ) {
- return Status::newGood();
- } else {
- return $lastStepStatus;
- }
- }
- /**
- * Write LocalSettings.php to a given path
- *
- * @param string $path Full path to write LocalSettings.php to
- */
- public function writeConfigurationFile( $path ) {
- $ls = InstallerOverrides::getLocalSettingsGenerator( $this );
- $ls->writeFile( "$path/LocalSettings.php" );
- }
- public function startStage( $step ) {
- // Messages: config-install-database, config-install-tables, config-install-interwiki,
- // config-install-stats, config-install-keys, config-install-sysop, config-install-mainpage,
- // config-install-extensions
- $this->showMessage( "config-install-$step" );
- }
- public function endStage( $step, $status ) {
- $this->showStatusMessage( $status );
- $this->showMessage( 'config-install-step-done' );
- }
- public function showMessage( $msg, ...$params ) {
- echo $this->getMessageText( $msg, $params ) . "\n";
- flush();
- }
- public function showError( $msg, ...$params ) {
- echo "***{$this->getMessageText( $msg, $params )}***\n";
- flush();
- }
- /**
- * @param string $msg
- * @param array $params
- *
- * @return string
- */
- protected function getMessageText( $msg, $params ) {
- $text = wfMessage( $msg, $params )->parse();
- $text = preg_replace( '/<a href="(.*?)".*?>(.*?)<\/a>/', '$2 <$1>', $text );
- return Sanitizer::stripAllTags( $text );
- }
- /**
- * Dummy
- */
- public function showHelpBox( $msg /*, ... */ ) {
- }
- public function showStatusMessage( Status $status ) {
- $warnings = array_merge( $status->getWarningsArray(),
- $status->getErrorsArray() );
- if ( count( $warnings ) !== 0 ) {
- foreach ( $warnings as $w ) {
- $this->showMessage( ...$w );
- }
- }
- }
- public function envCheckPath() {
- if ( !$this->specifiedScriptPath ) {
- $this->showMessage( 'config-no-cli-uri', $this->getVar( "wgScriptPath" ) );
- }
- return parent::envCheckPath();
- }
- protected function envGetDefaultServer() {
- // Use a basic value if the user didn't pass in --server
- return 'http://localhost';
- }
- public function dirIsExecutable( $dir, $url ) {
- $this->showMessage( 'config-no-cli-uploads-check', $dir );
- return false;
- }
- }
|