MediaWiki  REL1_20
DatabaseInstaller.php
Go to the documentation of this file.
00001 <?php
00030 abstract class DatabaseInstaller {
00031 
00039         public $parent;
00040 
00046         public $db = null;
00047 
00053         protected $internalDefaults = array();
00054 
00060         protected $globalNames = array();
00061 
00065         public abstract function getName();
00066 
00070         public abstract function isCompiled();
00071 
00077         public function checkPrerequisites() {
00078                 return Status::newGood();
00079         }
00080 
00088         public abstract function getConnectForm();
00089 
00099         public abstract function submitConnectForm();
00100 
00108         public function getSettingsForm() {
00109                 return false;
00110         }
00111 
00118         public function submitSettingsForm() {
00119                 return Status::newGood();
00120         }
00121 
00130         public abstract function openConnection();
00131 
00138         public abstract function setupDatabase();
00139 
00149         public function getConnection() {
00150                 if ( $this->db ) {
00151                         return Status::newGood( $this->db );
00152                 }
00153 
00154                 $status = $this->openConnection();
00155                 if ( $status->isOK() ) {
00156                         $this->db = $status->value;
00157                         // Enable autocommit
00158                         $this->db->clearFlag( DBO_TRX );
00159                         $this->db->commit( __METHOD__ );
00160                 }
00161                 return $status;
00162         }
00163 
00169         public function createTables() {
00170                 $status = $this->getConnection();
00171                 if ( !$status->isOK() ) {
00172                         return $status;
00173                 }
00174                 $this->db->selectDB( $this->getVar( 'wgDBname' ) );
00175 
00176                 if( $this->db->tableExists( 'archive', __METHOD__ ) ) {
00177                         $status->warning( 'config-install-tables-exist' );
00178                         $this->enableLB();
00179                         return $status;
00180                 }
00181 
00182                 $this->db->setFlag( DBO_DDLMODE ); // For Oracle's handling of schema files
00183                 $this->db->begin( __METHOD__ );
00184 
00185                 $error = $this->db->sourceFile( $this->db->getSchemaPath() );
00186                 if( $error !== true ) {
00187                         $this->db->reportQueryError( $error, 0, '', __METHOD__ );
00188                         $this->db->rollback( __METHOD__ );
00189                         $status->fatal( 'config-install-tables-failed', $error );
00190                 } else {
00191                         $this->db->commit( __METHOD__ );
00192                 }
00193                 // Resume normal operations
00194                 if( $status->isOk() ) {
00195                         $this->enableLB();
00196                 }
00197                 return $status;
00198         }
00199 
00204         public function createExtensionTables() {
00205                 $status = $this->getConnection();
00206                 if ( !$status->isOK() ) {
00207                         return $status;
00208                 }
00209 
00210                 // Now run updates to create tables for old extensions
00211                 DatabaseUpdater::newForDB( $this->db )->doUpdates( array( 'extensions' ) );
00212 
00213                 return $status;
00214         }
00215 
00221         public abstract function getLocalSettings();
00222 
00228         public function getSchemaVars() {
00229                 return array();
00230         }
00231 
00238         public function setupSchemaVars() {
00239                 $status = $this->getConnection();
00240                 if ( $status->isOK() ) {
00241                         $status->value->setSchemaVars( $this->getSchemaVars() );
00242                 } else {
00243                         throw new MWException( __METHOD__.': unexpected DB connection error' );
00244                 }
00245         }
00246 
00252         public function enableLB() {
00253                 $status = $this->getConnection();
00254                 if ( !$status->isOK() ) {
00255                         throw new MWException( __METHOD__.': unexpected DB connection error' );
00256                 }
00257                 LBFactory::setInstance( new LBFactory_Single( array(
00258                         'connection' => $status->value ) ) );
00259         }
00260 
00266         public function doUpgrade() {
00267                 $this->setupSchemaVars();
00268                 $this->enableLB();
00269 
00270                 $ret = true;
00271                 ob_start( array( $this, 'outputHandler' ) );
00272                 try {
00273                         $up = DatabaseUpdater::newForDB( $this->db );
00274                         $up->doUpdates();
00275                 } catch ( MWException $e ) {
00276                         echo "\nAn error occurred:\n";
00277                         echo $e->getText();
00278                         $ret = false;
00279                 }
00280                 ob_end_flush();
00281                 return $ret;
00282         }
00283 
00289         public function preInstall() {
00290 
00291         }
00292 
00296         public function preUpgrade() {
00297 
00298         }
00299 
00304         public function getGlobalNames() {
00305                 return $this->globalNames;
00306         }
00307 
00313         public function __construct( $parent ) {
00314                 $this->parent = $parent;
00315         }
00316 
00325         protected static function checkExtension( $name ) {
00326                 wfSuppressWarnings();
00327                 $compiled = wfDl( $name );
00328                 wfRestoreWarnings();
00329                 return $compiled;
00330         }
00331 
00336         public function getReadableName() {
00337                 return wfMessage( 'config-type-' . $this->getName() )->text();
00338         }
00339 
00345         public function getGlobalDefaults() {
00346                 return array();
00347         }
00348 
00353         public function getInternalDefaults() {
00354                 return $this->internalDefaults;
00355         }
00356 
00363         public function getVar( $var, $default = null ) {
00364                 $defaults = $this->getGlobalDefaults();
00365                 $internal = $this->getInternalDefaults();
00366                 if ( isset( $defaults[$var] ) ) {
00367                         $default = $defaults[$var];
00368                 } elseif ( isset( $internal[$var] ) ) {
00369                         $default = $internal[$var];
00370                 }
00371                 return $this->parent->getVar( $var, $default );
00372         }
00373 
00379         public function setVar( $name, $value ) {
00380                 $this->parent->setVar( $name, $value );
00381         }
00382 
00392         public function getTextBox( $var, $label, $attribs = array(), $helpData = "" ) {
00393                 $name = $this->getName() . '_' . $var;
00394                 $value = $this->getVar( $var );
00395                 if ( !isset( $attribs ) ) {
00396                         $attribs = array();
00397                 }
00398                 return $this->parent->getTextBox( array(
00399                         'var' => $var,
00400                         'label' => $label,
00401                         'attribs' => $attribs,
00402                         'controlName' => $name,
00403                         'value' => $value,
00404                         'help' => $helpData
00405                 ) );
00406         }
00407 
00418         public function getPasswordBox( $var, $label, $attribs = array(), $helpData = "" ) {
00419                 $name = $this->getName() . '_' . $var;
00420                 $value = $this->getVar( $var );
00421                 if ( !isset( $attribs ) ) {
00422                         $attribs = array();
00423                 }
00424                 return $this->parent->getPasswordBox( array(
00425                         'var' => $var,
00426                         'label' => $label,
00427                         'attribs' => $attribs,
00428                         'controlName' => $name,
00429                         'value' => $value,
00430                         'help' => $helpData
00431                 ) );
00432         }
00433 
00439         public function getCheckBox( $var, $label, $attribs = array(), $helpData = "" ) {
00440                 $name = $this->getName() . '_' . $var;
00441                 $value = $this->getVar( $var );
00442                 return $this->parent->getCheckBox( array(
00443                         'var' => $var,
00444                         'label' => $label,
00445                         'attribs' => $attribs,
00446                         'controlName' => $name,
00447                         'value' => $value,
00448                         'help' => $helpData
00449                 ));
00450         }
00451 
00465         public function getRadioSet( $params ) {
00466                 $params['controlName'] = $this->getName() . '_' . $params['var'];
00467                 $params['value'] = $this->getVar( $params['var'] );
00468                 return $this->parent->getRadioSet( $params );
00469         }
00470 
00478         public function setVarsFromRequest( $varNames ) {
00479                 return $this->parent->setVarsFromRequest( $varNames, $this->getName() . '_' );
00480         }
00481 
00492         public function needsUpgrade() {
00493                 $status = $this->getConnection();
00494                 if ( !$status->isOK() ) {
00495                         return false;
00496                 }
00497 
00498                 if ( !$this->db->selectDB( $this->getVar( 'wgDBname' ) ) ) {
00499                         return false;
00500                 }
00501                 return $this->db->tableExists( 'cur', __METHOD__ ) || $this->db->tableExists( 'revision', __METHOD__ );
00502         }
00503 
00509         public function getInstallUserBox() {
00510                 return
00511                         Html::openElement( 'fieldset' ) .
00512                         Html::element( 'legend', array(), wfMessage( 'config-db-install-account' )->text() ) .
00513                         $this->getTextBox( '_InstallUser', 'config-db-username', array( 'dir' => 'ltr' ), $this->parent->getHelpBox( 'config-db-install-username' ) ) .
00514                         $this->getPasswordBox( '_InstallPassword', 'config-db-password', array( 'dir' => 'ltr' ), $this->parent->getHelpBox( 'config-db-install-password' ) ) .
00515                         Html::closeElement( 'fieldset' );
00516         }
00517 
00522         public function submitInstallUserBox() {
00523                 $this->setVarsFromRequest( array( '_InstallUser', '_InstallPassword' ) );
00524                 return Status::newGood();
00525         }
00526 
00534         public function getWebUserBox( $noCreateMsg = false ) {
00535                 $wrapperStyle = $this->getVar( '_SameAccount' ) ? 'display: none' : '';
00536                 $s = Html::openElement( 'fieldset' ) .
00537                         Html::element( 'legend', array(), wfMessage( 'config-db-web-account' )->text() ) .
00538                         $this->getCheckBox(
00539                                 '_SameAccount', 'config-db-web-account-same',
00540                                 array( 'class' => 'hideShowRadio', 'rel' => 'dbOtherAccount' )
00541                         ) .
00542                         Html::openElement( 'div', array( 'id' => 'dbOtherAccount', 'style' => $wrapperStyle ) ) .
00543                         $this->getTextBox( 'wgDBuser', 'config-db-username' ) .
00544                         $this->getPasswordBox( 'wgDBpassword', 'config-db-password' ) .
00545                         $this->parent->getHelpBox( 'config-db-web-help' );
00546                 if ( $noCreateMsg ) {
00547                         $s .= $this->parent->getWarningBox( wfMessage( $noCreateMsg )->plain() );
00548                 } else {
00549                         $s .= $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create' );
00550                 }
00551                 $s .= Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' );
00552                 return $s;
00553         }
00554 
00560         public function submitWebUserBox() {
00561                 $this->setVarsFromRequest(
00562                         array( 'wgDBuser', 'wgDBpassword', '_SameAccount', '_CreateDBAccount' )
00563                 );
00564 
00565                 if ( $this->getVar( '_SameAccount' ) ) {
00566                         $this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) );
00567                         $this->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) );
00568                 }
00569 
00570                 if( $this->getVar( '_CreateDBAccount' ) && strval( $this->getVar( 'wgDBpassword' ) ) == '' ) {
00571                         return Status::newFatal( 'config-db-password-empty', $this->getVar( 'wgDBuser' ) );
00572                 }
00573 
00574                 return Status::newGood();
00575         }
00576 
00582         public function populateInterwikiTable() {
00583                 $status = $this->getConnection();
00584                 if ( !$status->isOK() ) {
00585                         return $status;
00586                 }
00587                 $this->db->selectDB( $this->getVar( 'wgDBname' ) );
00588 
00589                 if( $this->db->selectRow( 'interwiki', '*', array(), __METHOD__ ) ) {
00590                         $status->warning( 'config-install-interwiki-exists' );
00591                         return $status;
00592                 }
00593                 global $IP;
00594                 wfSuppressWarnings();
00595                 $rows = file( "$IP/maintenance/interwiki.list",
00596                         FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
00597                 wfRestoreWarnings();
00598                 $interwikis = array();
00599                 if ( !$rows ) {
00600                         return Status::newFatal( 'config-install-interwiki-list' );
00601                 }
00602                 foreach( $rows as $row ) {
00603                         $row = preg_replace( '/^\s*([^#]*?)\s*(#.*)?$/', '\\1', $row ); // strip comments - whee
00604                         if ( $row == "" ) continue;
00605                         $row .= "||";
00606                         $interwikis[] = array_combine(
00607                                 array( 'iw_prefix', 'iw_url', 'iw_local', 'iw_api', 'iw_wikiid' ),
00608                                 explode( '|', $row )
00609                         );
00610                 }
00611                 $this->db->insert( 'interwiki', $interwikis, __METHOD__ );
00612                 return Status::newGood();
00613         }
00614 
00615         public function outputHandler( $string ) {
00616                 return htmlspecialchars( $string );
00617         }
00618 }