Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
91.23% |
52 / 57 |
|
87.50% |
14 / 16 |
CRAP | |
0.00% |
0 / 1 |
environment | |
91.23% |
52 / 57 |
|
87.50% |
14 / 16 |
29.57 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
2 | |||
get_phpbb_extensions | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
get_phpbb_config | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
get_phpbb_root_path | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
get_filesystem | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
get_web_root_path | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
get_path_helper | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
get_assets_bag | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getNamespaceLookUpOrder | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setNamespaceLookUpOrder | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
render | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
display | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
display_with_assets | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
4 | |||
inject_assets | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
loadTemplate | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
5.39 | |||
findTemplate | |
62.50% |
5 / 8 |
|
0.00% |
0 / 1 |
6.32 |
1 | <?php |
2 | /** |
3 | * |
4 | * This file is part of the phpBB Forum Software package. |
5 | * |
6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
7 | * @license GNU General Public License, version 2 (GPL-2.0) |
8 | * |
9 | * For full copyright and license information, please see |
10 | * the docs/CREDITS.txt file. |
11 | * |
12 | */ |
13 | |
14 | namespace phpbb\template\twig; |
15 | |
16 | use phpbb\config\config; |
17 | use phpbb\event\dispatcher_interface; |
18 | use phpbb\extension\manager; |
19 | use phpbb\filesystem\filesystem; |
20 | use phpbb\path_helper; |
21 | use phpbb\template\assets_bag; |
22 | use Twig\Loader\LoaderInterface; |
23 | |
24 | class environment extends \Twig\Environment |
25 | { |
26 | /** @var config */ |
27 | protected $phpbb_config; |
28 | |
29 | /** @var filesystem */ |
30 | protected $filesystem; |
31 | |
32 | /** @var path_helper */ |
33 | protected $phpbb_path_helper; |
34 | |
35 | /** @var \Symfony\Component\DependencyInjection\ContainerInterface */ |
36 | protected $container; |
37 | |
38 | /** @var manager */ |
39 | protected $extension_manager; |
40 | |
41 | /** @var dispatcher_interface */ |
42 | protected $phpbb_dispatcher; |
43 | |
44 | /** @var string */ |
45 | protected $phpbb_root_path; |
46 | |
47 | /** @var string */ |
48 | protected $web_root_path; |
49 | |
50 | /** @var array **/ |
51 | protected $namespace_look_up_order = array('__main__'); |
52 | |
53 | /** @var assets_bag */ |
54 | protected $assets_bag; |
55 | |
56 | /** |
57 | * Constructor |
58 | * |
59 | * @param assets_bag $assets_bag Assets bag |
60 | * @param config $phpbb_config The phpBB configuration |
61 | * @param filesystem $filesystem |
62 | * @param path_helper $path_helper phpBB path helper |
63 | * @param string $cache_path The path to the cache directory |
64 | * @param manager|null $extension_manager phpBB extension manager |
65 | * @param LoaderInterface|null $loader Twig loader interface |
66 | * @param dispatcher_interface|null $phpbb_dispatcher Event dispatcher object |
67 | * @param array $options Array of options to pass to Twig |
68 | */ |
69 | public function __construct(assets_bag $assets_bag, config $phpbb_config, filesystem $filesystem, path_helper $path_helper, $cache_path, manager $extension_manager = null, LoaderInterface $loader = null, dispatcher_interface $phpbb_dispatcher = null, $options = array()) |
70 | { |
71 | $this->phpbb_config = $phpbb_config; |
72 | |
73 | $this->filesystem = $filesystem; |
74 | $this->phpbb_path_helper = $path_helper; |
75 | $this->extension_manager = $extension_manager; |
76 | $this->phpbb_dispatcher = $phpbb_dispatcher; |
77 | |
78 | $this->phpbb_root_path = $this->phpbb_path_helper->get_phpbb_root_path(); |
79 | |
80 | $this->assets_bag = $assets_bag; |
81 | |
82 | $options = array_merge(array( |
83 | 'cache' => (defined('IN_INSTALL')) ? false : $cache_path, |
84 | 'debug' => false, |
85 | 'auto_reload' => (bool) $this->phpbb_config['load_tplcompile'], |
86 | 'autoescape' => false, |
87 | ), $options); |
88 | |
89 | parent::__construct($loader, $options); |
90 | } |
91 | |
92 | /** |
93 | * Get the list of enabled phpBB extensions |
94 | * |
95 | * Used in EVENT node |
96 | * |
97 | * @return array |
98 | */ |
99 | public function get_phpbb_extensions() |
100 | { |
101 | return ($this->extension_manager) ? $this->extension_manager->all_enabled() : array(); |
102 | } |
103 | |
104 | /** |
105 | * Get phpBB config |
106 | * |
107 | * @return config |
108 | */ |
109 | public function get_phpbb_config() |
110 | { |
111 | return $this->phpbb_config; |
112 | } |
113 | |
114 | /** |
115 | * Get the phpBB root path |
116 | * |
117 | * @return string |
118 | */ |
119 | public function get_phpbb_root_path() |
120 | { |
121 | return $this->phpbb_root_path; |
122 | } |
123 | |
124 | /** |
125 | * Get the filesystem object |
126 | * |
127 | * @return filesystem |
128 | */ |
129 | public function get_filesystem() |
130 | { |
131 | return $this->filesystem; |
132 | } |
133 | |
134 | /** |
135 | * Get the web root path |
136 | * |
137 | * @return string |
138 | */ |
139 | public function get_web_root_path() |
140 | { |
141 | return $this->web_root_path ?? $this->web_root_path = $this->phpbb_path_helper->get_web_root_path(); |
142 | } |
143 | |
144 | /** |
145 | * Get the phpbb path helper object |
146 | * |
147 | * @return path_helper |
148 | */ |
149 | public function get_path_helper() |
150 | { |
151 | return $this->phpbb_path_helper; |
152 | } |
153 | |
154 | /** |
155 | * Gets the assets bag |
156 | * |
157 | * @return assets_bag |
158 | */ |
159 | public function get_assets_bag() |
160 | { |
161 | return $this->assets_bag; |
162 | } |
163 | |
164 | /** |
165 | * Get the namespace look up order |
166 | * |
167 | * @return array |
168 | */ |
169 | public function getNamespaceLookUpOrder() |
170 | { |
171 | return $this->namespace_look_up_order; |
172 | } |
173 | |
174 | /** |
175 | * Set the namespace look up order to load templates from |
176 | * |
177 | * @param array $namespace |
178 | * @return \Twig\Environment |
179 | */ |
180 | public function setNamespaceLookUpOrder($namespace) |
181 | { |
182 | $this->namespace_look_up_order = $namespace; |
183 | |
184 | return $this; |
185 | } |
186 | |
187 | /** |
188 | * {@inheritdoc} |
189 | */ |
190 | public function render($name, array $context = []) : string |
191 | { |
192 | return $this->display_with_assets($name, $context); |
193 | } |
194 | |
195 | /** |
196 | * {@inheritdoc} |
197 | */ |
198 | public function display($name, array $context = []) : void |
199 | { |
200 | echo $this->display_with_assets($name, $context); |
201 | } |
202 | |
203 | /** |
204 | * Get template with assets |
205 | */ |
206 | private function display_with_assets($name, array $context = []) |
207 | { |
208 | $placeholder_salt = unique_id(); |
209 | |
210 | if (array_key_exists('definition', $context)) |
211 | { |
212 | $context['definition']->set('SCRIPTS', '__SCRIPTS_' . $placeholder_salt . '__'); |
213 | $context['definition']->set('STYLESHEETS', '__STYLESHEETS_' . $placeholder_salt . '__'); |
214 | } |
215 | |
216 | /** |
217 | * Allow changing the template output stream before rendering |
218 | * |
219 | * @event core.twig_environment_render_template_before |
220 | * @var array context Array with template variables |
221 | * @var string name The template name |
222 | * @since 3.2.1-RC1 |
223 | */ |
224 | if ($this->phpbb_dispatcher) |
225 | { |
226 | $vars = array('context', 'name'); |
227 | extract($this->phpbb_dispatcher->trigger_event('core.twig_environment_render_template_before', compact($vars))); |
228 | } |
229 | |
230 | $output = parent::render($name, $context); |
231 | |
232 | /** |
233 | * Allow changing the template output stream after rendering |
234 | * |
235 | * @event core.twig_environment_render_template_after |
236 | * @var array context Array with template variables |
237 | * @var string name The template name |
238 | * @var string output Rendered template output stream |
239 | * @since 3.2.1-RC1 |
240 | */ |
241 | if ($this->phpbb_dispatcher) |
242 | { |
243 | $vars = array('context', 'name', 'output'); |
244 | extract($this->phpbb_dispatcher->trigger_event('core.twig_environment_render_template_after', compact($vars))); |
245 | } |
246 | |
247 | return $this->inject_assets($output, $placeholder_salt); |
248 | } |
249 | |
250 | /** |
251 | * Injects the assets (from INCLUDECSS/JS) in the output. |
252 | * |
253 | * @param string $output |
254 | * |
255 | * @return string |
256 | */ |
257 | private function inject_assets($output, $placeholder_salt) |
258 | { |
259 | $output = str_replace('__STYLESHEETS_' . $placeholder_salt . '__', $this->assets_bag->get_stylesheets_content(), $output); |
260 | $output = str_replace('__SCRIPTS_' . $placeholder_salt . '__', $this->assets_bag->get_scripts_content(), $output); |
261 | |
262 | return $output; |
263 | } |
264 | |
265 | /** |
266 | * Loads a template by name. |
267 | * |
268 | * @param string $cls The template class associated with the given template name |
269 | * @param string $name The template name |
270 | * @param integer|null $index The index if it is an embedded template |
271 | * @return \Twig\Template A template instance representing the given template name |
272 | * @throws \Twig\Error\LoaderError |
273 | */ |
274 | public function loadTemplate(string $cls, string $name, int $index = null) : \Twig\Template |
275 | { |
276 | if (strpos($name, '@') === false) |
277 | { |
278 | foreach ($this->getNamespaceLookUpOrder() as $namespace) |
279 | { |
280 | try |
281 | { |
282 | if ($namespace === '__main__') |
283 | { |
284 | return parent::loadTemplate($cls, $name, $index); |
285 | } |
286 | |
287 | return parent::loadTemplate($this->getTemplateClass('@' . $namespace . '/' . $name), '@' . $namespace . '/' . $name, $index); |
288 | } |
289 | catch (\Twig\Error\LoaderError $e) |
290 | { |
291 | } |
292 | } |
293 | |
294 | // We were unable to load any templates |
295 | throw $e; |
296 | } |
297 | else |
298 | { |
299 | return parent::loadTemplate($cls, $name, $index); |
300 | } |
301 | } |
302 | |
303 | /** |
304 | * Finds a template by name. |
305 | * |
306 | * @param string $name The template name |
307 | * @return string |
308 | * @throws \Twig\Error\LoaderError |
309 | */ |
310 | public function findTemplate($name) |
311 | { |
312 | if (strpos($name, '@') === false) |
313 | { |
314 | foreach ($this->getNamespaceLookUpOrder() as $namespace) |
315 | { |
316 | try |
317 | { |
318 | if ($namespace === '__main__') |
319 | { |
320 | return parent::getLoader()->getCacheKey($name); |
321 | } |
322 | |
323 | return parent::getLoader()->getCacheKey('@' . $namespace . '/' . $name); |
324 | } |
325 | catch (\Twig\Error\LoaderError $e) |
326 | { |
327 | } |
328 | } |
329 | |
330 | // We were unable to load any templates |
331 | throw $e; |
332 | } |
333 | else |
334 | { |
335 | return parent::getLoader()->getCacheKey($name); |
336 | } |
337 | } |
338 | } |