MediaWiki  REL1_19
DatabaseInstaller.php
Go to the documentation of this file.
00001 <?php
00015 abstract class DatabaseInstaller {
00016 
00024         public $parent;
00025 
00031         public $db = null;
00032 
00038         protected $internalDefaults = array();
00039 
00045         protected $globalNames = array();
00046 
00050         public abstract function getName();
00051 
00055         public abstract function isCompiled();
00056 
00062         public function checkPrerequisites() {
00063                 return Status::newGood();
00064         }
00065 
00073         public abstract function getConnectForm();
00074 
00084         public abstract function submitConnectForm();
00085 
00092         public function getSettingsForm() {
00093                 return false;
00094         }
00095 
00102         public function submitSettingsForm() {
00103                 return Status::newGood();
00104         }
00105 
00114         public abstract function openConnection();
00115 
00122         public abstract function setupDatabase();
00123 
00133         public function getConnection() {
00134                 if ( $this->db ) {
00135                         return Status::newGood( $this->db );
00136                 }
00137 
00138                 $status = $this->openConnection();
00139                 if ( $status->isOK() ) {
00140                         $this->db = $status->value;
00141                         // Enable autocommit
00142                         $this->db->clearFlag( DBO_TRX );
00143                         $this->db->commit();
00144                 }
00145                 return $status;
00146         }
00147 
00153         public function createTables() {
00154                 $status = $this->getConnection();
00155                 if ( !$status->isOK() ) {
00156                         return $status;
00157                 }
00158                 $this->db->selectDB( $this->getVar( 'wgDBname' ) );
00159 
00160                 if( $this->db->tableExists( 'archive', __METHOD__ ) ) {
00161                         $status->warning( 'config-install-tables-exist' );
00162                         $this->enableLB();
00163                         return $status;
00164                 }
00165 
00166                 $this->db->setFlag( DBO_DDLMODE ); // For Oracle's handling of schema files
00167                 $this->db->begin( __METHOD__ );
00168 
00169                 $error = $this->db->sourceFile( $this->db->getSchemaPath() );
00170                 if( $error !== true ) {
00171                         $this->db->reportQueryError( $error, 0, '', __METHOD__ );
00172                         $this->db->rollback( __METHOD__ );
00173                         $status->fatal( 'config-install-tables-failed', $error );
00174                 } else {
00175                         $this->db->commit( __METHOD__ );
00176                 }
00177                 // Resume normal operations
00178                 if( $status->isOk() ) {
00179                         $this->enableLB();
00180                 }
00181                 return $status;
00182         }
00183 
00188         public function createExtensionTables() {
00189                 $status = $this->getConnection();
00190                 if ( !$status->isOK() ) {
00191                         return $status;
00192                 }
00193 
00194                 // Now run updates to create tables for old extensions
00195                 DatabaseUpdater::newForDB( $this->db )->doUpdates( array( 'extensions' ) );
00196 
00197                 return $status;
00198         }
00199 
00205         public abstract function getLocalSettings();
00206 
00211         public function getSchemaVars() {
00212                 return array();
00213         }
00214 
00221         public function setupSchemaVars() {
00222                 $status = $this->getConnection();
00223                 if ( $status->isOK() ) {
00224                         $status->value->setSchemaVars( $this->getSchemaVars() );
00225                 } else {
00226                         throw new MWException( __METHOD__.': unexpected DB connection error' );
00227                 }
00228         }
00229 
00235         public function enableLB() {
00236                 $status = $this->getConnection();
00237                 if ( !$status->isOK() ) {
00238                         throw new MWException( __METHOD__.': unexpected DB connection error' );
00239                 }
00240                 LBFactory::setInstance( new LBFactory_Single( array(
00241                         'connection' => $status->value ) ) );
00242         }
00243 
00249         public function doUpgrade() {
00250                 $this->setupSchemaVars();
00251                 $this->enableLB();
00252 
00253                 $ret = true;
00254                 ob_start( array( $this, 'outputHandler' ) );
00255                 try {
00256                         $up = DatabaseUpdater::newForDB( $this->db );
00257                         $up->doUpdates();
00258                 } catch ( MWException $e ) {
00259                         echo "\nAn error occured:\n";
00260                         echo $e->getText();
00261                         $ret = false;
00262                 }
00263                 ob_end_flush();
00264                 return $ret;
00265         }
00266 
00272         public function preInstall() {
00273 
00274         }
00275 
00279         public function preUpgrade() {
00280 
00281         }
00282 
00286         public function getGlobalNames() {
00287                 return $this->globalNames;
00288         }
00289 
00295         public function __construct( $parent ) {
00296                 $this->parent = $parent;
00297         }
00298 
00307         protected static function checkExtension( $name ) {
00308                 wfSuppressWarnings();
00309                 $compiled = wfDl( $name );
00310                 wfRestoreWarnings();
00311                 return $compiled;
00312         }
00313 
00317         public function getReadableName() {
00318                 return wfMsg( 'config-type-' . $this->getName() );
00319         }
00320 
00325         public function getGlobalDefaults() {
00326                 return array();
00327         }
00328 
00332         public function getInternalDefaults() {
00333                 return $this->internalDefaults;
00334         }
00335 
00342         public function getVar( $var, $default = null ) {
00343                 $defaults = $this->getGlobalDefaults();
00344                 $internal = $this->getInternalDefaults();
00345                 if ( isset( $defaults[$var] ) ) {
00346                         $default = $defaults[$var];
00347                 } elseif ( isset( $internal[$var] ) ) {
00348                         $default = $internal[$var];
00349                 }
00350                 return $this->parent->getVar( $var, $default );
00351         }
00352 
00358         public function setVar( $name, $value ) {
00359                 $this->parent->setVar( $name, $value );
00360         }
00361 
00371         public function getTextBox( $var, $label, $attribs = array(), $helpData = "" ) {
00372                 $name = $this->getName() . '_' . $var;
00373                 $value = $this->getVar( $var );
00374                 if ( !isset( $attribs ) ) {
00375                         $attribs = array();
00376                 }
00377                 return $this->parent->getTextBox( array(
00378                         'var' => $var,
00379                         'label' => $label,
00380                         'attribs' => $attribs,
00381                         'controlName' => $name,
00382                         'value' => $value,
00383                         'help' => $helpData
00384                 ) );
00385         }
00386 
00397         public function getPasswordBox( $var, $label, $attribs = array(), $helpData = "" ) {
00398                 $name = $this->getName() . '_' . $var;
00399                 $value = $this->getVar( $var );
00400                 if ( !isset( $attribs ) ) {
00401                         $attribs = array();
00402                 }
00403                 return $this->parent->getPasswordBox( array(
00404                         'var' => $var,
00405                         'label' => $label,
00406                         'attribs' => $attribs,
00407                         'controlName' => $name,
00408                         'value' => $value,
00409                         'help' => $helpData
00410                 ) );
00411         }
00412 
00418         public function getCheckBox( $var, $label, $attribs = array(), $helpData = "" ) {
00419                 $name = $this->getName() . '_' . $var;
00420                 $value = $this->getVar( $var );
00421                 return $this->parent->getCheckBox( array(
00422                         'var' => $var,
00423                         'label' => $label,
00424                         'attribs' => $attribs,
00425                         'controlName' => $name,
00426                         'value' => $value,
00427                         'help' => $helpData
00428                 ));
00429         }
00430 
00443         public function getRadioSet( $params ) {
00444                 $params['controlName'] = $this->getName() . '_' . $params['var'];
00445                 $params['value'] = $this->getVar( $params['var'] );
00446                 return $this->parent->getRadioSet( $params );
00447         }
00448 
00455         public function setVarsFromRequest( $varNames ) {
00456                 return $this->parent->setVarsFromRequest( $varNames, $this->getName() . '_' );
00457         }
00458 
00469         public function needsUpgrade() {
00470                 $status = $this->getConnection();
00471                 if ( !$status->isOK() ) {
00472                         return false;
00473                 }
00474 
00475                 if ( !$this->db->selectDB( $this->getVar( 'wgDBname' ) ) ) {
00476                         return false;
00477                 }
00478                 return $this->db->tableExists( 'cur', __METHOD__ ) || $this->db->tableExists( 'revision', __METHOD__ );
00479         }
00480 
00486         public function getInstallUserBox() {
00487                 return
00488                         Html::openElement( 'fieldset' ) .
00489                         Html::element( 'legend', array(), wfMsg( 'config-db-install-account' ) ) .
00490                         $this->getTextBox( '_InstallUser', 'config-db-username', array( 'dir' => 'ltr' ), $this->parent->getHelpBox( 'config-db-install-username' ) ) .
00491                         $this->getPasswordBox( '_InstallPassword', 'config-db-password', array( 'dir' => 'ltr' ), $this->parent->getHelpBox( 'config-db-install-password' ) ) .
00492                         Html::closeElement( 'fieldset' );
00493         }
00494 
00498         public function submitInstallUserBox() {
00499                 $this->setVarsFromRequest( array( '_InstallUser', '_InstallPassword' ) );
00500                 return Status::newGood();
00501         }
00502 
00510         public function getWebUserBox( $noCreateMsg = false ) {
00511                 $wrapperStyle = $this->getVar( '_SameAccount' ) ? 'display: none' : '';
00512                 $s = Html::openElement( 'fieldset' ) .
00513                         Html::element( 'legend', array(), wfMsg( 'config-db-web-account' ) ) .
00514                         $this->getCheckBox(
00515                                 '_SameAccount', 'config-db-web-account-same',
00516                                 array( 'class' => 'hideShowRadio', 'rel' => 'dbOtherAccount' )
00517                         ) .
00518                         Html::openElement( 'div', array( 'id' => 'dbOtherAccount', 'style' => $wrapperStyle ) ) .
00519                         $this->getTextBox( 'wgDBuser', 'config-db-username' ) .
00520                         $this->getPasswordBox( 'wgDBpassword', 'config-db-password' ) .
00521                         $this->parent->getHelpBox( 'config-db-web-help' );
00522                 if ( $noCreateMsg ) {
00523                         $s .= $this->parent->getWarningBox( wfMsgNoTrans( $noCreateMsg ) );
00524                 } else {
00525                         $s .= $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create' );
00526                 }
00527                 $s .= Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' );
00528                 return $s;
00529         }
00530 
00536         public function submitWebUserBox() {
00537                 $this->setVarsFromRequest(
00538                         array( 'wgDBuser', 'wgDBpassword', '_SameAccount', '_CreateDBAccount' )
00539                 );
00540 
00541                 if ( $this->getVar( '_SameAccount' ) ) {
00542                         $this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) );
00543                         $this->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) );
00544                 }
00545 
00546                 if( $this->getVar( '_CreateDBAccount' ) && strval( $this->getVar( 'wgDBpassword' ) ) == '' ) {
00547                         return Status::newFatal( 'config-db-password-empty', $this->getVar( 'wgDBuser' ) );
00548                 }
00549 
00550                 return Status::newGood();
00551         }
00552 
00558         public function populateInterwikiTable() {
00559                 $status = $this->getConnection();
00560                 if ( !$status->isOK() ) {
00561                         return $status;
00562                 }
00563                 $this->db->selectDB( $this->getVar( 'wgDBname' ) );
00564 
00565                 if( $this->db->selectRow( 'interwiki', '*', array(), __METHOD__ ) ) {
00566                         $status->warning( 'config-install-interwiki-exists' );
00567                         return $status;
00568                 }
00569                 global $IP;
00570                 wfSuppressWarnings();
00571                 $rows = file( "$IP/maintenance/interwiki.list",
00572                         FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
00573                 wfRestoreWarnings();
00574                 $interwikis = array();
00575                 if ( !$rows ) {
00576                         return Status::newFatal( 'config-install-interwiki-list' );
00577                 }
00578                 foreach( $rows as $row ) {
00579                         $row = preg_replace( '/^\s*([^#]*?)\s*(#.*)?$/', '\\1', $row ); // strip comments - whee
00580                         if ( $row == "" ) continue;
00581                         $row .= "||";
00582                         $interwikis[] = array_combine(
00583                                 array( 'iw_prefix', 'iw_url', 'iw_local', 'iw_api', 'iw_wikiid' ),
00584                                 explode( '|', $row )
00585                         );
00586                 }
00587                 $this->db->insert( 'interwiki', $interwikis, __METHOD__ );
00588                 return Status::newGood();
00589         }
00590 
00591         public function outputHandler( $string ) {
00592                 return htmlspecialchars( $string );
00593         }
00594 }