MediaWiki  REL1_23
WebInstaller.php
Go to the documentation of this file.
00001 <?php
00030 class WebInstaller extends Installer {
00031 
00035     public $output;
00036 
00042     public $request;
00043 
00049     protected $session;
00050 
00056     protected $phpErrors;
00057 
00068     public $pageSequence = array(
00069         'Language',
00070         'ExistingWiki',
00071         'Welcome',
00072         'DBConnect',
00073         'Upgrade',
00074         'DBSettings',
00075         'Name',
00076         'Options',
00077         'Install',
00078         'Complete',
00079     );
00080 
00086     protected $otherPages = array(
00087         'Restart',
00088         'Readme',
00089         'ReleaseNotes',
00090         'Copying',
00091         'UpgradeDoc', // Can't use Upgrade due to Upgrade step
00092     );
00093 
00100     protected $happyPages;
00101 
00109     protected $skippedPages;
00110 
00116     public $showSessionWarning = false;
00117 
00123     protected $tabIndex = 1;
00124 
00130     protected $currentPageName;
00131 
00137     public function __construct( WebRequest $request ) {
00138         parent::__construct();
00139         $this->output = new WebInstallerOutput( $this );
00140         $this->request = $request;
00141 
00142         // Add parser hooks
00143         global $wgParser;
00144         $wgParser->setHook( 'downloadlink', array( $this, 'downloadLinkHook' ) );
00145         $wgParser->setHook( 'doclink', array( $this, 'docLink' ) );
00146     }
00147 
00155     public function execute( array $session ) {
00156         $this->session = $session;
00157 
00158         if ( isset( $session['settings'] ) ) {
00159             $this->settings = $session['settings'] + $this->settings;
00160         }
00161 
00162         $this->exportVars();
00163         $this->setupLanguage();
00164 
00165         if ( ( $this->getVar( '_InstallDone' ) || $this->getVar( '_UpgradeDone' ) )
00166             && $this->request->getVal( 'localsettings' )
00167         ) {
00168             $this->request->response()->header( 'Content-type: application/x-httpd-php' );
00169             $this->request->response()->header(
00170                 'Content-Disposition: attachment; filename="LocalSettings.php"'
00171             );
00172 
00173             $ls = InstallerOverrides::getLocalSettingsGenerator( $this );
00174             $rightsProfile = $this->rightsProfiles[$this->getVar( '_RightsProfile' )];
00175             foreach ( $rightsProfile as $group => $rightsArr ) {
00176                 $ls->setGroupRights( $group, $rightsArr );
00177             }
00178             echo $ls->getText();
00179 
00180             return $this->session;
00181         }
00182 
00183         $cssDir = $this->request->getVal( 'css' );
00184         if ( $cssDir ) {
00185             $cssDir = ( $cssDir == 'rtl' ? 'rtl' : 'ltr' );
00186             $this->request->response()->header( 'Content-type: text/css' );
00187             echo $this->output->getCSS( $cssDir );
00188 
00189             return $this->session;
00190         }
00191 
00192         if ( isset( $session['happyPages'] ) ) {
00193             $this->happyPages = $session['happyPages'];
00194         } else {
00195             $this->happyPages = array();
00196         }
00197 
00198         if ( isset( $session['skippedPages'] ) ) {
00199             $this->skippedPages = $session['skippedPages'];
00200         } else {
00201             $this->skippedPages = array();
00202         }
00203 
00204         $lowestUnhappy = $this->getLowestUnhappy();
00205 
00206         # Special case for Creative Commons partner chooser box.
00207         if ( $this->request->getVal( 'SubmitCC' ) ) {
00208             $page = $this->getPageByName( 'Options' );
00209             $this->output->useShortHeader();
00210             $this->output->allowFrames();
00211             $page->submitCC();
00212 
00213             return $this->finish();
00214         }
00215 
00216         if ( $this->request->getVal( 'ShowCC' ) ) {
00217             $page = $this->getPageByName( 'Options' );
00218             $this->output->useShortHeader();
00219             $this->output->allowFrames();
00220             $this->output->addHTML( $page->getCCDoneBox() );
00221 
00222             return $this->finish();
00223         }
00224 
00225         # Get the page name.
00226         $pageName = $this->request->getVal( 'page' );
00227 
00228         if ( in_array( $pageName, $this->otherPages ) ) {
00229             # Out of sequence
00230             $pageId = false;
00231             $page = $this->getPageByName( $pageName );
00232         } else {
00233             # Main sequence
00234             if ( !$pageName || !in_array( $pageName, $this->pageSequence ) ) {
00235                 $pageId = $lowestUnhappy;
00236             } else {
00237                 $pageId = array_search( $pageName, $this->pageSequence );
00238             }
00239 
00240             # If necessary, move back to the lowest-numbered unhappy page
00241             if ( $pageId > $lowestUnhappy ) {
00242                 $pageId = $lowestUnhappy;
00243                 if ( $lowestUnhappy == 0 ) {
00244                     # Knocked back to start, possible loss of session data.
00245                     $this->showSessionWarning = true;
00246                 }
00247             }
00248 
00249             $pageName = $this->pageSequence[$pageId];
00250             $page = $this->getPageByName( $pageName );
00251         }
00252 
00253         # If a back button was submitted, go back without submitting the form data.
00254         if ( $this->request->wasPosted() && $this->request->getBool( 'submit-back' ) ) {
00255             if ( $this->request->getVal( 'lastPage' ) ) {
00256                 $nextPage = $this->request->getVal( 'lastPage' );
00257             } elseif ( $pageId !== false ) {
00258                 # Main sequence page
00259                 # Skip the skipped pages
00260                 $nextPageId = $pageId;
00261 
00262                 do {
00263                     $nextPageId--;
00264                     $nextPage = $this->pageSequence[$nextPageId];
00265                 } while ( isset( $this->skippedPages[$nextPage] ) );
00266             } else {
00267                 $nextPage = $this->pageSequence[$lowestUnhappy];
00268             }
00269 
00270             $this->output->redirect( $this->getUrl( array( 'page' => $nextPage ) ) );
00271 
00272             return $this->finish();
00273         }
00274 
00275         # Execute the page.
00276         $this->currentPageName = $page->getName();
00277         $this->startPageWrapper( $pageName );
00278 
00279         if ( $page->isSlow() ) {
00280             $this->disableTimeLimit();
00281         }
00282 
00283         $result = $page->execute();
00284 
00285         $this->endPageWrapper();
00286 
00287         if ( $result == 'skip' ) {
00288             # Page skipped without explicit submission.
00289             # Skip it when we click "back" so that we don't just go forward again.
00290             $this->skippedPages[$pageName] = true;
00291             $result = 'continue';
00292         } else {
00293             unset( $this->skippedPages[$pageName] );
00294         }
00295 
00296         # If it was posted, the page can request a continue to the next page.
00297         if ( $result === 'continue' && !$this->output->headerDone() ) {
00298             if ( $pageId !== false ) {
00299                 $this->happyPages[$pageId] = true;
00300             }
00301 
00302             $lowestUnhappy = $this->getLowestUnhappy();
00303 
00304             if ( $this->request->getVal( 'lastPage' ) ) {
00305                 $nextPage = $this->request->getVal( 'lastPage' );
00306             } elseif ( $pageId !== false ) {
00307                 $nextPage = $this->pageSequence[$pageId + 1];
00308             } else {
00309                 $nextPage = $this->pageSequence[$lowestUnhappy];
00310             }
00311 
00312             if ( array_search( $nextPage, $this->pageSequence ) > $lowestUnhappy ) {
00313                 $nextPage = $this->pageSequence[$lowestUnhappy];
00314             }
00315 
00316             $this->output->redirect( $this->getUrl( array( 'page' => $nextPage ) ) );
00317         }
00318 
00319         return $this->finish();
00320     }
00321 
00326     public function getLowestUnhappy() {
00327         if ( count( $this->happyPages ) == 0 ) {
00328             return 0;
00329         } else {
00330             return max( array_keys( $this->happyPages ) ) + 1;
00331         }
00332     }
00333 
00340     public function startSession() {
00341         if ( wfIniGetBool( 'session.auto_start' ) || session_id() ) {
00342             // Done already
00343             return true;
00344         }
00345 
00346         $this->phpErrors = array();
00347         set_error_handler( array( $this, 'errorHandler' ) );
00348         try {
00349             session_start();
00350         } catch ( Exception $e ) {
00351             restore_error_handler();
00352             throw $e;
00353         }
00354         restore_error_handler();
00355 
00356         if ( $this->phpErrors ) {
00357             $this->showError( 'config-session-error', $this->phpErrors[0] );
00358 
00359             return false;
00360         }
00361 
00362         return true;
00363     }
00364 
00373     public function getFingerprint() {
00374         // Get the base URL of the installation
00375         $url = $this->request->getFullRequestURL();
00376         if ( preg_match( '!^(.*\?)!', $url, $m ) ) {
00377             // Trim query string
00378             $url = $m[1];
00379         }
00380         if ( preg_match( '!^(.*)/[^/]*/[^/]*$!', $url, $m ) ) {
00381             // This... seems to try to get the base path from
00382             // the /mw-config/index.php. Kinda scary though?
00383             $url = $m[1];
00384         }
00385 
00386         return md5( serialize( array(
00387             'local path' => dirname( __DIR__ ),
00388             'url' => $url,
00389             'version' => $GLOBALS['wgVersion']
00390         ) ) );
00391     }
00392 
00397     public function showError( $msg /*...*/ ) {
00398         $args = func_get_args();
00399         array_shift( $args );
00400         $args = array_map( 'htmlspecialchars', $args );
00401         $msg = wfMessage( $msg, $args )->useDatabase( false )->plain();
00402         $this->output->addHTML( $this->getErrorBox( $msg ) );
00403     }
00404 
00411     public function errorHandler( $errno, $errstr ) {
00412         $this->phpErrors[] = $errstr;
00413     }
00414 
00420     public function finish() {
00421         $this->output->output();
00422 
00423         $this->session['happyPages'] = $this->happyPages;
00424         $this->session['skippedPages'] = $this->skippedPages;
00425         $this->session['settings'] = $this->settings;
00426 
00427         return $this->session;
00428     }
00429 
00433     public function reset() {
00434         $this->session = array();
00435         $this->happyPages = array();
00436         $this->settings = array();
00437     }
00438 
00446     public function getUrl( $query = array() ) {
00447         $url = $this->request->getRequestURL();
00448         # Remove existing query
00449         $url = preg_replace( '/\?.*$/', '', $url );
00450 
00451         if ( $query ) {
00452             $url .= '?' . wfArrayToCgi( $query );
00453         }
00454 
00455         return $url;
00456     }
00457 
00464     public function getPageByName( $pageName ) {
00465         $pageClass = 'WebInstaller_' . $pageName;
00466 
00467         return new $pageClass( $this );
00468     }
00469 
00478     public function getSession( $name, $default = null ) {
00479         if ( !isset( $this->session[$name] ) ) {
00480             return $default;
00481         } else {
00482             return $this->session[$name];
00483         }
00484     }
00485 
00492     public function setSession( $name, $value ) {
00493         $this->session[$name] = $value;
00494     }
00495 
00501     public function nextTabIndex() {
00502         return $this->tabIndex++;
00503     }
00504 
00508     public function setupLanguage() {
00509         global $wgLang, $wgContLang, $wgLanguageCode;
00510 
00511         if ( $this->getSession( 'test' ) === null && !$this->request->wasPosted() ) {
00512             $wgLanguageCode = $this->getAcceptLanguage();
00513             $wgLang = $wgContLang = Language::factory( $wgLanguageCode );
00514             $this->setVar( 'wgLanguageCode', $wgLanguageCode );
00515             $this->setVar( '_UserLang', $wgLanguageCode );
00516         } else {
00517             $wgLanguageCode = $this->getVar( 'wgLanguageCode' );
00518             $wgContLang = Language::factory( $wgLanguageCode );
00519         }
00520     }
00521 
00527     public function getAcceptLanguage() {
00528         global $wgLanguageCode, $wgRequest;
00529 
00530         $mwLanguages = Language::fetchLanguageNames();
00531         $headerLanguages = array_keys( $wgRequest->getAcceptLang() );
00532 
00533         foreach ( $headerLanguages as $lang ) {
00534             if ( isset( $mwLanguages[$lang] ) ) {
00535                 return $lang;
00536             }
00537         }
00538 
00539         return $wgLanguageCode;
00540     }
00541 
00547     private function startPageWrapper( $currentPageName ) {
00548         $s = "<div class=\"config-page-wrapper\">\n";
00549         $s .= "<div class=\"config-page\">\n";
00550         $s .= "<div class=\"config-page-list\"><ul>\n";
00551         $lastHappy = -1;
00552 
00553         foreach ( $this->pageSequence as $id => $pageName ) {
00554             $happy = !empty( $this->happyPages[$id] );
00555             $s .= $this->getPageListItem(
00556                 $pageName,
00557                 $happy || $lastHappy == $id - 1,
00558                 $currentPageName
00559             );
00560 
00561             if ( $happy ) {
00562                 $lastHappy = $id;
00563             }
00564         }
00565 
00566         $s .= "</ul><br/><ul>\n";
00567         $s .= $this->getPageListItem( 'Restart', true, $currentPageName );
00568         // End list pane
00569         $s .= "</ul></div>\n";
00570 
00571         // Messages:
00572         // config-page-language, config-page-welcome, config-page-dbconnect, config-page-upgrade,
00573         // config-page-dbsettings, config-page-name, config-page-options, config-page-install,
00574         // config-page-complete, config-page-restart, config-page-readme, config-page-releasenotes,
00575         // config-page-copying, config-page-upgradedoc, config-page-existingwiki
00576         $s .= Html::element( 'h2', array(),
00577             wfMessage( 'config-page-' . strtolower( $currentPageName ) )->text() );
00578 
00579         $this->output->addHTMLNoFlush( $s );
00580     }
00581 
00591     private function getPageListItem( $pageName, $enabled, $currentPageName ) {
00592         $s = "<li class=\"config-page-list-item\">";
00593 
00594         // Messages:
00595         // config-page-language, config-page-welcome, config-page-dbconnect, config-page-upgrade,
00596         // config-page-dbsettings, config-page-name, config-page-options, config-page-install,
00597         // config-page-complete, config-page-restart, config-page-readme, config-page-releasenotes,
00598         // config-page-copying, config-page-upgradedoc, config-page-existingwiki
00599         $name = wfMessage( 'config-page-' . strtolower( $pageName ) )->text();
00600 
00601         if ( $enabled ) {
00602             $query = array( 'page' => $pageName );
00603 
00604             if ( !in_array( $pageName, $this->pageSequence ) ) {
00605                 if ( in_array( $currentPageName, $this->pageSequence ) ) {
00606                     $query['lastPage'] = $currentPageName;
00607                 }
00608 
00609                 $link = Html::element( 'a',
00610                     array(
00611                         'href' => $this->getUrl( $query )
00612                     ),
00613                     $name
00614                 );
00615             } else {
00616                 $link = htmlspecialchars( $name );
00617             }
00618 
00619             if ( $pageName == $currentPageName ) {
00620                 $s .= "<span class=\"config-page-current\">$link</span>";
00621             } else {
00622                 $s .= $link;
00623             }
00624         } else {
00625             $s .= Html::element( 'span',
00626                 array(
00627                     'class' => 'config-page-disabled'
00628                 ),
00629                 $name
00630             );
00631         }
00632 
00633         $s .= "</li>\n";
00634 
00635         return $s;
00636     }
00637 
00641     private function endPageWrapper() {
00642         $this->output->addHTMLNoFlush(
00643             "<div class=\"visualClear\"></div>\n" .
00644             "</div>\n" .
00645             "<div class=\"visualClear\"></div>\n" .
00646             "</div>" );
00647     }
00648 
00656     public function getErrorBox( $text ) {
00657         return $this->getInfoBox( $text, 'critical-32.png', 'config-error-box' );
00658     }
00659 
00667     public function getWarningBox( $text ) {
00668         return $this->getInfoBox( $text, 'warning-32.png', 'config-warning-box' );
00669     }
00670 
00680     public function getInfoBox( $text, $icon = false, $class = false ) {
00681         $text = $this->parse( $text, true );
00682         $icon = ( $icon == false ) ?
00683             '../skins/common/images/info-32.png' :
00684             '../skins/common/images/' . $icon;
00685         $alt = wfMessage( 'config-information' )->text();
00686 
00687         return Html::infoBox( $text, $icon, $alt, $class, false );
00688     }
00689 
00697     public function getHelpBox( $msg /*, ... */ ) {
00698         $args = func_get_args();
00699         array_shift( $args );
00700         $args = array_map( 'htmlspecialchars', $args );
00701         $text = wfMessage( $msg, $args )->useDatabase( false )->plain();
00702         $html = $this->parse( $text, true );
00703 
00704         return "<div class=\"mw-help-field-container\">\n" .
00705             "<span class=\"mw-help-field-hint\">" . wfMessage( 'config-help' )->escaped() .
00706             "</span>\n" .
00707             "<span class=\"mw-help-field-data\">" . $html . "</span>\n" .
00708             "</div>\n";
00709     }
00710 
00715     public function showHelpBox( $msg /*, ... */ ) {
00716         $args = func_get_args();
00717         $html = call_user_func_array( array( $this, 'getHelpBox' ), $args );
00718         $this->output->addHTML( $html );
00719     }
00720 
00727     public function showMessage( $msg /*, ... */ ) {
00728         $args = func_get_args();
00729         array_shift( $args );
00730         $html = '<div class="config-message">' .
00731             $this->parse( wfMessage( $msg, $args )->useDatabase( false )->plain() ) .
00732             "</div>\n";
00733         $this->output->addHTML( $html );
00734     }
00735 
00739     public function showStatusMessage( Status $status ) {
00740         $errors = array_merge( $status->getErrorsArray(), $status->getWarningsArray() );
00741         foreach ( $errors as $error ) {
00742             call_user_func_array( array( $this, 'showMessage' ), $error );
00743         }
00744     }
00745 
00756     public function label( $msg, $forId, $contents, $helpData = "" ) {
00757         if ( strval( $msg ) == '' ) {
00758             $labelText = '&#160;';
00759         } else {
00760             $labelText = wfMessage( $msg )->escaped();
00761         }
00762 
00763         $attributes = array( 'class' => 'config-label' );
00764 
00765         if ( $forId ) {
00766             $attributes['for'] = $forId;
00767         }
00768 
00769         return "<div class=\"config-block\">\n" .
00770             "  <div class=\"config-block-label\">\n" .
00771             Xml::tags( 'label',
00772                 $attributes,
00773                 $labelText
00774             ) . "\n" .
00775             $helpData .
00776             "  </div>\n" .
00777             "  <div class=\"config-block-elements\">\n" .
00778             $contents .
00779             "  </div>\n" .
00780             "</div>\n";
00781     }
00782 
00797     public function getTextBox( $params ) {
00798         if ( !isset( $params['controlName'] ) ) {
00799             $params['controlName'] = 'config_' . $params['var'];
00800         }
00801 
00802         if ( !isset( $params['value'] ) ) {
00803             $params['value'] = $this->getVar( $params['var'] );
00804         }
00805 
00806         if ( !isset( $params['attribs'] ) ) {
00807             $params['attribs'] = array();
00808         }
00809         if ( !isset( $params['help'] ) ) {
00810             $params['help'] = "";
00811         }
00812 
00813         return $this->label(
00814             $params['label'],
00815             $params['controlName'],
00816             Xml::input(
00817                 $params['controlName'],
00818                 30, // intended to be overridden by CSS
00819                 $params['value'],
00820                 $params['attribs'] + array(
00821                     'id' => $params['controlName'],
00822                     'class' => 'config-input-text',
00823                     'tabindex' => $this->nextTabIndex()
00824                 )
00825             ),
00826             $params['help']
00827         );
00828     }
00829 
00844     public function getTextArea( $params ) {
00845         if ( !isset( $params['controlName'] ) ) {
00846             $params['controlName'] = 'config_' . $params['var'];
00847         }
00848 
00849         if ( !isset( $params['value'] ) ) {
00850             $params['value'] = $this->getVar( $params['var'] );
00851         }
00852 
00853         if ( !isset( $params['attribs'] ) ) {
00854             $params['attribs'] = array();
00855         }
00856         if ( !isset( $params['help'] ) ) {
00857             $params['help'] = "";
00858         }
00859 
00860         return $this->label(
00861             $params['label'],
00862             $params['controlName'],
00863             Xml::textarea(
00864                 $params['controlName'],
00865                 $params['value'],
00866                 30,
00867                 5,
00868                 $params['attribs'] + array(
00869                     'id' => $params['controlName'],
00870                     'class' => 'config-input-text',
00871                     'tabindex' => $this->nextTabIndex()
00872                 )
00873             ),
00874             $params['help']
00875         );
00876     }
00877 
00893     public function getPasswordBox( $params ) {
00894         if ( !isset( $params['value'] ) ) {
00895             $params['value'] = $this->getVar( $params['var'] );
00896         }
00897 
00898         if ( !isset( $params['attribs'] ) ) {
00899             $params['attribs'] = array();
00900         }
00901 
00902         $params['value'] = $this->getFakePassword( $params['value'] );
00903         $params['attribs']['type'] = 'password';
00904 
00905         return $this->getTextBox( $params );
00906     }
00907 
00922     public function getCheckBox( $params ) {
00923         if ( !isset( $params['controlName'] ) ) {
00924             $params['controlName'] = 'config_' . $params['var'];
00925         }
00926 
00927         if ( !isset( $params['value'] ) ) {
00928             $params['value'] = $this->getVar( $params['var'] );
00929         }
00930 
00931         if ( !isset( $params['attribs'] ) ) {
00932             $params['attribs'] = array();
00933         }
00934         if ( !isset( $params['help'] ) ) {
00935             $params['help'] = "";
00936         }
00937         if ( isset( $params['rawtext'] ) ) {
00938             $labelText = $params['rawtext'];
00939         } else {
00940             $labelText = $this->parse( wfMessage( $params['label'] )->text() );
00941         }
00942 
00943         return "<div class=\"config-input-check\">\n" .
00944             $params['help'] .
00945             "<label>\n" .
00946             Xml::check(
00947                 $params['controlName'],
00948                 $params['value'],
00949                 $params['attribs'] + array(
00950                     'id' => $params['controlName'],
00951                     'tabindex' => $this->nextTabIndex(),
00952                 )
00953             ) .
00954             $labelText . "\n" .
00955             "</label>\n" .
00956             "</div>\n";
00957     }
00958 
00976     public function getRadioSet( $params ) {
00977         if ( !isset( $params['controlName'] ) ) {
00978             $params['controlName'] = 'config_' . $params['var'];
00979         }
00980 
00981         if ( !isset( $params['value'] ) ) {
00982             $params['value'] = $this->getVar( $params['var'] );
00983         }
00984 
00985         if ( !isset( $params['label'] ) ) {
00986             $label = '';
00987         } else {
00988             $label = $params['label'];
00989         }
00990         if ( !isset( $params['help'] ) ) {
00991             $params['help'] = "";
00992         }
00993         $s = "<ul>\n";
00994         foreach ( $params['values'] as $value ) {
00995             $itemAttribs = array();
00996 
00997             if ( isset( $params['commonAttribs'] ) ) {
00998                 $itemAttribs = $params['commonAttribs'];
00999             }
01000 
01001             if ( isset( $params['itemAttribs'][$value] ) ) {
01002                 $itemAttribs = $params['itemAttribs'][$value] + $itemAttribs;
01003             }
01004 
01005             $checked = $value == $params['value'];
01006             $id = $params['controlName'] . '_' . $value;
01007             $itemAttribs['id'] = $id;
01008             $itemAttribs['tabindex'] = $this->nextTabIndex();
01009 
01010             $s .=
01011                 '<li>' .
01012                 Xml::radio( $params['controlName'], $value, $checked, $itemAttribs ) .
01013                 '&#160;' .
01014                 Xml::tags( 'label', array( 'for' => $id ), $this->parse(
01015                     wfMessage( $params['itemLabelPrefix'] . strtolower( $value ) )->plain()
01016                 ) ) .
01017                 "</li>\n";
01018         }
01019 
01020         $s .= "</ul>\n";
01021 
01022         return $this->label( $label, $params['controlName'], $s, $params['help'] );
01023     }
01024 
01030     public function showStatusBox( $status ) {
01031         if ( !$status->isGood() ) {
01032             $text = $status->getWikiText();
01033 
01034             if ( $status->isOk() ) {
01035                 $box = $this->getWarningBox( $text );
01036             } else {
01037                 $box = $this->getErrorBox( $text );
01038             }
01039 
01040             $this->output->addHTML( $box );
01041         }
01042     }
01043 
01054     public function setVarsFromRequest( $varNames, $prefix = 'config_' ) {
01055         $newValues = array();
01056 
01057         foreach ( $varNames as $name ) {
01058             $value = trim( $this->request->getVal( $prefix . $name ) );
01059             $newValues[$name] = $value;
01060 
01061             if ( $value === null ) {
01062                 // Checkbox?
01063                 $this->setVar( $name, false );
01064             } else {
01065                 if ( stripos( $name, 'password' ) !== false ) {
01066                     $this->setPassword( $name, $value );
01067                 } else {
01068                     $this->setVar( $name, $value );
01069                 }
01070             }
01071         }
01072 
01073         return $newValues;
01074     }
01075 
01083     protected function getDocUrl( $page ) {
01084         $url = "{$_SERVER['PHP_SELF']}?page=" . urlencode( $page );
01085 
01086         if ( in_array( $this->currentPageName, $this->pageSequence ) ) {
01087             $url .= '&lastPage=' . urlencode( $this->currentPageName );
01088         }
01089 
01090         return $url;
01091     }
01092 
01102     public function docLink( $linkText, $attribs, $parser ) {
01103         $url = $this->getDocUrl( $attribs['href'] );
01104 
01105         return '<a href="' . htmlspecialchars( $url ) . '">' .
01106             htmlspecialchars( $linkText ) .
01107             '</a>';
01108     }
01109 
01119     public function downloadLinkHook( $text, $attribs, $parser ) {
01120         $img = Html::element( 'img', array(
01121             'src' => '../skins/common/images/download-32.png',
01122             'width' => '32',
01123             'height' => '32',
01124         ) );
01125         $anchor = Html::rawElement( 'a',
01126             array( 'href' => $this->getURL( array( 'localsettings' => 1 ) ) ),
01127             $img . ' ' . wfMessage( 'config-download-localsettings' )->parse() );
01128 
01129         return Html::rawElement( 'div', array( 'class' => 'config-download-link' ), $anchor );
01130     }
01131 
01135     public function envCheckPath() {
01136         // PHP_SELF isn't available sometimes, such as when PHP is CGI but
01137         // cgi.fix_pathinfo is disabled. In that case, fall back to SCRIPT_NAME
01138         // to get the path to the current script... hopefully it's reliable. SIGH
01139         $path = false;
01140         if ( !empty( $_SERVER['PHP_SELF'] ) ) {
01141             $path = $_SERVER['PHP_SELF'];
01142         } elseif ( !empty( $_SERVER['SCRIPT_NAME'] ) ) {
01143             $path = $_SERVER['SCRIPT_NAME'];
01144         }
01145         if ( $path !== false ) {
01146             $uri = preg_replace( '{^(.*)/(mw-)?config.*$}', '$1', $path );
01147             $this->setVar( 'wgScriptPath', $uri );
01148         } else {
01149             $this->showError( 'config-no-uri' );
01150 
01151             return false;
01152         }
01153 
01154         return parent::envCheckPath();
01155     }
01156 
01160     protected function envGetDefaultServer() {
01161         return WebRequest::detectServer();
01162     }
01163 
01164 }