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