Bartosz Dziewoński has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/148508

Change subject: Use a special fallback skin when selected skin is unavailable
......................................................................

Use a special fallback skin when selected skin is unavailable

It displays a helpful message that explains why and how to
install and enable skins.

Bug: 68332
Change-Id: Id14fbb8733cd8fbb912a724ac658f5e7244364b5
---
M includes/AutoLoader.php
M includes/DefaultSettings.php
M includes/Setup.php
A includes/SkinFallback.php
M languages/i18n/en.json
M languages/i18n/qqq.json
6 files changed, 288 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/08/148508/1

diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php
index 046a0df..4f61a9b 100644
--- a/includes/AutoLoader.php
+++ b/includes/AutoLoader.php
@@ -159,6 +159,8 @@
        'SiteStatsInit' => 'includes/SiteStats.php',
        'Skin' => 'includes/Skin.php',
        'SkinTemplate' => 'includes/SkinTemplate.php',
+       'SkinFallback' => 'includes/SkinFallback.php',
+       'SkinFallbackTemplate' => 'includes/SkinFallback.php',
        'SquidPurgeClient' => 'includes/SquidPurgeClient.php',
        'SquidPurgeClientPool' => 'includes/SquidPurgeClient.php',
        'StatCounter' => 'includes/StatCounter.php',
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 8046449..20970f1 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -2966,7 +2966,7 @@
 /**
  * Fallback skin used when the skin defined by $wgDefaultSkin can't be found.
  */
