Removing trailing whitespace
[lhc/web/wiklou.git] / includes / installer / WebInstaller.php
1 <?php
2 /**
3 * Core installer web interface.
4 *
5 * @file
6 * @ingroup Deployment
7 */
8
9 /**
10 * Class for the core installer web interface.
11 *
12 * @ingroup Deployment
13 * @since 1.17
14 */
15 class WebInstaller extends CoreInstaller {
16
17 /**
18 * @var WebInstallerOutput
19 */
20 public $output;
21
22 /**
23 * WebRequest object.
24 *
25 * @var WebRequest
26 */
27 public $request;
28
29 /**
30 * Cached session array.
31 *
32 * @var array
33 */
34 public $session;
35
36 /**
37 * Captured PHP error text. Temporary.
38 */
39 public $phpErrors;
40
41 /**
42 * The main sequence of page names. These will be displayed in turn.
43 * To add one:
44 * * Add it here
45 * * Add a config-page-<name> message
46 * * Add a WebInstaller_<name> class
47 */
48 public $pageSequence = array(
49 'Language',
50 'ExistingWiki',
51 'Welcome',
52 'DBConnect',
53 'Upgrade',
54 'DBSettings',
55 'Name',
56 'Options',
57 'Install',
58 'Complete',
59 );
60
61 /**
62 * Out of sequence pages, selectable by the user at any time.
63 */
64 public $otherPages = array(
65 'Restart',
66 'Readme',
67 'ReleaseNotes',
68 'Copying',
69 'UpgradeDoc', // Can't use Upgrade due to Upgrade step
70 );
71
72 /**
73 * Array of pages which have declared that they have been submitted, have validated
74 * their input, and need no further processing.
75 */
76 public $happyPages;
77
78 /**
79 * List of "skipped" pages. These are pages that will automatically continue
80 * to the next page on any GET request. To avoid breaking the "back" button,
81 * they need to be skipped during a back operation.
82 */
83 public $skippedPages;
84
85 /**
86 * Flag indicating that session data may have been lost.
87 */
88 public $showSessionWarning = false;
89
90 public $tabIndex = 1;
91
92 public $currentPageName;
93
94 /**
95 * Constructor.
96 *
97 * @param $request WebRequest
98 */
99 public function __construct( WebRequest $request ) {
100 parent::__construct();
101 $this->output = new WebInstallerOutput( $this );
102 $this->request = $request;
103
104 // Add parser hook for WebInstaller_Complete
105 global $wgParser;
106 $wgParser->setHook( 'downloadlink', array( $this, 'downloadLinkHook' ) );
107 }
108
109 /**
110 * Main entry point.
111 *
112 * @param $session Array: initial session array
113 *
114 * @return Array: new session array
115 */
116 public function execute( array $session ) {
117 $this->session = $session;
118
119 if ( isset( $session['settings'] ) ) {
120 $this->settings = $session['settings'] + $this->settings;
121 }
122
123 $this->exportVars();
124 $this->setupLanguage();
125
126 if( ( $this->getVar( '_InstallDone' ) || $this->getVar( '_UpgradeDone' ) )
127 && $this->request->getVal( 'localsettings' ) )
128 {
129 $this->request->response()->header( 'Content-type: application/x-httpd-php' );
130 $this->request->response()->header(
131 'Content-Disposition: attachment; filename="LocalSettings.php"'
132 );
133
134 $ls = new LocalSettingsGenerator( $this );
135 echo $ls->getText();
136 return $this->session;
137 }
138
139 $cssDir = $this->request->getVal( 'css' );
140 if( $cssDir ) {
141 $cssDir = ( $cssDir == 'rtl' ? 'rtl' : 'ltr' );
142 $this->request->response()->header( 'Content-type: text/css' );
143 echo $this->output->getCSS( $cssDir );
144 return $this->session;
145 }
146
147 if ( isset( $session['happyPages'] ) ) {
148 $this->happyPages = $session['happyPages'];
149 } else {
150 $this->happyPages = array();
151 }
152
153 if ( isset( $session['skippedPages'] ) ) {
154 $this->skippedPages = $session['skippedPages'];
155 } else {
156 $this->skippedPages = array();
157 }
158
159 $lowestUnhappy = $this->getLowestUnhappy();
160
161 # Special case for Creative Commons partner chooser box.
162 if ( $this->request->getVal( 'SubmitCC' ) ) {
163 $page = $this->getPageByName( 'Options' );
164 $this->output->useShortHeader();
165 $page->submitCC();
166 return $this->finish();
167 }
168
169 if ( $this->request->getVal( 'ShowCC' ) ) {
170 $page = $this->getPageByName( 'Options' );
171 $this->output->useShortHeader();
172 $this->output->addHTML( $page->getCCDoneBox() );
173 return $this->finish();
174 }
175
176 # Get the page name.
177 $pageName = $this->request->getVal( 'page' );
178
179 if ( in_array( $pageName, $this->otherPages ) ) {
180 # Out of sequence
181 $pageId = false;
182 $page = $this->getPageByName( $pageName );
183 } else {
184 # Main sequence
185 if ( !$pageName || !in_array( $pageName, $this->pageSequence ) ) {
186 $pageId = $lowestUnhappy;
187 } else {
188 $pageId = array_search( $pageName, $this->pageSequence );
189 }
190
191 # If necessary, move back to the lowest-numbered unhappy page
192 if ( $pageId > $lowestUnhappy ) {
193 $pageId = $lowestUnhappy;
194 if ( $lowestUnhappy == 0 ) {
195 # Knocked back to start, possible loss of session data.
196 $this->showSessionWarning = true;
197 }
198 }
199
200 $pageName = $this->pageSequence[$pageId];
201 $page = $this->getPageByName( $pageName );
202 }
203
204 # If a back button was submitted, go back without submitting the form data.
205 if ( $this->request->wasPosted() && $this->request->getBool( 'submit-back' ) ) {
206 if ( $this->request->getVal( 'lastPage' ) ) {
207 $nextPage = $this->request->getVal( 'lastPage' );
208 } elseif ( $pageId !== false ) {
209 # Main sequence page
210 # Skip the skipped pages
211 $nextPageId = $pageId;
212
213 do {
214 $nextPageId--;
215 $nextPage = $this->pageSequence[$nextPageId];
216 } while( isset( $this->skippedPages[$nextPage] ) );
217 } else {
218 $nextPage = $this->pageSequence[$lowestUnhappy];
219 }
220
221 $this->output->redirect( $this->getUrl( array( 'page' => $nextPage ) ) );
222 return $this->finish();
223 }
224
225 # Execute the page.
226 $this->currentPageName = $page->getName();
227 $this->startPageWrapper( $pageName );
228
229 $result = $page->execute();
230
231 $this->endPageWrapper();
232
233 if ( $result == 'skip' ) {
234 # Page skipped without explicit submission.
235 # Skip it when we click "back" so that we don't just go forward again.
236 $this->skippedPages[$pageName] = true;
237 $result = 'continue';
238 } else {
239 unset( $this->skippedPages[$pageName] );
240 }
241
242 # If it was posted, the page can request a continue to the next page.
243 if ( $result === 'continue' && !$this->output->headerDone() ) {
244 if ( $pageId !== false ) {
245 $this->happyPages[$pageId] = true;
246 }
247
248 $lowestUnhappy = $this->getLowestUnhappy();
249
250 if ( $this->request->getVal( 'lastPage' ) ) {
251 $nextPage = $this->request->getVal( 'lastPage' );
252 } elseif ( $pageId !== false ) {
253 $nextPage = $this->pageSequence[$pageId + 1];
254 } else {
255 $nextPage = $this->pageSequence[$lowestUnhappy];
256 }
257
258 if ( array_search( $nextPage, $this->pageSequence ) > $lowestUnhappy ) {
259 $nextPage = $this->pageSequence[$lowestUnhappy];
260 }
261
262 $this->output->redirect( $this->getUrl( array( 'page' => $nextPage ) ) );
263 }
264
265 return $this->finish();
266 }
267
268 public function getLowestUnhappy() {
269 if ( count( $this->happyPages ) == 0 ) {
270 return 0;
271 } else {
272 return max( array_keys( $this->happyPages ) ) + 1;
273 }
274 }
275
276 /**
277 * Start the PHP session. This may be called before execute() to start the PHP session.
278 */
279 public function startSession() {
280 if( wfIniGetBool( 'session.auto_start' ) || session_id() ) {
281 // Done already
282 return true;
283 }
284
285 $this->phpErrors = array();
286 set_error_handler( array( $this, 'errorHandler' ) );
287 session_start();
288 restore_error_handler();
289
290 if ( $this->phpErrors ) {
291 $this->showError( 'config-session-error', $this->phpErrors[0] );
292 return false;
293 }
294
295 return true;
296 }
297
298 /**
299 * Get a hash of data identifying this MW installation.
300 *
301 * This is used by config/index.php to prevent multiple installations of MW
302 * on the same cookie domain from interfering with each other.
303 */
304 public function getFingerprint() {
305 // Get the base URL of the installation
306 $url = $this->request->getFullRequestURL();
307 if ( preg_match( '!^(.*)/[^/]*/[^/]*$!', $url, $m ) ) {
308 $url = $m[1];
309 }
310 return md5( serialize( array(
311 'local path' => dirname( dirname( __FILE__ ) ),
312 'url' => $url,
313 'version' => $GLOBALS['wgVersion']
314 ) ) );
315 }
316
317 /**
318 * Show an error message in a box. Parameters are like wfMsg().
319 */
320 public function showError( $msg /*...*/ ) {
321 $args = func_get_args();
322 array_shift( $args );
323 $args = array_map( 'htmlspecialchars', $args );
324 $msg = wfMsgReal( $msg, $args, false, false, false );
325 $this->output->addHTML( $this->getErrorBox( $msg ) );
326 }
327
328 /**
329 * Temporary error handler for session start debugging.
330 */
331 public function errorHandler( $errno, $errstr ) {
332 $this->phpErrors[] = $errstr;
333 }
334
335 /**
336 * Clean up from execute()
337 *
338 * @return array
339 */
340 public function finish() {
341 $this->output->output();
342
343 $this->session['happyPages'] = $this->happyPages;
344 $this->session['skippedPages'] = $this->skippedPages;
345 $this->session['settings'] = $this->settings;
346
347 return $this->session;
348 }
349
350 /**
351 * Get a URL for submission back to the same script.
352 *
353 * @param $query: Array
354 */
355 public function getUrl( $query = array() ) {
356 $url = $this->request->getRequestURL();
357 # Remove existing query
358 $url = preg_replace( '/\?.*$/', '', $url );
359
360 if ( $query ) {
361 $url .= '?' . wfArrayToCGI( $query );
362 }
363
364 return $url;
365 }
366
367 /**
368 * Get a WebInstallerPage by name.
369 *
370 * @param $pageName String
371 *
372 * @return WebInstallerPage
373 */
374 public function getPageByName( $pageName ) {
375 // Totally lame way to force autoload of WebInstallerPage.php
376 class_exists( 'WebInstallerPage' );
377
378 $pageClass = 'WebInstaller_' . $pageName;
379
380 return new $pageClass( $this );
381 }
382
383 /**
384 * Get a session variable.
385 *
386 * @param $name String
387 * @param $default
388 */
389 public function getSession( $name, $default = null ) {
390 if ( !isset( $this->session[$name] ) ) {
391 return $default;
392 } else {
393 return $this->session[$name];
394 }
395 }
396
397 /**
398 * Set a session variable.
399 */
400 public function setSession( $name, $value ) {
401 $this->session[$name] = $value;
402 }
403
404 /**
405 * Get the next tabindex attribute value.
406 */
407 public function nextTabIndex() {
408 return $this->tabIndex++;
409 }
410
411 /**
412 * Initializes language-related variables.
413 */
414 public function setupLanguage() {
415 global $wgLang, $wgContLang, $wgLanguageCode;
416
417 if ( $this->getSession( 'test' ) === null && !$this->request->wasPosted() ) {
418 $wgLanguageCode = $this->getAcceptLanguage();
419 $wgLang = $wgContLang = Language::factory( $wgLanguageCode );
420 $this->setVar( 'wgLanguageCode', $wgLanguageCode );
421 $this->setVar( '_UserLang', $wgLanguageCode );
422 } else {
423 $wgLanguageCode = $this->getVar( 'wgLanguageCode' );
424 $wgLang = Language::factory( $this->getVar( '_UserLang' ) );
425 $wgContLang = Language::factory( $wgLanguageCode );
426 }
427 }
428
429 /**
430 * Retrieves MediaWiki language from Accept-Language HTTP header.
431 *
432 * @return string
433 */
434 public function getAcceptLanguage() {
435 global $wgLanguageCode, $wgRequest;
436
437 $mwLanguages = Language::getLanguageNames();
438 $headerLanguages = array_keys( $wgRequest->getAcceptLang() );
439
440 foreach ( $headerLanguages as $lang ) {
441 if ( isset( $mwLanguages[$lang] ) ) {
442 return $lang;
443 }
444 }
445
446 return $wgLanguageCode;
447 }
448
449 /**
450 * Called by execute() before page output starts, to show a page list.
451 *
452 * @param $currentPageName String
453 */
454 private function startPageWrapper( $currentPageName ) {
455 $s = "<div class=\"config-page-wrapper\">\n";
456 $s .= "<div class=\"config-page\">\n";
457 $s .= "<div class=\"config-page-list\"><ul>\n";
458 $lastHappy = -1;
459
460 foreach ( $this->pageSequence as $id => $pageName ) {
461 $happy = !empty( $this->happyPages[$id] );
462 $s .= $this->getPageListItem(
463 $pageName,
464 $happy || $lastHappy == $id - 1,
465 $currentPageName
466 );
467
468 if ( $happy ) {
469 $lastHappy = $id;
470 }
471 }
472
473 $s .= "</ul><br/><ul>\n";
474
475 foreach ( $this->otherPages as $pageName ) {
476 $s .= $this->getPageListItem( $pageName, true, $currentPageName );
477 }
478
479 $s .= "</ul></div>\n"; // end list pane
480 $s .= Html::element( 'h2', array(),
481 wfMsg( 'config-page-' . strtolower( $currentPageName ) ) );
482
483 $this->output->addHTMLNoFlush( $s );
484 }
485
486 /**
487 * Get a list item for the page list.
488 *
489 * @param $pageName String
490 * @param $enabled Boolean
491 * @param $currentPageName String
492 *
493 * @return string
494 */
495 private function getPageListItem( $pageName, $enabled, $currentPageName ) {
496 $s = "<li class=\"config-page-list-item\">";
497 $name = wfMsg( 'config-page-' . strtolower( $pageName ) );
498
499 if ( $enabled ) {
500 $query = array( 'page' => $pageName );
501
502 if ( !in_array( $pageName, $this->pageSequence ) ) {
503 if ( in_array( $currentPageName, $this->pageSequence ) ) {
504 $query['lastPage'] = $currentPageName;
505 }
506
507 $link = Html::element( 'a',
508 array(
509 'href' => $this->getUrl( $query )
510 ),
511 $name
512 );
513 } else {
514 $link = htmlspecialchars( $name );
515 }
516
517 if ( $pageName == $currentPageName ) {
518 $s .= "<span class=\"config-page-current\">$link</span>";
519 } else {
520 $s .= $link;
521 }
522 } else {
523 $s .= Html::element( 'span',
524 array(
525 'class' => 'config-page-disabled'
526 ),
527 $name
528 );
529 }
530
531 $s .= "</li>\n";
532
533 return $s;
534 }
535
536 /**
537 * Output some stuff after a page is finished.
538 */
539 private function endPageWrapper() {
540 $this->output->addHTMLNoFlush(
541 "</div>\n" .
542 "<br style=\"clear:both\"/>\n" .
543 "</div>" );
544 }
545
546 /**
547 * Get HTML for an error box with an icon.
548 *
549 * @param $text String: wikitext, get this with wfMsgNoTrans()
550 */
551 public function getErrorBox( $text ) {
552 return $this->getInfoBox( $text, 'critical-32.png', 'config-error-box' );
553 }
554
555 /**
556 * Get HTML for a warning box with an icon.
557 *
558 * @param $text String: wikitext, get this with wfMsgNoTrans()
559 */
560 public function getWarningBox( $text ) {
561 return $this->getInfoBox( $text, 'warning-32.png', 'config-warning-box' );
562 }
563
564 /**
565 * Get HTML for an info box with an icon.
566 *
567 * @param $text String: wikitext, get this with wfMsgNoTrans()
568 * @param $icon String: icon name, file in skins/common/images
569 * @param $class String: additional class name to add to the wrapper div
570 */
571 public function getInfoBox( $text, $icon = 'info-32.png', $class = false ) {
572 $s =
573 "<div class=\"config-info $class\">\n" .
574 "<div class=\"config-info-left\">\n" .
575 Html::element( 'img',
576 array(
577 'src' => '../skins/common/images/' . $icon,
578 'alt' => wfMsg( 'config-information' ),
579 )
580 ) . "\n" .
581 "</div>\n" .
582 "<div class=\"config-info-right\">\n" .
583 $this->parse( $text, true ) . "\n" .
584 "</div>\n" .
585 "<div style=\"clear: left;\"></div>\n" .
586 "</div>\n";
587 return $s;
588 }
589
590 /**
591 * Get small text indented help for a preceding form field.
592 * Parameters like wfMsg().
593 */
594 public function getHelpBox( $msg /*, ... */ ) {
595 $args = func_get_args();
596 array_shift( $args );
597 $args = array_map( 'htmlspecialchars', $args );
598 $text = wfMsgReal( $msg, $args, false, false, false );
599 $html = htmlspecialchars( $text );
600 $html = $this->parse( $text, true );
601
602 return "<div class=\"mw-help-field-container\">\n" .
603 "<span class=\"mw-help-field-hint\">" . wfMsgHtml( 'config-help' ) . "</span>\n" .
604 "<span class=\"mw-help-field-data\">" . $html . "</span>\n" .
605 "</div>\n";
606 }
607
608 /**
609 * Output a help box.
610 */
611 public function showHelpBox( $msg /*, ... */ ) {
612 $args = func_get_args();
613 $html = call_user_func_array( array( $this, 'getHelpBox' ), $args );
614 $this->output->addHTML( $html );
615 }
616
617 /**
618 * Show a short informational message.
619 * Output looks like a list.
620 *
621 * @param $msg string
622 */
623 public function showMessage( $msg /*, ... */ ) {
624 $args = func_get_args();
625 array_shift( $args );
626 $html = '<div class="config-message">' .
627 $this->parse( wfMsgReal( $msg, $args, false, false, false ) ) .
628 "</div>\n";
629 $this->output->addHTML( $html );
630 }
631
632 /**
633 * @param $status Status
634 */
635 public function showStatusMessage( Status $status ) {
636 $text = $status->getWikiText();
637 $this->output->addWikiText(
638 "<div class=\"config-message\">\n" .
639 $text .
640 "</div>"
641 );
642 }
643
644 /**
645 * Label a control by wrapping a config-input div around it and putting a
646 * label before it.
647 */
648 public function label( $msg, $forId, $contents, $helpData = "" ) {
649 if ( strval( $msg ) == '' ) {
650 $labelText = '&#160;';
651 } else {
652 $labelText = wfMsgHtml( $msg );
653 }
654
655 $attributes = array( 'class' => 'config-label' );
656
657 if ( $forId ) {
658 $attributes['for'] = $forId;
659 }
660
661 return
662 "<div class=\"config-block\">\n" .
663 " <div class=\"config-block-label\">\n" .
664 Xml::tags( 'label',
665 $attributes,
666 $labelText ) . "\n" .
667 $helpData .
668 " </div>\n" .
669 " <div class=\"config-block-elements\">\n" .
670 $contents .
671 " </div>\n" .
672 "</div>\n";
673 }
674
675 /**
676 * Get a labelled text box to configure a variable.
677 *
678 * @param $params Array
679 * Parameters are:
680 * var: The variable to be configured (required)
681 * label: The message name for the label (required)
682 * attribs: Additional attributes for the input element (optional)
683 * controlName: The name for the input element (optional)
684 * value: The current value of the variable (optional)
685 * help: The html for the help text (optional)
686 */
687 public function getTextBox( $params ) {
688 if ( !isset( $params['controlName'] ) ) {
689 $params['controlName'] = 'config_' . $params['var'];
690 }
691
692 if ( !isset( $params['value'] ) ) {
693 $params['value'] = $this->getVar( $params['var'] );
694 }
695
696 if ( !isset( $params['attribs'] ) ) {
697 $params['attribs'] = array();
698 }
699 if ( !isset( $params['help'] ) ) {
700 $params['help'] = "";
701 }
702 return
703 $this->label(
704 $params['label'],
705 $params['controlName'],
706 Xml::input(
707 $params['controlName'],
708 30, // intended to be overridden by CSS
709 $params['value'],
710 $params['attribs'] + array(
711 'id' => $params['controlName'],
712 'class' => 'config-input-text',
713 'tabindex' => $this->nextTabIndex()
714 )
715 ),
716 $params['help']
717 );
718 }
719
720 /**
721 * Get a labelled password box to configure a variable.
722 *
723 * Implements password hiding
724 * @param $params Array
725 * Parameters are:
726 * var: The variable to be configured (required)
727 * label: The message name for the label (required)
728 * attribs: Additional attributes for the input element (optional)
729 * controlName: The name for the input element (optional)
730 * value: The current value of the variable (optional)
731 * help: The html for the help text (optional)
732 */
733 public function getPasswordBox( $params ) {
734 if ( !isset( $params['value'] ) ) {
735 $params['value'] = $this->getVar( $params['var'] );
736 }
737
738 if ( !isset( $params['attribs'] ) ) {
739 $params['attribs'] = array();
740 }
741
742 $params['value'] = $this->getFakePassword( $params['value'] );
743 $params['attribs']['type'] = 'password';
744
745 return $this->getTextBox( $params );
746 }
747
748 /**
749 * Get a labelled checkbox to configure a boolean variable.
750 *
751 * @param $params Array
752 * Parameters are:
753 * var: The variable to be configured (required)
754 * label: The message name for the label (required)
755 * attribs: Additional attributes for the input element (optional)
756 * controlName: The name for the input element (optional)
757 * value: The current value of the variable (optional)
758 * help: The html for the help text (optional)
759 */
760 public function getCheckBox( $params ) {
761 if ( !isset( $params['controlName'] ) ) {
762 $params['controlName'] = 'config_' . $params['var'];
763 }
764
765 if ( !isset( $params['value'] ) ) {
766 $params['value'] = $this->getVar( $params['var'] );
767 }
768
769 if ( !isset( $params['attribs'] ) ) {
770 $params['attribs'] = array();
771 }
772 if ( !isset( $params['help'] ) ) {
773 $params['help'] = "";
774 }
775 if( isset( $params['rawtext'] ) ) {
776 $labelText = $params['rawtext'];
777 } else {
778 $labelText = $this->parse( wfMsg( $params['label'] ) );
779 }
780
781 return
782 "<div class=\"config-input-check\">\n" .
783 $params['help'] .
784 "<label>\n" .
785 Xml::check(
786 $params['controlName'],
787 $params['value'],
788 $params['attribs'] + array(
789 'id' => $params['controlName'],
790 'tabindex' => $this->nextTabIndex(),
791 )
792 ) .
793 $labelText . "\n" .
794 "</label>\n" .
795 "</div>\n";
796 }
797
798 /**
799 * Get a set of labelled radio buttons.
800 *
801 * @param $params Array
802 * Parameters are:
803 * var: The variable to be configured (required)
804 * label: The message name for the label (required)
805 * itemLabelPrefix: The message name prefix for the item labels (required)
806 * values: List of allowed values (required)
807 * itemAttribs Array of attribute arrays, outer key is the value name (optional)
808 * commonAttribs Attribute array applied to all items
809 * controlName: The name for the input element (optional)
810 * value: The current value of the variable (optional)
811 * help: The html for the help text (optional)
812 */
813 public function getRadioSet( $params ) {
814 if ( !isset( $params['controlName'] ) ) {
815 $params['controlName'] = 'config_' . $params['var'];
816 }
817
818 if ( !isset( $params['value'] ) ) {
819 $params['value'] = $this->getVar( $params['var'] );
820 }
821
822 if ( !isset( $params['label'] ) ) {
823 $label = '';
824 } else {
825 $label = $params['label'];
826 }
827 if ( !isset( $params['help'] ) ) {
828 $params['help'] = "";
829 }
830 $s = "<ul>\n";
831 foreach ( $params['values'] as $value ) {
832 $itemAttribs = array();
833
834 if ( isset( $params['commonAttribs'] ) ) {
835 $itemAttribs = $params['commonAttribs'];
836 }
837
838 if ( isset( $params['itemAttribs'][$value] ) ) {
839 $itemAttribs = $params['itemAttribs'][$value] + $itemAttribs;
840 }
841
842 $checked = $value == $params['value'];
843 $id = $params['controlName'] . '_' . $value;
844 $itemAttribs['id'] = $id;
845 $itemAttribs['tabindex'] = $this->nextTabIndex();
846
847 $s .=
848 '<li>' .
849 Xml::radio( $params['controlName'], $value, $checked, $itemAttribs ) .
850 '&#160;' .
851 Xml::tags( 'label', array( 'for' => $id ), $this->parse(
852 wfMsgNoTrans( $params['itemLabelPrefix'] . strtolower( $value ) )
853 ) ) .
854 "</li>\n";
855 }
856
857 $s .= "</ul>\n";
858
859 return $this->label( $label, $params['controlName'], $s, $params['help'] );
860 }
861
862 /**
863 * Output an error or warning box using a Status object.
864 */
865 public function showStatusBox( $status ) {
866 if( !$status->isGood() ) {
867 $text = $status->getWikiText();
868
869 if( $status->isOk() ) {
870 $box = $this->getWarningBox( $text );
871 } else {
872 $box = $this->getErrorBox( $text );
873 }
874
875 $this->output->addHTML( $box );
876 }
877 }
878
879 /**
880 * Convenience function to set variables based on form data.
881 * Assumes that variables containing "password" in the name are (potentially
882 * fake) passwords.
883 *
884 * @param $varNames Array
885 * @param $prefix String: the prefix added to variables to obtain form names
886 */
887 public function setVarsFromRequest( $varNames, $prefix = 'config_' ) {
888 $newValues = array();
889
890 foreach ( $varNames as $name ) {
891 $value = trim( $this->request->getVal( $prefix . $name ) );
892 $newValues[$name] = $value;
893
894 if ( $value === null ) {
895 // Checkbox?
896 $this->setVar( $name, false );
897 } else {
898 if ( stripos( $name, 'password' ) !== false ) {
899 $this->setPassword( $name, $value );
900 } else {
901 $this->setVar( $name, $value );
902 }
903 }
904 }
905
906 return $newValues;
907 }
908
909 /**
910 * Helper for Installer::docLink()
911 */
912 protected function getDocUrl( $page ) {
913 $url = "{$_SERVER['PHP_SELF']}?page=" . urlencode( $page );
914
915 if ( in_array( $this->currentPageName, $this->pageSequence ) ) {
916 $url .= '&lastPage=' . urlencode( $this->currentPageName );
917 }
918
919 return $url;
920 }
921
922 public function downloadLinkHook( $text, $attribs, $parser ) {
923 $img = Html::element( 'img', array(
924 'src' => '../skins/common/images/download-32.png',
925 'width' => '32',
926 'height' => '32',
927 ) );
928 $anchor = Html::rawElement( 'a',
929 array( 'href' => $this->getURL( array( 'localsettings' => 1 ) ) ),
930 $img . ' ' . wfMsgHtml( 'config-download-localsettings' ) );
931 return Html::rawElement( 'div', array( 'class' => 'config-download-link' ), $anchor );
932 }
933 }