MediaWiki  REL1_22
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 
00055     protected $phpErrors;
00056 
00066     public $pageSequence = array(
00067         'Language',
00068         'ExistingWiki',
00069         'Welcome',
00070         'DBConnect',
00071         'Upgrade',
00072         'DBSettings',
00073         'Name',
00074         'Options',
00075         'Install',
00076         'Complete',
00077     );
00078 
00083     protected $otherPages = array(
00084         'Restart',
00085         'Readme',
00086         'ReleaseNotes',
00087         'Copying',
00088         'UpgradeDoc', // Can't use Upgrade due to Upgrade step
00089     );
00090 
00096     protected $happyPages;
00097 
00104     protected $skippedPages;
00105 
00110     public $showSessionWarning = false;
00111 
00116     protected $tabIndex = 1;
00117 
00122     protected $currentPageName;
00123 
00129     public function __construct( WebRequest $request ) {
00130         parent::__construct();
00131         $this->output = new WebInstallerOutput( $this );
00132         $this->request = $request;
00133 
00134         // Add parser hooks
00135         global $wgParser;
00136         $wgParser->setHook( 'downloadlink', array( $this, 'downloadLinkHook' ) );
00137         $wgParser->setHook( 'doclink', array( $this, 'docLink' ) );
00138     }
00139 
00147     public function execute( array $session ) {
00148         $this->session = $session;
00149 
00150         if ( isset( $session['settings'] ) ) {
00151             $this->settings = $session['settings'] + $this->settings;
00152         }
00153 
00154         $this->exportVars();
00155         $this->setupLanguage();
00156 
00157         if ( ( $this->getVar( '_InstallDone' ) || $this->getVar( '_UpgradeDone' ) )
00158             && $this->request->getVal( 'localsettings' )
00159         ) {
00160             $this->request->response()->header( 'Content-type: application/x-httpd-php' );
00161             $this->request->response()->header(
00162                 'Content-Disposition: attachment; filename="LocalSettings.php"'
00163             );
00164 
00165             $ls = InstallerOverrides::getLocalSettingsGenerator( $this );
00166             $rightsProfile = $this->rightsProfiles[$this->getVar( '_RightsProfile' )];
00167             foreach ( $rightsProfile as $group => $rightsArr ) {
00168                 $ls->setGroupRights( $group, $rightsArr );
00169             }
00170             echo $ls->getText();
00171 
00172             return $this->session;
00173         }
00174 
00175         $cssDir = $this->request->getVal( 'css' );
00176         if ( $cssDir ) {
00177             $cssDir = ( $cssDir == 'rtl' ? 'rtl' : 'ltr' );
00178             $this->request->response()->header( 'Content-type: text/css' );
00179             echo $this->output->getCSS( $cssDir );
00180 
00181             return $this->session;
00182         }
00183 
00184         if ( isset( $session['happyPages'] ) ) {
00185             $this->happyPages = $session['happyPages'];
00186         } else {
00187             $this->happyPages = array();
00188         }
00189 
00190         if ( isset( $session['skippedPages'] ) ) {
00191             $this->skippedPages = $session['skippedPages'];
00192         } else {
00193             $this->skippedPages = array();
00194         }
00195 
00196         $lowestUnhappy = $this->getLowestUnhappy();
00197 
00198         # Special case for Creative Commons partner chooser box.
00199         if ( $this->request->getVal( 'SubmitCC' ) ) {
00200             $page = $this->getPageByName( 'Options' );
00201             $this->output->useShortHeader();
00202             $this->output->allowFrames();
00203             $page->submitCC();
00204 
00205             return $this->finish();
00206         }
00207 
00208         if ( $this->request->getVal( 'ShowCC' ) ) {
00209             $page = $this->getPageByName( 'Options' );
00210             $this->output->useShortHeader();
00211             $this->output->allowFrames();
00212             $this->output->addHTML( $page->getCCDoneBox() );
00213 
00214             return $this->finish();
00215         }
00216 
00217         # Get the page name.
00218         $pageName = $this->request->getVal( 'page' );
00219 
00220         if ( in_array( $pageName, $this->otherPages ) ) {
00221             # Out of sequence
00222             $pageId = false;
00223             $page = $this->getPageByName( $pageName );
00224         } else {
00225             # Main sequence
00226             if ( !$pageName || !in_array( $pageName, $this->pageSequence ) ) {
00227                 $pageId = $lowestUnhappy;
00228             } else {
00229                 $pageId = array_search( $pageName, $this->pageSequence );
00230             }
00231 
00232             # If necessary, move back to the lowest-numbered unhappy page
00233             if ( $pageId > $lowestUnhappy ) {
00234                 $pageId = $lowestUnhappy;
00235                 if ( $lowestUnhappy == 0 ) {
00236                     # Knocked back to start, possible loss of session data.
00237                     $this->showSessionWarning = true;
00238                 }
00239             }
00240 
00241             $pageName = $this->pageSequence[$pageId];
00242             $page = $this->getPageByName( $pageName );
00243         }
00244 
00245         # If a back button was submitted, go back without submitting the form data.
00246         if ( $this->request->wasPosted() && $this->request->getBool( 'submit-back' ) ) {
00247             if ( $this->request->getVal( 'lastPage' ) ) {
00248                 $nextPage = $this->request->getVal( 'lastPage' );
00249             } elseif ( $pageId !== false ) {
00250                 # Main sequence page
00251                 # Skip the skipped pages
00252                 $nextPageId = $pageId;
00253 
00254                 do {
00255                     $nextPageId--;
00256                     $nextPage = $this->pageSequence[$nextPageId];
00257                 } while ( isset( $this->skippedPages[$nextPage] ) );
00258             } else {
00259                 $nextPage = $this->pageSequence[$lowestUnhappy];
00260             }
00261 
00262             $this->output->redirect( $this->getUrl( array( 'page' => $nextPage ) ) );
00263 
00264             return $this->finish();
00265         }
00266 
00267         # Execute the page.
00268         $this->currentPageName = $page->getName();
00269         $this->startPageWrapper( $pageName );
00270 
00271         if ( $page->isSlow() ) {
00272             $this->disableTimeLimit();
00273         }
00274 
00275         $result = $page->execute();
00276 
00277         $this->endPageWrapper();
00278 
00279         if ( $result == 'skip' ) {
00280             # Page skipped without explicit submission.
00281             # Skip it when we click "back" so that we don't just go forward again.
00282             $this->skippedPages[$pageName] = true;
00283             $result = 'continue';
00284         } else {
00285             unset( $this->skippedPages[$pageName] );
00286         }
00287 
00288         # If it was posted, the page can request a continue to the next page.
00289         if ( $result === 'continue' && !$this->output->headerDone() ) {
00290             if ( $pageId !== false ) {
00291                 $this->happyPages[$pageId] = true;
00292             }
00293 
00294             $lowestUnhappy = $this->getLowestUnhappy();
00295 
00296             if ( $this->request->getVal( 'lastPage' ) ) {
00297                 $nextPage = $this->request->getVal( 'lastPage' );
00298             } elseif ( $pageId !== false ) {
00299                 $nextPage = $this->pageSequence[$pageId + 1];
00300             } else {
00301                 $nextPage = $this->pageSequence[$lowestUnhappy];
00302             }
00303 
00304             if ( array_search( $nextPage, $this->pageSequence ) > $lowestUnhappy ) {
00305                 $nextPage = $this->pageSequence[$lowestUnhappy];
00306             }
00307 
00308             $this->output->redirect( $this->getUrl( array( 'page' => $nextPage ) ) );
00309         }
00310 
00311         return $this->finish();
00312     }
00313 
00318     public function getLowestUnhappy() {
00319         if ( count( $this->happyPages ) == 0 ) {
00320             return 0;
00321         } else {
00322             return max( array_keys( $this->happyPages ) ) + 1;
00323         }
00324     }
00325 
00331     public function startSession() {
00332         if ( wfIniGetBool( 'session.auto_start' ) || session_id() ) {
00333             // Done already
00334             return true;
00335         }
00336 
00337         $this->phpErrors = array();
00338         set_error_handler( array( $this, 'errorHandler' ) );
00339         session_start();
00340         restore_error_handler();
00341 
00342         if ( $this->phpErrors ) {
00343             $this->showError( 'config-session-error', $this->phpErrors[0] );
00344 
00345             return false;
00346         }
00347 
00348         return true;
00349     }
00350 
00359     public function getFingerprint() {
00360         // Get the base URL of the installation
00361         $url = $this->request->getFullRequestURL();
00362         if ( preg_match( '!^(.*\?)!', $url, $m ) ) {
00363             // Trim query string
00364             $url = $m[1];
00365         }
00366         if ( preg_match( '!^(.*)/[^/]*/[^/]*$!', $url, $m ) ) {
00367             // This... seems to try to get the base path from
00368             // the /mw-config/index.php. Kinda scary though?
00369             $url = $m[1];
00370         }
00371 
00372         return md5( serialize( array(
00373             'local path' => dirname( __DIR__ ),
00374             'url' => $url,
00375             'version' => $GLOBALS['wgVersion']
00376         ) ) );
00377     }
00378 
00383     public function showError( $msg /*...*/ ) {
00384         $args = func_get_args();
00385         array_shift( $args );
00386         $args = array_map( 'htmlspecialchars', $args );
00387         $msg = wfMessage( $msg, $args )->useDatabase( false )->plain();
00388         $this->output->addHTML( $this->getErrorBox( $msg ) );
00389     }
00390 
00396     public function errorHandler( $errno, $errstr ) {
00397         $this->phpErrors[] = $errstr;
00398     }
00399 
00405     public function finish() {
00406         $this->output->output();
00407 
00408         $this->session['happyPages'] = $this->happyPages;
00409         $this->session['skippedPages'] = $this->skippedPages;
00410         $this->session['settings'] = $this->settings;
00411 
00412         return $this->session;
00413     }
00414 
00418     public function reset() {
00419         $this->session = array();
00420         $this->happyPages = array();
00421         $this->settings = array();
00422     }
00423 
00430     public function getUrl( $query = array() ) {
00431         $url = $this->request->getRequestURL();
00432         # Remove existing query
00433         $url = preg_replace( '/\?.*$/', '', $url );
00434 
00435         if ( $query ) {
00436             $url .= '?' . wfArrayToCgi( $query );
00437         }
00438 
00439         return $url;
00440     }
00441 
00448     public function getPageByName( $pageName ) {
00449         $pageClass = 'WebInstaller_' . $pageName;
00450 
00451         return new $pageClass( $this );
00452     }
00453 
00461     public function getSession( $name, $default = null ) {
00462         if ( !isset( $this->session[$name] ) ) {
00463             return $default;
00464         } else {
00465             return $this->session[$name];
00466         }
00467     }
00468 
00474     public function setSession( $name, $value ) {
00475         $this->session[$name] = $value;
00476     }
00477 
00482     public function nextTabIndex() {
00483         return $this->tabIndex++;
00484     }
00485 
00489     public function setupLanguage() {
00490         global $wgLang, $wgContLang, $wgLanguageCode;
00491 
00492         if ( $this->getSession( 'test' ) === null && !$this->request->wasPosted() ) {
00493             $wgLanguageCode = $this->getAcceptLanguage();
00494             $wgLang = $wgContLang = Language::factory( $wgLanguageCode );
00495             $this->setVar( 'wgLanguageCode', $wgLanguageCode );
00496             $this->setVar( '_UserLang', $wgLanguageCode );
00497         } else {
00498             $wgLanguageCode = $this->getVar( 'wgLanguageCode' );
00499             $wgContLang = Language::factory( $wgLanguageCode );
00500         }
00501     }
00502 
00508     public function getAcceptLanguage() {
00509         global $wgLanguageCode, $wgRequest;
00510 
00511         $mwLanguages = Language::fetchLanguageNames();
00512         $headerLanguages = array_keys( $wgRequest->getAcceptLang() );
00513 
00514         foreach ( $headerLanguages as $lang ) {
00515             if ( isset( $mwLanguages[$lang] ) ) {
00516                 return $lang;
00517             }
00518         }
00519 
00520         return $wgLanguageCode;
00521     }
00522 
00528     private function startPageWrapper( $currentPageName ) {
00529         $s = "<div class=\"config-page-wrapper\">\n";
00530         $s .= "<div class=\"config-page\">\n";
00531         $s .= "<div class=\"config-page-list\"><ul>\n";
00532         $lastHappy = -1;
00533 
00534         foreach ( $this->pageSequence as $id => $pageName ) {
00535             $happy = !empty( $this->happyPages[$id] );
00536             $s .= $this->getPageListItem(
00537                 $pageName,
00538                 $happy || $lastHappy == $id - 1,
00539                 $currentPageName
00540             );
00541 
00542             if ( $happy ) {
00543                 $lastHappy = $id;
00544             }
00545         }
00546 
00547         $s .= "</ul><br/><ul>\n";
00548         $s .= $this->getPageListItem( 'Restart', true, $currentPageName );
00549         // End list pane
00550         $s .= "</ul></div>\n";
00551 
00552         // Messages:
00553         // config-page-language, config-page-welcome, config-page-dbconnect, config-page-upgrade,
00554         // config-page-dbsettings, config-page-name, config-page-options, config-page-install,
00555         // config-page-complete, config-page-restart, config-page-readme, config-page-releasenotes,
00556         // config-page-copying, config-page-upgradedoc, config-page-existingwiki
00557         $s .= Html::element( 'h2', array(),
00558             wfMessage( 'config-page-' . strtolower( $currentPageName ) )->text() );
00559 
00560         $this->output->addHTMLNoFlush( $s );
00561     }
00562 
00572     private function getPageListItem( $pageName, $enabled, $currentPageName ) {
00573         $s = "<li class=\"config-page-list-item\">";
00574 
00575         // Messages:
00576         // config-page-language, config-page-welcome, config-page-dbconnect, config-page-upgrade,
00577         // config-page-dbsettings, config-page-name, config-page-options, config-page-install,
00578         // config-page-complete, config-page-restart, config-page-readme, config-page-releasenotes,
00579         // config-page-copying, config-page-upgradedoc, config-page-existingwiki
00580         $name = wfMessage( 'config-page-' . strtolower( $pageName ) )->text();
00581 
00582         if ( $enabled ) {
00583             $query = array( 'page' => $pageName );
00584 
00585             if ( !in_array( $pageName, $this->pageSequence ) ) {
00586                 if ( in_array( $currentPageName, $this->pageSequence ) ) {
00587                     $query['lastPage'] = $currentPageName;
00588                 }
00589 
00590                 $link = Html::element( 'a',
00591                     array(
00592                         'href' => $this->getUrl( $query )
00593                     ),
00594                     $name
00595                 );
00596             } else {
00597                 $link = htmlspecialchars( $name );
00598             }
00599 
00600             if ( $pageName == $currentPageName ) {
00601                 $s .= "<span class=\"config-page-current\">$link</span>";
00602             } else {
00603                 $s .= $link;
00604             }
00605         } else {
00606             $s .= Html::element( 'span',
00607                 array(
00608                     'class' => 'config-page-disabled'
00609                 ),
00610                 $name
00611             );
00612         }
00613 
00614         $s .= "</li>\n";
00615 
00616         return $s;
00617     }
00618 
00622     private function endPageWrapper() {
00623         $this->output->addHTMLNoFlush(
00624             "<div class=\"visualClear\"></div>\n" .
00625             "</div>\n" .
00626             "<div class=\"visualClear\"></div>\n" .
00627             "</div>" );
00628     }
00629 
00637     public function getErrorBox( $text ) {
00638         return $this->getInfoBox( $text, 'critical-32.png', 'config-error-box' );
00639     }
00640 
00648     public function getWarningBox( $text ) {
00649         return $this->getInfoBox( $text, 'warning-32.png', 'config-warning-box' );
00650     }
00651 
00661     public function getInfoBox( $text, $icon = false, $class = false ) {
00662         $text = $this->parse( $text, true );
00663         $icon = ( $icon == false ) ?
00664             '../skins/common/images/info-32.png' :
00665             '../skins/common/images/' . $icon;
00666         $alt = wfMessage( 'config-information' )->text();
00667 
00668         return Html::infoBox( $text, $icon, $alt, $class, false );
00669     }
00670 
00678     public function getHelpBox( $msg /*, ... */ ) {
00679         $args = func_get_args();
00680         array_shift( $args );
00681         $args = array_map( 'htmlspecialchars', $args );
00682         $text = wfMessage( $msg, $args )->useDatabase( false )->plain();
00683         $html = $this->parse( $text, true );
00684 
00685         return "<div class=\"mw-help-field-container\">\n" .
00686             "<span class=\"mw-help-field-hint\">" . wfMessage( 'config-help' )->escaped() .
00687             "</span>\n" .
00688             "<span class=\"mw-help-field-data\">" . $html . "</span>\n" .
00689             "</div>\n";
00690     }
00691 
00696     public function showHelpBox( $msg /*, ... */ ) {
00697         $args = func_get_args();
00698         $html = call_user_func_array( array( $this, 'getHelpBox' ), $args );
00699         $this->output->addHTML( $html );
00700     }
00701 
00708     public function showMessage( $msg /*, ... */ ) {
00709         $args = func_get_args();
00710         array_shift( $args );
00711         $html = '<div class="config-message">' .
00712             $this->parse( wfMessage( $msg, $args )->useDatabase( false )->plain() ) .
00713             "</div>\n";
00714         $this->output->addHTML( $html );
00715     }
00716 
00720     public function showStatusMessage( Status $status ) {
00721         $errors = array_merge( $status->getErrorsArray(), $status->getWarningsArray() );
00722         foreach ( $errors as $error ) {
00723             call_user_func_array( array( $this, 'showMessage' ), $error );
00724         }
00725     }
00726 
00737     public function label( $msg, $forId, $contents, $helpData = "" ) {
00738         if ( strval( $msg ) == '' ) {
00739             $labelText = '&#160;';
00740         } else {
00741             $labelText = wfMessage( $msg )->escaped();
00742         }
00743 
00744         $attributes = array( 'class' => 'config-label' );
00745 
00746         if ( $forId ) {
00747             $attributes['for'] = $forId;
00748         }
00749 
00750         return "<div class=\"config-block\">\n" .
00751             "  <div class=\"config-block-label\">\n" .
00752             Xml::tags( 'label',
00753                 $attributes,
00754                 $labelText
00755             ) . "\n" .
00756             $helpData .
00757             "  </div>\n" .
00758             "  <div class=\"config-block-elements\">\n" .
00759             $contents .
00760             "  </div>\n" .
00761             "</div>\n";
00762     }
00763 
00778     public function getTextBox( $params ) {
00779         if ( !isset( $params['controlName'] ) ) {
00780             $params['controlName'] = 'config_' . $params['var'];
00781         }
00782 
00783         if ( !isset( $params['value'] ) ) {
00784             $params['value'] = $this->getVar( $params['var'] );
00785         }
00786 
00787         if ( !isset( $params['attribs'] ) ) {
00788             $params['attribs'] = array();
00789         }
00790         if ( !isset( $params['help'] ) ) {
00791             $params['help'] = "";
00792         }
00793 
00794         return $this->label(
00795             $params['label'],
00796             $params['controlName'],
00797             Xml::input(
00798                 $params['controlName'],
00799                 30, // intended to be overridden by CSS
00800                 $params['value'],
00801                 $params['attribs'] + array(
00802                     'id' => $params['controlName'],
00803                     'class' => 'config-input-text',
00804                     'tabindex' => $this->nextTabIndex()
00805                 )
00806             ),
00807             $params['help']
00808         );
00809     }
00810 
00825     public function getTextArea( $params ) {
00826         if ( !isset( $params['controlName'] ) ) {
00827             $params['controlName'] = 'config_' . $params['var'];
00828         }
00829 
00830         if ( !isset( $params['value'] ) ) {
00831             $params['value'] = $this->getVar( $params['var'] );
00832         }
00833 
00834         if ( !isset( $params['attribs'] ) ) {
00835             $params['attribs'] = array();
00836         }
00837         if ( !isset( $params['help'] ) ) {
00838             $params['help'] = "";
00839         }
00840 
00841         return $this->label(
00842             $params['label'],
00843             $params['controlName'],
00844             Xml::textarea(
00845                 $params['controlName'],
00846                 $params['value'],
00847                 30,
00848                 5,
00849                 $params['attribs'] + array(
00850                     'id' => $params['controlName'],
00851                     'class' => 'config-input-text',
00852                     'tabindex' => $this->nextTabIndex()
00853                 )
00854             ),
00855             $params['help']
00856         );
00857     }
00858 
00874     public function getPasswordBox( $params ) {
00875         if ( !isset( $params['value'] ) ) {
00876             $params['value'] = $this->getVar( $params['var'] );
00877         }
00878 
00879         if ( !isset( $params['attribs'] ) ) {
00880             $params['attribs'] = array();
00881         }
00882 
00883         $params['value'] = $this->getFakePassword( $params['value'] );
00884         $params['attribs']['type'] = 'password';
00885 
00886         return $this->getTextBox( $params );
00887     }
00888 
00903     public function getCheckBox( $params ) {
00904         if ( !isset( $params['controlName'] ) ) {
00905             $params['controlName'] = 'config_' . $params['var'];
00906         }
00907 
00908         if ( !isset( $params['value'] ) ) {
00909             $params['value'] = $this->getVar( $params['var'] );
00910         }
00911 
00912         if ( !isset( $params['attribs'] ) ) {
00913             $params['attribs'] = array();
00914         }
00915         if ( !isset( $params['help'] ) ) {
00916             $params['help'] = "";
00917         }
00918         if ( isset( $params['rawtext'] ) ) {
00919             $labelText = $params['rawtext'];
00920         } elseif ( isset( $params['label'] ) ) {
00921             $labelText = $this->parse( wfMessage( $params['label'] )->text() );
00922         } else {
00923             $labelText = "";
00924         }
00925 
00926         return "<div class=\"config-input-check\">\n" .
00927             $params['help'] .
00928             "<label>\n" .
00929             Xml::check(
00930                 $params['controlName'],
00931                 $params['value'],
00932                 $params['attribs'] + array(
00933                     'id' => $params['controlName'],
00934                     'tabindex' => $this->nextTabIndex(),
00935                 )
00936             ) .
00937             $labelText . "\n" .
00938             "</label>\n" .
00939             "</div>\n";
00940     }
00941 
00959     public function getRadioSet( $params ) {
00960         if ( !isset( $params['controlName'] ) ) {
00961             $params['controlName'] = 'config_' . $params['var'];
00962         }
00963 
00964         if ( !isset( $params['value'] ) ) {
00965             $params['value'] = $this->getVar( $params['var'] );
00966         }
00967 
00968         if ( !isset( $params['label'] ) ) {
00969             $label = '';
00970         } else {
00971             $label = $params['label'];
00972         }
00973         if ( !isset( $params['help'] ) ) {
00974             $params['help'] = "";
00975         }
00976         $s = "<ul>\n";
00977         foreach ( $params['values'] as $value ) {
00978             $itemAttribs = array();
00979 
00980             if ( isset( $params['commonAttribs'] ) ) {
00981                 $itemAttribs = $params['commonAttribs'];
00982             }
00983 
00984             if ( isset( $params['itemAttribs'][$value] ) ) {
00985                 $itemAttribs = $params['itemAttribs'][$value] + $itemAttribs;
00986             }
00987 
00988             $checked = $value == $params['value'];
00989             $id = $params['controlName'] . '_' . $value;
00990             $itemAttribs['id'] = $id;
00991             $itemAttribs['tabindex'] = $this->nextTabIndex();
00992 
00993             $s .=
00994                 '<li>' .
00995                 Xml::radio( $params['controlName'], $value, $checked, $itemAttribs ) .
00996                 '&#160;' .
00997                 Xml::tags( 'label', array( 'for' => $id ), $this->parse(
00998                     wfMessage( $params['itemLabelPrefix'] . strtolower( $value ) )->plain()
00999                 ) ) .
01000                 "</li>\n";
01001         }
01002 
01003         $s .= "</ul>\n";
01004 
01005         return $this->label( $label, $params['controlName'], $s, $params['help'] );
01006     }
01007 
01013     public function showStatusBox( $status ) {
01014         if ( !$status->isGood() ) {
01015             $text = $status->getWikiText();
01016 
01017             if ( $status->isOk() ) {
01018                 $box = $this->getWarningBox( $text );
01019             } else {
01020                 $box = $this->getErrorBox( $text );
01021             }
01022 
01023             $this->output->addHTML( $box );
01024         }
01025     }
01026 
01037     public function setVarsFromRequest( $varNames, $prefix = 'config_' ) {
01038         $newValues = array();
01039 
01040         foreach ( $varNames as $name ) {
01041             $value = trim( $this->request->getVal( $prefix . $name ) );
01042             $newValues[$name] = $value;
01043 
01044             if ( $value === null ) {
01045                 // Checkbox?
01046                 $this->setVar( $name, false );
01047             } else {
01048                 if ( stripos( $name, 'password' ) !== false ) {
01049                     $this->setPassword( $name, $value );
01050                 } else {
01051                     $this->setVar( $name, $value );
01052                 }
01053             }
01054         }
01055 
01056         return $newValues;
01057     }
01058 
01065     protected function getDocUrl( $page ) {
01066         $url = "{$_SERVER['PHP_SELF']}?page=" . urlencode( $page );
01067 
01068         if ( in_array( $this->currentPageName, $this->pageSequence ) ) {
01069             $url .= '&lastPage=' . urlencode( $this->currentPageName );
01070         }
01071 
01072         return $url;
01073     }
01074 
01083     public function docLink( $linkText, $attribs, $parser ) {
01084         $url = $this->getDocUrl( $attribs['href'] );
01085 
01086         return '<a href="' . htmlspecialchars( $url ) . '">' .
01087             htmlspecialchars( $linkText ) .
01088             '</a>';
01089     }
01090 
01099     public function downloadLinkHook( $text, $attribs, $parser ) {
01100         $img = Html::element( 'img', array(
01101             'src' => '../skins/common/images/download-32.png',
01102             'width' => '32',
01103             'height' => '32',
01104         ) );
01105         $anchor = Html::rawElement( 'a',
01106             array( 'href' => $this->getURL( array( 'localsettings' => 1 ) ) ),
01107             $img . ' ' . wfMessage( 'config-download-localsettings' )->parse() );
01108 
01109         return Html::rawElement( 'div', array( 'class' => 'config-download-link' ), $anchor );
01110     }
01111 
01115     public function envCheckPath() {
01116         // PHP_SELF isn't available sometimes, such as when PHP is CGI but
01117         // cgi.fix_pathinfo is disabled. In that case, fall back to SCRIPT_NAME
01118         // to get the path to the current script... hopefully it's reliable. SIGH
01119         $path = false;
01120         if ( !empty( $_SERVER['PHP_SELF'] ) ) {
01121             $path = $_SERVER['PHP_SELF'];
01122         } elseif ( !empty( $_SERVER['SCRIPT_NAME'] ) ) {
01123             $path = $_SERVER['SCRIPT_NAME'];
01124         }
01125         if ( $path !== false ) {
01126             $uri = preg_replace( '{^(.*)/(mw-)?config.*$}', '$1', $path );
01127             $this->setVar( 'wgScriptPath', $uri );
01128         } else {
01129             $this->showError( 'config-no-uri' );
01130 
01131             return false;
01132         }
01133 
01134         return parent::envCheckPath();
01135     }
01136 
01137     protected function envGetDefaultServer() {
01138         return WebRequest::detectServer();
01139     }
01140 }