Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
82.61% covered (warning)
82.61%
19 / 23
77.78% covered (warning)
77.78%
7 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
MagicWordFactory
86.36% covered (warning)
86.36%
19 / 22
77.78% covered (warning)
77.78%
7 / 9
12.37
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getContentLanguage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getVariableIDs
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getSubstIDs
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getSubstArray
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCacheTTL
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDoubleUnderscoreArray
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 newArray
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21namespace MediaWiki\Parser;
22
23use Language;
24use MediaWiki\HookContainer\HookContainer;
25use MediaWiki\HookContainer\HookRunner;
26
27/**
28 * Store information about magic words, and create/cache MagicWord objects.
29 *
30 * See docs/magicword.md.
31 *
32 * Possible future improvements:
33 *   * Simultaneous searching for a number of magic words
34 *   * $mObjects in shared memory
35 *
36 * @since 1.32
37 * @ingroup Parser
38 */
39class MagicWordFactory {
40
41    private bool $mVariableIDsInitialised = false;
42
43    /** @var string[] */
44    private array $mVariableIDs = [
45        '!',
46        '=',
47        'currentmonth',
48        'currentmonth1',
49        'currentmonthname',
50        'currentmonthnamegen',
51        'currentmonthabbrev',
52        'currentday',
53        'currentday2',
54        'currentdayname',
55        'currentyear',
56        'currenttime',
57        'currenthour',
58        'localmonth',
59        'localmonth1',
60        'localmonthname',
61        'localmonthnamegen',
62        'localmonthabbrev',
63        'localday',
64        'localday2',
65        'localdayname',
66        'localyear',
67        'localtime',
68        'localhour',
69        'numberofarticles',
70        'numberoffiles',
71        'numberofedits',
72        'articlepath',
73        'pageid',
74        'sitename',
75        'server',
76        'servername',
77        'scriptpath',
78        'stylepath',
79        'pagename',
80        'pagenamee',
81        'fullpagename',
82        'fullpagenamee',
83        'namespace',
84        'namespacee',
85        'namespacenumber',
86        'currentweek',
87        'currentdow',
88        'localweek',
89        'localdow',
90        'revisionid',
91        'revisionday',
92        'revisionday2',
93        'revisionmonth',
94        'revisionmonth1',
95        'revisionyear',
96        'revisiontimestamp',
97        'revisionuser',
98        'revisionsize',
99        'subpagename',
100        'subpagenamee',
101        'talkspace',
102        'talkspacee',
103        'subjectspace',
104        'subjectspacee',
105        'talkpagename',
106        'talkpagenamee',
107        'subjectpagename',
108        'subjectpagenamee',
109        'numberofusers',
110        'numberofactiveusers',
111        'numberofpages',
112        'currentversion',
113        'rootpagename',
114        'rootpagenamee',
115        'basepagename',
116        'basepagenamee',
117        'currenttimestamp',
118        'localtimestamp',
119        'directionmark',
120        'contentlanguage',
121        'pagelanguage',
122        'numberofadmins',
123        'cascadingsources',
124    ];
125
126    /** @var string[] */
127    private array $mDoubleUnderscoreIDs = [
128        'notoc',
129        'nogallery',
130        'forcetoc',
131        'toc',
132        'noeditsection',
133        'newsectionlink',
134        'nonewsectionlink',
135        'hiddencat',
136        'expectunusedcategory',
137        'index',
138        'noindex',
139        'staticredirect',
140        'notitleconvert',
141        'nocontentconvert',
142    ];
143
144    /** @var array<string,MagicWord> */
145    private array $mObjects = [];
146    private ?MagicWordArray $mDoubleUnderscoreArray = null;
147
148    private Language $contLang;
149    private HookRunner $hookRunner;
150
151    /**
152     * @internal For ServiceWiring only
153     */
154    public function __construct( Language $contentLanguage, HookContainer $hookContainer ) {
155        $this->contLang = $contentLanguage;
156        $this->hookRunner = new HookRunner( $hookContainer );
157    }
158
159    public function getContentLanguage(): Language {
160        return $this->contLang;
161    }
162
163    /**
164     * Get a MagicWord object for a given internal ID
165     *
166     * @param string $id The internal name of the magic word
167     * @return MagicWord
168     */
169    public function get( $id ): MagicWord {
170        if ( !isset( $this->mObjects[$id] ) ) {
171            $mw = new MagicWord( null, [], false, $this->contLang );
172            $mw->load( $id );
173            $this->mObjects[$id] = $mw;
174        }
175        return $this->mObjects[$id];
176    }
177
178    /**
179     * Get an array of parser variable IDs
180     *
181     * @return string[]
182     */
183    public function getVariableIDs(): array {
184        if ( !$this->mVariableIDsInitialised ) {
185            # Get variable IDs
186            $this->hookRunner->onMagicWordwgVariableIDs( $this->mVariableIDs );
187            $this->hookRunner->onGetMagicVariableIDs( $this->mVariableIDs );
188            $this->mVariableIDsInitialised = true;
189        }
190        return $this->mVariableIDs;
191    }
192
193    /**
194     * Get an array of parser substitution modifier IDs
195     *
196     * @return string[]
197     * @deprecated since 1.42, use {@see getSubstArray} instead
198     */
199    public function getSubstIDs(): array {
200        wfDeprecated( __METHOD__, '1.42' );
201        return [ 'subst', 'safesubst' ];
202    }
203
204    /**
205     * @internal for use in {@see Parser::braceSubstitution} only
206     */
207    public function getSubstArray(): MagicWordArray {
208        return $this->newArray( [ 'subst', 'safesubst' ] );
209    }
210
211    /**
212     * Allow external reads of TTL array
213     *
214     * @param string $id
215     * @return int
216     * @deprecated Since 1.40
217     */
218    public function getCacheTTL( $id ) {
219        return -1;
220    }
221
222    /**
223     * Get a MagicWordArray of double-underscore entities
224     *
225     * @return MagicWordArray
226     */
227    public function getDoubleUnderscoreArray(): MagicWordArray {
228        if ( $this->mDoubleUnderscoreArray === null ) {
229            $this->hookRunner->onGetDoubleUnderscoreIDs( $this->mDoubleUnderscoreIDs );
230            $this->mDoubleUnderscoreArray = $this->newArray( $this->mDoubleUnderscoreIDs );
231        }
232        return $this->mDoubleUnderscoreArray;
233    }
234
235    /**
236     * Get a new MagicWordArray with provided $names
237     *
238     * @param string[] $names
239     * @return MagicWordArray
240     */
241    public function newArray( array $names = [] ): MagicWordArray {
242        return new MagicWordArray( $names, $this );
243    }
244}
245
246/** @deprecated class alias since 1.40 */
247class_alias( MagicWordFactory::class, 'MagicWordFactory' );