Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.36% covered (warning)
86.36%
19 / 22
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 MediaWiki\HookContainer\HookContainer;
24use MediaWiki\HookContainer\HookRunner;
25use MediaWiki\Language\Language;
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        'userlanguage',
122        'pagelanguage',
123        'numberofadmins',
124        'cascadingsources',
125        'bcp47',
126        'dir',
127        'language',
128    ];
129
130    /** @var string[] */
131    private array $mDoubleUnderscoreIDs = [
132        'notoc',
133        'nogallery',
134        'forcetoc',
135        'toc',
136        'noeditsection',
137        'newsectionlink',
138        'nonewsectionlink',
139        'hiddencat',
140        'expectunusedcategory',
141        'expectunusedtemplate',
142        'index',
143        'noindex',
144        'staticredirect',
145        'notitleconvert',
146        'nocontentconvert',
147    ];
148
149    /** @var array<string,MagicWord> */
150    private array $mObjects = [];
151    private ?MagicWordArray $mDoubleUnderscoreArray = null;
152
153    private Language $contLang;
154    private HookRunner $hookRunner;
155
156    /**
157     * @internal For ServiceWiring only
158     */
159    public function __construct( Language $contentLanguage, HookContainer $hookContainer ) {
160        $this->contLang = $contentLanguage;
161        $this->hookRunner = new HookRunner( $hookContainer );
162    }
163
164    public function getContentLanguage(): Language {
165        return $this->contLang;
166    }
167
168    /**
169     * Get a MagicWord object for a given internal ID
170     *
171     * @param string $id The internal name of the magic word
172     * @return MagicWord
173     */
174    public function get( $id ): MagicWord {
175        if ( !isset( $this->mObjects[$id] ) ) {
176            $mw = new MagicWord( null, [], false, $this->contLang );
177            $mw->load( $id );
178            $this->mObjects[$id] = $mw;
179        }
180        return $this->mObjects[$id];
181    }
182
183    /**
184     * Get an array of parser variable IDs
185     *
186     * @return string[]
187     */
188    public function getVariableIDs(): array {
189        if ( !$this->mVariableIDsInitialised ) {
190            # Get variable IDs
191            $this->hookRunner->onMagicWordwgVariableIDs( $this->mVariableIDs );
192            $this->hookRunner->onGetMagicVariableIDs( $this->mVariableIDs );
193            $this->mVariableIDsInitialised = true;
194        }
195        return $this->mVariableIDs;
196    }
197
198    /**
199     * Get an array of parser substitution modifier IDs
200     *
201     * @return string[]
202     * @deprecated since 1.42, use {@see getSubstArray} instead
203     */
204    public function getSubstIDs(): array {
205        wfDeprecated( __METHOD__, '1.42' );
206        return [ 'subst', 'safesubst' ];
207    }
208
209    /**
210     * @internal for use in {@see Parser::braceSubstitution} only
211     */
212    public function getSubstArray(): MagicWordArray {
213        return $this->newArray( [ 'subst', 'safesubst' ] );
214    }
215
216    /**
217     * Allow external reads of TTL array
218     *
219     * @param string $id
220     * @return int
221     * @deprecated Since 1.40
222     */
223    public function getCacheTTL( $id ) {
224        return -1;
225    }
226
227    /**
228     * Get a MagicWordArray of double-underscore entities
229     */
230    public function getDoubleUnderscoreArray(): MagicWordArray {
231        if ( $this->mDoubleUnderscoreArray === null ) {
232            $this->hookRunner->onGetDoubleUnderscoreIDs( $this->mDoubleUnderscoreIDs );
233            $this->mDoubleUnderscoreArray = $this->newArray( $this->mDoubleUnderscoreIDs );
234        }
235        return $this->mDoubleUnderscoreArray;
236    }
237
238    /**
239     * Get a new MagicWordArray with provided $names
240     *
241     * @param string[] $names
242     * @return MagicWordArray
243     */
244    public function newArray( array $names = [] ): MagicWordArray {
245        return new MagicWordArray( $names, $this );
246    }
247}