MediaWiki  1.23.6
WebInstallerPage.php
Go to the documentation of this file.
1 <?php
30 abstract class WebInstallerPage {
31 
37  public $parent;
38 
42  abstract public function execute();
43 
47  public function __construct( WebInstaller $parent ) {
48  $this->parent = $parent;
49  }
50 
58  public function isSlow() {
59  return false;
60  }
61 
65  public function addHTML( $html ) {
66  $this->parent->output->addHTML( $html );
67  }
68 
69  public function startForm() {
70  $this->addHTML(
71  "<div class=\"config-section\">\n" .
73  'form',
74  array(
75  'method' => 'post',
76  'action' => $this->parent->getUrl( array( 'page' => $this->getName() ) )
77  )
78  ) . "\n"
79  );
80  }
81 
86  public function endForm( $continue = 'continue', $back = 'back' ) {
87  $s = "<div class=\"config-submit\">\n";
88  $id = $this->getId();
89 
90  if ( $id === false ) {
91  $s .= Html::hidden( 'lastPage', $this->parent->request->getVal( 'lastPage' ) );
92  }
93 
94  if ( $continue ) {
95  // Fake submit button for enter keypress (bug 26267)
96  // Messages: config-continue, config-restart, config-regenerate
98  wfMessage( "config-$continue" )->text(),
99  array(
100  'name' => "enter-$continue",
101  'style' => 'visibility:hidden;overflow:hidden;width:1px;margin:0'
102  )
103  ) . "\n";
104  }
105 
106  if ( $back ) {
107  // Message: config-back
109  wfMessage( "config-$back" )->text(),
110  array(
111  'name' => "submit-$back",
112  'tabindex' => $this->parent->nextTabIndex()
113  )
114  ) . "\n";
115  }
116 
117  if ( $continue ) {
118  // Messages: config-continue, config-restart, config-regenerate
120  wfMessage( "config-$continue" )->text(),
121  array(
122  'name' => "submit-$continue",
123  'tabindex' => $this->parent->nextTabIndex(),
124  )
125  ) . "\n";
126  }
127 
128  $s .= "</div></form></div>\n";
129  $this->addHTML( $s );
130  }
131 
135  public function getName() {
136  return str_replace( 'WebInstaller_', '', get_class( $this ) );
137  }
138 
142  protected function getId() {
143  return array_search( $this->getName(), $this->parent->pageSequence );
144  }
145 
151  public function getVar( $var ) {
152  return $this->parent->getVar( $var );
153  }
154 
159  public function setVar( $name, $value ) {
160  $this->parent->setVar( $name, $value );
161  }
162 
170  protected function getFieldsetStart( $legend ) {
171  return "\n<fieldset><legend>" . wfMessage( $legend )->escaped() . "</legend>\n";
172  }
173 
179  protected function getFieldsetEnd() {
180  return "</fieldset>\n";
181  }
182 
186  protected function startLiveBox() {
187  $this->addHTML(
188  '<div id="config-spinner" style="display:none;">' .
189  '<img src="../skins/common/images/ajax-loader.gif" /></div>' .
190  '<script>jQuery( "#config-spinner" ).show();</script>' .
191  '<div id="config-live-log">' .
192  '<textarea name="LiveLog" rows="10" cols="30" readonly="readonly">'
193  );
194  $this->parent->output->flush();
195  }
196 
200  protected function endLiveBox() {
201  $this->addHTML( '</textarea></div>
202 <script>jQuery( "#config-spinner" ).hide()</script>' );
203  $this->parent->output->flush();
204  }
205 
206 }
207 
208 class WebInstaller_Language extends WebInstallerPage {
209 
213  public function execute() {
214  global $wgLang;
215  $r = $this->parent->request;
216  $userLang = $r->getVal( 'uselang' );
217  $contLang = $r->getVal( 'ContLang' );
218 
220  $lifetime = intval( ini_get( 'session.gc_maxlifetime' ) );
221  if ( !$lifetime ) {
222  $lifetime = 1440; // PHP default
223  }
224 
225  if ( $r->wasPosted() ) {
226  # Do session test
227  if ( $this->parent->getSession( 'test' ) === null ) {
228  $requestTime = $r->getVal( 'LanguageRequestTime' );
229  if ( !$requestTime ) {
230  // The most likely explanation is that the user was knocked back
231  // from another page on POST due to session expiry
232  $msg = 'config-session-expired';
233  } elseif ( time() - $requestTime > $lifetime ) {
234  $msg = 'config-session-expired';
235  } else {
236  $msg = 'config-no-session';
237  }
238  $this->parent->showError( $msg, $wgLang->formatTimePeriod( $lifetime ) );
239  } else {
240  if ( isset( $languages[$userLang] ) ) {
241  $this->setVar( '_UserLang', $userLang );
242  }
243  if ( isset( $languages[$contLang] ) ) {
244  $this->setVar( 'wgLanguageCode', $contLang );
245  }
246 
247  return 'continue';
248  }
249  } elseif ( $this->parent->showSessionWarning ) {
250  # The user was knocked back from another page to the start
251  # This probably indicates a session expiry
252  $this->parent->showError( 'config-session-expired',
253  $wgLang->formatTimePeriod( $lifetime ) );
254  }
255 
256  $this->parent->setSession( 'test', true );
257 
258  if ( !isset( $languages[$userLang] ) ) {
259  $userLang = $this->getVar( '_UserLang', 'en' );
260  }
261  if ( !isset( $languages[$contLang] ) ) {
262  $contLang = $this->getVar( 'wgLanguageCode', 'en' );
263  }
264  $this->startForm();
265  $s = Html::hidden( 'LanguageRequestTime', time() ) .
266  $this->getLanguageSelector( 'uselang', 'config-your-language', $userLang,
267  $this->parent->getHelpBox( 'config-your-language-help' ) ) .
268  $this->getLanguageSelector( 'ContLang', 'config-wiki-language', $contLang,
269  $this->parent->getHelpBox( 'config-wiki-language-help' ) );
270  $this->addHTML( $s );
271  $this->endForm( 'continue', false );
272 
273  return null;
274  }
275 
286  public function getLanguageSelector( $name, $label, $selectedCode, $helpHtml = '' ) {
287  global $wgDummyLanguageCodes;
288 
289  $s = $helpHtml;
290 
291  $s .= Html::openElement( 'select', array( 'id' => $name, 'name' => $name,
292  'tabindex' => $this->parent->nextTabIndex() ) ) . "\n";
293 
295  ksort( $languages );
296  foreach ( $languages as $code => $lang ) {
297  if ( isset( $wgDummyLanguageCodes[$code] ) ) {
298  continue;
299  }
300  $s .= "\n" . Xml::option( "$code - $lang", $code, $code == $selectedCode );
301  }
302  $s .= "\n</select>\n";
303 
304  return $this->parent->label( $label, $name, $s );
305  }
306 
307 }
308 
309 class WebInstaller_ExistingWiki extends WebInstallerPage {
310 
314  public function execute() {
315  // If there is no LocalSettings.php, continue to the installer welcome page
317  if ( !$vars ) {
318  return 'skip';
319  }
320 
321  // Check if the upgrade key supplied to the user has appeared in LocalSettings.php
322  if ( $vars['wgUpgradeKey'] !== false
323  && $this->getVar( '_UpgradeKeySupplied' )
324  && $this->getVar( 'wgUpgradeKey' ) === $vars['wgUpgradeKey']
325  ) {
326  // It's there, so the user is authorized
327  $status = $this->handleExistingUpgrade( $vars );
328  if ( $status->isOK() ) {
329  return 'skip';
330  } else {
331  $this->startForm();
332  $this->parent->showStatusBox( $status );
333  $this->endForm( 'continue' );
334 
335  return 'output';
336  }
337  }
338 
339  // If there is no $wgUpgradeKey, tell the user to add one to LocalSettings.php
340  if ( $vars['wgUpgradeKey'] === false ) {
341  if ( $this->getVar( 'wgUpgradeKey', false ) === false ) {
342  $secretKey = $this->getVar( 'wgSecretKey' ); // preserve $wgSecretKey
343  $this->parent->generateKeys();
344  $this->setVar( 'wgSecretKey', $secretKey );
345  $this->setVar( '_UpgradeKeySupplied', true );
346  }
347  $this->startForm();
348  $this->addHTML( $this->parent->getInfoBox(
349  wfMessage( 'config-upgrade-key-missing', "<pre dir=\"ltr\">\$wgUpgradeKey = '" .
350  $this->getVar( 'wgUpgradeKey' ) . "';</pre>" )->plain()
351  ) );
352  $this->endForm( 'continue' );
353 
354  return 'output';
355  }
356 
357  // If there is an upgrade key, but it wasn't supplied, prompt the user to enter it
358 
359  $r = $this->parent->request;
360  if ( $r->wasPosted() ) {
361  $key = $r->getText( 'config_wgUpgradeKey' );
362  if ( !$key || $key !== $vars['wgUpgradeKey'] ) {
363  $this->parent->showError( 'config-localsettings-badkey' );
364  $this->showKeyForm();
365 
366  return 'output';
367  }
368  // Key was OK
369  $status = $this->handleExistingUpgrade( $vars );
370  if ( $status->isOK() ) {
371  return 'continue';
372  } else {
373  $this->parent->showStatusBox( $status );
374  $this->showKeyForm();
375 
376  return 'output';
377  }
378  } else {
379  $this->showKeyForm();
380 
381  return 'output';
382  }
383  }
384 
388  protected function showKeyForm() {
389  $this->startForm();
390  $this->addHTML(
391  $this->parent->getInfoBox( wfMessage( 'config-localsettings-upgrade' )->plain() ) .
392  '<br />' .
393  $this->parent->getTextBox( array(
394  'var' => 'wgUpgradeKey',
395  'label' => 'config-localsettings-key',
396  'attribs' => array( 'autocomplete' => 'off' ),
397  ) )
398  );
399  $this->endForm( 'continue' );
400  }
401 
408  protected function importVariables( $names, $vars ) {
409  $status = Status::newGood();
410  foreach ( $names as $name ) {
411  if ( !isset( $vars[$name] ) ) {
412  $status->fatal( 'config-localsettings-incomplete', $name );
413  }
414  $this->setVar( $name, $vars[$name] );
415  }
416 
417  return $status;
418  }
419 
427  protected function handleExistingUpgrade( $vars ) {
428  // Check $wgDBtype
429  if ( !isset( $vars['wgDBtype'] ) ||
430  !in_array( $vars['wgDBtype'], Installer::getDBTypes() )
431  ) {
432  return Status::newFatal( 'config-localsettings-connection-error', '' );
433  }
434 
435  // Set the relevant variables from LocalSettings.php
436  $requiredVars = array( 'wgDBtype' );
437  $status = $this->importVariables( $requiredVars, $vars );
438  $installer = $this->parent->getDBInstaller();
439  $status->merge( $this->importVariables( $installer->getGlobalNames(), $vars ) );
440  if ( !$status->isOK() ) {
441  return $status;
442  }
443 
444  if ( isset( $vars['wgDBadminuser'] ) ) {
445  $this->setVar( '_InstallUser', $vars['wgDBadminuser'] );
446  } else {
447  $this->setVar( '_InstallUser', $vars['wgDBuser'] );
448  }
449  if ( isset( $vars['wgDBadminpassword'] ) ) {
450  $this->setVar( '_InstallPassword', $vars['wgDBadminpassword'] );
451  } else {
452  $this->setVar( '_InstallPassword', $vars['wgDBpassword'] );
453  }
454 
455  // Test the database connection
456  $status = $installer->getConnection();
457  if ( !$status->isOK() ) {
458  // Adjust the error message to explain things correctly
459  $status->replaceMessage( 'config-connection-error',
460  'config-localsettings-connection-error' );
461 
462  return $status;
463  }
464 
465  // All good
466  $this->setVar( '_ExistingDBSettings', true );
467 
468  return $status;
469  }
470 
471 }
472 
473 class WebInstaller_Welcome extends WebInstallerPage {
474 
478  public function execute() {
479  if ( $this->parent->request->wasPosted() ) {
480  if ( $this->getVar( '_Environment' ) ) {
481  return 'continue';
482  }
483  }
484  $this->parent->output->addWikiText( wfMessage( 'config-welcome' )->plain() );
485  $status = $this->parent->doEnvironmentChecks();
486  if ( $status->isGood() ) {
487  $this->parent->output->addHTML( '<span class="success-message">' .
488  wfMessage( 'config-env-good' )->escaped() . '</span>' );
489  $this->parent->output->addWikiText( wfMessage( 'config-copyright',
491  $this->startForm();
492  $this->endForm();
493  } else {
494  $this->parent->showStatusMessage( $status );
495  }
496 
497  return '';
498  }
499 
500 }
501 
502 class WebInstaller_DBConnect extends WebInstallerPage {
503 
507  public function execute() {
508  if ( $this->getVar( '_ExistingDBSettings' ) ) {
509  return 'skip';
510  }
511 
512  $r = $this->parent->request;
513  if ( $r->wasPosted() ) {
514  $status = $this->submit();
515 
516  if ( $status->isGood() ) {
517  $this->setVar( '_UpgradeDone', false );
518 
519  return 'continue';
520  } else {
521  $this->parent->showStatusBox( $status );
522  }
523  }
524 
525  $this->startForm();
526 
527  $types = "<ul class=\"config-settings-block\">\n";
528  $settings = '';
529  $defaultType = $this->getVar( 'wgDBtype' );
530 
531  // Messages: config-dbsupport-mysql, config-dbsupport-postgres, config-dbsupport-oracle,
532  // config-dbsupport-sqlite, config-dbsupport-mssql
533  $dbSupport = '';
534  foreach ( Installer::getDBTypes() as $type ) {
535  $dbSupport .= wfMessage( "config-dbsupport-$type" )->plain() . "\n";
536  }
537  $this->addHTML( $this->parent->getInfoBox(
538  wfMessage( 'config-support-info', trim( $dbSupport ) )->text() ) );
539 
540  // It's possible that the library for the default DB type is not compiled in.
541  // In that case, instead select the first supported DB type in the list.
542  $compiledDBs = $this->parent->getCompiledDBs();
543  if ( !in_array( $defaultType, $compiledDBs ) ) {
544  $defaultType = $compiledDBs[0];
545  }
546 
547  foreach ( $compiledDBs as $type ) {
548  $installer = $this->parent->getDBInstaller( $type );
549  $types .=
550  '<li>' .
552  $installer->getReadableName(),
553  'DBType',
554  $type,
555  "DBType_$type",
556  $type == $defaultType,
557  array( 'class' => 'dbRadio', 'rel' => "DB_wrapper_$type" )
558  ) .
559  "</li>\n";
560 
561  // Messages: config-header-mysql, config-header-postgres, config-header-oracle,
562  // config-header-sqlite
563  $settings .= Html::openElement(
564  'div',
565  array(
566  'id' => 'DB_wrapper_' . $type,
567  'class' => 'dbWrapper'
568  )
569  ) .
570  Html::element( 'h3', array(), wfMessage( 'config-header-' . $type )->text() ) .
571  $installer->getConnectForm() .
572  "</div>\n";
573  }
574 
575  $types .= "</ul><br style=\"clear: left\"/>\n";
576 
577  $this->addHTML( $this->parent->label( 'config-db-type', false, $types ) . $settings );
578  $this->endForm();
579 
580  return null;
581  }
582 
586  public function submit() {
587  $r = $this->parent->request;
588  $type = $r->getVal( 'DBType' );
589  if ( !$type ) {
590  return Status::newFatal( 'config-invalid-db-type' );
591  }
592  $this->setVar( 'wgDBtype', $type );
593  $installer = $this->parent->getDBInstaller( $type );
594  if ( !$installer ) {
595  return Status::newFatal( 'config-invalid-db-type' );
596  }
597 
598  return $installer->submitConnectForm();
599  }
600 
601 }
602 
603 class WebInstaller_Upgrade extends WebInstallerPage {
604 
608  public function isSlow() {
609  return true;
610  }
611 
615  public function execute() {
616  if ( $this->getVar( '_UpgradeDone' ) ) {
617  // Allow regeneration of LocalSettings.php, unless we are working
618  // from a pre-existing LocalSettings.php file and we want to avoid
619  // leaking its contents
620  if ( $this->parent->request->wasPosted() && !$this->getVar( '_ExistingDBSettings' ) ) {
621  // Done message acknowledged
622  return 'continue';
623  } else {
624  // Back button click
625  // Show the done message again
626  // Make them click back again if they want to do the upgrade again
627  $this->showDoneMessage();
628 
629  return 'output';
630  }
631  }
632 
633  // wgDBtype is generally valid here because otherwise the previous page
634  // (connect) wouldn't have declared its happiness
635  $type = $this->getVar( 'wgDBtype' );
636  $installer = $this->parent->getDBInstaller( $type );
637 
638  if ( !$installer->needsUpgrade() ) {
639  return 'skip';
640  }
641 
642  if ( $this->parent->request->wasPosted() ) {
643  $installer->preUpgrade();
644 
645  $this->startLiveBox();
646  $result = $installer->doUpgrade();
647  $this->endLiveBox();
648 
649  if ( $result ) {
650  // If they're going to possibly regenerate LocalSettings, we
651  // need to create the upgrade/secret keys. Bug 26481
652  if ( !$this->getVar( '_ExistingDBSettings' ) ) {
653  $this->parent->generateKeys();
654  }
655  $this->setVar( '_UpgradeDone', true );
656  $this->showDoneMessage();
657 
658  return 'output';
659  }
660  }
661 
662  $this->startForm();
663  $this->addHTML( $this->parent->getInfoBox(
664  wfMessage( 'config-can-upgrade', $GLOBALS['wgVersion'] )->plain() ) );
665  $this->endForm();
666 
667  return null;
668  }
669 
670  public function showDoneMessage() {
671  $this->startForm();
672  $regenerate = !$this->getVar( '_ExistingDBSettings' );
673  if ( $regenerate ) {
674  $msg = 'config-upgrade-done';
675  } else {
676  $msg = 'config-upgrade-done-no-regenerate';
677  }
678  $this->parent->disableLinkPopups();
679  $this->addHTML(
680  $this->parent->getInfoBox(
681  wfMessage( $msg,
682  $this->getVar( 'wgServer' ) .
683  $this->getVar( 'wgScriptPath' ) . '/index' .
684  $this->getVar( 'wgScriptExtension' )
685  )->plain(), 'tick-32.png'
686  )
687  );
688  $this->parent->restoreLinkPopups();
689  $this->endForm( $regenerate ? 'regenerate' : false, false );
690  }
691 
692 }
693 
694 class WebInstaller_DBSettings extends WebInstallerPage {
695 
699  public function execute() {
700  $installer = $this->parent->getDBInstaller( $this->getVar( 'wgDBtype' ) );
701 
702  $r = $this->parent->request;
703  if ( $r->wasPosted() ) {
704  $status = $installer->submitSettingsForm();
705  if ( $status === false ) {
706  return 'skip';
707  } elseif ( $status->isGood() ) {
708  return 'continue';
709  } else {
710  $this->parent->showStatusBox( $status );
711  }
712  }
713 
714  $form = $installer->getSettingsForm();
715  if ( $form === false ) {
716  return 'skip';
717  }
718 
719  $this->startForm();
720  $this->addHTML( $form );
721  $this->endForm();
722 
723  return null;
724  }
725 
726 }
727 
728 class WebInstaller_Name extends WebInstallerPage {
729 
733  public function execute() {
734  $r = $this->parent->request;
735  if ( $r->wasPosted() ) {
736  if ( $this->submit() ) {
737  return 'continue';
738  }
739  }
740 
741  $this->startForm();
742 
743  // Encourage people to not name their site 'MediaWiki' by blanking the
744  // field. I think that was the intent with the original $GLOBALS['wgSitename']
745  // but these two always were the same so had the effect of making the
746  // installer forget $wgSitename when navigating back to this page.
747  if ( $this->getVar( 'wgSitename' ) == 'MediaWiki' ) {
748  $this->setVar( 'wgSitename', '' );
749  }
750 
751  // Set wgMetaNamespace to something valid before we show the form.
752  // $wgMetaNamespace defaults to $wgSiteName which is 'MediaWiki'
753  $metaNS = $this->getVar( 'wgMetaNamespace' );
754  $this->setVar(
755  'wgMetaNamespace',
756  wfMessage( 'config-ns-other-default' )->inContentLanguage()->text()
757  );
758 
759  $this->addHTML(
760  $this->parent->getTextBox( array(
761  'var' => 'wgSitename',
762  'label' => 'config-site-name',
763  'help' => $this->parent->getHelpBox( 'config-site-name-help' )
764  ) ) .
765  // getRadioSet() builds a set of labeled radio buttons.
766  // For grep: The following messages are used as the item labels:
767  // config-ns-site-name, config-ns-generic, config-ns-other
768  $this->parent->getRadioSet( array(
769  'var' => '_NamespaceType',
770  'label' => 'config-project-namespace',
771  'itemLabelPrefix' => 'config-ns-',
772  'values' => array( 'site-name', 'generic', 'other' ),
773  'commonAttribs' => array( 'class' => 'enableForOther',
774  'rel' => 'config_wgMetaNamespace' ),
775  'help' => $this->parent->getHelpBox( 'config-project-namespace-help' )
776  ) ) .
777  $this->parent->getTextBox( array(
778  'var' => 'wgMetaNamespace',
779  'label' => '', // @todo Needs a label?
780  'attribs' => array( 'readonly' => 'readonly', 'class' => 'enabledByOther' )
781  ) ) .
782  $this->getFieldSetStart( 'config-admin-box' ) .
783  $this->parent->getTextBox( array(
784  'var' => '_AdminName',
785  'label' => 'config-admin-name',
786  'help' => $this->parent->getHelpBox( 'config-admin-help' )
787  ) ) .
788  $this->parent->getPasswordBox( array(
789  'var' => '_AdminPassword',
790  'label' => 'config-admin-password',
791  ) ) .
792  $this->parent->getPasswordBox( array(
793  'var' => '_AdminPassword2',
794  'label' => 'config-admin-password-confirm'
795  ) ) .
796  $this->parent->getTextBox( array(
797  'var' => '_AdminEmail',
798  'label' => 'config-admin-email',
799  'help' => $this->parent->getHelpBox( 'config-admin-email-help' )
800  ) ) .
801  $this->parent->getCheckBox( array(
802  'var' => '_Subscribe',
803  'label' => 'config-subscribe',
804  'help' => $this->parent->getHelpBox( 'config-subscribe-help' )
805  ) ) .
806  $this->getFieldSetEnd() .
807  $this->parent->getInfoBox( wfMessage( 'config-almost-done' )->text() ) .
808  // getRadioSet() builds a set of labeled radio buttons.
809  // For grep: The following messages are used as the item labels:
810  // config-optional-continue, config-optional-skip
811  $this->parent->getRadioSet( array(
812  'var' => '_SkipOptional',
813  'itemLabelPrefix' => 'config-optional-',
814  'values' => array( 'continue', 'skip' )
815  ) )
816  );
817 
818  // Restore the default value
819  $this->setVar( 'wgMetaNamespace', $metaNS );
820 
821  $this->endForm();
822 
823  return 'output';
824  }
825 
829  public function submit() {
830  $retVal = true;
831  $this->parent->setVarsFromRequest( array( 'wgSitename', '_NamespaceType',
832  '_AdminName', '_AdminPassword', '_AdminPassword2', '_AdminEmail',
833  '_Subscribe', '_SkipOptional', 'wgMetaNamespace' ) );
834 
835  // Validate site name
836  if ( strval( $this->getVar( 'wgSitename' ) ) === '' ) {
837  $this->parent->showError( 'config-site-name-blank' );
838  $retVal = false;
839  }
840 
841  // Fetch namespace
842  $nsType = $this->getVar( '_NamespaceType' );
843  if ( $nsType == 'site-name' ) {
844  $name = $this->getVar( 'wgSitename' );
845  // Sanitize for namespace
846  // This algorithm should match the JS one in WebInstallerOutput.php
847  $name = preg_replace( '/[\[\]\{\}|#<>%+? ]/', '_', $name );
848  $name = str_replace( '&', '&amp;', $name );
849  $name = preg_replace( '/__+/', '_', $name );
850  $name = ucfirst( trim( $name, '_' ) );
851  } elseif ( $nsType == 'generic' ) {
852  $name = wfMessage( 'config-ns-generic' )->text();
853  } else { // other
854  $name = $this->getVar( 'wgMetaNamespace' );
855  }
856 
857  // Validate namespace
858  if ( strpos( $name, ':' ) !== false ) {
859  $good = false;
860  } else {
861  // Title-style validation
863  if ( !$title ) {
864  $good = $nsType == 'site-name';
865  } else {
866  $name = $title->getDBkey();
867  $good = true;
868  }
869  }
870  if ( !$good ) {
871  $this->parent->showError( 'config-ns-invalid', $name );
872  $retVal = false;
873  }
874 
875  // Make sure it won't conflict with any existing namespaces
877  $nsIndex = $wgContLang->getNsIndex( $name );
878  if ( $nsIndex !== false && $nsIndex !== NS_PROJECT ) {
879  $this->parent->showError( 'config-ns-conflict', $name );
880  $retVal = false;
881  }
882 
883  $this->setVar( 'wgMetaNamespace', $name );
884 
885  // Validate username for creation
886  $name = $this->getVar( '_AdminName' );
887  if ( strval( $name ) === '' ) {
888  $this->parent->showError( 'config-admin-name-blank' );
889  $cname = $name;
890  $retVal = false;
891  } else {
892  $cname = User::getCanonicalName( $name, 'creatable' );
893  if ( $cname === false ) {
894  $this->parent->showError( 'config-admin-name-invalid', $name );
895  $retVal = false;
896  } else {
897  $this->setVar( '_AdminName', $cname );
898  }
899  }
900 
901  // Validate password
902  $msg = false;
903  $pwd = $this->getVar( '_AdminPassword' );
904  $user = User::newFromName( $cname );
905  if ( $user ) {
906  $valid = $user->getPasswordValidity( $pwd );
907  } else {
908  $valid = 'config-admin-name-invalid';
909  }
910  if ( strval( $pwd ) === '' ) {
911  # $user->getPasswordValidity just checks for $wgMinimalPasswordLength.
912  # This message is more specific and helpful.
913  $msg = 'config-admin-password-blank';
914  } elseif ( $pwd !== $this->getVar( '_AdminPassword2' ) ) {
915  $msg = 'config-admin-password-mismatch';
916  } elseif ( $valid !== true ) {
917  $msg = $valid;
918  }
919  if ( $msg !== false ) {
920  call_user_func_array( array( $this->parent, 'showError' ), (array)$msg );
921  $this->setVar( '_AdminPassword', '' );
922  $this->setVar( '_AdminPassword2', '' );
923  $retVal = false;
924  }
925 
926  // Validate e-mail if provided
927  $email = $this->getVar( '_AdminEmail' );
928  if ( $email && !Sanitizer::validateEmail( $email ) ) {
929  $this->parent->showError( 'config-admin-error-bademail' );
930  $retVal = false;
931  }
932  // If they asked to subscribe to mediawiki-announce but didn't give
933  // an e-mail, show an error. Bug 29332
934  if ( !$email && $this->getVar( '_Subscribe' ) ) {
935  $this->parent->showError( 'config-subscribe-noemail' );
936  $retVal = false;
937  }
938 
939  return $retVal;
940  }
941 
942 }
943 
944 class WebInstaller_Options extends WebInstallerPage {
945 
949  public function execute() {
950  if ( $this->getVar( '_SkipOptional' ) == 'skip' ) {
951  return 'skip';
952  }
953  if ( $this->parent->request->wasPosted() ) {
954  if ( $this->submit() ) {
955  return 'continue';
956  }
957  }
958 
959  $emailwrapperStyle = $this->getVar( 'wgEnableEmail' ) ? '' : 'display: none';
960  $this->startForm();
961  $this->addHTML(
962  # User Rights
963  // getRadioSet() builds a set of labeled radio buttons.
964  // For grep: The following messages are used as the item labels:
965  // config-profile-wiki, config-profile-no-anon, config-profile-fishbowl, config-profile-private
966  $this->parent->getRadioSet( array(
967  'var' => '_RightsProfile',
968  'label' => 'config-profile',
969  'itemLabelPrefix' => 'config-profile-',
970  'values' => array_keys( $this->parent->rightsProfiles ),
971  ) ) .
972  $this->parent->getInfoBox( wfMessage( 'config-profile-help' )->plain() ) .
973 
974  # Licensing
975  // getRadioSet() builds a set of labeled radio buttons.
976  // For grep: The following messages are used as the item labels:
977  // config-license-cc-by, config-license-cc-by-sa, config-license-cc-by-nc-sa,
978  // config-license-cc-0, config-license-pd, config-license-gfdl,
979  // config-license-none, config-license-cc-choose
980  $this->parent->getRadioSet( array(
981  'var' => '_LicenseCode',
982  'label' => 'config-license',
983  'itemLabelPrefix' => 'config-license-',
984  'values' => array_keys( $this->parent->licenses ),
985  'commonAttribs' => array( 'class' => 'licenseRadio' ),
986  ) ) .
987  $this->getCCChooser() .
988  $this->parent->getHelpBox( 'config-license-help' ) .
989 
990  # E-mail
991  $this->getFieldSetStart( 'config-email-settings' ) .
992  $this->parent->getCheckBox( array(
993  'var' => 'wgEnableEmail',
994  'label' => 'config-enable-email',
995  'attribs' => array( 'class' => 'showHideRadio', 'rel' => 'emailwrapper' ),
996  ) ) .
997  $this->parent->getHelpBox( 'config-enable-email-help' ) .
998  "<div id=\"emailwrapper\" style=\"$emailwrapperStyle\">" .
999  $this->parent->getTextBox( array(
1000  'var' => 'wgPasswordSender',
1001  'label' => 'config-email-sender'
1002  ) ) .
1003  $this->parent->getHelpBox( 'config-email-sender-help' ) .
1004  $this->parent->getCheckBox( array(
1005  'var' => 'wgEnableUserEmail',
1006  'label' => 'config-email-user',
1007  ) ) .
1008  $this->parent->getHelpBox( 'config-email-user-help' ) .
1009  $this->parent->getCheckBox( array(
1010  'var' => 'wgEnotifUserTalk',
1011  'label' => 'config-email-usertalk',
1012  ) ) .
1013  $this->parent->getHelpBox( 'config-email-usertalk-help' ) .
1014  $this->parent->getCheckBox( array(
1015  'var' => 'wgEnotifWatchlist',
1016  'label' => 'config-email-watchlist',
1017  ) ) .
1018  $this->parent->getHelpBox( 'config-email-watchlist-help' ) .
1019  $this->parent->getCheckBox( array(
1020  'var' => 'wgEmailAuthentication',
1021  'label' => 'config-email-auth',
1022  ) ) .
1023  $this->parent->getHelpBox( 'config-email-auth-help' ) .
1024  "</div>" .
1025  $this->getFieldSetEnd()
1026  );
1027 
1028  $extensions = $this->parent->findExtensions();
1029 
1030  if ( $extensions ) {
1031  $extHtml = $this->getFieldSetStart( 'config-extensions' );
1032 
1033  foreach ( $extensions as $ext ) {
1034  $extHtml .= $this->parent->getCheckBox( array(
1035  'var' => "ext-$ext",
1036  'rawtext' => $ext,
1037  ) );
1038  }
1039 
1040  $extHtml .= $this->parent->getHelpBox( 'config-extensions-help' ) .
1041  $this->getFieldSetEnd();
1042  $this->addHTML( $extHtml );
1043  }
1044 
1045  // Having / in paths in Windows looks funny :)
1046  $this->setVar( 'wgDeletedDirectory',
1047  str_replace(
1048  '/', DIRECTORY_SEPARATOR,
1049  $this->getVar( 'wgDeletedDirectory' )
1050  )
1051  );
1052 
1053  $uploadwrapperStyle = $this->getVar( 'wgEnableUploads' ) ? '' : 'display: none';
1054  $this->addHTML(
1055  # Uploading
1056  $this->getFieldSetStart( 'config-upload-settings' ) .
1057  $this->parent->getCheckBox( array(
1058  'var' => 'wgEnableUploads',
1059  'label' => 'config-upload-enable',
1060  'attribs' => array( 'class' => 'showHideRadio', 'rel' => 'uploadwrapper' ),
1061  'help' => $this->parent->getHelpBox( 'config-upload-help' )
1062  ) ) .
1063  '<div id="uploadwrapper" style="' . $uploadwrapperStyle . '">' .
1064  $this->parent->getTextBox( array(
1065  'var' => 'wgDeletedDirectory',
1066  'label' => 'config-upload-deleted',
1067  'attribs' => array( 'dir' => 'ltr' ),
1068  'help' => $this->parent->getHelpBox( 'config-upload-deleted-help' )
1069  ) ) .
1070  '</div>' .
1071  $this->parent->getTextBox( array(
1072  'var' => 'wgLogo',
1073  'label' => 'config-logo',
1074  'attribs' => array( 'dir' => 'ltr' ),
1075  'help' => $this->parent->getHelpBox( 'config-logo-help' )
1076  ) )
1077  );
1078  $this->addHTML(
1079  $this->parent->getCheckBox( array(
1080  'var' => 'wgUseInstantCommons',
1081  'label' => 'config-instantcommons',
1082  'help' => $this->parent->getHelpBox( 'config-instantcommons-help' )
1083  ) ) .
1084  $this->getFieldSetEnd()
1085  );
1086 
1087  $caches = array( 'none' );
1088  if ( count( $this->getVar( '_Caches' ) ) ) {
1089  $caches[] = 'accel';
1090  }
1091  $caches[] = 'memcached';
1092 
1093  // We'll hide/show this on demand when the value changes, see config.js.
1094  $cacheval = $this->getVar( 'wgMainCacheType' );
1095  if ( !$cacheval ) {
1096  // We need to set a default here; but don't hardcode it
1097  // or we lose it every time we reload the page for validation
1098  // or going back!
1099  $cacheval = 'none';
1100  }
1101  $hidden = ( $cacheval == 'memcached' ) ? '' : 'display: none';
1102  $this->addHTML(
1103  # Advanced settings
1104  $this->getFieldSetStart( 'config-advanced-settings' ) .
1105  # Object cache settings
1106  // getRadioSet() builds a set of labeled radio buttons.
1107  // For grep: The following messages are used as the item labels:
1108  // config-cache-none, config-cache-accel, config-cache-memcached
1109  $this->parent->getRadioSet( array(
1110  'var' => 'wgMainCacheType',
1111  'label' => 'config-cache-options',
1112  'itemLabelPrefix' => 'config-cache-',
1113  'values' => $caches,
1114  'value' => $cacheval,
1115  ) ) .
1116  $this->parent->getHelpBox( 'config-cache-help' ) .
1117  "<div id=\"config-memcachewrapper\" style=\"$hidden\">" .
1118  $this->parent->getTextArea( array(
1119  'var' => '_MemCachedServers',
1120  'label' => 'config-memcached-servers',
1121  'help' => $this->parent->getHelpBox( 'config-memcached-help' )
1122  ) ) .
1123  '</div>' .
1124  $this->getFieldSetEnd()
1125  );
1126  $this->endForm();
1127 
1128  return null;
1129  }
1130 
1134  public function getCCPartnerUrl() {
1135  $server = $this->getVar( 'wgServer' );
1136  $exitUrl = $server . $this->parent->getUrl( array(
1137  'page' => 'Options',
1138  'SubmitCC' => 'indeed',
1139  'config__LicenseCode' => 'cc',
1140  'config_wgRightsUrl' => '[license_url]',
1141  'config_wgRightsText' => '[license_name]',
1142  'config_wgRightsIcon' => '[license_button]',
1143  ) );
1144  $styleUrl = $server . dirname( dirname( $this->parent->getUrl() ) ) .
1145  '/skins/common/config-cc.css';
1146  $iframeUrl = 'http://creativecommons.org/license/?' .
1148  'partner' => 'MediaWiki',
1149  'exit_url' => $exitUrl,
1150  'lang' => $this->getVar( '_UserLang' ),
1151  'stylesheet' => $styleUrl,
1152  ) );
1153 
1154  return $iframeUrl;
1155  }
1156 
1160  public function getCCChooser() {
1161  $iframeAttribs = array(
1162  'class' => 'config-cc-iframe',
1163  'name' => 'config-cc-iframe',
1164  'id' => 'config-cc-iframe',
1165  'frameborder' => 0,
1166  'width' => '100%',
1167  'height' => '100%',
1168  );
1169  if ( $this->getVar( '_CCDone' ) ) {
1170  $iframeAttribs['src'] = $this->parent->getUrl( array( 'ShowCC' => 'yes' ) );
1171  } else {
1172  $iframeAttribs['src'] = $this->getCCPartnerUrl();
1173  }
1174  $wrapperStyle = ( $this->getVar( '_LicenseCode' ) == 'cc-choose' ) ? '' : 'display: none';
1175 
1176  return "<div class=\"config-cc-wrapper\" id=\"config-cc-wrapper\" style=\"$wrapperStyle\">\n" .
1177  Html::element( 'iframe', $iframeAttribs, '', false /* not short */ ) .
1178  "</div>\n";
1179  }
1180 
1184  public function getCCDoneBox() {
1185  $js = "parent.document.getElementById('config-cc-wrapper').style.height = '$1';";
1186  // If you change this height, also change it in config.css
1187  $expandJs = str_replace( '$1', '54em', $js );
1188  $reduceJs = str_replace( '$1', '70px', $js );
1189 
1190  return '<p>' .
1191  Html::element( 'img', array( 'src' => $this->getVar( 'wgRightsIcon' ) ) ) .
1192  '&#160;&#160;' .
1193  htmlspecialchars( $this->getVar( 'wgRightsText' ) ) .
1194  "</p>\n" .
1195  "<p style=\"text-align: center;\">" .
1196  Html::element( 'a',
1197  array(
1198  'href' => $this->getCCPartnerUrl(),
1199  'onclick' => $expandJs,
1200  ),
1201  wfMessage( 'config-cc-again' )->text()
1202  ) .
1203  "</p>\n" .
1204  "<script>\n" .
1205  # Reduce the wrapper div height
1206  htmlspecialchars( $reduceJs ) .
1207  "\n" .
1208  "</script>\n";
1209  }
1210 
1211  public function submitCC() {
1212  $newValues = $this->parent->setVarsFromRequest(
1213  array( 'wgRightsUrl', 'wgRightsText', 'wgRightsIcon' ) );
1214  if ( count( $newValues ) != 3 ) {
1215  $this->parent->showError( 'config-cc-error' );
1216 
1217  return;
1218  }
1219  $this->setVar( '_CCDone', true );
1220  $this->addHTML( $this->getCCDoneBox() );
1221  }
1222 
1226  public function submit() {
1227  $this->parent->setVarsFromRequest( array( '_RightsProfile', '_LicenseCode',
1228  'wgEnableEmail', 'wgPasswordSender', 'wgEnableUploads', 'wgLogo',
1229  'wgEnableUserEmail', 'wgEnotifUserTalk', 'wgEnotifWatchlist',
1230  'wgEmailAuthentication', 'wgMainCacheType', '_MemCachedServers',
1231  'wgUseInstantCommons' ) );
1232 
1233  if ( !array_key_exists( $this->getVar( '_RightsProfile' ), $this->parent->rightsProfiles )
1234  ) {
1235  reset( $this->parent->rightsProfiles );
1236  $this->setVar( '_RightsProfile', key( $this->parent->rightsProfiles ) );
1237  }
1238 
1239  $code = $this->getVar( '_LicenseCode' );
1240  if ( $code == 'cc-choose' ) {
1241  if ( !$this->getVar( '_CCDone' ) ) {
1242  $this->parent->showError( 'config-cc-not-chosen' );
1243 
1244  return false;
1245  }
1246  } elseif ( array_key_exists( $code, $this->parent->licenses ) ) {
1247  // Messages:
1248  // config-license-cc-by, config-license-cc-by-sa, config-license-cc-by-nc-sa,
1249  // config-license-cc-0, config-license-pd, config-license-gfdl, config-license-none,
1250  // config-license-cc-choose
1251  $entry = $this->parent->licenses[$code];
1252  if ( isset( $entry['text'] ) ) {
1253  $this->setVar( 'wgRightsText', $entry['text'] );
1254  } else {
1255  $this->setVar( 'wgRightsText', wfMessage( 'config-license-' . $code )->text() );
1256  }
1257  $this->setVar( 'wgRightsUrl', $entry['url'] );
1258  $this->setVar( 'wgRightsIcon', $entry['icon'] );
1259  } else {
1260  $this->setVar( 'wgRightsText', '' );
1261  $this->setVar( 'wgRightsUrl', '' );
1262  $this->setVar( 'wgRightsIcon', '' );
1263  }
1264 
1265  $extsAvailable = $this->parent->findExtensions();
1266  $extsToInstall = array();
1267  foreach ( $extsAvailable as $ext ) {
1268  if ( $this->parent->request->getCheck( 'config_ext-' . $ext ) ) {
1269  $extsToInstall[] = $ext;
1270  }
1271  }
1272  $this->parent->setVar( '_Extensions', $extsToInstall );
1273 
1274  if ( $this->getVar( 'wgMainCacheType' ) == 'memcached' ) {
1275  $memcServers = explode( "\n", $this->getVar( '_MemCachedServers' ) );
1276  if ( !$memcServers ) {
1277  $this->parent->showError( 'config-memcache-needservers' );
1278 
1279  return false;
1280  }
1281 
1282  foreach ( $memcServers as $server ) {
1283  $memcParts = explode( ":", $server, 2 );
1284  if ( !isset( $memcParts[0] )
1285  || ( !IP::isValid( $memcParts[0] )
1286  && ( gethostbyname( $memcParts[0] ) == $memcParts[0] ) )
1287  ) {
1288  $this->parent->showError( 'config-memcache-badip', $memcParts[0] );
1289 
1290  return false;
1291  } elseif ( !isset( $memcParts[1] ) ) {
1292  $this->parent->showError( 'config-memcache-noport', $memcParts[0] );
1293 
1294  return false;
1295  } elseif ( $memcParts[1] < 1 || $memcParts[1] > 65535 ) {
1296  $this->parent->showError( 'config-memcache-badport', 1, 65535 );
1297 
1298  return false;
1299  }
1300  }
1301  }
1302 
1303  return true;
1304  }
1305 
1306 }
1307 
1308 class WebInstaller_Install extends WebInstallerPage {
1309 
1313  public function isSlow() {
1314  return true;
1315  }
1316 
1320  public function execute() {
1321  if ( $this->getVar( '_UpgradeDone' ) ) {
1322  return 'skip';
1323  } elseif ( $this->getVar( '_InstallDone' ) ) {
1324  return 'continue';
1325  } elseif ( $this->parent->request->wasPosted() ) {
1326  $this->startForm();
1327  $this->addHTML( "<ul>" );
1328  $results = $this->parent->performInstallation(
1329  array( $this, 'startStage' ),
1330  array( $this, 'endStage' )
1331  );
1332  $this->addHTML( "</ul>" );
1333  // PerformInstallation bails on a fatal, so make sure the last item
1334  // completed before giving 'next.' Likewise, only provide back on failure
1335  $lastStep = end( $results );
1336  $continue = $lastStep->isOK() ? 'continue' : false;
1337  $back = $lastStep->isOK() ? false : 'back';
1338  $this->endForm( $continue, $back );
1339  } else {
1340  $this->startForm();
1341  $this->addHTML( $this->parent->getInfoBox( wfMessage( 'config-install-begin' )->plain() ) );
1342  $this->endForm();
1343  }
1344 
1345  return true;
1346  }
1347 
1351  public function startStage( $step ) {
1352  // Messages: config-install-database, config-install-tables, config-install-interwiki,
1353  // config-install-stats, config-install-keys, config-install-sysop, config-install-mainpage
1354  $this->addHTML( "<li>" . wfMessage( "config-install-$step" )->escaped() .
1355  wfMessage( 'ellipsis' )->escaped() );
1356 
1357  if ( $step == 'extension-tables' ) {
1358  $this->startLiveBox();
1359  }
1360  }
1361 
1366  public function endStage( $step, $status ) {
1367  if ( $step == 'extension-tables' ) {
1368  $this->endLiveBox();
1369  }
1370  $msg = $status->isOk() ? 'config-install-step-done' : 'config-install-step-failed';
1371  $html = wfMessage( 'word-separator' )->escaped() . wfMessage( $msg )->escaped();
1372  if ( !$status->isOk() ) {
1373  $html = "<span class=\"error\">$html</span>";
1374  }
1375  $this->addHTML( $html . "</li>\n" );
1376  if ( !$status->isGood() ) {
1377  $this->parent->showStatusBox( $status );
1378  }
1379  }
1380 
1381 }
1382 
1383 class WebInstaller_Complete extends WebInstallerPage {
1384 
1385  public function execute() {
1386  // Pop up a dialog box, to make it difficult for the user to forget
1387  // to download the file
1388  $lsUrl = $this->getVar( 'wgServer' ) . $this->parent->getURL( array( 'localsettings' => 1 ) );
1389  if ( isset( $_SERVER['HTTP_USER_AGENT'] ) &&
1390  strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) !== false
1391  ) {
1392  // JS appears to be the only method that works consistently with IE7+
1393  $this->addHtml( "\n<script>jQuery( function () { document.location = " .
1394  Xml::encodeJsVar( $lsUrl ) . "; } );</script>\n" );
1395  } else {
1396  $this->parent->request->response()->header( "Refresh: 0;url=$lsUrl" );
1397  }
1398 
1399  $this->startForm();
1400  $this->parent->disableLinkPopups();
1401  $this->addHTML(
1402  $this->parent->getInfoBox(
1403  wfMessage( 'config-install-done',
1404  $lsUrl,
1405  $this->getVar( 'wgServer' ) .
1406  $this->getVar( 'wgScriptPath' ) . '/index' .
1407  $this->getVar( 'wgScriptExtension' ),
1408  '<downloadlink/>'
1409  )->plain(), 'tick-32.png'
1410  )
1411  );
1412  $this->addHTML( $this->parent->getInfoBox(
1413  wfMessage( 'config-extension-link' )->text() ) );
1414 
1415  $this->parent->restoreLinkPopups();
1416  $this->endForm( false, false );
1417  }
1418 
1419 }
1420 
1421 class WebInstaller_Restart extends WebInstallerPage {
1422 
1426  public function execute() {
1427  $r = $this->parent->request;
1428  if ( $r->wasPosted() ) {
1429  $really = $r->getVal( 'submit-restart' );
1430  if ( $really ) {
1431  $this->parent->reset();
1432  }
1433 
1434  return 'continue';
1435  }
1436 
1437  $this->startForm();
1438  $s = $this->parent->getWarningBox( wfMessage( 'config-help-restart' )->plain() );
1439  $this->addHTML( $s );
1440  $this->endForm( 'restart' );
1441 
1442  return null;
1443  }
1444 
1445 }
1446 
1447 abstract class WebInstaller_Document extends WebInstallerPage {
1448 
1452  abstract protected function getFileName();
1453 
1454  public function execute() {
1455  $text = $this->getFileContents();
1456  $text = InstallDocFormatter::format( $text );
1457  $this->parent->output->addWikiText( $text );
1458  $this->startForm();
1459  $this->endForm( false );
1460  }
1461 
1465  public function getFileContents() {
1466  $file = __DIR__ . '/../../' . $this->getFileName();
1467  if ( !file_exists( $file ) ) {
1468  return wfMessage( 'config-nofile', $file )->plain();
1469  }
1470 
1471  return file_get_contents( $file );
1472  }
1473 
1474 }
1475 
1476 class WebInstaller_Readme extends WebInstaller_Document {
1477 
1481  protected function getFileName() {
1482  return 'README';
1483  }
1484 
1485 }
1486 
1487 class WebInstaller_ReleaseNotes extends WebInstaller_Document {
1488 
1493  protected function getFileName() {
1494  global $wgVersion;
1495 
1496  if ( !preg_match( '/^(\d+)\.(\d+).*/i', $wgVersion, $result ) ) {
1497  throw new MWException( 'Variable $wgVersion has an invalid value.' );
1498  }
1499 
1500  return 'RELEASE-NOTES-' . $result[1] . '.' . $result[2];
1501  }
1502 
1503 }
1504 
1505 class WebInstaller_UpgradeDoc extends WebInstaller_Document {
1506 
1510  protected function getFileName() {
1511  return 'UPGRADE';
1512  }
1513 
1514 }
1515 
1516 class WebInstaller_Copying extends WebInstaller_Document {
1517 
1521  protected function getFileName() {
1522  return 'COPYING';
1523  }
1524 
1525 }
$result
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message. Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item. $reader:XMLReader object $logInfo:Array of information Return false to stop further processing of the tag 'ImportHandlePageXMLTag':When parsing a XML tag in a page. $reader:XMLReader object $pageInfo:Array of information Return false to stop further processing of the tag 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision. $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information Return false to stop further processing of the tag 'ImportHandleToplevelXMLTag':When parsing a top level XML tag. $reader:XMLReader object Return false to stop further processing of the tag 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload. $reader:XMLReader object $revisionInfo:Array of information Return false to stop further processing of the tag 'InfoAction':When building information to display on the action=info page. $context:IContextSource object & $pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect. $title:Title object for the current page $request:WebRequest $ignoreRedirect:boolean to skip redirect check $target:Title/string of redirect target $article:Article object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not. Return true without providing an interwiki to continue interwiki search. $prefix:interwiki prefix we are looking for. & $iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InternalParseBeforeSanitize':during Parser 's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings. Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InternalParseBeforeLinks':during Parser 's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InvalidateEmailComplete':Called after a user 's email has been invalidated successfully. $user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification. Callee may modify $url and $query, URL will be constructed as $url . $query & $url:URL to index.php & $query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) $article:article(object) being checked 'IsTrustedProxy':Override the result of wfIsTrustedProxy() $ip:IP being check $result:Change this value to override the result of wfIsTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from & $allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of User::isValidEmailAddr(), for instance to return false if the domain name doesn 't match your organization. $addr:The e-mail address entered by the user & $result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user & $result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we 're looking for a messages file for & $file:The messages file path, you can override this to change the location. 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces. Do not use this hook to add namespaces. Use CanonicalNamespaces for that. & $namespaces:Array of namespaces indexed by their numbers 'LanguageGetMagic':DEPRECATED, use $magicWords in a file listed in $wgExtensionMessagesFiles instead. Use this to define synonyms of magic words depending of the language $magicExtensions:associative array of magic words synonyms $lang:language code(string) 'LanguageGetSpecialPageAliases':DEPRECATED, use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead. Use to define aliases of special pages names depending of the language $specialPageAliases:associative array of magic words synonyms $lang:language code(string) 'LanguageGetTranslatedLanguageNames':Provide translated language names. & $names:array of language code=> language name $code language of the preferred translations 'LanguageLinks':Manipulate a page 's language links. This is called in various places to allow extensions to define the effective language links for a page. $title:The page 's Title. & $links:Associative array mapping language codes to prefixed links of the form "language:title". & $linkFlags:Associative array mapping prefixed links to arrays of flags. Currently unused, but planned to provide support for marking individual language links in the UI, e.g. for featured articles. 'LinkBegin':Used when generating internal and interwiki links in Linker::link(), before processing starts. Return false to skip default processing and return $ret. See documentation for Linker::link() for details on the expected meanings of parameters. $skin:the Skin object $target:the Title that the link is pointing to & $html:the contents that the< a > tag should have(raw HTML) $result
Definition: hooks.txt:1528
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:189
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
$html
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses & $html
Definition: hooks.txt:1530
$extensions
$extensions
Definition: importImages.php:62
text
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
Definition: design.txt:12
$form
usually copyright or history_copyright This message must be in HTML not wikitext $subpages will be ignored and the rest of subPageSubtitle() will run. 'SkinTemplateBuildNavUrlsNav_urlsAfterPermalink' whether MediaWiki currently thinks this is a CSS JS page Hooks may change this value to override the return value of Title::isCssOrJsPage(). 'TitleIsAlwaysKnown' whether MediaWiki currently thinks this page is known isMovable() always returns false. $title whether MediaWiki currently thinks this page is movable Hooks may change this value to override the return value of Title::isMovable(). 'TitleIsWikitextPage' whether MediaWiki currently thinks this is a wikitext page Hooks may change this value to override the return value of Title::isWikitextPage() 'TitleMove' use UploadVerification and UploadVerifyFile instead $form
Definition: hooks.txt:2573
SpecialVersion\getCopyrightAndAuthorList
static getCopyrightAndAuthorList()
Get the "MediaWiki is copyright 2001-20xx by lots of cool guys" text.
Definition: SpecialVersion.php:170
Xml\option
static option( $text, $value=null, $selected=false, $attribs=array())
Convenience function to build an HTML drop-down list item.
Definition: Xml.php:475
WebInstaller
Class for the core installer web interface.
Definition: WebInstaller.php:30
Status\newGood
static newGood( $value=null)
Factory function for good results.
Definition: Status.php:77
Sanitizer\validateEmail
static validateEmail( $addr)
Does a string look like an e-mail address?
Definition: Sanitizer.php:1847
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:388
$s
$s
Definition: mergeMessageFileList.php:156
Html\hidden
static hidden( $name, $value, $attribs=array())
Convenience function to produce an input element with type=hidden.
Definition: Html.php:662
$wgContLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
Definition: design.txt:56
cache
you have access to all of the normal MediaWiki so you can get a DB use the cache
Definition: maintenance.txt:52
Xml\encodeJsVar
static encodeJsVar( $value, $pretty=false)
Encode a variable of arbitrary type to JavaScript.
Definition: Xml.php:647
Xml\radioLabel
static radioLabel( $label, $name, $value, $id, $checked=false, $attribs=array())
Convenience function to build an HTML radio button with a label.
Definition: Xml.php:451
key
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add in any and then calling but I prefer the flexibility This should also do the output encoding The system allocates a global one in $wgOut Title Represents the title of an and does all the work of translating among various forms such as plain database key
Definition: design.txt:25
Html\openElement
static openElement( $element, $attribs=array())
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:166
MWException
MediaWiki exception.
Definition: MWException.php:26
NS_PROJECT
const NS_PROJECT
Definition: Defines.php:83
Language\fetchLanguageNames
static fetchLanguageNames( $inLanguage=null, $include='mw')
Get an array of language names, indexed by code.
Definition: Language.php:875
Html\element
static element( $element, $attribs=array(), $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:148
wfMessage
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing after in associative array form externallinks including delete and has completed for all link tables default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "&lt
Installer\getExistingLocalSettings
static getExistingLocalSettings()
Determine if LocalSettings.php exists.
Definition: Installer.php:501
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
settings
globals will be eliminated from MediaWiki replaced by an application object which would be passed to constructors Whether that would be an convenient solution remains to be but certainly PHP makes such object oriented programming models easier than they were in previous versions For the time being MediaWiki programmers will have to work in an environment with some global context At the time of globals were initialised on startup by MediaWiki of these were configuration settings
Definition: globals.txt:25
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:188
execute
$batch execute()
InstallDocFormatter\format
static format( $text)
Definition: InstallDocFormatter.php:24
$languages
$languages
Definition: rebuildLanguage.php:129
$title
presenting them properly to the user as errors is done by the caller $title
Definition: hooks.txt:1324
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:336
$value
$value
Definition: styleTest.css.php:45
mail
address of the mail
Definition: All_system_messages.txt:1386
IP\isValid
static isValid( $ip)
Validate an IP address.
Definition: IP.php:108
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:237
$file
if(PHP_SAPI !='cli') $file
Definition: UtfNormalTest2.php:30
$wgLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as $wgLang
Definition: design.txt:56
$ext
$ext
Definition: NoLocalSettings.php:34
User\getCanonicalName
static getCanonicalName( $name, $validate='valid')
Given unvalidated user input, return a canonical username, or false if the username is invalid.
Definition: User.php:883
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
Xml\submitButton
static submitButton( $value, $attribs=array())
Convenience function to build an HTML submit button.
Definition: Xml.php:463
Installer\getDBTypes
static getDBTypes()
Get a list of known DB types.
Definition: Installer.php:387
$vars
static configuration should be added through ResourceLoaderGetConfigVars instead & $vars
Definition: hooks.txt:1679
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:59
$GLOBALS
$GLOBALS['IP']
Definition: ComposerHookHandler.php:6
Status\newFatal
static newFatal( $message)
Factory function for fatal errors.
Definition: Status.php:63
wfArrayToCgi
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes two arrays as input, and returns a CGI-style string, e.g.
Definition: GlobalFunctions.php:367
$type
$type
Definition: testCompression.php:46