31 if ( $this->
getVar(
'_SkipOptional' ) ==
'skip' ) {
35 if ( $this->parent->request->wasPosted() && $this->submit() ) {
40 $this->addModeOptions();
41 $this->addEmailOptions();
42 $this->addSkinOptions();
43 $this->addExtensionOptions();
44 $this->addFileOptions();
45 $this->addPersonalizationOptions();
46 $this->addAdvancedOptions();
52 private function addPersonalizationOptions() {
56 Html::rawElement(
'div', [
57 'class' =>
'config-drag-drop'
58 ],
wfMessage(
'config-logo-summary' )->parse() ) .
59 Html::openElement(
'div', [
60 'class' =>
'config-personalization-options'
62 Html::hidden(
'config_LogoSiteName', $this->
getVar(
'wgSitename' ) ) .
66 'value' =>
'$wgResourceBasePath/resources/assets/change-your-logo.svg',
67 'label' =>
'config-logo-icon',
68 'attribs' => [
'dir' =>
'ltr' ],
72 'var' =>
'_LogoWordmark',
73 'label' =>
'config-logo-wordmark',
74 'attribs' => [
'dir' =>
'ltr' ],
78 'var' =>
'_LogoTagline',
79 'label' =>
'config-logo-tagline',
80 'attribs' => [
'dir' =>
'ltr' ],
85 'label' =>
'config-logo-sidebar',
86 'attribs' => [
'dir' =>
'ltr' ],
89 Html::openElement(
'div', [
90 'class' =>
'logo-preview-area',
91 'data-main-page' =>
wfMessage(
'config-logo-preview-main' ),
92 'data-filedrop' =>
wfMessage(
'config-logo-filedrop' )
94 Html::closeElement(
'div' ) .
95 Html::closeElement(
'div' ) .
104 private function addModeOptions(): void {
110 $this->parent->getRadioSet( [
111 'var' =>
'_RightsProfile',
112 'label' =>
'config-profile',
113 'itemLabelPrefix' =>
'config-profile-',
114 'values' => array_keys( $this->parent->rightsProfiles ),
116 $this->parent->getInfoBox(
wfMessage(
'config-profile-help' )->plain() ) .
124 $this->parent->getRadioSet( [
125 'var' =>
'_LicenseCode',
126 'label' =>
'config-license',
127 'itemLabelPrefix' =>
'config-license-',
128 'values' => array_keys( $this->parent->licenses ),
129 'commonAttribs' => [
'class' =>
'licenseRadio' ],
132 $this->parent->getHelpBox(
'config-license-help' )
140 private function addEmailOptions(): void {
141 $emailwrapperStyle = $this->getVar(
'wgEnableEmail' ) ?
'' :
'display: none';
143 $this->getFieldsetStart(
'config-email-settings' ) .
144 $this->parent->getCheckBox( [
145 'var' =>
'wgEnableEmail',
146 'label' =>
'config-enable-email',
147 'attribs' => [
'class' =>
'showHideRadio',
'rel' =>
'emailwrapper' ],
149 $this->parent->getHelpBox(
'config-enable-email-help' ) .
150 "<div id=\"emailwrapper\" style=\"$emailwrapperStyle\">" .
151 $this->parent->getTextBox( [
152 'var' =>
'wgPasswordSender',
153 'label' =>
'config-email-sender'
155 $this->parent->getHelpBox(
'config-email-sender-help' ) .
156 $this->parent->getCheckBox( [
157 'var' =>
'wgEnableUserEmail',
158 'label' =>
'config-email-user',
160 $this->parent->getHelpBox(
'config-email-user-help' ) .
161 $this->parent->getCheckBox( [
162 'var' =>
'wgEnotifUserTalk',
163 'label' =>
'config-email-usertalk',
165 $this->parent->getHelpBox(
'config-email-usertalk-help' ) .
166 $this->parent->getCheckBox( [
167 'var' =>
'wgEnotifWatchlist',
168 'label' =>
'config-email-watchlist',
170 $this->parent->getHelpBox(
'config-email-watchlist-help' ) .
171 $this->parent->getCheckBox( [
172 'var' =>
'wgEmailAuthentication',
173 'label' =>
'config-email-auth',
175 $this->parent->getHelpBox(
'config-email-auth-help' ) .
177 $this->getFieldsetEnd()
185 private function addSkinOptions(): void {
186 $skins = $this->parent->findExtensions(
'skins' )->value;
187 '@phan-var array[] $skins';
188 $skinHtml = $this->getFieldsetStart(
'config-skins' );
190 $skinNames = array_map(
'strtolower', array_keys( $skins ) );
191 $chosenSkinName = $this->getVar(
'wgDefaultSkin', $this->parent->getDefaultSkin( $skinNames ) );
194 $radioButtons = $this->parent->getRadioElements( [
195 'var' =>
'wgDefaultSkin',
196 'itemLabels' => array_fill_keys( $skinNames,
'config-skins-use-as-default' ),
197 'values' => $skinNames,
198 'value' => $chosenSkinName,
201 foreach ( $skins as $skin => $info ) {
202 if ( isset( $info[
'screenshots'] ) ) {
203 $screenshotText = $this->makeScreenshotsLink( $skin, $info[
'screenshots'] );
205 $screenshotText = htmlspecialchars( $skin );
208 '<div class="config-skins-item">' .
209 $this->parent->getCheckBox( [
210 'var' =>
"skin-$skin",
211 'rawtext' => $screenshotText . $this->makeMoreInfoLink( $info ),
212 'value' => $this->getVar(
"skin-$skin",
true ),
214 '<div class="config-skins-use-as-default">' . $radioButtons[strtolower( $skin )] .
'</div>' .
219 Html::warningBox(
wfMessage(
'config-skins-missing' )->plain(),
'config-warning-box' ) .
220 Html::hidden(
'config_wgDefaultSkin', $chosenSkinName );
223 $skinHtml .= $this->parent->getHelpBox(
'config-skins-help' ) .
224 $this->getFieldsetEnd();
225 $this->addHTML( $skinHtml );
232 private function addExtensionOptions(): void {
235 $extensions = $this->parent->findExtensions()->value;
236 '@phan-var array[] $extensions';
240 $extHtml = $this->getFieldsetStart(
'config-extensions' );
245 foreach ( $extensions as
$ext => $info ) {
246 if ( !isset( $info[
'type'] ) || !isset( $types[$info[
'type']] ) ) {
250 $info[
'type'] =
'other';
252 $extByType[$info[
'type']][
$ext] = $info;
255 foreach ( $types as
$type => $message ) {
256 if ( !isset( $extByType[
$type] ) ) {
259 $extHtml .= Html::element(
'h2', [], $message );
260 foreach ( $extByType[
$type] as
$ext => $info ) {
263 'class' =>
'config-ext-input'
266 if ( isset( $info[
'requires'][
'extensions'] ) ) {
267 $dependencyMap[
$ext][
'extensions'] = $info[
'requires'][
'extensions'];
268 $labelAttribs[
'class'] =
'mw-ext-with-dependencies';
270 if ( isset( $info[
'requires'][
'skins'] ) ) {
271 $dependencyMap[
$ext][
'skins'] = $info[
'requires'][
'skins'];
272 $labelAttribs[
'class'] =
'mw-ext-with-dependencies';
274 if ( isset( $dependencyMap[
$ext] ) ) {
278 if ( isset( $dependencyMap[
$ext][
'extensions'] ) ) {
279 foreach ( $dependencyMap[
$ext][
'extensions'] as $name ) {
280 $links[] = Html::element(
282 [
'href' =>
"#config_ext-$name" ],
287 if ( isset( $dependencyMap[
$ext][
'skins'] ) ) {
289 foreach ( $dependencyMap[
$ext][
'skins'] as $name ) {
290 $links[] = Html::element(
292 [
'href' =>
"#config_skin-$name" ],
298 $text =
wfMessage(
'config-extensions-requires' )
304 $extHtml .= $this->parent->getCheckBox( [
306 'rawtext' => $text . $this->makeMoreInfoLink( $info ),
307 'attribs' => $attribs,
308 'labelAttribs' => $labelAttribs,
313 $extHtml .= $this->parent->getHelpBox(
'config-extensions-help' ) .
314 $this->getFieldsetEnd();
315 $this->addHTML( $extHtml );
317 $this->addHTML( Html::inlineScript(
318 'var extDependencyMap = ' . Xml::encodeJsVar( $dependencyMap )
327 private function addFileOptions(): void {
329 $this->setVar(
'wgDeletedDirectory',
331 '/', DIRECTORY_SEPARATOR,
332 $this->getVar(
'wgDeletedDirectory' )
336 $uploadwrapperStyle = $this->getVar(
'wgEnableUploads' ) ?
'' :
'display: none';
339 $this->getFieldsetStart(
'config-upload-settings' ) .
340 $this->parent->getCheckBox( [
341 'var' =>
'wgEnableUploads',
342 'label' =>
'config-upload-enable',
343 'attribs' => [
'class' =>
'showHideRadio',
'rel' =>
'uploadwrapper' ],
344 'help' => $this->parent->getHelpBox(
'config-upload-help' )
346 '<div id="uploadwrapper" style="' . $uploadwrapperStyle .
'">' .
347 $this->parent->getTextBox( [
348 'var' =>
'wgDeletedDirectory',
349 'label' =>
'config-upload-deleted',
350 'attribs' => [
'dir' =>
'ltr' ],
351 'help' => $this->parent->getHelpBox(
'config-upload-deleted-help' )
356 $this->parent->getCheckBox( [
357 'var' =>
'wgUseInstantCommons',
358 'label' =>
'config-instantcommons',
359 'help' => $this->parent->getHelpBox(
'config-instantcommons-help' )
361 $this->getFieldsetEnd()
369 private function addAdvancedOptions(): void {
370 $caches = [
'none' ];
371 $cachevalDefault =
'none';
373 if ( count( $this->getVar(
'_Caches' ) ) ) {
376 $cachevalDefault =
'accel';
378 $caches[] =
'memcached';
381 $cacheval = $this->getVar(
'_MainCacheType' );
386 $cacheval = $cachevalDefault;
388 $hidden = ( $cacheval ==
'memcached' ) ?
'' :
'display: none';
391 $this->getFieldsetStart(
'config-advanced-settings' ) .
392 # Object cache settings
396 $this->parent->getRadioSet( [
397 'var' =>
'_MainCacheType',
398 'label' =>
'config-cache-options',
399 'itemLabelPrefix' =>
'config-cache-',
401 'value' => $cacheval,
403 $this->parent->getHelpBox(
'config-cache-help' ) .
404 "<div id=\"config-memcachewrapper\" style=\"$hidden\">" .
405 $this->parent->getTextArea( [
406 'var' =>
'_MemCachedServers',
407 'label' =>
'config-memcached-servers',
408 'help' => $this->parent->getHelpBox(
'config-memcached-help' )
411 $this->getFieldsetEnd()
420 private function makeScreenshotsLink( $name, $screenshots ) {
422 if ( count( $screenshots ) > 1 ) {
426 foreach ( $screenshots as $shot ) {
427 $links[] = Html::element(
429 [
'href' => $shot,
'target' =>
'_blank' ],
430 $wgLang->formatNum( $counter++ )
433 return wfMessage(
'config-skins-screenshots' )
434 ->rawParams( $name,
$wgLang->commaList( $links ) )
437 $link = Html::element(
439 [
'href' => $screenshots[0],
'target' =>
'_blank' ],
442 return wfMessage(
'config-skins-screenshot', $name )->rawParams( $link )->escaped();
450 private function makeMoreInfoLink( $info ) {
451 if ( !isset( $info[
'url'] ) ) {
454 return ' ' .
wfMessage(
'parentheses' )->rawParams(
457 [
'href' => $info[
'url'] ],
458 wfMessage(
'config-ext-skins-more-info' )->text()
467 $server = $this->getVar(
'wgServer' );
468 $exitUrl = $server . $this->parent->getUrl( [
470 'SubmitCC' =>
'indeed',
471 'config__LicenseCode' =>
'cc',
472 'config_wgRightsUrl' =>
'[license_url]',
473 'config_wgRightsText' =>
'[license_name]',
474 'config_wgRightsIcon' =>
'[license_button]',
476 $styleUrl = $server . dirname( dirname( $this->parent->getUrl() ) ) .
477 '/mw-config/config-cc.css';
478 $iframeUrl =
'https://creativecommons.org/license/?' .
480 'partner' =>
'MediaWiki',
481 'exit_url' => $exitUrl,
482 'lang' => $this->getVar(
'_UserLang' ),
483 'stylesheet' => $styleUrl,
494 'class' =>
'config-cc-iframe',
495 'name' =>
'config-cc-iframe',
496 'id' =>
'config-cc-iframe',
501 if ( $this->getVar(
'_CCDone' ) ) {
502 $iframeAttribs[
'src'] = $this->parent->getUrl( [
'ShowCC' =>
'yes' ] );
504 $iframeAttribs[
'src'] = $this->getCCPartnerUrl();
506 $wrapperStyle = ( $this->getVar(
'_LicenseCode' ) ==
'cc-choose' ) ?
'' :
'display: none';
508 return "<div class=\"config-cc-wrapper\" id=\"config-cc-wrapper\" style=\"$wrapperStyle\">\n" .
509 Html::element(
'iframe', $iframeAttribs ) .
517 $js =
"parent.document.getElementById('config-cc-wrapper').style.height = '$1';";
519 $expandJs = str_replace(
'$1',
'54em', $js );
520 $reduceJs = str_replace(
'$1',
'70px', $js );
523 Html::element(
'img', [
'src' => $this->getVar(
'wgRightsIcon' ) ] ) .
525 htmlspecialchars( $this->getVar(
'wgRightsText' ) ) .
527 "<p style=\"text-align: center;\">" .
530 'href' => $this->getCCPartnerUrl(),
531 'onclick' => $expandJs,
537 # Reduce the wrapper div height
538 htmlspecialchars( $reduceJs ) .
544 $newValues = $this->parent->setVarsFromRequest(
545 [
'wgRightsUrl',
'wgRightsText',
'wgRightsIcon' ] );
546 if ( count( $newValues ) != 3 ) {
547 $this->parent->showError(
'config-cc-error' );
551 $this->setVar(
'_CCDone',
true );
552 $this->addHTML( $this->getCCDoneBox() );
562 $skins = array_keys( $this->parent->findExtensions(
'skins' )->value );
563 $this->parent->setVar(
'_Skins', $skins );
566 $skinNames = array_map(
'strtolower', $skins );
567 $this->parent->setVar(
'wgDefaultSkin', $this->parent->getDefaultSkin( $skinNames ) );
577 $this->parent->setVarsFromRequest( [
'_RightsProfile',
'_LicenseCode',
578 'wgEnableEmail',
'wgPasswordSender',
'wgEnableUploads',
579 '_Logo1x',
'_LogoWordmark',
'_LogoTagline',
'_LogoIcon',
580 'wgEnableUserEmail',
'wgEnotifUserTalk',
'wgEnotifWatchlist',
581 'wgEmailAuthentication',
'_MainCacheType',
'_MemCachedServers',
582 'wgUseInstantCommons',
'wgDefaultSkin' ] );
586 if ( !array_key_exists( $this->getVar(
'_RightsProfile' ), $this->parent->rightsProfiles ) ) {
587 $this->setVar(
'_RightsProfile', array_key_first( $this->parent->rightsProfiles ) );
590 $code = $this->getVar(
'_LicenseCode' );
591 if ( $code ==
'cc-choose' ) {
592 if ( !$this->getVar(
'_CCDone' ) ) {
593 $this->parent->showError(
'config-cc-not-chosen' );
596 } elseif ( array_key_exists( $code, $this->parent->licenses ) ) {
601 $entry = $this->parent->licenses[$code];
602 $this->setVar(
'wgRightsText',
603 $entry[
'text'] ??
wfMessage(
'config-license-' . $code )->text() );
604 $this->setVar(
'wgRightsUrl', $entry[
'url'] );
605 $this->setVar(
'wgRightsIcon', $entry[
'icon'] );
607 $this->setVar(
'wgRightsText',
'' );
608 $this->setVar(
'wgRightsUrl',
'' );
609 $this->setVar(
'wgRightsIcon',
'' );
612 $skinsAvailable = array_keys( $this->parent->findExtensions(
'skins' )->value );
613 $skinsToInstall = [];
614 foreach ( $skinsAvailable as $skin ) {
615 $this->parent->setVarsFromRequest( [
"skin-$skin" ] );
616 if ( $this->getVar(
"skin-$skin" ) ) {
617 $skinsToInstall[] = $skin;
620 $this->parent->setVar(
'_Skins', $skinsToInstall );
622 if ( !$skinsToInstall && $skinsAvailable ) {
623 $this->parent->showError(
'config-skins-must-enable-some' );
626 $defaultSkin = $this->getVar(
'wgDefaultSkin' );
627 $skinsToInstallLowercase = array_map(
'strtolower', $skinsToInstall );
628 if ( $skinsToInstall && !in_array( $defaultSkin, $skinsToInstallLowercase ) ) {
629 $this->parent->showError(
'config-skins-must-enable-default' );
633 $extsAvailable = array_keys( $this->parent->findExtensions()->value );
635 foreach ( $extsAvailable as
$ext ) {
636 $this->parent->setVarsFromRequest( [
"ext-$ext" ] );
637 if ( $this->getVar(
"ext-$ext" ) ) {
638 $extsToInstall[] =
$ext;
641 $this->parent->setVar(
'_Extensions', $extsToInstall );
643 if ( $this->getVar(
'_MainCacheType' ) ==
'memcached' ) {
644 $memcServers = explode(
"\n", $this->getVar(
'_MemCachedServers' ) );
648 if ( !$memcServers ) {
649 $this->parent->showError(
'config-memcache-needservers' );
653 foreach ( $memcServers as $server ) {
654 $memcParts = explode(
":", $server, 2 );
655 if ( !isset( $memcParts[0] )
656 || ( !IPUtils::isValid( $memcParts[0] )
657 && ( gethostbyname( $memcParts[0] ) == $memcParts[0] ) )
659 $this->parent->showError(
'config-memcache-badip', $memcParts[0] );
661 } elseif ( !isset( $memcParts[1] ) ) {
662 $this->parent->showError(
'config-memcache-noport', $memcParts[0] );
664 } elseif ( $memcParts[1] < 1 || $memcParts[1] > 65535 ) {
665 $this->parent->showError(
'config-memcache-badport', 1, 65535 );
Abstract class to define pages for the web installer.
WebInstaller $parent
The WebInstaller object this WebInstallerPage belongs to.
endForm( $continue='continue', $back='back')
getFieldsetStart( $legend)
Get the starting tags of a fieldset.