MediaWiki  master
WebInstallerOptions.php
Go to the documentation of this file.
1 <?php
22 use Wikimedia\IPUtils;
23 
25 
29  public function execute() {
30  if ( $this->getVar( '_SkipOptional' ) == 'skip' ) {
31  $this->submitSkins();
32  return 'skip';
33  }
34  if ( $this->parent->request->wasPosted() && $this->submit() ) {
35  return 'continue';
36  }
37 
38  $this->startForm();
39  $this->addModeOptions();
40  $this->addEmailOptions();
41  $this->addSkinOptions();
42  $this->addExtensionOptions();
43  $this->addFileOptions();
45  $this->addAdvancedOptions();
46  $this->endForm();
47 
48  return null;
49  }
50 
51  private function addPersonalizationOptions() {
53  $this->addHTML(
54  $this->getFieldsetStart( 'config-personalization-settings' ) .
55  Html::rawElement( 'div', [
56  'class' => 'config-drag-drop'
57  ], wfMessage( 'config-logo-summary' )->parse() ) .
58  Html::openElement( 'div', [
59  'class' => 'config-personalization-options'
60  ] ) .
61  Html::hidden( 'config_LogoSiteName', $this->getVar( 'wgSitename' ) ) .
63  'var' => '_LogoIcon',
64  // Single quotes are intentional, LocalSettingsGenerator must output this unescaped.
65  'value' => '$wgResourceBasePath/resources/assets/change-your-logo.svg',
66  'label' => 'config-logo-icon',
67  'attribs' => [ 'dir' => 'ltr' ],
68  'help' => $parent->getHelpBox( 'config-logo-icon-help' )
69  ] ) .
71  'var' => '_LogoWordmark',
72  'label' => 'config-logo-wordmark',
73  'attribs' => [ 'dir' => 'ltr' ],
74  'help' => $parent->getHelpBox( 'config-logo-wordmark-help' )
75  ] ) .
77  'var' => '_LogoTagline',
78  'label' => 'config-logo-tagline',
79  'attribs' => [ 'dir' => 'ltr' ],
80  'help' => $parent->getHelpBox( 'config-logo-tagline-help' )
81  ] ) .
83  'var' => '_Logo1x',
84  'label' => 'config-logo-sidebar',
85  'attribs' => [ 'dir' => 'ltr' ],
86  'help' => $parent->getHelpBox( 'config-logo-sidebar-help' )
87  ] ) .
88  Html::openElement( 'div', [
89  'class' => 'logo-preview-area',
90  'data-main-page' => wfMessage( 'config-logo-preview-main' ),
91  'data-filedrop' => wfMessage( 'config-logo-filedrop' )
92  ] ) .
93  Html::closeElement( 'div' ) .
94  Html::closeElement( 'div' )
95  );
96  }
97 
102  private function addModeOptions(): void {
103  $this->addHTML(
104  # User Rights
105  // getRadioSet() builds a set of labeled radio buttons.
106  // For grep: The following messages are used as the item labels:
107  // config-profile-wiki, config-profile-no-anon, config-profile-fishbowl, config-profile-private
108  $this->parent->getRadioSet( [
109  'var' => '_RightsProfile',
110  'label' => 'config-profile',
111  'itemLabelPrefix' => 'config-profile-',
112  'values' => array_keys( $this->parent->rightsProfiles ),
113  ] ) .
114  $this->parent->getInfoBox( wfMessage( 'config-profile-help' )->plain() ) .
115 
116  # Licensing
117  // getRadioSet() builds a set of labeled radio buttons.
118  // For grep: The following messages are used as the item labels:
119  // config-license-cc-by, config-license-cc-by-sa, config-license-cc-by-nc-sa,
120  // config-license-cc-0, config-license-pd, config-license-gfdl,
121  // config-license-none, config-license-cc-choose
122  $this->parent->getRadioSet( [
123  'var' => '_LicenseCode',
124  'label' => 'config-license',
125  'itemLabelPrefix' => 'config-license-',
126  'values' => array_keys( $this->parent->licenses ),
127  'commonAttribs' => [ 'class' => 'licenseRadio' ],
128  ] ) .
129  $this->getCCChooser() .
130  $this->parent->getHelpBox( 'config-license-help' )
131  );
132  }
133 
138  private function addEmailOptions(): void {
139  $emailwrapperStyle = $this->getVar( 'wgEnableEmail' ) ? '' : 'display: none';
140  $this->addHTML(
141  $this->getFieldsetStart( 'config-email-settings' ) .
142  $this->parent->getCheckBox( [
143  'var' => 'wgEnableEmail',
144  'label' => 'config-enable-email',
145  'attribs' => [ 'class' => 'showHideRadio', 'rel' => 'emailwrapper' ],
146  ] ) .
147  $this->parent->getHelpBox( 'config-enable-email-help' ) .
148  "<div id=\"emailwrapper\" style=\"$emailwrapperStyle\">" .
149  $this->parent->getTextBox( [
150  'var' => 'wgPasswordSender',
151  'label' => 'config-email-sender'
152  ] ) .
153  $this->parent->getHelpBox( 'config-email-sender-help' ) .
154  $this->parent->getCheckBox( [
155  'var' => 'wgEnableUserEmail',
156  'label' => 'config-email-user',
157  ] ) .
158  $this->parent->getHelpBox( 'config-email-user-help' ) .
159  $this->parent->getCheckBox( [
160  'var' => 'wgEnotifUserTalk',
161  'label' => 'config-email-usertalk',
162  ] ) .
163  $this->parent->getHelpBox( 'config-email-usertalk-help' ) .
164  $this->parent->getCheckBox( [
165  'var' => 'wgEnotifWatchlist',
166  'label' => 'config-email-watchlist',
167  ] ) .
168  $this->parent->getHelpBox( 'config-email-watchlist-help' ) .
169  $this->parent->getCheckBox( [
170  'var' => 'wgEmailAuthentication',
171  'label' => 'config-email-auth',
172  ] ) .
173  $this->parent->getHelpBox( 'config-email-auth-help' ) .
174  "</div>" .
175  $this->getFieldsetEnd()
176  );
177  }
178 
183  private function addSkinOptions(): void {
184  $skins = $this->parent->findExtensions( 'skins' )->value;
185  '@phan-var array[] $skins';
186  $skinHtml = $this->getFieldsetStart( 'config-skins' );
187 
188  $skinNames = array_map( 'strtolower', array_keys( $skins ) );
189  $chosenSkinName = $this->getVar( 'wgDefaultSkin', $this->parent->getDefaultSkin( $skinNames ) );
190 
191  if ( $skins ) {
192  $radioButtons = $this->parent->getRadioElements( [
193  'var' => 'wgDefaultSkin',
194  'itemLabels' => array_fill_keys( $skinNames, 'config-skins-use-as-default' ),
195  'values' => $skinNames,
196  'value' => $chosenSkinName,
197  ] );
198 
199  foreach ( $skins as $skin => $info ) {
200  if ( isset( $info['screenshots'] ) ) {
201  $screenshotText = $this->makeScreenshotsLink( $skin, $info['screenshots'] );
202  } else {
203  $screenshotText = htmlspecialchars( $skin );
204  }
205  $skinHtml .=
206  '<div class="config-skins-item">' .
207  // @phan-suppress-next-line SecurityCheck-DoubleEscaped
208  $this->parent->getCheckBox( [
209  'var' => "skin-$skin",
210  'rawtext' => $screenshotText,
211  'value' => $this->getVar( "skin-$skin", true ), // all found skins enabled by default
212  ] ) .
213  '<div class="config-skins-use-as-default">' . $radioButtons[strtolower( $skin )] . '</div>' .
214  '</div>';
215  }
216  } else {
217  $skinHtml .=
218  Html::warningBox( wfMessage( 'config-skins-missing' )->plain(), 'config-warning-box' ) .
219  Html::hidden( 'config_wgDefaultSkin', $chosenSkinName );
220  }
221 
222  $skinHtml .= $this->parent->getHelpBox( 'config-skins-help' ) .
223  $this->getFieldsetEnd();
224  $this->addHTML( $skinHtml );
225  }
226 
231  private function addExtensionOptions(): void {
232  global $wgLang;
233 
234  $extensions = $this->parent->findExtensions()->value;
235  '@phan-var array[] $extensions';
236  $dependencyMap = [];
237 
238  if ( $extensions ) {
239  $extHtml = $this->getFieldsetStart( 'config-extensions' );
240 
241  $extByType = [];
243  // Sort by type first
244  foreach ( $extensions as $ext => $info ) {
245  if ( !isset( $info['type'] ) || !isset( $types[$info['type']] ) ) {
246  // We let extensions normally define custom types, but
247  // since we aren't loading extensions, we'll have to
248  // categorize them under other
249  $info['type'] = 'other';
250  }
251  $extByType[$info['type']][$ext] = $info;
252  }
253 
254  foreach ( $types as $type => $message ) {
255  if ( !isset( $extByType[$type] ) ) {
256  continue;
257  }
258  $extHtml .= Html::element( 'h2', [], $message );
259  foreach ( $extByType[$type] as $ext => $info ) {
260  $urlText = '';
261  if ( isset( $info['url'] ) ) {
262  $urlText = ' ' . Html::element( 'a', [ 'href' => $info['url'] ], '(more information)' );
263  }
264  $attribs = [
265  'data-name' => $ext,
266  'class' => 'config-ext-input'
267  ];
268  $labelAttribs = [];
269  $fullDepList = [];
270  if ( isset( $info['requires']['extensions'] ) ) {
271  $dependencyMap[$ext]['extensions'] = $info['requires']['extensions'];
272  $labelAttribs['class'] = 'mw-ext-with-dependencies';
273  }
274  if ( isset( $info['requires']['skins'] ) ) {
275  $dependencyMap[$ext]['skins'] = $info['requires']['skins'];
276  $labelAttribs['class'] = 'mw-ext-with-dependencies';
277  }
278  if ( isset( $dependencyMap[$ext] ) ) {
279  $links = [];
280  // For each dependency, link to the checkbox for each
281  // extension/skin that is required
282  if ( isset( $dependencyMap[$ext]['extensions'] ) ) {
283  foreach ( $dependencyMap[$ext]['extensions'] as $name ) {
284  $links[] = Html::element(
285  'a',
286  [ 'href' => "#config_ext-$name" ],
287  $name
288  );
289  }
290  }
291  if ( isset( $dependencyMap[$ext]['skins'] ) ) {
292  // @phan-suppress-next-line PhanTypeMismatchForeach Phan internal bug
293  foreach ( $dependencyMap[$ext]['skins'] as $name ) {
294  $links[] = Html::element(
295  'a',
296  [ 'href' => "#config_skin-$name" ],
297  $name
298  );
299  }
300  }
301 
302  // @phan-suppress-next-line SecurityCheck-XSS
303  $text = wfMessage( 'config-extensions-requires' )
304  ->rawParams( $ext, $wgLang->commaList( $links ) )
305  ->escaped();
306  } else {
307  $text = $ext;
308  }
309  // @phan-suppress-next-line SecurityCheck-DoubleEscaped
310  $extHtml .= $this->parent->getCheckBox( [
311  'var' => "ext-$ext",
312  'rawtext' => $text,
313  'attribs' => $attribs,
314  'labelAttribs' => $labelAttribs,
315  ] );
316  }
317  }
318 
319  $extHtml .= $this->parent->getHelpBox( 'config-extensions-help' ) .
320  $this->getFieldsetEnd();
321  $this->addHTML( $extHtml );
322  // Push the dependency map to the client side
323  $this->addHTML( Html::inlineScript(
324  'var extDependencyMap = ' . Xml::encodeJsVar( $dependencyMap )
325  ) );
326  }
327  }
328 
333  private function addFileOptions(): void {
334  // Having / in paths in Windows looks funny :)
335  $this->setVar( 'wgDeletedDirectory',
336  str_replace(
337  '/', DIRECTORY_SEPARATOR,
338  $this->getVar( 'wgDeletedDirectory' )
339  )
340  );
341 
342  $uploadwrapperStyle = $this->getVar( 'wgEnableUploads' ) ? '' : 'display: none';
343  $this->addHTML(
344  # Uploading
345  $this->getFieldsetStart( 'config-upload-settings' ) .
346  $this->parent->getCheckBox( [
347  'var' => 'wgEnableUploads',
348  'label' => 'config-upload-enable',
349  'attribs' => [ 'class' => 'showHideRadio', 'rel' => 'uploadwrapper' ],
350  'help' => $this->parent->getHelpBox( 'config-upload-help' )
351  ] ) .
352  '<div id="uploadwrapper" style="' . $uploadwrapperStyle . '">' .
353  $this->parent->getTextBox( [
354  'var' => 'wgDeletedDirectory',
355  'label' => 'config-upload-deleted',
356  'attribs' => [ 'dir' => 'ltr' ],
357  'help' => $this->parent->getHelpBox( 'config-upload-deleted-help' )
358  ] ) .
359  '</div>'
360  );
361  $this->addHTML(
362  $this->parent->getCheckBox( [
363  'var' => 'wgUseInstantCommons',
364  'label' => 'config-instantcommons',
365  'help' => $this->parent->getHelpBox( 'config-instantcommons-help' )
366  ] ) .
367  $this->getFieldsetEnd()
368  );
369  }
370 
375  private function addAdvancedOptions(): void {
376  $caches = [ 'none' ];
377  $cachevalDefault = 'none';
378 
379  if ( count( $this->getVar( '_Caches' ) ) ) {
380  // A CACHE_ACCEL implementation is available
381  $caches[] = 'accel';
382  $cachevalDefault = 'accel';
383  }
384  $caches[] = 'memcached';
385 
386  // We'll hide/show this on demand when the value changes, see config.js.
387  $cacheval = $this->getVar( '_MainCacheType' );
388  if ( !$cacheval ) {
389  // We need to set a default here; but don't hardcode it
390  // or we lose it every time we reload the page for validation
391  // or going back!
392  $cacheval = $cachevalDefault;
393  }
394  $hidden = ( $cacheval == 'memcached' ) ? '' : 'display: none';
395  $this->addHTML(
396  # Advanced settings
397  $this->getFieldsetStart( 'config-advanced-settings' ) .
398  # Object cache settings
399  // getRadioSet() builds a set of labeled radio buttons.
400  // For grep: The following messages are used as the item labels:
401  // config-cache-none, config-cache-accel, config-cache-memcached
402  $this->parent->getRadioSet( [
403  'var' => '_MainCacheType',
404  'label' => 'config-cache-options',
405  'itemLabelPrefix' => 'config-cache-',
406  'values' => $caches,
407  'value' => $cacheval,
408  ] ) .
409  $this->parent->getHelpBox( 'config-cache-help' ) .
410  "<div id=\"config-memcachewrapper\" style=\"$hidden\">" .
411  $this->parent->getTextArea( [
412  'var' => '_MemCachedServers',
413  'label' => 'config-memcached-servers',
414  'help' => $this->parent->getHelpBox( 'config-memcached-help' )
415  ] ) .
416  '</div>' .
417  $this->getFieldsetEnd()
418  );
419  }
420 
426  private function makeScreenshotsLink( $name, $screenshots ) {
427  global $wgLang;
428  if ( count( $screenshots ) > 1 ) {
429  $links = [];
430  $counter = 1;
431 
432  foreach ( $screenshots as $shot ) {
433  $links[] = Html::element(
434  'a',
435  [ 'href' => $shot, 'target' => '_blank' ],
436  $wgLang->formatNum( $counter++ )
437  );
438  }
439  return wfMessage( 'config-skins-screenshots' )
440  ->rawParams( $name, $wgLang->commaList( $links ) )
441  ->escaped();
442  } else {
443  $link = Html::element(
444  'a',
445  [ 'href' => $screenshots[0], 'target' => '_blank' ],
446  wfMessage( 'config-screenshot' )->text()
447  );
448  return wfMessage( 'config-skins-screenshot', $name )->rawParams( $link )->escaped();
449  }
450  }
451 
455  public function getCCPartnerUrl() {
456  $server = $this->getVar( 'wgServer' );
457  $exitUrl = $server . $this->parent->getUrl( [
458  'page' => 'Options',
459  'SubmitCC' => 'indeed',
460  'config__LicenseCode' => 'cc',
461  'config_wgRightsUrl' => '[license_url]',
462  'config_wgRightsText' => '[license_name]',
463  'config_wgRightsIcon' => '[license_button]',
464  ] );
465  $styleUrl = $server . dirname( dirname( $this->parent->getUrl() ) ) .
466  '/mw-config/config-cc.css';
467  $iframeUrl = 'https://creativecommons.org/license/?' .
468  wfArrayToCgi( [
469  'partner' => 'MediaWiki',
470  'exit_url' => $exitUrl,
471  'lang' => $this->getVar( '_UserLang' ),
472  'stylesheet' => $styleUrl,
473  ] );
474 
475  return $iframeUrl;
476  }
477 
481  public function getCCChooser() {
482  $iframeAttribs = [
483  'class' => 'config-cc-iframe',
484  'name' => 'config-cc-iframe',
485  'id' => 'config-cc-iframe',
486  'frameborder' => 0,
487  'width' => '100%',
488  'height' => '100%',
489  ];
490  if ( $this->getVar( '_CCDone' ) ) {
491  $iframeAttribs['src'] = $this->parent->getUrl( [ 'ShowCC' => 'yes' ] );
492  } else {
493  $iframeAttribs['src'] = $this->getCCPartnerUrl();
494  }
495  $wrapperStyle = ( $this->getVar( '_LicenseCode' ) == 'cc-choose' ) ? '' : 'display: none';
496 
497  return "<div class=\"config-cc-wrapper\" id=\"config-cc-wrapper\" style=\"$wrapperStyle\">\n" .
498  Html::element( 'iframe', $iframeAttribs ) .
499  "</div>\n";
500  }
501 
505  public function getCCDoneBox() {
506  $js = "parent.document.getElementById('config-cc-wrapper').style.height = '$1';";
507  // If you change this height, also change it in config.css
508  $expandJs = str_replace( '$1', '54em', $js );
509  $reduceJs = str_replace( '$1', '70px', $js );
510 
511  return '<p>' .
512  Html::element( 'img', [ 'src' => $this->getVar( 'wgRightsIcon' ) ] ) .
513  "\u{00A0}\u{00A0}" .
514  htmlspecialchars( $this->getVar( 'wgRightsText' ) ) .
515  "</p>\n" .
516  "<p style=\"text-align: center;\">" .
517  Html::element( 'a',
518  [
519  'href' => $this->getCCPartnerUrl(),
520  'onclick' => $expandJs,
521  ],
522  wfMessage( 'config-cc-again' )->text()
523  ) .
524  "</p>\n" .
525  "<script>\n" .
526  # Reduce the wrapper div height
527  htmlspecialchars( $reduceJs ) .
528  "\n" .
529  "</script>\n";
530  }
531 
532  public function submitCC() {
533  $newValues = $this->parent->setVarsFromRequest(
534  [ 'wgRightsUrl', 'wgRightsText', 'wgRightsIcon' ] );
535  if ( count( $newValues ) != 3 ) {
536  $this->parent->showError( 'config-cc-error' );
537 
538  return;
539  }
540  $this->setVar( '_CCDone', true );
541  $this->addHTML( $this->getCCDoneBox() );
542  }
543 
550  public function submitSkins() {
551  $skins = array_keys( $this->parent->findExtensions( 'skins' )->value );
552  $this->parent->setVar( '_Skins', $skins );
553 
554  if ( $skins ) {
555  $skinNames = array_map( 'strtolower', $skins );
556  $this->parent->setVar( 'wgDefaultSkin', $this->parent->getDefaultSkin( $skinNames ) );
557  }
558 
559  return true;
560  }
561 
565  public function submit() {
566  $this->parent->setVarsFromRequest( [ '_RightsProfile', '_LicenseCode',
567  'wgEnableEmail', 'wgPasswordSender', 'wgEnableUploads',
568  '_Logo1x', '_LogoWordmark', '_LogoTagline', '_LogoIcon',
569  'wgEnableUserEmail', 'wgEnotifUserTalk', 'wgEnotifWatchlist',
570  'wgEmailAuthentication', '_MainCacheType', '_MemCachedServers',
571  'wgUseInstantCommons', 'wgDefaultSkin' ] );
572 
573  $retVal = true;
574 
575  if ( !array_key_exists( $this->getVar( '_RightsProfile' ), $this->parent->rightsProfiles ) ) {
576  reset( $this->parent->rightsProfiles );
577  $this->setVar( '_RightsProfile', key( $this->parent->rightsProfiles ) );
578  }
579 
580  $code = $this->getVar( '_LicenseCode' );
581  if ( $code == 'cc-choose' ) {
582  if ( !$this->getVar( '_CCDone' ) ) {
583  $this->parent->showError( 'config-cc-not-chosen' );
584  $retVal = false;
585  }
586  } elseif ( array_key_exists( $code, $this->parent->licenses ) ) {
587  // Messages:
588  // config-license-cc-by, config-license-cc-by-sa, config-license-cc-by-nc-sa,
589  // config-license-cc-0, config-license-pd, config-license-gfdl, config-license-none,
590  // config-license-cc-choose
591  $entry = $this->parent->licenses[$code];
592  $this->setVar( 'wgRightsText',
593  $entry['text'] ?? wfMessage( 'config-license-' . $code )->text() );
594  $this->setVar( 'wgRightsUrl', $entry['url'] );
595  $this->setVar( 'wgRightsIcon', $entry['icon'] );
596  } else {
597  $this->setVar( 'wgRightsText', '' );
598  $this->setVar( 'wgRightsUrl', '' );
599  $this->setVar( 'wgRightsIcon', '' );
600  }
601 
602  $skinsAvailable = array_keys( $this->parent->findExtensions( 'skins' )->value );
603  $skinsToInstall = [];
604  foreach ( $skinsAvailable as $skin ) {
605  $this->parent->setVarsFromRequest( [ "skin-$skin" ] );
606  if ( $this->getVar( "skin-$skin" ) ) {
607  $skinsToInstall[] = $skin;
608  }
609  }
610  $this->parent->setVar( '_Skins', $skinsToInstall );
611 
612  if ( !$skinsToInstall && $skinsAvailable ) {
613  $this->parent->showError( 'config-skins-must-enable-some' );
614  $retVal = false;
615  }
616  $defaultSkin = $this->getVar( 'wgDefaultSkin' );
617  $skinsToInstallLowercase = array_map( 'strtolower', $skinsToInstall );
618  if ( $skinsToInstall && array_search( $defaultSkin, $skinsToInstallLowercase ) === false ) {
619  $this->parent->showError( 'config-skins-must-enable-default' );
620  $retVal = false;
621  }
622 
623  $extsAvailable = array_keys( $this->parent->findExtensions()->value );
624  $extsToInstall = [];
625  foreach ( $extsAvailable as $ext ) {
626  $this->parent->setVarsFromRequest( [ "ext-$ext" ] );
627  if ( $this->getVar( "ext-$ext" ) ) {
628  $extsToInstall[] = $ext;
629  }
630  }
631  $this->parent->setVar( '_Extensions', $extsToInstall );
632 
633  if ( $this->getVar( '_MainCacheType' ) == 'memcached' ) {
634  $memcServers = explode( "\n", $this->getVar( '_MemCachedServers' ) );
635  // FIXME: explode() will always result in an array of at least one string, even on null (when
636  // the string will be empty and you'll get a PHP warning), so this has never worked?
637  // @phan-suppress-next-line PhanImpossibleCondition
638  if ( !$memcServers ) {
639  $this->parent->showError( 'config-memcache-needservers' );
640  $retVal = false;
641  }
642 
643  foreach ( $memcServers as $server ) {
644  $memcParts = explode( ":", $server, 2 );
645  if ( !isset( $memcParts[0] )
646  || ( !IPUtils::isValid( $memcParts[0] )
647  && ( gethostbyname( $memcParts[0] ) == $memcParts[0] ) )
648  ) {
649  $this->parent->showError( 'config-memcache-badip', $memcParts[0] );
650  $retVal = false;
651  } elseif ( !isset( $memcParts[1] ) ) {
652  $this->parent->showError( 'config-memcache-noport', $memcParts[0] );
653  $retVal = false;
654  } elseif ( $memcParts[1] < 1 || $memcParts[1] > 65535 ) {
655  $this->parent->showError( 'config-memcache-badport', 1, 65535 );
656  $retVal = false;
657  }
658  }
659  }
660 
661  return $retVal;
662  }
663 
664 }
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(!defined( 'MW_NO_SESSION') &&! $wgCommandLineMode) $wgLang
Definition: Setup.php:485
static inlineScript( $contents, $nonce=null)
Output an HTML script tag with the given contents.
Definition: Html.php:593
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:236
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:214
static warningBox( $html, $className='')
Return a warning box.
Definition: Html.php:775
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:256
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:320
static hidden( $name, $value, array $attribs=[])
Convenience function to produce an input element with type=hidden.
Definition: Html.php:851
static getExtensionTypes()
Returns an array with the base extension types.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:68
addSkinOptions()
Opt-in for bundled skins.
addAdvancedOptions()
System administration related options.
addFileOptions()
Image and file upload options.
addExtensionOptions()
Opt-in for bundled extensions.
addModeOptions()
Wiki mode - user rights and copyright model.
makeScreenshotsLink( $name, $screenshots)
addEmailOptions()
User email options.
submitSkins()
If the user skips this installer page, we still need to set up the default skins, but ignore everythi...
Abstract class to define pages for the web installer.
WebInstaller $parent
The WebInstaller object this WebInstallerPage belongs to.
endForm( $continue='continue', $back='back')
getVar( $var, $default=null)
getFieldsetStart( $legend)
Get the starting tags of a fieldset.
getTextBox( $params)
Get a labelled text box to configure a variable.
getHelpBox( $msg,... $args)
Get small text indented help for a preceding form field.
static encodeJsVar( $value, $pretty=false)
Encode a variable of arbitrary type to JavaScript.
Definition: Xml.php:678
if(!is_readable( $file)) $ext
Definition: router.php:48