21 if ( $this->
getVar(
'_SkipOptional' ) ==
'skip' ) {
25 if ( $this->parent->request->wasPosted() && $this->submit() ) {
30 $this->addModeOptions();
31 $this->addEmailOptions();
32 $this->addSkinOptions();
33 $this->addExtensionOptions();
34 $this->addFileOptions();
35 $this->addPersonalizationOptions();
36 $this->addAdvancedOptions();
42 private function addPersonalizationOptions() {
46 Html::rawElement(
'div', [
47 'class' =>
'config-drag-drop'
48 ],
wfMessage(
'config-logo-summary' )->parse() ) .
49 Html::openElement(
'div', [
50 'class' =>
'config-personalization-options'
52 Html::hidden(
'config_LogoSiteName', $this->
getVar(
'wgSitename' ) ) .
56 'value' =>
'$wgResourceBasePath/resources/assets/change-your-logo.svg',
57 'label' =>
'config-logo-icon',
58 'attribs' => [
'dir' =>
'ltr' ],
62 'var' =>
'_LogoWordmark',
63 'label' =>
'config-logo-wordmark',
64 'attribs' => [
'dir' =>
'ltr' ],
68 'var' =>
'_LogoTagline',
69 'label' =>
'config-logo-tagline',
70 'attribs' => [
'dir' =>
'ltr' ],
75 'label' =>
'config-logo-sidebar',
76 'attribs' => [
'dir' =>
'ltr' ],
79 Html::openElement(
'div', [
80 'class' =>
'logo-preview-area',
81 'data-main-page' =>
wfMessage(
'config-logo-preview-main' ),
82 'data-filedrop' =>
wfMessage(
'config-logo-filedrop' )
84 Html::closeElement(
'div' ) .
85 Html::closeElement(
'div' ) .
93 private function addModeOptions(): void {
99 $this->parent->getRadioSet( [
100 'var' =>
'_RightsProfile',
101 'label' =>
'config-profile',
102 'itemLabelPrefix' =>
'config-profile-',
103 'values' => array_keys( $this->parent->rightsProfiles ),
105 $this->parent->getInfoBox(
wfMessage(
'config-profile-help' )->plain() ) .
113 $this->parent->getRadioSet( [
114 'var' =>
'_LicenseCode',
115 'label' =>
'config-license',
116 'itemLabelPrefix' =>
'config-license-',
117 'values' => array_keys( $this->parent->licenses ),
118 'commonAttribs' => [
'class' =>
'licenseRadio' ],
120 $this->parent->getHelpBox(
'config-license-help' )
127 private function addEmailOptions(): void {
128 $emailwrapperStyle = $this->getVar(
'wgEnableEmail' ) ?
'' :
'display: none';
130 $this->getFieldsetStart(
'config-email-settings' ) .
131 $this->parent->getCheckBox( [
132 'var' =>
'wgEnableEmail',
133 'label' =>
'config-enable-email',
134 'attribs' => [
'class' =>
'showHideRadio',
'rel' =>
'emailwrapper' ],
136 $this->parent->getHelpBox(
'config-enable-email-help' ) .
137 "<div id=\"emailwrapper\" style=\"$emailwrapperStyle\">" .
138 $this->parent->getTextBox( [
139 'var' =>
'wgPasswordSender',
140 'label' =>
'config-email-sender'
142 $this->parent->getHelpBox(
'config-email-sender-help' ) .
143 $this->parent->getCheckBox( [
144 'var' =>
'wgEnableUserEmail',
145 'label' =>
'config-email-user',
147 $this->parent->getHelpBox(
'config-email-user-help' ) .
148 $this->parent->getCheckBox( [
149 'var' =>
'wgEnotifUserTalk',
150 'label' =>
'config-email-usertalk',
152 $this->parent->getHelpBox(
'config-email-usertalk-help' ) .
153 $this->parent->getCheckBox( [
154 'var' =>
'wgEnotifWatchlist',
155 'label' =>
'config-email-watchlist',
157 $this->parent->getHelpBox(
'config-email-watchlist-help' ) .
158 $this->parent->getCheckBox( [
159 'var' =>
'wgEmailAuthentication',
160 'label' =>
'config-email-auth',
162 $this->parent->getHelpBox(
'config-email-auth-help' ) .
164 $this->getFieldsetEnd()
171 private function addSkinOptions(): void {
172 $skins = $this->parent->findExtensions(
'skins' )->value;
173 '@phan-var array[] $skins';
174 $skinHtml = $this->getFieldsetStart(
'config-skins' );
176 $skinNames = array_map(
'strtolower', array_keys( $skins ) );
177 $chosenSkinName = $this->getVar(
'wgDefaultSkin', $this->parent->getDefaultSkin( $skinNames ) );
180 $radioButtons = $this->parent->getRadioElements( [
181 'var' =>
'wgDefaultSkin',
182 'itemLabels' => array_fill_keys( $skinNames,
'config-skins-use-as-default' ),
183 'values' => $skinNames,
184 'value' => $chosenSkinName,
187 foreach ( $skins as $skin => $info ) {
188 if ( isset( $info[
'screenshots'] ) ) {
189 $screenshotText = $this->makeScreenshotsLink( $skin, $info[
'screenshots'] );
191 $screenshotText = htmlspecialchars( $skin );
194 '<div class="config-skins-item">' .
195 $this->parent->getCheckBox( [
196 'var' =>
"skin-$skin",
197 'rawtext' => $screenshotText . $this->makeMoreInfoLink( $info ),
198 'value' => $this->getVar(
"skin-$skin",
true ),
200 '<div class="config-skins-use-as-default">' . $radioButtons[strtolower( $skin )] .
'</div>' .
205 Html::warningBox(
wfMessage(
'config-skins-missing' )->parse(),
'config-warning-box' ) .
206 Html::hidden(
'config_wgDefaultSkin', $chosenSkinName );
209 $skinHtml .= $this->parent->getHelpBox(
'config-skins-help' ) .
210 $this->getFieldsetEnd();
211 $this->addHTML( $skinHtml );
217 private function addExtensionOptions(): void {
220 $extensions = $this->parent->findExtensions()->value;
221 '@phan-var array[] $extensions';
225 $extHtml = $this->getFieldsetStart(
'config-extensions' );
228 $types = SpecialVersion::getExtensionTypes();
230 foreach ( $extensions as $ext => $info ) {
231 if ( !isset( $info[
'type'] ) || !isset( $types[$info[
'type']] ) ) {
235 $info[
'type'] =
'other';
237 $extByType[$info[
'type']][$ext] = $info;
240 foreach ( $types as $type => $message ) {
241 if ( !isset( $extByType[$type] ) ) {
244 $extHtml .= Html::element(
'h2', [], $message );
245 foreach ( $extByType[$type] as $ext => $info ) {
248 'class' =>
'config-ext-input cdx-checkbox__input'
251 if ( isset( $info[
'requires'][
'extensions'] ) ) {
252 $dependencyMap[$ext][
'extensions'] = $info[
'requires'][
'extensions'];
253 $labelAttribs[
'class'] =
'mw-ext-with-dependencies';
255 if ( isset( $info[
'requires'][
'skins'] ) ) {
256 $dependencyMap[$ext][
'skins'] = $info[
'requires'][
'skins'];
257 $labelAttribs[
'class'] =
'mw-ext-with-dependencies';
259 if ( isset( $dependencyMap[$ext] ) ) {
263 if ( isset( $dependencyMap[$ext][
'extensions'] ) ) {
264 foreach ( $dependencyMap[$ext][
'extensions'] as $name ) {
265 $links[] = Html::element(
267 [
'href' =>
"#config_ext-$name" ],
272 if ( isset( $dependencyMap[$ext][
'skins'] ) ) {
274 foreach ( $dependencyMap[$ext][
'skins'] as $name ) {
275 $links[] = Html::element(
277 [
'href' =>
"#config_skin-$name" ],
283 $text =
wfMessage(
'config-extensions-requires', $ext )
284 ->rawParams(
$wgLang->commaList( $links ) )
287 $text = htmlspecialchars( $ext );
289 $extHtml .= $this->parent->getCheckBox( [
291 'rawtext' => $text . $this->makeMoreInfoLink( $info ),
292 'attribs' => $attribs,
293 'labelAttribs' => $labelAttribs,
298 $extHtml .= $this->parent->getHelpBox(
'config-extensions-help' ) .
299 $this->getFieldsetEnd();
300 $this->addHTML( $extHtml );
302 $this->addHTML( $this->inlineScript(
303 'var extDependencyMap = ' . Html::encodeJsVar( $dependencyMap )
311 private function addFileOptions(): void {
313 $this->setVar(
'wgDeletedDirectory',
315 '/', DIRECTORY_SEPARATOR,
316 $this->getVar(
'wgDeletedDirectory' )
320 $uploadwrapperStyle = $this->getVar(
'wgEnableUploads' ) ?
'' :
'display: none';
323 $this->getFieldsetStart(
'config-upload-settings' ) .
324 $this->parent->getCheckBox( [
325 'var' =>
'wgEnableUploads',
326 'label' =>
'config-upload-enable',
327 'attribs' => [
'class' =>
'showHideRadio',
'rel' =>
'uploadwrapper' ],
328 'help' => $this->parent->getHelpBox(
'config-upload-help' )
330 '<div id="uploadwrapper" style="' . $uploadwrapperStyle .
'">' .
331 $this->parent->getTextBox( [
332 'var' =>
'wgDeletedDirectory',
333 'label' =>
'config-upload-deleted',
334 'attribs' => [
'dir' =>
'ltr' ],
335 'help' => $this->parent->getHelpBox(
'config-upload-deleted-help' )
340 $this->parent->getCheckBox( [
341 'var' =>
'wgUseInstantCommons',
342 'label' =>
'config-instantcommons',
343 'help' => $this->parent->getHelpBox(
'config-instantcommons-help' )
345 $this->getFieldsetEnd()
352 private function addAdvancedOptions(): void {
353 $caches = [
'none' ];
354 $cachevalDefault =
'none';
356 if ( count( $this->getVar(
'_Caches' ) ) ) {
359 $cachevalDefault =
'accel';
361 $caches[] =
'memcached';
364 $cacheval = $this->getVar(
'_MainCacheType' );
369 $cacheval = $cachevalDefault;
371 $hidden = ( $cacheval ==
'memcached' ) ?
'' :
'display: none';
374 $this->getFieldsetStart(
'config-advanced-settings' ) .
375 # Object cache settings
379 $this->parent->getRadioSet( [
380 'var' =>
'_MainCacheType',
381 'label' =>
'config-cache-options',
382 'itemLabelPrefix' =>
'config-cache-',
384 'value' => $cacheval,
386 $this->parent->getHelpBox(
'config-cache-help' ) .
387 "<div id=\"config-memcachewrapper\" style=\"$hidden\">" .
388 $this->parent->getTextArea( [
389 'var' =>
'_MemCachedServers',
390 'label' =>
'config-memcached-servers',
391 'help' => $this->parent->getHelpBox(
'config-memcached-help' )
394 $this->getFieldsetEnd()
403 private function makeScreenshotsLink( $name, $screenshots ) {
405 if ( count( $screenshots ) > 1 ) {
409 foreach ( $screenshots as $shot ) {
410 $links[] = Html::element(
412 [
'href' => $shot,
'target' =>
'_blank' ],
413 $wgLang->formatNum( $counter++ )
416 return wfMessage(
'config-skins-screenshots', $name )
417 ->rawParams(
$wgLang->commaList( $links ) )
420 $link = Html::element(
422 [
'href' => $screenshots[0],
'target' =>
'_blank' ],
425 return wfMessage(
'config-skins-screenshot', $name )->rawParams( $link )->escaped();
433 private function makeMoreInfoLink( $info ) {
434 if ( !isset( $info[
'url'] ) ) {
437 return ' ' .
wfMessage(
'parentheses' )->rawParams(
440 [
'href' => $info[
'url'] ],
441 wfMessage(
'config-ext-skins-more-info' )->text()
453 $skins = array_keys( $this->parent->findExtensions(
'skins' )->value );
454 $this->parent->setVar(
'_Skins', $skins );
457 $skinNames = array_map(
'strtolower', $skins );
458 $this->parent->setVar(
'wgDefaultSkin', $this->parent->getDefaultSkin( $skinNames ) );
468 $this->parent->setVarsFromRequest( [
'_RightsProfile',
'_LicenseCode',
469 'wgEnableEmail',
'wgPasswordSender',
'wgEnableUploads',
470 '_Logo1x',
'_LogoWordmark',
'_LogoTagline',
'_LogoIcon',
471 'wgEnableUserEmail',
'wgEnotifUserTalk',
'wgEnotifWatchlist',
472 'wgEmailAuthentication',
'_MainCacheType',
'_MemCachedServers',
473 'wgUseInstantCommons',
'wgDefaultSkin' ] );
477 if ( !array_key_exists( $this->getVar(
'_RightsProfile' ), $this->parent->rightsProfiles ) ) {
478 $this->setVar(
'_RightsProfile', array_key_first( $this->parent->rightsProfiles ) );
481 $code = $this->getVar(
'_LicenseCode' );
482 if ( array_key_exists( $code, $this->parent->licenses ) ) {
486 $entry = $this->parent->licenses[$code];
487 $this->setVar(
'wgRightsText',
488 $entry[
'text'] ??
wfMessage(
'config-license-' . $code )->text() );
489 $this->setVar(
'wgRightsUrl', $entry[
'url'] );
490 $this->setVar(
'wgRightsIcon', $entry[
'icon'] );
492 $this->setVar(
'wgRightsText',
'' );
493 $this->setVar(
'wgRightsUrl',
'' );
494 $this->setVar(
'wgRightsIcon',
'' );
497 $skinsAvailable = array_keys( $this->parent->findExtensions(
'skins' )->value );
498 $skinsToInstall = [];
499 foreach ( $skinsAvailable as $skin ) {
500 $this->parent->setVarsFromRequest( [
"skin-$skin" ] );
501 if ( $this->getVar(
"skin-$skin" ) ) {
502 $skinsToInstall[] = $skin;
505 $this->parent->setVar(
'_Skins', $skinsToInstall );
507 if ( !$skinsToInstall && $skinsAvailable ) {
508 $this->parent->showError(
'config-skins-must-enable-some' );
511 $defaultSkin = $this->getVar(
'wgDefaultSkin' );
512 $skinsToInstallLowercase = array_map(
'strtolower', $skinsToInstall );
513 if ( $skinsToInstall && !in_array( $defaultSkin, $skinsToInstallLowercase ) ) {
514 $this->parent->showError(
'config-skins-must-enable-default' );
518 $extsAvailable = array_keys( $this->parent->findExtensions()->value );
520 foreach ( $extsAvailable as $ext ) {
521 $this->parent->setVarsFromRequest( [
"ext-$ext" ] );
522 if ( $this->getVar(
"ext-$ext" ) ) {
523 $extsToInstall[] = $ext;
526 $this->parent->setVar(
'_Extensions', $extsToInstall );
528 if ( $this->getVar(
'_MainCacheType' ) ==
'memcached' ) {
529 $memcServers = explode(
"\n", $this->getVar(
'_MemCachedServers' ) );
533 if ( !$memcServers ) {
534 $this->parent->showError(
'config-memcache-needservers' );
538 foreach ( $memcServers as $server ) {
539 $memcParts = explode(
":", $server, 2 );
540 if ( !isset( $memcParts[0] )
541 || ( !IPUtils::isValid( $memcParts[0] )
542 && ( gethostbyname( $memcParts[0] ) == $memcParts[0] ) )
544 $this->parent->showError(
'config-memcache-badip', $memcParts[0] );
546 } elseif ( !isset( $memcParts[1] ) ) {
547 $this->parent->showError(
'config-memcache-noport', $memcParts[0] );
549 } elseif ( $memcParts[1] < 1 || $memcParts[1] > 65535 ) {
550 $this->parent->showError(
'config-memcache-badport', 1, 65535 );