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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
Template.php
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