-$wgFallbackSkin = 'vector';
+$wgFallbackSkin = 'fallback';
 
 /**
  * Specify the names of skins that should not be presented in the list of
diff --git a/includes/Setup.php b/includes/Setup.php
index 040aba5..e40f44a 100644
--- a/includes/Setup.php
+++ b/includes/Setup.php
@@ -272,6 +272,10 @@
        $wgSkipSkins[] = $wgSkipSkin;
 }
 
+// Register a hidden "fallback" skin
+$wgValidSkinNames['fallback'] = 'Fallback'; // SkinFallback
+$wgSkipSkins[] = 'fallback';
+
 if ( $wgLocalInterwiki ) {
        array_unshift( $wgLocalInterwikis, $wgLocalInterwiki );
 }
diff --git a/includes/SkinFallback.php b/includes/SkinFallback.php
new file mode 100644
index 0000000..11470f3
--- /dev/null
+++ b/includes/SkinFallback.php
@@ -0,0 +1,271 @@
+<?php
+/**
+ * Skin file for the fallback skin.
+ *
+ * The structure is copied from the example skin (mediawiki/skins/Example).
+ *
+ * @file
+ */
+
+/**
+ * SkinTemplate class for the fallback skin
+ */
+class SkinFallback extends SkinTemplate {
+       var $skinname = 'fallback', $template = 'SkinFallbackTemplate';
+
+       /**
+        * Add CSS via ResourceLoader
+        *
+        * @param $out OutputPage
+        */
+       function setupSkinUserCss( OutputPage $out ) {
+               parent::setupSkinUserCss( $out );
+               $out->addModuleStyles( 'mediawiki.skinning.interface' );
+       }
+}
+
+/**
+ * BaseTemplate class for the fallback skin
+ */
+class SkinFallbackTemplate extends BaseTemplate {
+       /**
+        * Outputs a single sidebar portlet of any kind.
+        */
+       private function outputPortlet( $box ) {
+               if ( !$box['content'] ) {
+                       return;
+               }
+
+               ?>
+               <div
+                       role="navigation"
+                       class="mw-portlet"
+                       id="<?php echo Sanitizer::escapeId( $box['id'] ) ?>"
+                       <?php echo Linker::tooltip( $box['id'] ) ?>
+               >
+                       <h3>
+                               <?php
+                               if ( isset( $box['headerMessage'] ) ) {
+                                       $this->msg( $box['headerMessage'] );
+                               } else {
+                                       echo htmlspecialchars( $box['header'] );
+                               }
+                               ?>
+                       </h3>
+
+                       <?php
+                       if ( is_array( $box['content'] ) ) {
+                               echo '<ul>';
+                               foreach ( $box['content'] as $key => $item ) {
+                                       echo $this->makeListItem( $key, $item );
+                               }
+                               echo '</ul>';
+                       } else {
+                               echo $box['content'];
+                       }?>
+               </div>
+               <?php
+       }
+
+       private function findInstalledSkins() {
+               global $wgStyleDirectory;
+
+               // Get all subdirectories which might contains skins
+               $possibleSkins = scandir( $wgStyleDirectory );
+               $possibleSkins = array_filter( $possibleSkins, function ( 
$maybeDir ) {
+                       global $wgStyleDirectory;
+                       return $maybeDir !== '.' && $maybeDir !== '..' && 
is_dir( "$wgStyleDirectory/$maybeDir" );
+               } );
+
+               // Only keep the ones that contain a .php file with the same 
name inside
+               $possibleSkins = array_filter( $possibleSkins, function ( 
$skinDir ) {
+                       global $wgStyleDirectory;
+                       return is_file( 
"$wgStyleDirectory/$skinDir/$skinDir.php" );
+               } );
+
+               return $possibleSkins;
+       }
+
+       /**
+        * Inform the user why they are seeing this.
+        *
+        * @return string
+        */
+       private function buildHelpfulInformationMessage() {
+               global $wgDefaultSkin, $wgValidSkinNames;
+
+               $installedSkins = $this->findInstalledSkins();
+               $enabledSkins = $wgValidSkinNames;
+               $enabledSkins = array_change_key_case( $enabledSkins, 
CASE_LOWER );
+
+               if ( $installedSkins ) {
+                       $skinsInstalledText = array();
+                       $skinsInstalledSnippet = array();
+
+                       foreach ( $installedSkins as $skin ) {
+                               $normalizedKey = strtolower( $skin );
+                               $isEnabled = array_key_exists( $normalizedKey, 
$enabledSkins );
+                               if ( $isEnabled ) {
+                                       $skinsInstalledText[] = wfMessage( 
'default-skin-not-found-row-enabled' )
+                                               ->params( $normalizedKey, $skin 
)->plain();
+                               } else {
+                                       $skinsInstalledText[] = wfMessage( 
'default-skin-not-found-row-disabled' )
+                                               ->params( $normalizedKey, $skin 
)->plain();
+                                       $skinsInstalledSnippet[] = 
"require_once \"\$IP/skins/$skin/$skin.php\";";
+                               }
+                       }
+
+                       return wfMessage( 'default-skin-not-found' )->params(
+                               $wgDefaultSkin,
+                               implode( "\n", $skinsInstalledText ),
+                               implode( "\n", $skinsInstalledSnippet )
+                       )->parseAsBlock();
+               } else {
+                       return wfMessage( 'default-skin-not-found-no-skins' 
)->params(
+                               $wgDefaultSkin
+                       )->parseAsBlock();
+               }
+       }
+
+       /**
+        * Outputs the entire contents of the page
+        */
+       public function execute() {
+               $this->html( 'headelement' ) ?>
+               <div id="mw-wrapper">
+                       <a
+                               id="p-logo"
+                               role="banner"
+                               href="<?php echo htmlspecialchars( 
$this->data['nav_urls']['mainpage']['href'] ) ?>"
+                               <?php echo Xml::expandAttributes( 
Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) ) ?>
+                       >
+                               <img
+                                       src="<?php $this->text( 'logopath' ) ?>"
+                                       alt="<?php $this->text( 'sitename' ) ?>"
+                               />
+                       </a>
+
+
+                       <div class="warningbox">
+                               <?php echo 
$this->buildHelpfulInformationMessage() ?>
+                       </div>
+
+
+                       <div class="mw-body" role="main">
+                               <?php if ( $this->data['sitenotice'] ) { ?>
+                                       <div id="siteNotice"><?php $this->html( 
'sitenotice' ) ?></div>
+                               <?php } ?>
+
+                               <?php if ( $this->data['newtalk'] ) { ?>
+                                       <div class="usermessage"><?php 
$this->html( 'newtalk' ) ?></div>
+                               <?php } ?>
+
+                               <h1 class="firstHeading">
+                                       <span dir="auto"><?php $this->html( 
'title' ) ?></span>
+                               </h1>
+
+                               <div id="siteSub"><?php $this->msg( 'tagline' ) 
?></div>
+
+                               <div class="mw-body-content">
+                                       <div id="contentSub">
+                                               <?php if ( 
$this->data['subtitle'] ) { ?>
+                                                       <p><?php $this->html( 
'subtitle' ) ?></p>
+                                               <?php } ?>
+                                               <?php if ( 
$this->data['undelete'] ) { ?>
+                                                       <p><?php $this->html( 
'undelete' ) ?></p>
+                                               <?php } ?>
+                                       </div>
+
+                                       <?php $this->html( 'bodytext' ) ?>
+
+                                       <?php $this->html( 'catlinks' ) ?>
+
+                                       <?php $this->html( 'dataAfterContent' 
); ?>
+
+                               </div>
+                       </div>
+
+
+                       <div id="mw-navigation">
+                               <h2><?php $this->msg( 'navigation-heading' ) 
?></h2>
+
+                               <form
+                                       action="<?php $this->text( 'wgScript' ) 
?>"
+                                       role="search"
+                                       class="mw-portlet"
+                                       id="p-search"
+                               >
+                                       <input type="hidden" name="title" 
value="<?php $this->text( 'searchtitle' ) ?>" />
+
+                                       <h3><label for="searchInput"><?php 
$this->msg( 'search' ) ?></label></h3>
+
+                                       <?php echo $this->makeSearchInput( 
array( "id" => "searchInput" ) ) ?>
+                                       <?php echo $this->makeSearchButton( 
'go' ) ?>
+
+                               </form>
+
+                               <?php
+
+                               $this->outputPortlet( array(
+                                       'id' => 'p-personal',
+                                       'headerMessage' => 'personaltools',
+                                       'content' => $this->getPersonalTools(),
+                               ) );
+
+                               $this->outputPortlet( array(
+                                       'id' => 'p-namespaces',
+                                       'headerMessage' => 'namespaces',
+                                       'content' => 
$this->data['content_navigation']['namespaces'],
+                               ) );
+                               $this->outputPortlet( array(
+                                       'id' => 'p-variants',
+                                       'headerMessage' => 'variants',
+                                       'content' => 
$this->data['content_navigation']['variants'],
+                               ) );
+                               $this->outputPortlet( array(
+                                       'id' => 'p-views',
+                                       'headerMessage' => 'views',
+                                       'content' => 
$this->data['content_navigation']['views'],
+                               ) );
+                               $this->outputPortlet( array(
+                                       'id' => 'p-actions',
+                                       'headerMessage' => 'actions',
+                                       'content' => 
$this->data['content_navigation']['actions'],
+                               ) );
+
+                               foreach ( $this->getSidebar() as $boxName => 
$box ) {
+                                       $this->outputPortlet( $box );
+                               }
+
+                               ?>
+                       </div>
+
+                       <div id="mw-footer">
+                               <?php foreach ( $this->getFooterLinks() as 
$category => $links ) { ?>
+                                       <ul role="contentinfo">
+                                               <?php foreach ( $links as $key 
) { ?>
+                                                       <li><?php $this->html( 
$key ) ?></li>
+                                               <?php } ?>
+                                       </ul>
+                               <?php } ?>
+
+                               <ul role="contentinfo">
+                                       <?php foreach ( $this->getFooterIcons( 
'icononly' ) as $blockName => $footerIcons ) { ?>
+                                               <li>
+                                                       <?php
+                                                       foreach ( $footerIcons 
as $icon ) {
+                                                               echo 
$this->getSkin()->makeFooterIcon( $icon );
+                                                       }
+                                                       ?>
+                                               </li>
+                                       <?php } ?>
+                               </ul>
+                       </div>
+               </div>
+
+               <?php $this->printTrail() ?>
+               </body></html>
+
+               <?php
+       }
+}
diff --git a/languages/i18n/en.json b/languages/i18n/en.json
index e42d716..5c7f67c 100644
--- a/languages/i18n/en.json
+++ b/languages/i18n/en.json
@@ -3525,5 +3525,9 @@
        "action-pagelang": "change the page language",
        "log-name-pagelang": "Change language log",
        "log-description-pagelang": "This is a log of changes in page 
