* Add Status::getWikiTextArray() to allow different ways of formating a bunch of status messages (e.g. CLI output)
* Clean up messages in CliInstaller, use more i18n
* Use warning messages from Status return object in CLI installer
* Make Installer::isCompiled static so we don't have to create an object just to see that we can't use it.
* Add Installer::addInstallStepFollowing so we don't have MySQLInstaller mucking in its parent's data
}
}
if ( count( $this->errors ) == 1 ) {
- $params = array_map( 'wfEscapeWikiText', $this->cleanParams( $this->errors[0]['params'] ) );
- $s = wfMsgReal( $this->errors[0]['message'], $params, true, false, false );
+ $s = $this->getWikiTextForError( $this->errors[0], $this->errors[0] );
if ( $shortContext ) {
$s = wfMsgNoTrans( $shortContext, $s );
} elseif ( $longContext ) {
$s = wfMsgNoTrans( $longContext, "* $s\n" );
}
} else {
- $s = '';
- foreach ( $this->errors as $error ) {
- $params = array_map( 'wfEscapeWikiText', $this->cleanParams( $error['params'] ) );
- $s .= '* ' . wfMsgReal( $error['message'], $params, true, false, false ) . "\n";
- }
+ $s = '* '. implode("\n* ",
+ $this->getWikiTextArray( $this->errors ) ) . "\n";
if ( $longContext ) {
$s = wfMsgNoTrans( $longContext, $s );
} elseif ( $shortContext ) {
return $s;
}
+ /**
+ * Return the wiki text for a single error.
+ * @param $error Mixed With an array & two values keyed by
+ * 'message' and 'params', use those keys-value pairs.
+ * Otherwise, if its an array, just use the first value as the
+ * message and the remaining items as the params.
+ *
+ * @return String
+ */
+ protected function getWikiTextForError( $error ) {
+ if ( is_array( $error ) ) {
+ if ( isset( $error['message'] ) && isset( $error['params'] ) ) {
+ return wfMsgReal( $error['message'],
+ array_map( 'wfEscapeWikiText', $this->cleanParams( $error['params'] ) ),
+ true, false, false );
+ } else {
+ $message = array_shift($error);
+ return wfMsgReal( $message,
+ array_map( 'wfEscapeWikiText', $this->cleanParams( $error ) ),
+ true, false, false );
+ }
+ } else {
+ return wfMsgReal( $error, array(), true, false, false);
+ }
+ }
+
+ /**
+ * Return an array with the wikitext for each item in the array.
+ * @param $errors Array
+ * @return Array
+ */
+ function getWikiTextArray( $errors ) {
+ return array_map( array( $this, 'getWikiTextForError' ), $errors );
+ }
+
/**
* Merge another status object into this one
*
* @return Array
*/
function getErrorsArray() {
+ return $this->getStatArray( "error" );
+ }
+
+ /**
+ * Get the list of warnings (but not errors)
+ *
+ * @return Array
+ */
+ function getWarningsArray() {
+ return $this->getStatArray( "warning" );
+ }
+
+ /**
+ * Returns a list of status messages of the given type
+ * @param $type String
+ *
+ * @return Array
+ */
+ protected function getStatArray( $type ) {
$result = array();
foreach ( $this->errors as $error ) {
- if ( $error['type'] == 'error' )
- if( $error['params'] )
+ if ( $error['type'] === $type ) {
+ if( $error['params'] ) {
$result[] = array_merge( array( $error['message'] ), $error['params'] );
- else
+ } else {
$result[] = $error['message'];
+ }
+ }
}
return $result;
}
-
/**
* Returns true if the specified message is present as a warning or error
*
* Main entry point.
*/
function execute( ) {
- foreach( $this->getInstallSteps() as $step ) {
- $this->showMessage("Installing $step... ");
+ foreach( $this->getInstallSteps() as $stepObj ) {
+ $step = is_array( $stepObj ) ? $stepObj['name'] : $stepObj;
+ $this->showMessage( wfMsg( "config-install-$step") .
+ wfMsg( 'ellipsis' ) . wfMsg( 'word-separator' ) );
$func = 'install' . ucfirst( $step );
$status = $this->{$func}();
+ $warnings = $status->getWarningsArray();
if ( !$status->isOk() ) {
$this->showStatusMessage( $status );
+ echo "\n";
exit;
- } elseif ( !$status->isGood() ) {
- $this->showStatusMessage( $status );
+ } elseif ( count($warnings) !== 0 ) {
+ foreach ( $status->getWikiTextArray( $warnings ) as $w ) {
+ $this->showMessage( $w . wfMsg( 'ellipsis') .
+ wfMsg( 'word-separator' ) );
+ }
}
- $this->showMessage("done\n");
+ $this->showMessage( wfMsg( 'config-install-step-done' ) ."\n");
}
}
+++ /dev/null
-<?php
-
-/**
- * Output class modelled on OutputPage.
- *
- * I've opted to use a distinct class rather than derive from OutputPage here in
- * the interests of separation of concerns: if we used a subclass, there would be
- * quite a lot of things you could do in OutputPage that would break the installer,
- * that wouldn't be immediately obvious.
- */
-class CliInstallerOutput {
-
- function __construct( $parent ) {
- $this->parent = $parent;
- }
-
- function addHTML( $html ) {
- $this->contents .= $html;
- }
-
- function addWikiText( $text ) {
- $this->addHTML( $this->parent->parse( $text ) );
- }
-
- function addHTMLNoFlush( $html ) {
- $this->contents .= $html;
- }
-
- function addWarning( $msg ) {
- $this->warnings .= "<p>$msg</p>\n";
- }
-
- function addWarningMsg( $msg /*, ... */ ) {
- $params = func_get_args();
- array_shift( $params );
- $this->addWarning( wfMsg( $msg, $params ) );
- }
-
- function redirect( $url ) {
- if ( $this->headerDone ) {
- throw new MWException( __METHOD__ . ' called after sending headers' );
- }
- $this->redirectTarget = $url;
- }
-
- function output() {
- $this->flush();
- }
-
- function useShortHeader( $use = true ) {
- }
-
- function flush() {
- echo html_entity_decode( strip_tags( $this->contents ), ENT_QUOTES );
- flush();
- $this->contents = '';
- }
-
- function getDir() {
- global $wgLang;
- if( !is_object( $wgLang ) || !$wgLang->isRtl() )
- return 'ltr';
- else
- return 'rtl';
- }
-
- function getLanguageCode() {
- global $wgLang;
- if( !is_object( $wgLang ) )
- return 'en';
- else
- return $wgLang->getCode();
- }
-
- function outputWarnings() {
- $this->addHTML( $this->warnings );
- $this->warnings = '';
- }
-}
foreach ( $this->defaultVarNames as $var ) {
$this->settings[$var] = $GLOBALS[$var];
}
-
- $this->parserTitle = Title::newFromText( 'Installer' );
- $this->parserOptions = new ParserOptions;
- $this->parserOptions->setEditSection( false );
- }
-
- /*
- * Set up our database objects. They need to inject some of their
- * own configuration into our global context. Usually this'll just be
- * things like the default $wgDBname.
- */
- function setupDatabaseObjects() {
foreach ( $this->dbTypes as $type ) {
$installer = $this->getDBInstaller( $type );
- if ( !$installer->isCompiled() ) {
+ if ( !$installer ) {
continue;
}
$defaults = $installer->getGlobalDefaults();
}
}
}
+
+ $this->parserTitle = Title::newFromText( 'Installer' );
+ $this->parserOptions = new ParserOptions;
+ $this->parserOptions->setEditSection( false );
}
/**
if ( !$type ) {
$type = $this->getVar( 'wgDBtype' );
}
+ $type = strtolower($type);
+
if ( !isset( $this->dbInstallers[$type] ) ) {
$class = ucfirst( $type ). 'Installer';
- $this->dbInstallers[$type] = new $class( $this );
+ if ($class::isCompiled()) {
+ $this->dbInstallers[$type] = new $class( $this );
+ } else {
+ $this->dbInstallers[$type] = false;
+ }
}
return $this->dbInstallers[$type];
}
foreach ( $this->dbTypes as $name ) {
$db = $this->getDBInstaller( $name );
$readableName = wfMsg( 'config-type-' . $name );
- if ( $db->isCompiled() ) {
+ if ( $db ) {
$compiledDBs[] = $name;
$goodNames[] = $readableName;
}
}
public function installDatabase() {
- $installer = $this->getDBInstaller( $this->getVar( 'wgDBtype' ) );
- $status = $installer->setupDatabase();
+ $type = $this->getVar( 'wgDBtype' );
+ $installer = $this->getDBInstaller( $type );
+ if(!$installer) {
+ $status = Status::newFatal( "config-no-db", $type );
+ } else {
+ $status = $installer->setupDatabase();
+ }
return $status;
}
$GLOBALS['wgShowSQLErrors'] = true;
$GLOBALS['wgShowDBErrorBacktrace'] = true;
}
+
+ /**
+ * Add an installation step following the given step.
+ * @param $findStep String the step to find. Use NULL to put the step at the beginning.
+ * @param $callback array
+ */
+ function addInstallStepFollowing( $findStep, $callback ) {
+ $where = 0;
+ if( $findStep !== null ) $where = array_search( $findStep, $this->installSteps );
+
+ array_splice( $this->installSteps, $where, 0, $callback );
+ }
+
+
}
/**
* @return true if the client library is compiled in
*/
- abstract function isCompiled();
+ abstract static function isCompiled();
/**
* Get an array of MW configuration globals that will be configured by this class.
* Convenience function
* Check if a named extension is present
*/
- function checkExtension( $name ) {
+ static function checkExtension( $name ) {
wfSuppressWarnings();
$compiled = wfDl( $name );
wfRestoreWarnings();
return;
}
+ if ( $this->parent->getVar( 'wgDBtype' ) !== $this->getName() ) {
+ return;
+ }
+
# Add our user callback to installSteps, right before the tables are created.
- $where_tables = array_search( "tables", $this->parent->installSteps );
+
+ debug_print_backtrace();
$callback = array(
array(
'name' => 'user',
'callback' => array( &$this, 'setupUser' ),
)
);
- array_splice( $this->parent->installSteps, $where_tables, 0, $callback );
+ $this->parent->addInstallStepFollowing( "tables", $callback );
}
-
- function isCompiled() {
- return $this->checkExtension( 'mysql' );
+
+ static function isCompiled() {
+ return self::checkExtension( 'mysql' );
}
function getGlobalDefaults() {
return 'oracle';
}
- function isCompiled() {
- return $this->checkExtension( 'oci8' );
+ static function isCompiled() {
+ return self::checkExtension( 'oci8' );
}
function getConnectForm() {
return 'postgres';
}
- function isCompiled() {
- return $this->checkExtension( 'pgsql' );
+ static function isCompiled() {
+ return self::checkExtension( 'pgsql' );
}
function getConnectForm() {
return 'sqlite';
}
- function isCompiled() {
- return $this->checkExtension( 'pdo_sqlite' );
+ static function isCompiled() {
+ return self::checkExtension( 'pdo_sqlite' );
}
function getGlobalDefaults() {