Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
87.04% covered (warning)
87.04%
47 / 54
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ParserFactory
87.04% covered (warning)
87.04%
47 / 54
50.00% covered (danger)
50.00%
2 / 4
6.08
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
1 / 1
1
 create
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
1 / 1
1
 getMainInstance
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getInstance
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
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 * @ingroup Parser
20 */
21
22use MediaWiki\Category\TrackingCategories;
23use MediaWiki\Config\ServiceOptions;
24use MediaWiki\HookContainer\HookContainer;
25use MediaWiki\Http\HttpRequestFactory;
26use MediaWiki\Languages\LanguageConverterFactory;
27use MediaWiki\Linker\LinkRendererFactory;
28use MediaWiki\Page\File\BadFileLookup;
29use MediaWiki\Parser\MagicWordFactory;
30use MediaWiki\Parser\Parser;
31use MediaWiki\Preferences\SignatureValidatorFactory;
32use MediaWiki\SpecialPage\SpecialPageFactory;
33use MediaWiki\Tidy\TidyDriverBase;
34use MediaWiki\Title\NamespaceInfo;
35use MediaWiki\Title\TitleFormatter;
36use MediaWiki\User\Options\UserOptionsLookup;
37use MediaWiki\User\UserFactory;
38use MediaWiki\User\UserNameUtils;
39use MediaWiki\Utils\UrlUtils;
40use Psr\Log\LoggerInterface;
41
42/**
43 * @since 1.32
44 */
45class ParserFactory {
46    /** @var ServiceOptions */
47    private $svcOptions;
48
49    /** @var MagicWordFactory */
50    private $magicWordFactory;
51
52    /** @var Language */
53    private $contLang;
54
55    /** @var UrlUtils */
56    private $urlUtils;
57
58    /** @var SpecialPageFactory */
59    private $specialPageFactory;
60
61    /** @var LinkRendererFactory */
62    private $linkRendererFactory;
63
64    /** @var NamespaceInfo */
65    private $nsInfo;
66
67    /** @var LoggerInterface */
68    private $logger;
69
70    /** @var BadFileLookup */
71    private $badFileLookup;
72
73    /** @var LanguageConverterFactory */
74    private $languageConverterFactory;
75
76    /** @var UserOptionsLookup */
77    private $userOptionsLookup;
78
79    /** @var UserFactory */
80    private $userFactory;
81
82    /** @var TitleFormatter */
83    private $titleFormatter;
84
85    /** @var HttpRequestFactory */
86    private $httpRequestFactory;
87
88    /** @var TrackingCategories */
89    private $trackingCategories;
90
91    /** @var SignatureValidatorFactory */
92    private $signatureValidatorFactory;
93
94    /** @var UserNameUtils */
95    private $userNameUtils;
96
97    /**
98     * Track calls to Parser constructor to aid in deprecation of direct
99     * Parser invocation.  This is temporary: it will be removed once the
100     * deprecation notice period is over and the underlying method calls
101     * are refactored.
102     * @internal
103     * @var int
104     */
105    public static $inParserFactory = 0;
106
107    /** @var HookContainer */
108    private $hookContainer;
109
110    /** @var TidyDriverBase */
111    private $tidy;
112
113    /** @var WANObjectCache */
114    private $wanCache;
115
116    /** @var Parser|null */
117    private $mainInstance;
118
119    /**
120     * @param ServiceOptions $svcOptions
121     * @param MagicWordFactory $magicWordFactory
122     * @param Language $contLang Content language
123     * @param UrlUtils $urlUtils
124     * @param SpecialPageFactory $spFactory
125     * @param LinkRendererFactory $linkRendererFactory
126     * @param NamespaceInfo $nsInfo
127     * @param LoggerInterface $logger
128     * @param BadFileLookup $badFileLookup
129     * @param LanguageConverterFactory $languageConverterFactory
130     * @param HookContainer $hookContainer
131     * @param TidyDriverBase $tidy
132     * @param WANObjectCache $wanCache
133     * @param UserOptionsLookup $userOptionsLookup
134     * @param UserFactory $userFactory
135     * @param TitleFormatter $titleFormatter
136     * @param HttpRequestFactory $httpRequestFactory
137     * @param TrackingCategories $trackingCategories
138     * @param SignatureValidatorFactory $signatureValidatorFactory
139     * @param UserNameUtils $userNameUtils
140     * @since 1.32
141     * @internal
142     */
143    public function __construct(
144        ServiceOptions $svcOptions,
145        MagicWordFactory $magicWordFactory,
146        Language $contLang,
147        UrlUtils $urlUtils,
148        SpecialPageFactory $spFactory,
149        LinkRendererFactory $linkRendererFactory,
150        NamespaceInfo $nsInfo,
151        LoggerInterface $logger,
152        BadFileLookup $badFileLookup,
153        LanguageConverterFactory $languageConverterFactory,
154        HookContainer $hookContainer,
155        TidyDriverBase $tidy,
156        WANObjectCache $wanCache,
157        UserOptionsLookup $userOptionsLookup,
158        UserFactory $userFactory,
159        TitleFormatter $titleFormatter,
160        HttpRequestFactory $httpRequestFactory,
161        TrackingCategories $trackingCategories,
162        SignatureValidatorFactory $signatureValidatorFactory,
163        UserNameUtils $userNameUtils
164    ) {
165        $svcOptions->assertRequiredOptions( Parser::CONSTRUCTOR_OPTIONS );
166
167        wfDebug( __CLASS__ . ": using default preprocessor" );
168
169        $this->svcOptions = $svcOptions;
170        $this->magicWordFactory = $magicWordFactory;
171        $this->contLang = $contLang;
172        $this->urlUtils = $urlUtils;
173        $this->specialPageFactory = $spFactory;
174        $this->linkRendererFactory = $linkRendererFactory;
175        $this->nsInfo = $nsInfo;
176        $this->logger = $logger;
177        $this->badFileLookup = $badFileLookup;
178        $this->languageConverterFactory = $languageConverterFactory;
179        $this->hookContainer = $hookContainer;
180        $this->tidy = $tidy;
181        $this->wanCache = $wanCache;
182        $this->userOptionsLookup = $userOptionsLookup;
183        $this->userFactory = $userFactory;
184        $this->titleFormatter = $titleFormatter;
185        $this->httpRequestFactory = $httpRequestFactory;
186        $this->trackingCategories = $trackingCategories;
187        $this->signatureValidatorFactory = $signatureValidatorFactory;
188        $this->userNameUtils = $userNameUtils;
189    }
190
191    /**
192     * Creates a new parser
193     *
194     * @note Use this function to get a new Parser instance to store
195     * in a local class property.  Where possible use lazy creation and
196     * create the Parser only when needed, not directly in service wiring.
197     *
198     * @return Parser
199     * @since 1.32
200     */
201    public function create(): Parser {
202        self::$inParserFactory++;
203        try {
204            return new Parser(
205                $this->svcOptions,
206                $this->magicWordFactory,
207                $this->contLang,
208                $this,
209                $this->urlUtils,
210                $this->specialPageFactory,
211                $this->linkRendererFactory,
212                $this->nsInfo,
213                $this->logger,
214                $this->badFileLookup,
215                $this->languageConverterFactory,
216                $this->hookContainer,
217                $this->tidy,
218                $this->wanCache,
219                $this->userOptionsLookup,
220                $this->userFactory,
221                $this->titleFormatter,
222                $this->httpRequestFactory,
223                $this->trackingCategories,
224                $this->signatureValidatorFactory,
225                $this->userNameUtils
226            );
227        } finally {
228            self::$inParserFactory--;
229        }
230    }
231
232    /**
233     * Get the main shared instance. This is unsafe when the caller is not in
234     * a top-level context, because re-entering the parser will throw an
235     * exception.
236     *
237     * @note This function is used to get metadata from the parser. Avoid
238     * using this function to parse wikitext.  (Generally avoid using this
239     * function at all in new code.)
240     *
241     * @since 1.39
242     * @return Parser
243     */
244    public function getMainInstance() {
245        if ( $this->mainInstance === null ) {
246            $this->mainInstance = $this->create();
247        }
248        return $this->mainInstance;
249    }
250
251    /**
252     * Get the main shared instance, or if it is locked, get a new instance
253     *
254     * @note This function was used to parse wikitext. The instance it
255     * returned should be used only in local scope.  Do not hold a
256     * reference to this parser in class properties.  In general,
257     * avoid using this method and use ::create() instead.
258     *
259     * @since 1.39
260     * @return Parser
261     */
262    public function getInstance() {
263        $instance = $this->getMainInstance();
264        if ( $instance->isLocked() ) {
265            $instance = $this->create();
266        }
267        return $instance;
268    }
269
270}