languages.",
-       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|changed}} page language 
for $3 from $4 to $5."
+       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|changed}} page language 
for $3 from $4 to $5.",
+       "default-skin-not-found": "Whoops! The default skin for your wiki 
(<code>$wgDefaultSkin</code>), <code>$1</code>, is not available.\n\nYour 
installation seems to include the following skins. See 
[https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin 
configuration] for information how to enable them and choose the 
default.\n\n$2\n\n; If you have just installed MediaWiki:\n: You probably 
installed from git, or directly from the source code using some other method. 
This is expected.\n:* Try installing some skins from 
[https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin 
directory].\n:* Download the [https://www.mediawiki.org/wiki/Download tarball 
installer], which comes with several skins and extensions. You can copy and 
paste the <code>skins/</code> directory from it.\n: Doing this should not 
interfere with your git repository if you're a MediaWiki developer.\n\n; If you 
have just upgraded MediaWiki:\n: MediaWiki 1.24 and newer no longer 
automatically enables installed skins (see 
[https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual:Skin 
autodiscovery]). You can paste the following lines into LocalSettings.php to 
enable all currently installed skins:\n\n<pre>$3</pre>\n\n; If you have just 
modified LocalSettings.php:\n: Double-check the skin names for typos.",
+       "default-skin-not-found-no-skins": "Whoops! The default skin for your 
wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, is not available.\n\nYou 
have no installed skins.\n\n; If you have just installed MediaWiki:\n: You 
probably installed from git, or directly from the source code using some other 
method. This is expected.\n:* Try installing some skins from 
[https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin 
directory].\n:* Download the [https://www.mediawiki.org/wiki/Download tarball 
installer], which comes with several skins and extensions. You can copy and 
paste the <code>skins/</code> directory from it.\n: Doing this should not 
interfere with your git repository if you're a MediaWiki developer. See 
[https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin 
configuration] for information how to enable skins and choose the default.\n",
+       "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 
(enabled)",
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 
('''disabled''')"
 }
diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json
index ad5b288..9683874 100644
--- a/languages/i18n/qqq.json
+++ b/languages/i18n/qqq.json
@@ -3687,5 +3687,9 @@
        "action-pagelang": "{{Doc-action|pagelang}}",
        "log-name-pagelang": "Display entry for log name for changes in page 
language in Special:Log.",
        "log-description-pagelang": "Display description for log name for 
changes in page language in Special:Log.",
-       "logentry-pagelang-pagelang": "{{Logentry}}\nAdditional parameters:\n* 
$4 - old language code, or \"[def]\" (hard-coded)\n* $5 - new language code, or 
\"[def]\" (hard-coded)"
+       "logentry-pagelang-pagelang": "{{Logentry}}\nAdditional parameters:\n* 
$4 - old language code, or \"[def]\" (hard-coded)\n* $5 - new language code, or 
\"[def]\" (hard-coded)",
+       "default-skin-not-found": "Message shown when the default skin for this 
MediaWiki installation can not be found.\n\nParameters:\n* $1: skin identifier 
for the default skin\n* $2: list of installed skins, composed using 
{{msg-mw|default-skin-not-found-row-enabled}} and 
{{msg-mw|default-skin-not-found-row-disabled}}\n* $3: code snippet to use to 
enable installed skins",
+       "default-skin-not-found-no-skins": "Message shown when the default skin 
for this MediaWiki installation can not be found and the installation has no 
skins at all.\n\nParameters:\n* $1: name of the default skin",
+       "default-skin-not-found-row-enabled": "One row of the list of installed 
skins shown as a part of {{msg-mw|default-skin-not-found}}, for an enabled 
skin.\n\nParameters:\n* $1: skin identifier\n$2: human-readable skin name",
+       "default-skin-not-found-row-disabled": "One row of the list of 
installed skins shown as a part of {{msg-mw|default-skin-not-found}}, for a 
disabled skin.\n\nParameters:\n* $1: skin identifier\n$2: human-readable skin 
name"
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/148508
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id14fbb8733cd8fbb912a724ac658f5e7244364b5
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Bartosz Dziewoński <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to