Completed
Push — master ( c8702c...a22429 )
by Tobias
09:12
created

ParserFirstCallInit::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 6
cts 6
cp 1
rs 9.4285
cc 1
eloc 5
nc 1
nop 3
crap 1
1
<?php
2
/**
3
 * Contains the class creating the ParserFirstCallInit hook callback.
4
 *
5
 * @copyright (C) 2018, Tobias Oetterer, Paderborn University
6
 * @license       https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 (or later)
7
 *
8
 * This file is part of the MediaWiki extension BootstrapComponents.
9
 * The BootstrapComponents extension is free software: you can redistribute it
10
 * and/or modify it under the terms of the GNU General Public License as published
11
 * by the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * The BootstrapComponents extension is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
 *
22
 * @file
23
 * @ingroup       BootstrapComponents
24
 * @author        Tobias Oetterer
25
 */
26
27
namespace BootstrapComponents\Hooks;
28
29
use \BootstrapComponents\ApplicationFactory;
30
use \BootstrapComponents\ComponentLibrary;
31
use \BootstrapComponents\NestingController;
32
use \BootstrapComponents\ParserOutputHelper;
33
use \Parser;
34
use \ReflectionClass;
35
36
/**
37
 * Class ParserFirstCallInit
38
 *
39
 * Provides the operations for the ParserFirstCallInit hook call. Called when the parser initializes for the first time.
40
 *
41
 * @see https://www.mediawiki.org/wiki/Manual:Hooks/ParserFirstCallInit
42
 *
43
 * @since 1.2
44
 */
45
class ParserFirstCallInit {
46
47
	/**
48
	 * @var ComponentLibrary $componentLibrary
49
	 */
50
	private $componentLibrary;
51
52
	/**
53
	 * @var NestingController $nestingController
54
	 */
55
	private $nestingController;
56
57
	/**
58
	 * @var Parser $parser
59
	 */
60
	private $parser;
61
62
	/**
63
	 * @var ParserOutputHelper $parserOutputHelper
64
	 */
65
	private $parserOutputHelper;
66
67
	/**
68
	 * ParserFirstCallInit constructor.
69
	 *
70
	 * @param Parser            $parser
71
	 * @param ComponentLibrary  $componentLibrary
72
	 * @param NestingController $nestingController
73
	 */
74 3
	public function __construct( $parser, $componentLibrary, $nestingController ) {
75 3
		$this->componentLibrary = $componentLibrary;
76 3
		$this->nestingController = $nestingController;
77 3
		$this->parser = $parser;
78 3
		$this->parserOutputHelper = ApplicationFactory::getInstance()->getParserOutputHelper( $parser );
79 3
	}
80
81
	/**
82
	 * @return bool
83
	 */
84 2
	public function process() {
85
86 2
		foreach ( $this->getComponentLibrary()->getRegisteredComponents() as $componentName ) {
87
88 2
			$parserHookString = ComponentLibrary::compileParserHookStringFor( $componentName );
89 2
			$callback = $this->createParserHookCallbackFor( $componentName );
90
91 2
			if ( $this->getComponentLibrary()->isParserFunction( $componentName ) ) {
92 2
				$this->getParser()->setFunctionHook( $parserHookString, $callback );
93 2
			} elseif ( $this->getComponentLibrary()->isTagExtension( $componentName ) ) {
94 2
				$this->getParser()->setHook( $parserHookString, $callback );
95 2
			} else {
96
				wfDebugLog(
97
					'BootstrapComponents',
98
					'Unknown handler type (' . $this->getComponentLibrary()->getHandlerTypeFor( $componentName )
99
					. ') detected for component ' . $parserHookString
100
				);
101
			}
102 2
		}
103 2
		return true;
104
	}
105
106
	/**
107
	 * @return ComponentLibrary
108
	 */
109 2
	protected function getComponentLibrary() {
110 2
		return $this->componentLibrary;
111
	}
112
113
	/**
114
	 * @return NestingController
115
	 */
116 2
	protected function getNestingController() {
117 2
		return $this->nestingController;
118
	}
119
120
	/**
121
	 * @return Parser
122
	 */
123 2
	protected function getParser() {
124 2
		return $this->parser;
125
	}
126
127
	/**
128
	 * @return ParserOutputHelper
129
	 */
130 2
	protected function getParserOutputHelper() {
131 2
		return $this->parserOutputHelper;
132
	}
133
134
	/**
135
	 * Creates the callback to be registered with {@see \Parser::setFunctionHook} or {@see \Parser::setHook}.
136
	 *
137
	 * @param string $componentName
138
	 *
139
	 * @return \Closure
140
	 */
141 16
	private function createParserHookCallbackFor( $componentName ) {
142
143 2
		$componentLibrary = $this->getComponentLibrary();
144 2
		$nestingController = $this->getNestingController();
145 2
		$parserOutputHelper = $this->getParserOutputHelper();
146
147 16
		return function() use ( $componentName, $componentLibrary, $nestingController, $parserOutputHelper ) {
148
149 16
			$componentClass = $componentLibrary->getClassFor( $componentName );
150 16
			$objectReflection = new ReflectionClass( $componentClass );
151 16
			$object = $objectReflection->newInstanceArgs( [ $componentLibrary, $parserOutputHelper, $nestingController ] );
152
153 16
			$parserRequest = ApplicationFactory::getInstance()->getNewParserRequest(
154 16
				func_get_args(),
155 16
				$componentLibrary->isParserFunction( $componentName ),
156
				$componentName
157 16
			);
158
			/** @var \BootstrapComponents\AbstractComponent $object */
159 16
			return $object->parseComponent( $parserRequest );
160 2
		};
161
	}
162
}
163