* Add Status::getWarningsArray() to complement Status::getErrorsArray()

* 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
This commit is contained in:
Mark A. Hershberger 2010-07-07 02:53:19 +00:00
parent 83ff1577b7
commit bec7a947e7
9 changed files with 126 additions and 125 deletions

View file

@ -179,19 +179,15 @@ class Status {
}
}
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 ) {
@ -201,6 +197,41 @@ class Status {
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
*
@ -223,17 +254,37 @@ class Status {
* @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
*

View file

@ -68,17 +68,24 @@ class CliInstaller extends Installer {
* 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");
}
}

View file

@ -1,79 +0,0 @@
<?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 = '';
}
}

View file

@ -233,21 +233,9 @@ abstract class Installer {
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();
@ -259,6 +247,10 @@ abstract class Installer {
}
}
}
$this->parserTitle = Title::newFromText( 'Installer' );
$this->parserOptions = new ParserOptions;
$this->parserOptions->setEditSection( false );
}
/**
@ -286,9 +278,15 @@ abstract class Installer {
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];
}
@ -410,7 +408,7 @@ abstract class Installer {
foreach ( $this->dbTypes as $name ) {
$db = $this->getDBInstaller( $name );
$readableName = wfMsg( 'config-type-' . $name );
if ( $db->isCompiled() ) {
if ( $db ) {
$compiledDBs[] = $name;
$goodNames[] = $readableName;
}
@ -901,8 +899,13 @@ abstract class Installer {
}
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;
}
@ -1046,4 +1049,18 @@ abstract class Installer {
$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 );
}
}

View file

@ -24,7 +24,7 @@ abstract class InstallerDBType {
/**
* @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.
@ -126,7 +126,7 @@ abstract class InstallerDBType {
* Convenience function
* Check if a named extension is present
*/
function checkExtension( $name ) {
static function checkExtension( $name ) {
wfSuppressWarnings();
$compiled = wfDl( $name );
wfRestoreWarnings();

View file

@ -39,19 +39,24 @@ class MysqlInstaller extends InstallerDBType {
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() {

View file

@ -19,8 +19,8 @@ class OracleInstaller extends InstallerDBType {
return 'oracle';
}
function isCompiled() {
return $this->checkExtension( 'oci8' );
static function isCompiled() {
return self::checkExtension( 'oci8' );
}
function getConnectForm() {

View file

@ -25,8 +25,8 @@ class PostgresInstaller extends InstallerDBType {
return 'postgres';
}
function isCompiled() {
return $this->checkExtension( 'pgsql' );
static function isCompiled() {
return self::checkExtension( 'pgsql' );
}
function getConnectForm() {

View file

@ -10,8 +10,8 @@ class SqliteInstaller extends InstallerDBType {
return 'sqlite';
}
function isCompiled() {
return $this->checkExtension( 'pdo_sqlite' );
static function isCompiled() {
return self::checkExtension( 'pdo_sqlite' );
}
function getGlobalDefaults() {