MediaWiki  REL1_21
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         abstract public function getName();
00066 
00070         abstract public function isCompiled();
00071 
00077         public function checkPrerequisites() {
00078                 return Status::newGood();
00079         }
00080 
00088         abstract public function getConnectForm();
00089 
00099         abstract public function submitConnectForm();
00100 
00108         public function getSettingsForm() {
00109                 return false;
00110         }
00111 
00118         public function submitSettingsForm() {
00119                 return Status::newGood();
00120         }
00121 
00130         abstract public function openConnection();
00131 
00138         abstract public 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         abstract public 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                 $up = DatabaseUpdater::newForDB( $this->db );
00273                 try {
00274                         $up->doUpdates();
00275                 } catch ( MWException $e ) {
00276                         echo "\nAn error occurred:\n";
00277                         echo $e->getText();
00278                         $ret = false;
00279                 }
00280                 $up->purgeCache();
00281                 ob_end_flush();
00282                 return $ret;
00283         }
00284 
00290         public function preInstall() {
00291 
00292         }
00293 
00297         public function preUpgrade() {
00298 
00299         }
00300 
00305         public function getGlobalNames() {
00306                 return $this->globalNames;
00307         }
00308 
00314         public function __construct( $parent ) {
00315                 $this->parent = $parent;
00316         }
00317 
00326         protected static function checkExtension( $name ) {
00327                 wfSuppressWarnings();
00328                 $compiled = wfDl( $name );
00329                 wfRestoreWarnings();
00330                 return $compiled;
00331         }
00332 
00337         public function getReadableName() {
00338                 return wfMessage( 'config-type-' . $this->getName() )->text();
00339         }
00340 
00346         public function getGlobalDefaults() {
00347                 return array();
00348         }
00349 
00354         public function getInternalDefaults() {
00355                 return $this->internalDefaults;
00356         }
00357 
00364         public function getVar( $var, $default = null ) {
00365                 $defaults = $this->getGlobalDefaults();
00366                 $internal = $this->getInternalDefaults();
00367                 if ( isset( $defaults[$var] ) ) {
00368                         $default = $defaults[$var];
00369                 } elseif ( isset( $internal[$var] ) ) {
00370                         $default = $internal[$var];
00371                 }
00372                 return $this->parent->getVar( $var, $default );
00373         }
00374 
00380         public function setVar( $name, $value ) {
00381                 $this->parent->setVar( $name, $value );
00382         }
00383 
00393         public function getTextBox( $var, $label, $attribs = array(), $helpData = "" ) {
00394                 $name = $this->getName() . '_' . $var;
00395                 $value = $this->getVar( $var );
00396                 if ( !isset( $attribs ) ) {
00397                         $attribs = array();
00398                 }
00399                 return $this->parent->getTextBox( array(
00400                         'var' => $var,
00401                         'label' => $label,
00402                         'attribs' => $attribs,
00403                         'controlName' => $name,
00404                         'value' => $value,
00405                         'help' => $helpData
00406                 ) );
00407         }
00408 
00419         public function getPasswordBox( $var, $label, $attribs = array(), $helpData = "" ) {
00420                 $name = $this->getName() . '_' . $var;
00421                 $value = $this->getVar( $var );
00422                 if ( !isset( $attribs ) ) {
00423                         $attribs = array();
00424                 }
00425                 return $this->parent->getPasswordBox( array(
00426                         'var' => $var,
00427                         'label' => $label,
00428                         'attribs' => $attribs,
00429                         'controlName' => $name,
00430                         'value' => $value,
00431                         'help' => $helpData
00432                 ) );
00433         }
00434 
00440         public function getCheckBox( $var, $label, $attribs = array(), $helpData = "" ) {
00441                 $name = $this->getName() . '_' . $var;
00442                 $value = $this->getVar( $var );
00443                 return $this->parent->getCheckBox( array(
00444                         'var' => $var,
00445                         'label' => $label,
00446                         'attribs' => $attribs,
00447                         'controlName' => $name,
00448                         'value' => $value,
00449                         'help' => $helpData
00450                 ));
00451         }
00452 
00466         public function getRadioSet( $params ) {
00467                 $params['controlName'] = $this->getName() . '_' . $params['var'];
00468                 $params['value'] = $this->getVar( $params['var'] );
00469                 return $this->parent->getRadioSet( $params );
00470         }
00471 
00479         public function setVarsFromRequest( $varNames ) {
00480                 return $this->parent->setVarsFromRequest( $varNames, $this->getName() . '_' );
00481         }
00482 
00493         public function needsUpgrade() {
00494                 $status = $this->getConnection();
00495                 if ( !$status->isOK() ) {
00496                         return false;
00497                 }
00498 
00499                 if ( !$this->db->selectDB( $this->getVar( 'wgDBname' ) ) ) {
00500                         return false;
00501                 }
00502                 return $this->db->tableExists( 'cur', __METHOD__ ) || $this->db->tableExists( 'revision', __METHOD__ );
00503         }
00504 
00510         public function getInstallUserBox() {
00511                 return
00512                         Html::openElement( 'fieldset' ) .
00513                         Html::element( 'legend', array(), wfMessage( 'config-db-install-account' )->text() ) .
00514                         $this->getTextBox( '_InstallUser', 'config-db-username', array( 'dir' => 'ltr' ), $this->parent->getHelpBox( 'config-db-install-username' ) ) .
00515                         $this->getPasswordBox( '_InstallPassword', 'config-db-password', array( 'dir' => 'ltr' ), $this->parent->getHelpBox( 'config-db-install-password' ) ) .
00516                         Html::closeElement( 'fieldset' );
00517         }
00518 
00523         public function submitInstallUserBox() {
00524                 $this->setVarsFromRequest( array( '_InstallUser', '_InstallPassword' ) );
00525                 return Status::newGood();
00526         }
00527 
00535         public function getWebUserBox( $noCreateMsg = false ) {
00536                 $wrapperStyle = $this->getVar( '_SameAccount' ) ? 'display: none' : '';
00537                 $s = Html::openElement( 'fieldset' ) .
00538                         Html::element( 'legend', array(), wfMessage( 'config-db-web-account' )->text() ) .
00539                         $this->getCheckBox(
00540                                 '_SameAccount', 'config-db-web-account-same',
00541                                 array( 'class' => 'hideShowRadio', 'rel' => 'dbOtherAccount' )
00542                         ) .
00543                         Html::openElement( 'div', array( 'id' => 'dbOtherAccount', 'style' => $wrapperStyle ) ) .
00544                         $this->getTextBox( 'wgDBuser', 'config-db-username' ) .
00545                         $this->getPasswordBox( 'wgDBpassword', 'config-db-password' ) .
00546                         $this->parent->getHelpBox( 'config-db-web-help' );
00547                 if ( $noCreateMsg ) {
00548                         $s .= $this->parent->getWarningBox( wfMessage( $noCreateMsg )->plain() );
00549                 } else {
00550                         $s .= $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create' );
00551                 }
00552                 $s .= Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' );
00553                 return $s;
00554         }
00555 
00561         public function submitWebUserBox() {
00562                 $this->setVarsFromRequest(
00563                         array( 'wgDBuser', 'wgDBpassword', '_SameAccount', '_CreateDBAccount' )
00564                 );
00565 
00566                 if ( $this->getVar( '_SameAccount' ) ) {
00567                         $this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) );
00568                         $this->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) );
00569                 }
00570 
00571                 if( $this->getVar( '_CreateDBAccount' ) && strval( $this->getVar( 'wgDBpassword' ) ) == '' ) {
00572                         return Status::newFatal( 'config-db-password-empty', $this->getVar( 'wgDBuser' ) );
00573                 }
00574 
00575                 return Status::newGood();
00576         }
00577 
00583         public function populateInterwikiTable() {
00584                 $status = $this->getConnection();
00585                 if ( !$status->isOK() ) {
00586                         return $status;
00587                 }
00588                 $this->db->selectDB( $this->getVar( 'wgDBname' ) );
00589 
00590                 if( $this->db->selectRow( 'interwiki', '*', array(), __METHOD__ ) ) {
00591                         $status->warning( 'config-install-interwiki-exists' );
00592                         return $status;
00593                 }
00594                 global $IP;
00595                 wfSuppressWarnings();
00596                 $rows = file( "$IP/maintenance/interwiki.list",
00597                         FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
00598                 wfRestoreWarnings();
00599                 $interwikis = array();
00600                 if ( !$rows ) {
00601                         return Status::newFatal( 'config-install-interwiki-list' );
00602                 }
00603                 foreach( $rows as $row ) {
00604                         $row = preg_replace( '/^\s*([^#]*?)\s*(#.*)?$/', '\\1', $row ); // strip comments - whee
00605                         if ( $row == "" ) continue;
00606                         $row .= "||";
00607                         $interwikis[] = array_combine(
00608                                 array( 'iw_prefix', 'iw_url', 'iw_local', 'iw_api', 'iw_wikiid' ),
00609                                 explode( '|', $row )
00610                         );
00611                 }
00612                 $this->db->insert( 'interwiki', $interwikis, __METHOD__ );
00613                 return Status::newGood();
00614         }
00615 
00616         public function outputHandler( $string ) {
00617                 return htmlspecialchars( $string );
00618         }
00619 }