Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
78.95% covered (warning)
78.95%
30 / 38
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ParserFactory
81.08% covered (warning)
81.08%
30 / 37
50.00% covered (danger)
50.00%
2 / 4
6.24
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
 create
100.00% covered (success)
100.00%
28 / 28
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 * @license GPL-2.0-or-later
4 * @file
5 * @ingroup Parser
6 */
7
8namespace MediaWiki\Parser;
9
10use MediaWiki\Category\TrackingCategories;
11use MediaWiki\Config\ServiceOptions;
12use MediaWiki\FileRepo\RepoGroup;
13use MediaWiki\HookContainer\HookContainer;
14use MediaWiki\Http\HttpRequestFactory;
15use MediaWiki\Language\Language;
16use MediaWiki\Language\LanguageConverterFactory;
17use MediaWiki\Language\LanguageFactory;
18use MediaWiki\Language\LanguageNameUtils;
19use MediaWiki\Linker\LinkRendererFactory;
20use MediaWiki\Page\File\BadFileLookup;
21use MediaWiki\Preferences\SignatureValidatorFactory;
22use MediaWiki\SpecialPage\SpecialPageFactory;
23use MediaWiki\Tidy\TidyDriverBase;
24use MediaWiki\Title\NamespaceInfo;
25use MediaWiki\Title\TitleFormatter;
26use MediaWiki\User\Options\UserOptionsLookup;
27use MediaWiki\User\UserFactory;
28use MediaWiki\User\UserNameUtils;
29use MediaWiki\Utils\UrlUtils;
30use Psr\Log\LoggerInterface;
31use Wikimedia\ObjectCache\WANObjectCache;
32
33/**
34 * @since 1.32
35 */
36class ParserFactory {
37    /**
38     * Track calls to Parser constructor to aid in deprecation of direct
39     * Parser invocation.  This is temporary: it will be removed once the
40     * deprecation notice period is over and the underlying method calls
41     * are refactored.
42     * @internal
43     * @var int
44     */
45    public static $inParserFactory = 0;
46
47    /** @var Parser|null */
48    private $mainInstance;
49
50    /**
51     * @since 1.32
52     * @internal
53     */
54    public function __construct(
55        private readonly ServiceOptions $svcOptions,
56        private readonly ParserCoreTagHooks $parserCoreTagHooks,
57        private readonly MagicWordFactory $magicWordFactory,
58        private readonly Language $contLang,
59        private readonly UrlUtils $urlUtils,
60        private readonly SpecialPageFactory $specialPageFactory,
61        private readonly LinkRendererFactory $linkRendererFactory,
62        private readonly NamespaceInfo $nsInfo,
63        private readonly LoggerInterface $logger,
64        private readonly BadFileLookup $badFileLookup,
65        private readonly RepoGroup $repoGroup,
66        private readonly LanguageFactory $languageFactory,
67        private readonly LanguageConverterFactory $languageConverterFactory,
68        private readonly LanguageNameUtils $languageNameUtils,
69        private readonly HookContainer $hookContainer,
70        private readonly TidyDriverBase $tidy,
71        private readonly WANObjectCache $wanCache,
72        private readonly UserOptionsLookup $userOptionsLookup,
73        private readonly UserFactory $userFactory,
74        private readonly TitleFormatter $titleFormatter,
75        private readonly HttpRequestFactory $httpRequestFactory,
76        private readonly TrackingCategories $trackingCategories,
77        private readonly SignatureValidatorFactory $signatureValidatorFactory,
78        private readonly UserNameUtils $userNameUtils,
79    ) {
80        $svcOptions->assertRequiredOptions( Parser::CONSTRUCTOR_OPTIONS );
81
82        wfDebug( __CLASS__ . ": using default preprocessor" );
83    }
84
85    /**
86     * Creates a new parser
87     *
88     * @note Use this function to get a new Parser instance to store
89     * in a local class property.  Where possible use lazy creation and
90     * create the Parser only when needed, not directly in service wiring.
91     *
92     * @return Parser
93     * @since 1.32
94     */
95    public function create(): Parser {
96        self::$inParserFactory++;
97        try {
98            return new Parser(
99                $this->svcOptions,
100                $this->parserCoreTagHooks,
101                $this->magicWordFactory,
102                $this->contLang,
103                $this->urlUtils,
104                $this->specialPageFactory,
105                $this->linkRendererFactory,
106                $this->nsInfo,
107                $this->logger,
108                $this->badFileLookup,
109                $this->repoGroup,
110                $this->languageFactory,
111                $this->languageConverterFactory,
112                $this->languageNameUtils,
113                $this->hookContainer,
114                $this->tidy,
115                $this->wanCache,
116                $this->userOptionsLookup,
117                $this->userFactory,
118                $this->titleFormatter,
119                $this->httpRequestFactory,
120                $this->trackingCategories,
121                $this->signatureValidatorFactory,
122                $this->userNameUtils
123            );
124        } finally {
125            self::$inParserFactory--;
126        }
127    }
128
129    /**
130     * Get the main shared instance. This is unsafe when the caller is not in
131     * a top-level context, because re-entering the parser will throw an
132     * exception.
133     *
134     * @note This function is used to get metadata from the parser. Avoid
135     * using this function to parse wikitext.  (Generally avoid using this
136     * function at all in new code.)
137     *
138     * @since 1.39
139     * @return Parser
140     */
141    public function getMainInstance() {
142        if ( $this->mainInstance === null ) {
143            $this->mainInstance = $this->create();
144        }
145        return $this->mainInstance;
146    }
147
148    /**
149     * Get the main shared instance, or if it is locked, get a new instance
150     *
151     * @note This function was used to parse wikitext. The instance it
152     * returned should be used only in local scope.  Do not hold a
153     * reference to this parser in class properties.  In general,
154     * avoid using this method and use ::create() instead.
155     *
156     * @since 1.39
157     * @return Parser
158     */
159    public function getInstance() {
160        $instance = $this->getMainInstance();
161        if ( $instance->isLocked() ) {
162            $instance = $this->create();
163        }
164        return $instance;
165    }
166
167}
168
169/** @deprecated class alias since 1.43 */
170class_alias( ParserFactory::class, 'ParserFactory' );