Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
SkinFallback
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 5
182
0.00% covered (danger)
0.00%
0 / 1
 initPage
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 findInstalledSkins
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
20
 buildHelpfulInformationMessage
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
20
 getSnippetForSkin
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getTemplateData
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * Skin file for the fallback skin.
4 *
5 * @since 1.24
6 * @file
7 */
8
9use MediaWiki\Html\Html;
10use MediaWiki\MainConfigNames;
11use MediaWiki\MediaWikiServices;
12use MediaWiki\Output\OutputPage;
13
14/**
15 * SkinTemplate class for the fallback skin
16 */
17class SkinFallback extends SkinMustache {
18    public $skinname = 'fallback';
19
20    /**
21     * @param OutputPage $out
22     */
23    public function initPage( OutputPage $out ) {
24        parent::initPage( $out );
25        $out->disableClientCache();
26    }
27
28    /**
29     * @return array
30     */
31    private function findInstalledSkins() {
32        $config = $this->getConfig();
33        $styleDirectory = $config->get( MainConfigNames::StyleDirectory );
34        // Get all subdirectories which might contains skins
35        $possibleSkins = scandir( $styleDirectory );
36        $possibleSkins = array_filter( $possibleSkins, static function ( $maybeDir ) use ( $styleDirectory ) {
37            return $maybeDir !== '.' && $maybeDir !== '..' && is_dir( "$styleDirectory/$maybeDir" );
38        } );
39
40        // Filter out skins that aren't installed
41        $possibleSkins = array_filter( $possibleSkins, static function ( $skinDir ) use ( $styleDirectory ) {
42            return is_file( "$styleDirectory/$skinDir/skin.json" )
43                || is_file( "$styleDirectory/$skinDir/$skinDir.php" );
44        } );
45
46        return $possibleSkins;
47    }
48
49    /**
50     * Inform the user why they are seeing this skin.
51     *
52     * @return string
53     */
54    private function buildHelpfulInformationMessage() {
55        $config = $this->getConfig();
56        $defaultSkin = $config->get( MainConfigNames::DefaultSkin );
57        $installedSkins = $this->findInstalledSkins();
58        $skinFactory = MediaWikiServices::getInstance()->getSkinFactory();
59        $enabledSkins = $skinFactory->getInstalledSkins();
60        $enabledSkins = array_change_key_case( $enabledSkins, CASE_LOWER );
61
62        if ( $installedSkins ) {
63            $skinsInstalledText = [];
64            $skinsInstalledSnippet = [];
65
66            foreach ( $installedSkins as $skinKey ) {
67                $normalizedKey = strtolower( $skinKey );
68                $isEnabled = array_key_exists( $normalizedKey, $enabledSkins );
69                if ( $isEnabled ) {
70                    $skinsInstalledText[] = $this->msg( 'default-skin-not-found-row-enabled' )
71                        ->params( $normalizedKey, $skinKey )->plain();
72                } else {
73                    $skinsInstalledText[] = $this->msg( 'default-skin-not-found-row-disabled' )
74                        ->params( $normalizedKey, $skinKey )->plain();
75                    $skinsInstalledSnippet[] = $this->getSnippetForSkin( $skinKey );
76                }
77            }
78
79            return $this->msg( 'default-skin-not-found' )->params(
80                $defaultSkin,
81                implode( "\n", $skinsInstalledText ),
82                implode( "\n", $skinsInstalledSnippet ) )->numParams(
83                    count( $skinsInstalledText ),
84                    count( $skinsInstalledSnippet )
85            )->parseAsBlock();
86        } else {
87            return $this->msg( 'default-skin-not-found-no-skins' )->params(
88                $defaultSkin
89            )->parseAsBlock();
90        }
91    }
92
93    /**
94     * Get the appropriate LocalSettings.php snippet to enable the given skin
95     *
96     * @param string $skin
97     * @return string
98     */
99    private static function getSnippetForSkin( $skin ) {
100        global $IP;
101        if ( file_exists( "$IP/skins/$skin/skin.json" ) ) {
102            return "wfLoadSkin( '$skin' );";
103        } else {
104            return "require_once \"\$IP/skins/$skin/$skin.php\";";
105        }
106    }
107
108    /**
109     * Adds an `html-fallback-warning` template to inform system administrators
110     * that their mediawiki skin is incorrectly setup.
111     * It's recommended that skin developers do not add further to date here
112     *  and instead work on improving SkinMustache::getTemplateData where necessary
113     *  to improve flexibility of the data for all skin developers.
114     * @inheritDoc
115     * @return array
116     */
117    public function getTemplateData() {
118        $config = $this->getConfig();
119        $skinFactory = MediaWikiServices::getInstance()->getSkinFactory();
120        $data = parent::getTemplateData();
121        // If the default skin isn't configured correctly, append a warning to the
122        // subtitle to alert a sysadmin.
123        if ( !isset(
124            $skinFactory->getInstalledSkins()[$config->get( MainConfigNames::DefaultSkin )]
125        ) ) {
126            $data['html-fallback-warning'] = Html::warningBox( $this->buildHelpfulInformationMessage() );
127        }
128        return $data;
129    }
130}