Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
40.00% covered (danger)
40.00%
22 / 55
11.11% covered (danger)
11.11%
1 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
ProofreadPageInit
40.00% covered (danger)
40.00%
22 / 55
11.11% covered (danger)
11.11%
1 / 9
137.26
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onSetupAfterCache
50.00% covered (danger)
50.00%
3 / 6
0.00% covered (danger)
0.00%
0 / 1
2.50
 initNamespace
61.54% covered (warning)
61.54%
8 / 13
0.00% covered (danger)
0.00%
0 / 1
8.05
 getNamespaceIdForDefaultName
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 createNamespace
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 createNamespaceAliases
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getNamespaceAliases
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getNamespaceName
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 getNamespaceId
87.50% covered (warning)
87.50%
7 / 8
0.00% covered (danger)
0.00%
0 / 1
2.01
1<?php
2
3namespace ProofreadPage;
4
5use MediaWiki\Config\Config;
6use MediaWiki\Config\ConfigException;
7use MediaWiki\Hook\SetupAfterCacheHook;
8
9/**
10 * @license GPL-2.0-or-later
11 *
12 * Class that contain init system of the ProofreadPage extension
13 */
14class ProofreadPageInit implements SetupAfterCacheHook {
15
16    /** @var Config */
17    private $config;
18
19    /**
20     * @param Config $config
21     */
22    public function __construct( Config $config ) {
23        $this->config = $config;
24    }
25
26    /**
27     * @var int[] the default namespace id for each namespaces
28     * Called by the SetupAfterCache hook
29     */
30    protected static $defaultNamespaceIds = [
31        'page' => 250,
32        'index' => 252
33    ];
34
35    /**
36     * @see https://www.mediawiki.org/wiki/Manual:Hooks/SetupAfterCache
37     */
38    public function onSetupAfterCache() {
39        global $wgTemplateStylesNamespaces, $wgProofreadPageNamespaceIds;
40        self::initNamespace( 'page' );
41        self::initNamespace( 'index' );
42
43        if ( \ExtensionRegistry::getInstance()->isLoaded( 'TemplateStyles' ) ) {
44            // Also Add Index NS to the TemplateStyles auto-CSS list
45            // so that /styles.css can be created
46            $templateStylesNamespaces = $this->config->get( 'TemplateStylesNamespaces' );
47            $templateStylesNamespaces[ $wgProofreadPageNamespaceIds[ 'index' ] ] = true;
48            $wgTemplateStylesNamespaces = $templateStylesNamespaces;
49        }
50    }
51
52    /**
53     * Create a namespace and his discussion one
54     * @param string $key the key of the namespace in the i18n file
55     */
56    protected static function initNamespace( $key ) {
57        global $wgContentNamespaces, $wgExtraNamespaces, $wgProofreadPageNamespaceIds;
58
59        if ( isset( $wgProofreadPageNamespaceIds[$key] ) ) {
60            if ( !is_numeric( $wgProofreadPageNamespaceIds[$key] ) ) {
61                throw new ConfigException(
62                    '$wgProofreadPageNamespaceIds[' . $key . '] must be a number.'
63                );
64            }
65
66            if ( !isset( $wgExtraNamespaces[$wgProofreadPageNamespaceIds[$key]] ) ) {
67                self::createNamespace( $wgProofreadPageNamespaceIds[$key], $key );
68            }
69        } else {
70             // try to find if a namespace with a known name is set (for backward compatibility)
71            $id = self::getNamespaceIdForDefaultName( $key );
72            if ( $id !== false ) {
73                $wgProofreadPageNamespaceIds[$key] = $id;
74            } else {
75
76                if ( self::createNamespace( self::$defaultNamespaceIds[$key], $key ) ) {
77                    $wgProofreadPageNamespaceIds[$key] = self::$defaultNamespaceIds[$key];
78                }
79                // else: the relevant error message is output by getNamespaceId
80            }
81        }
82
83        // Also Add Page/Index namespace to $wgContentNamespaces
84        $wgContentNamespaces[] = $wgProofreadPageNamespaceIds[$key];
85    }
86
87    /**
88     * Find if a namespace with the default name is already set (for backward compatibility) and
89     * return his id
90     * @param string $key the key of the namespace in the i18n file
91     * @return int|false the id of the namespace or false if it doesn't exist
92     */
93    protected static function getNamespaceIdForDefaultName( $key ) {
94        global $wgExtraNamespaces;
95
96        $xNamespaces = [];
97        foreach ( $wgExtraNamespaces as $i => $text ) {
98            $xNamespaces[strtolower( $text )] = $i;
99        }
100
101        $name = strtolower( self::getNamespaceName( $key ) );
102
103        return array_key_exists( $name, $xNamespaces ) ? $xNamespaces[$name] : false;
104    }
105
106    /**
107     * Create a namespace and his discussion one
108     * @param int $id the namespace id
109     * @param string $key the key of the namespace in the i18n file
110     * @return bool false if there is an error, true if not
111     */
112    protected static function createNamespace( $id, $key ) {
113        global $wgCanonicalNamespaceNames, $wgExtraNamespaces, $wgNamespacesWithSubpages;
114
115        if ( isset( $wgExtraNamespaces[$id] ) || isset( $wgExtraNamespaces[$id + 1] ) ) {
116            return false;
117        }
118
119        $talkKey = $key . '_talk';
120
121        $wgExtraNamespaces[$id] = self::getNamespaceName( $key );
122        $wgExtraNamespaces[$id + 1] = self::getNamespaceName( $talkKey );
123
124        // Very hugly but needed because initNamespaces() is called after the add of
125        // $wgExtraNamespaces into $wgCanonicalNamespaceNames
126        $wgCanonicalNamespaceNames[$id] = $wgExtraNamespaces[$id];
127        $wgCanonicalNamespaceNames[$id + 1] = $wgExtraNamespaces[$id + 1];
128
129        // ProofreadPage's namespaces should have subpages - T256410
130        $wgNamespacesWithSubpages[$id] = true;
131        $wgNamespacesWithSubpages[$id + 1] = true;
132
133        self::createNamespaceAliases( $key, $id );
134        self::createNamespaceAliases( $talkKey, $id + 1 );
135
136        return true;
137    }
138
139    /**
140     * @param string $key
141     * @param int $id
142     */
143    private static function createNamespaceAliases( $key, $id ) {
144        global $wgNamespaceAliases;
145
146        $aliases = self::getNamespaceAliases( $key );
147        foreach ( $aliases as $alias ) {
148            $wgNamespaceAliases[$alias] = $id;
149        }
150    }
151
152    /**
153     * @param string $key
154     *
155     * @return string[]
156     */
157    private static function getNamespaceAliases( $key ) {
158        global $proofreadPageNamespaceAliases, $wgLanguageCode;
159
160        if ( !isset( $proofreadPageNamespaceAliases[$wgLanguageCode][$key] ) ) {
161            return [];
162        }
163
164        return $proofreadPageNamespaceAliases[$wgLanguageCode][$key];
165    }
166
167    /**
168     * Return the internationalized name of a namespace as set in proofreadPageNamespaceNames.
169     * The english language is used as fallback.
170     * @param string $key namespace key in the array
171     * @param string $lang language code by default the wiki language
172     * @return string
173     */
174    protected static function getNamespaceName( $key, $lang = '' ) {
175        global $proofreadPageNamespaceNames, $wgLanguageCode;
176
177        if ( $lang === '' ) {
178            $lang = $wgLanguageCode;
179        }
180
181        return $proofreadPageNamespaceNames[$lang][$key]
182            ?? $proofreadPageNamespaceNames['en'][$key];
183    }
184
185    /**
186     * Get the id of the namespace. Required that MediaWiki is loaded and
187     * ProofreadPageInit::initNamespace has been executed for the relevant namespace.
188     * Warning: It's not the function you search. If you want to know the index or page namespace
189     * id use ProofreadPage::getIndexNamespaceId() or ProofreadPage::getPageNamespaceId()
190     * @param string $key the key of the namespace in the i18n file
191     * @return int
192     */
193    public static function getNamespaceId( $key ) {
194        global $wgProofreadPageNamespaceIds;
195
196        if ( !isset( $wgProofreadPageNamespaceIds[$key] ) ) {
197            // The only case where $wgProofreadPageNamespaceIds is not set is
198            // when a namespace with the default id already exist
199            // and is not a prp namespace.
200            throw new ConfigException( 'Namespace with id ' . self::$defaultNamespaceIds[$key] .
201                ' is already set ! ProofreadPage can\'t use his id in order to create ' .
202                self::getNamespaceName( $key, 'en' ) .
203                ' namespace. Update your LocalSettings.php adding $wgProofreadPageNamespaceIds[' .
204                $key . '] = /* NUMERICAL ID OF THE ' . self::getNamespaceName( $key, 'en' ) .
205                ' NAMESPACE */; AFTER the inclusion of Proofread Page' );
206        }
207
208        return $wgProofreadPageNamespaceIds[$key];
209    }
210}