Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Template.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 12.83 KiB


001  <?php
002   
003  /*
004   * This file is part of Twig.
005   *
006   * (c) Fabien Potencier
007   * (c) Armin Ronacher
008   *
009   * For the full copyright and license information, please view the LICENSE
010   * file that was distributed with this source code.
011   */
012   
013  namespace Twig;
014   
015  use Twig\Error\Error;
016  use Twig\Error\LoaderError;
017  use Twig\Error\RuntimeError;
018   
019  /**
020   * Default base class for compiled templates.
021   *
022   * This class is an implementation detail of how template compilation currently
023   * works, which might change. It should never be used directly. Use $twig->load()
024   * instead, which returns an instance of \Twig\TemplateWrapper.
025   *
026   * @author Fabien Potencier <fabien@symfony.com>
027   *
028   * @internal
029   */
030  abstract class Template
031  {
032      public const ANY_CALL = 'any';
033      public const ARRAY_CALL = 'array';
034      public const METHOD_CALL = 'method';
035   
036      protected $parent;
037      protected $parents = [];
038      protected $env;
039      protected $blocks = [];
040      protected $traits = [];
041      protected $extensions = [];
042      protected $sandbox;
043   
044      public function __construct(Environment $env)
045      {
046          $this->env = $env;
047          $this->extensions = $env->getExtensions();
048      }
049   
050      /**
051       * @internal this method will be removed in 3.0 and is only used internally to provide an upgrade path from 1.x to 2.0
052       */
053      public function __toString()
054      {
055          return $this->getTemplateName();
056      }
057   
058      /**
059       * Returns the template name.
060       *
061       * @return string The template name
062       */
063      abstract public function getTemplateName();
064   
065      /**
066       * Returns debug information about the template.
067       *
068       * @return array Debug information
069       */
070      abstract public function getDebugInfo();
071   
072      /**
073       * Returns information about the original template source code.
074       *
075       * @return Source
076       */
077      public function getSourceContext()
078      {
079          return new Source('', $this->getTemplateName());
080      }
081   
082      /**
083       * Returns the parent template.
084       *
085       * This method is for internal use only and should never be called
086       * directly.
087       *
088       * @return Template|TemplateWrapper|false The parent template or false if there is no parent
089       */
090      public function getParent(array $context)
091      {
092          if (null !== $this->parent) {
093              return $this->parent;
094          }
095   
096          try {
097              $parent = $this->doGetParent($context);
098   
099              if (false === $parent) {
100                  return false;
101              }
102   
103              if ($parent instanceof self || $parent instanceof TemplateWrapper) {
104                  return $this->parents[$parent->getSourceContext()->getName()] = $parent;
105              }
106   
107              if (!isset($this->parents[$parent])) {
108                  $this->parents[$parent] = $this->loadTemplate($parent);
109              }
110          } catch (LoaderError $e) {
111              $e->setSourceContext(null);
112              $e->guess();
113   
114              throw $e;
115          }
116   
117          return $this->parents[$parent];
118      }
119   
120      protected function doGetParent(array $context)
121      {
122          return false;
123      }
124   
125      public function isTraitable()
126      {
127          return true;
128      }
129   
130      /**
131       * Displays a parent block.
132       *
133       * This method is for internal use only and should never be called
134       * directly.
135       *
136       * @param string $name    The block name to display from the parent
137       * @param array  $context The context
138       * @param array  $blocks  The current set of blocks
139       */
140      public function displayParentBlock($name, array $context, array $blocks = [])
141      {
142          if (isset($this->traits[$name])) {
143              $this->traits[$name][0]->displayBlock($name, $context, $blocks, false);
144          } elseif (false !== $parent = $this->getParent($context)) {
145              $parent->displayBlock($name, $context, $blocks, false);
146          } else {
147              throw new RuntimeError(sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getSourceContext());
148          }
149      }
150   
151      /**
152       * Displays a block.
153       *
154       * This method is for internal use only and should never be called
155       * directly.
156       *
157       * @param string $name      The block name to display
158       * @param array  $context   The context
159       * @param array  $blocks    The current set of blocks
160       * @param bool   $useBlocks Whether to use the current set of blocks
161       */
162      public function displayBlock($name, array $context, array $blocks = [], $useBlocks = true, self $templateContext = null)
163      {
164          if ($useBlocks && isset($blocks[$name])) {
165              $template = $blocks[$name][0];
166              $block = $blocks[$name][1];
167          } elseif (isset($this->blocks[$name])) {
168              $template = $this->blocks[$name][0];
169              $block = $this->blocks[$name][1];
170          } else {
171              $template = null;
172              $block = null;
173          }
174   
175          // avoid RCEs when sandbox is enabled
176          if (null !== $template && !$template instanceof self) {
177              throw new \LogicException('A block must be a method on a \Twig\Template instance.');
178          }
179   
180          if (null !== $template) {
181              try {
182                  $template->$block($context, $blocks);
183              } catch (Error $e) {
184                  if (!$e->getSourceContext()) {
185                      $e->setSourceContext($template->getSourceContext());
186                  }
187   
188                  // this is mostly useful for \Twig\Error\LoaderError exceptions
189                  // see \Twig\Error\LoaderError
190                  if (-1 === $e->getTemplateLine()) {
191                      $e->guess();
192                  }
193   
194                  throw $e;
195              } catch (\Exception $e) {
196                  $e = new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e);
197                  $e->guess();
198   
199                  throw $e;
200              }
201          } elseif (false !== $parent = $this->getParent($context)) {
202              $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false, $templateContext ?? $this);
203          } elseif (isset($blocks[$name])) {
204              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());
205          } else {
206              throw new RuntimeError(sprintf('Block "%s" on template "%s" does not exist.', $name, $this->getTemplateName()), -1, ($templateContext ?? $this)->getSourceContext());
207          }
208      }
209   
210      /**
211       * Renders a parent block.
212       *
213       * This method is for internal use only and should never be called
214       * directly.
215       *
216       * @param string $name    The block name to render from the parent
217       * @param array  $context The context
218       * @param array  $blocks  The current set of blocks
219       *
220       * @return string The rendered block
221       */
222      public function renderParentBlock($name, array $context, array $blocks = [])
223      {
224          if ($this->env->isDebug()) {
225              ob_start();
226          } else {
227              ob_start(function () { return ''; });
228          }
229          $this->displayParentBlock($name, $context, $blocks);
230   
231          return ob_get_clean();
232      }
233   
234      /**
235       * Renders a block.
236       *
237       * This method is for internal use only and should never be called
238       * directly.
239       *
240       * @param string $name      The block name to render
241       * @param array  $context   The context
242       * @param array  $blocks    The current set of blocks
243       * @param bool   $useBlocks Whether to use the current set of blocks
244       *
245       * @return string The rendered block
246       */
247      public function renderBlock($name, array $context, array $blocks = [], $useBlocks = true)
248      {
249          if ($this->env->isDebug()) {
250              ob_start();
251          } else {
252              ob_start(function () { return ''; });
253          }
254          $this->displayBlock($name, $context, $blocks, $useBlocks);
255   
256          return ob_get_clean();
257      }
258   
259      /**
260       * Returns whether a block exists or not in the current context of the template.
261       *
262       * This method checks blocks defined in the current template
263       * or defined in "used" traits or defined in parent templates.
264       *
265       * @param string $name    The block name
266       * @param array  $context The context
267       * @param array  $blocks  The current set of blocks
268       *
269       * @return bool true if the block exists, false otherwise
270       */
271      public function hasBlock($name, array $context, array $blocks = [])
272      {
273          if (isset($blocks[$name])) {
274              return $blocks[$name][0] instanceof self;
275          }
276   
277          if (isset($this->blocks[$name])) {
278              return true;
279          }
280   
281          if (false !== $parent = $this->getParent($context)) {
282              return $parent->hasBlock($name, $context);
283          }
284   
285          return false;
286      }
287   
288      /**
289       * Returns all block names in the current context of the template.
290       *
291       * This method checks blocks defined in the current template
292       * or defined in "used" traits or defined in parent templates.
293       *
294       * @param array $context The context
295       * @param array $blocks  The current set of blocks
296       *
297       * @return array An array of block names
298       */
299      public function getBlockNames(array $context, array $blocks = [])
300      {
301          $names = array_merge(array_keys($blocks), array_keys($this->blocks));
302   
303          if (false !== $parent = $this->getParent($context)) {
304              $names = array_merge($names, $parent->getBlockNames($context));
305          }
306   
307          return array_unique($names);
308      }
309   
310      /**
311       * @return Template|TemplateWrapper
312       */
313      protected function loadTemplate($template, $templateName = null, $line = null, $index = null)
314      {
315          try {
316              if (\is_array($template)) {
317                  return $this->env->resolveTemplate($template);
318              }
319   
320              if ($template instanceof self || $template instanceof TemplateWrapper) {
321                  return $template;
322              }
323   
324              if ($template === $this->getTemplateName()) {
325                  $class = static::class;
326                  if (false !== $pos = strrpos($class, '___', -1)) {
327                      $class = substr($class, 0, $pos);
328                  }
329   
330                  return $this->env->loadClass($class, $template, $index);
331              }
332   
333              return $this->env->loadTemplate($template, $index);
334          } catch (Error $e) {
335              if (!$e->getSourceContext()) {
336                  $e->setSourceContext($templateName ? new Source('', $templateName) : $this->getSourceContext());
337              }
338   
339              if ($e->getTemplateLine() > 0) {
340                  throw $e;
341              }
342   
343              if (!$line) {
344                  $e->guess();
345              } else {
346                  $e->setTemplateLine($line);
347              }
348   
349              throw $e;
350          }
351      }
352   
353      /**
354       * @internal
355       *
356       * @return Template
357       */
358      public function unwrap()
359      {
360          return $this;
361      }
362   
363      /**
364       * Returns all blocks.
365       *
366       * This method is for internal use only and should never be called
367       * directly.
368       *
369       * @return array An array of blocks
370       */
371      public function getBlocks()
372      {
373          return $this->blocks;
374      }
375   
376      public function display(array $context, array $blocks = [])
377      {
378          $this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks));
379      }
380   
381      public function render(array $context)
382      {
383          $level = ob_get_level();
384          if ($this->env->isDebug()) {
385              ob_start();
386          } else {
387              ob_start(function () { return ''; });
388          }
389          try {
390              $this->display($context);
391          } catch (\Throwable $e) {
392              while (ob_get_level() > $level) {
393                  ob_end_clean();
394              }
395   
396              throw $e;
397          }
398   
399          return ob_get_clean();
400      }
401   
402      protected function displayWithErrorHandling(array $context, array $blocks = [])
403      {
404          try {
405              $this->doDisplay($context, $blocks);
406          } catch (Error $e) {
407              if (!$e->getSourceContext()) {
408                  $e->setSourceContext($this->getSourceContext());
409              }
410   
411              // this is mostly useful for \Twig\Error\LoaderError exceptions
412              // see \Twig\Error\LoaderError
413              if (-1 === $e->getTemplateLine()) {
414                  $e->guess();
415              }
416   
417              throw $e;
418          } catch (\Exception $e) {
419              $e = new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e);
420              $e->guess();
421   
422              throw $e;
423          }
424      }
425   
426      /**
427       * Auto-generated method to display the template with the given context.
428       *
429       * @param array $context An array of parameters to pass to the template
430       * @param array $blocks  An array of blocks to pass to the template
431       */
432      abstract protected function doDisplay(array $context, array $blocks = []);
433  }
434   
435  class_alias('Twig\Template', 'Twig_Template');
436