PluginProbe
Elementor Website Builder – more than just a page builder / 3.28.0-dev1
Elementor Website Builder – more than just a page builder v3.28.0-dev1
4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 All 452 releases
elementor / vendor_prefixed / twig / src / Template.php

Template.php in Elementor Website Builder – more than just a page builder 3.28.0-dev1, at vendor_prefixed/twig/src/Template.php

440 lines 14.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of Twig.
5 *
6 * (c) Fabien Potencier
7 * (c) Armin Ronacher
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12 namespace ElementorDeps\Twig;
13
14 use ElementorDeps\Twig\Error\Error;
15 use ElementorDeps\Twig\Error\LoaderError;
16 use ElementorDeps\Twig\Error\RuntimeError;
17 /**
18 * Default base class for compiled templates.
19 *
20 * This class is an implementation detail of how template compilation currently
21 * works, which might change. It should never be used directly. Use $twig->load()
22 * instead, which returns an instance of \Twig\TemplateWrapper.
23 *
24 * @author Fabien Potencier <fabien@symfony.com>
25 *
26 * @internal
27 */
28 abstract class Template
29 {
30 public const ANY_CALL = 'any';
31 public const ARRAY_CALL = 'array';
32 public const METHOD_CALL = 'method';
33 protected $parent;
34 protected $parents = [];
35 protected $env;
36 protected $blocks = [];
37 protected $traits = [];
38 protected $extensions = [];
39 protected $sandbox;
40 private $useYield;
41 public function __construct(Environment $env)
42 {
43 $this->env = $env;
44 $this->useYield = $env->useYield();
45 $this->extensions = $env->getExtensions();
46 }
47 /**
48 * Returns the template name.
49 *
50 * @return string The template name
51 */
52 public abstract function getTemplateName();
53 /**
54 * Returns debug information about the template.
55 *
56 * @return array Debug information
57 */
58 public abstract function getDebugInfo();
59 /**
60 * Returns information about the original template source code.
61 *
62 * @return Source
63 */
64 public abstract function getSourceContext();
65 /**
66 * Returns the parent template.
67 *
68 * This method is for internal use only and should never be called
69 * directly.
70 *
71 * @return self|TemplateWrapper|false The parent template or false if there is no parent
72 */
73 public function getParent(array $context)
74 {
75 if (null !== $this->parent) {
76 return $this->parent;
77 }
78 try {
79 if (!($parent = $this->doGetParent($context))) {
80 return \false;
81 }
82 if ($parent instanceof self || $parent instanceof TemplateWrapper) {
83 return $this->parents[$parent->getSourceContext()->getName()] = $parent;
84 }
85 if (!isset($this->parents[$parent])) {
86 $this->parents[$parent] = $this->loadTemplate($parent);
87 }
88 } catch (LoaderError $e) {
89 $e->setSourceContext(null);
90 $e->guess();
91 throw $e;
92 }
93 return $this->parents[$parent];
94 }
95 protected function doGetParent(array $context)
96 {
97 return \false;
98 }
99 public function isTraitable()
100 {
101 return \true;
102 }
103 /**
104 * Displays a parent block.
105 *
106 * This method is for internal use only and should never be called
107 * directly.
108 *
109 * @param string $name The block name to display from the parent
110 * @param array $context The context
111 * @param array $blocks The current set of blocks
112 */
113 public function displayParentBlock($name, array $context, array $blocks = [])
114 {
115 foreach ($this->yieldParentBlock($name, $context, $blocks) as $data) {
116 echo $data;
117 }
118 }
119 /**
120 * Displays a block.
121 *
122 * This method is for internal use only and should never be called
123 * directly.
124 *
125 * @param string $name The block name to display
126 * @param array $context The context
127 * @param array $blocks The current set of blocks
128 * @param bool $useBlocks Whether to use the current set of blocks
129 */
130 public function displayBlock($name, array $context, array $blocks = [], $useBlocks = \true, ?self $templateContext = null)
131 {
132 foreach ($this->yieldBlock($name, $context, $blocks, $useBlocks, $templateContext) as $data) {
133 echo $data;
134 }
135 }
136 /**
137 * Renders a parent block.
138 *
139 * This method is for internal use only and should never be called
140 * directly.
141 *
142 * @param string $name The block name to render from the parent
143 * @param array $context The context
144 * @param array $blocks The current set of blocks
145 *
146 * @return string The rendered block
147 */
148 public function renderParentBlock($name, array $context, array $blocks = [])
149 {
150 $content = '';
151 foreach ($this->yieldParentBlock($name, $context, $blocks) as $data) {
152 $content .= $data;
153 }
154 return $content;
155 }
156 /**
157 * Renders a block.
158 *
159 * This method is for internal use only and should never be called
160 * directly.
161 *
162 * @param string $name The block name to render
163 * @param array $context The context
164 * @param array $blocks The current set of blocks
165 * @param bool $useBlocks Whether to use the current set of blocks
166 *
167 * @return string The rendered block
168 */
169 public function renderBlock($name, array $context, array $blocks = [], $useBlocks = \true)
170 {
171 $content = '';
172 foreach ($this->yieldBlock($name, $context, $blocks, $useBlocks) as $data) {
173 $content .= $data;
174 }
175 return $content;
176 }
177 /**
178 * Returns whether a block exists or not in the current context of the template.
179 *
180 * This method checks blocks defined in the current template
181 * or defined in "used" traits or defined in parent templates.
182 *
183 * @param string $name The block name
184 * @param array $context The context
185 * @param array $blocks The current set of blocks
186 *
187 * @return bool true if the block exists, false otherwise
188 */
189 public function hasBlock($name, array $context, array $blocks = [])
190 {
191 if (isset($blocks[$name])) {
192 return $blocks[$name][0] instanceof self;
193 }
194 if (isset($this->blocks[$name])) {
195 return \true;
196 }
197 if ($parent = $this->getParent($context)) {
198 return $parent->hasBlock($name, $context);
199 }
200 return \false;
201 }
202 /**
203 * Returns all block names in the current context of the template.
204 *
205 * This method checks blocks defined in the current template
206 * or defined in "used" traits or defined in parent templates.
207 *
208 * @param array $context The context
209 * @param array $blocks The current set of blocks
210 *
211 * @return array An array of block names
212 */
213 public function getBlockNames(array $context, array $blocks = [])
214 {
215 $names = \array_merge(\array_keys($blocks), \array_keys($this->blocks));
216 if ($parent = $this->getParent($context)) {
217 $names = \array_merge($names, $parent->getBlockNames($context));
218 }
219 return \array_unique($names);
220 }
221 /**
222 * @param string|TemplateWrapper|array<string|TemplateWrapper> $template
223 *
224 * @return self|TemplateWrapper
225 */
226 protected function loadTemplate($template, $templateName = null, $line = null, $index = null)
227 {
228 try {
229 if (\is_array($template)) {
230 return $this->env->resolveTemplate($template);
231 }
232 if ($template instanceof TemplateWrapper) {
233 return $template;
234 }
235 if ($template instanceof self) {
236 trigger_deprecation('twig/twig', '3.9', 'Passing a "%s" instance to "%s" is deprecated.', self::class, __METHOD__);
237 return $template;
238 }
239 if ($template === $this->getTemplateName()) {
240 $class = static::class;
241 if (\false !== ($pos = \strrpos($class, '___', -1))) {
242 $class = \substr($class, 0, $pos);
243 }
244 } else {
245 $class = $this->env->getTemplateClass($template);
246 }
247 return $this->env->loadTemplate($class, $template, $index);
248 } catch (Error $e) {
249 if (!$e->getSourceContext()) {
250 $e->setSourceContext($templateName ? new Source('', $templateName) : $this->getSourceContext());
251 }
252 if ($e->getTemplateLine() > 0) {
253 throw $e;
254 }
255 if (!$line) {
256 $e->guess();
257 } else {
258 $e->setTemplateLine($line);
259 }
260 throw $e;
261 }
262 }
263 /**
264 * @internal
265 *
266 * @return self
267 */
268 public function unwrap()
269 {
270 return $this;
271 }
272 /**
273 * Returns all blocks.
274 *
275 * This method is for internal use only and should never be called
276 * directly.
277 *
278 * @return array An array of blocks
279 */
280 public function getBlocks()
281 {
282 return $this->blocks;
283 }
284 public function display(array $context, array $blocks = []) : void
285 {
286 foreach ($this->yield($context, $blocks) as $data) {
287 echo $data;
288 }
289 }
290 public function render(array $context) : string
291 {
292 $content = '';
293 foreach ($this->yield($context) as $data) {
294 $content .= $data;
295 }
296 return $content;
297 }
298 /**
299 * @return iterable<string>
300 */
301 public function yield(array $context, array $blocks = []) : iterable
302 {
303 $context = $this->env->mergeGlobals($context);
304 $blocks = \array_merge($this->blocks, $blocks);
305 try {
306 if ($this->useYield) {
307 yield from $this->doDisplay($context, $blocks);
308 return;
309 }
310 $level = \ob_get_level();
311 \ob_start();
312 foreach ($this->doDisplay($context, $blocks) as $data) {
313 if (\ob_get_length()) {
314 $data = \ob_get_clean() . $data;
315 \ob_start();
316 }
317 (yield $data);
318 }
319 if (\ob_get_length()) {
320 (yield \ob_get_clean());
321 }
322 } catch (Error $e) {
323 if (!$e->getSourceContext()) {
324 $e->setSourceContext($this->getSourceContext());
325 }
326 // this is mostly useful for \Twig\Error\LoaderError exceptions
327 // see \Twig\Error\LoaderError
328 if (-1 === $e->getTemplateLine()) {
329 $e->guess();
330 }
331 throw $e;
332 } catch (\Throwable $e) {
333 $e = new RuntimeError(\sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e);
334 $e->guess();
335 throw $e;
336 } finally {
337 if (!$this->useYield) {
338 while (\ob_get_level() > $level) {
339 \ob_end_clean();
340 }
341 }
342 }
343 }
344 /**
345 * @return iterable<string>
346 */
347 public function yieldBlock($name, array $context, array $blocks = [], $useBlocks = \true, ?self $templateContext = null)
348 {
349 if ($useBlocks && isset($blocks[$name])) {
350 $template = $blocks[$name][0];
351 $block = $blocks[$name][1];
352 } elseif (isset($this->blocks[$name])) {
353 $template = $this->blocks[$name][0];
354 $block = $this->blocks[$name][1];
355 } else {
356 $template = null;
357 $block = null;
358 }
359 // avoid RCEs when sandbox is enabled
360 if (null !== $template && !$template instanceof self) {
361 throw new \LogicException('A block must be a method on a \\Twig\\Template instance.');
362 }
363 if (null !== $template) {
364 try {
365 if ($this->useYield) {
366 yield from $template->{$block}($context, $blocks);
367 return;
368 }
369 $level = \ob_get_level();
370 \ob_start();
371 foreach ($template->{$block}($context, $blocks) as $data) {
372 if (\ob_get_length()) {
373 $data = \ob_get_clean() . $data;
374 \ob_start();
375 }
376 (yield $data);
377 }
378 if (\ob_get_length()) {
379 (yield \ob_get_clean());
380 }
381 } catch (Error $e) {
382 if (!$e->getSourceContext()) {
383 $e->setSourceContext($template->getSourceContext());
384 }
385 // this is mostly useful for \Twig\Error\LoaderError exceptions
386 // see \Twig\Error\LoaderError
387 if (-1 === $e->getTemplateLine()) {
388 $e->guess();
389 }
390 throw $e;
391 } catch (\Throwable $e) {
392 $e = new RuntimeError(\sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e);
393 $e->guess();
394 throw $e;
395 } finally {
396 if (!$this->useYield) {
397 while (\ob_get_level() > $level) {
398 \ob_end_clean();
399 }
400 }
401 }
402 } elseif ($parent = $this->getParent($context)) {
403 yield from $parent->unwrap()->yieldBlock($name, $context, \array_merge($this->blocks, $blocks), \false, $templateContext ?? $this);
404 } elseif (isset($blocks[$name])) {
405 throw new RuntimeError(\sprintf('Block "%s" should not call parent() in "%s" as the block does not exist in the parent template "%s".', $name, $blocks[$name][0]->getTemplateName(), $this->getTemplateName()), -1, $blocks[$name][0]->getSourceContext());
406 } else {
407 throw new RuntimeError(\sprintf('Block "%s" on template "%s" does not exist.', $name, $this->getTemplateName()), -1, ($templateContext ?? $this)->getSourceContext());
408 }
409 }
410 /**
411 * Yields a parent block.
412 *
413 * This method is for internal use only and should never be called
414 * directly.
415 *
416 * @param string $name The block name to display from the parent
417 * @param array $context The context
418 * @param array $blocks The current set of blocks
419 *
420 * @return iterable<string>
421 */
422 public function yieldParentBlock($name, array $context, array $blocks = [])
423 {
424 if (isset($this->traits[$name])) {
425 yield from $this->traits[$name][0]->yieldBlock($name, $context, $blocks, \false);
426 } elseif ($parent = $this->getParent($context)) {
427 yield from $parent->unwrap()->yieldBlock($name, $context, $blocks, \false);
428 } else {
429 throw new RuntimeError(\sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getSourceContext());
430 }
431 }
432 /**
433 * Auto-generated method to display the template with the given context.
434 *
435 * @param array $context An array of parameters to pass to the template
436 * @param array $blocks An array of blocks to pass to the template
437 */
438 protected abstract function doDisplay(array $context, array $blocks = []);
439 }
440