]>
git.immae.eu Git - github/wallabag/wallabag.git/blob - vendor/twig/twig/lib/Twig/Template.php
4 * This file is part of Twig.
6 * (c) 2009 Fabien Potencier
7 * (c) 2009 Armin Ronacher
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
14 * Default base class for compiled templates.
16 * @author Fabien Potencier <fabien@symfony.com>
18 abstract class Twig_Template
implements Twig_TemplateInterface
20 protected static $cache = array ();
31 * @param Twig_Environment $env A Twig_Environment instance
33 public function __construct ( Twig_Environment
$env )
36 $this- > blocks
= array ();
37 $this- > traits
= array ();
41 * Returns the template name.
43 * @return string The template name
45 abstract public function getTemplateName ();
50 public function getEnvironment ()
56 * Returns the parent template.
58 * This method is for internal use only and should never be called
61 * @return Twig_TemplateInterface|false The parent template or false if there is no parent
63 public function getParent ( array $context )
65 if ( null !== $this- > parent
) {
69 $parent = $this- > doGetParent ( $context );
70 if ( false === $parent ) {
72 } elseif ( $parent instanceof Twig_Template
) {
73 $name = $parent- > getTemplateName ();
74 $this- > parents
[ $name ] = $parent ;
76 } elseif (! isset ( $this- > parents
[ $parent ])) {
77 $this- > parents
[ $parent ] = $this- > env
-> loadTemplate ( $parent );
80 return $this- > parents
[ $parent ];
83 protected function doGetParent ( array $context )
88 public function isTraitable ()
94 * Displays a parent block.
96 * This method is for internal use only and should never be called
99 * @param string $name The block name to display from the parent
100 * @param array $context The context
101 * @param array $blocks The current set of blocks
103 public function displayParentBlock ( $name , array $context , array $blocks = array ())
105 $name = ( string ) $name ;
107 if ( isset ( $this- > traits
[ $name ])) {
108 $this- > traits
[ $name ][ 0 ]-> displayBlock ( $name , $context , $blocks );
109 } elseif ( false !== $parent = $this- > getParent ( $context )) {
110 $parent- > displayBlock ( $name , $context , $blocks );
112 throw new Twig_Error_Runtime ( sprintf ( 'The template has no parent and no traits defining the "%s" block' , $name ), - 1 , $this- > getTemplateName ());
119 * This method is for internal use only and should never be called
122 * @param string $name The block name to display
123 * @param array $context The context
124 * @param array $blocks The current set of blocks
126 public function displayBlock ( $name , array $context , array $blocks = array ())
128 $name = ( string ) $name ;
130 if ( isset ( $blocks [ $name ])) {
133 call_user_func ( $blocks [ $name ], $context , $b );
134 } elseif ( isset ( $this- > blocks
[ $name ])) {
135 call_user_func ( $this- > blocks
[ $name ], $context , $blocks );
136 } elseif ( false !== $parent = $this- > getParent ( $context )) {
137 $parent- > displayBlock ( $name , $context , array_merge ( $this- > blocks
, $blocks ));
142 * Renders a parent block.
144 * This method is for internal use only and should never be called
147 * @param string $name The block name to render from the parent
148 * @param array $context The context
149 * @param array $blocks The current set of blocks
151 * @return string The rendered block
153 public function renderParentBlock ( $name , array $context , array $blocks = array ())
156 $this- > displayParentBlock ( $name , $context , $blocks );
158 return ob_get_clean ();
164 * This method is for internal use only and should never be called
167 * @param string $name The block name to render
168 * @param array $context The context
169 * @param array $blocks The current set of blocks
171 * @return string The rendered block
173 public function renderBlock ( $name , array $context , array $blocks = array ())
176 $this- > displayBlock ( $name , $context , $blocks );
178 return ob_get_clean ();
182 * Returns whether a block exists or not.
184 * This method is for internal use only and should never be called
187 * This method does only return blocks defined in the current template
188 * or defined in "used" traits.
190 * It does not return blocks from parent templates as the parent
191 * template name can be dynamic, which is only known based on the
194 * @param string $name The block name
196 * @return Boolean true if the block exists, false otherwise
198 public function hasBlock ( $name )
200 return isset ( $this- > blocks
[( string ) $name ]);
204 * Returns all block names.
206 * This method is for internal use only and should never be called
209 * @return array An array of block names
213 public function getBlockNames ()
215 return array_keys ( $this- > blocks
);
219 * Returns all blocks.
221 * This method is for internal use only and should never be called
224 * @return array An array of blocks
228 public function getBlocks ()
230 return $this- > blocks
;
236 public function display ( array $context , array $blocks = array ())
238 $this- > displayWithErrorHandling ( $this- > env
-> mergeGlobals ( $context ), $blocks );
244 public function render ( array $context )
246 $level = ob_get_level ();
249 $this- > display ( $context );
250 } catch ( Exception
$e ) {
251 while ( ob_get_level () > $level ) {
258 return ob_get_clean ();
261 protected function displayWithErrorHandling ( array $context , array $blocks = array ())
264 $this- > doDisplay ( $context , $blocks );
265 } catch ( Twig_Error
$e ) {
266 if (! $e- > getTemplateFile ()) {
267 $e- > setTemplateFile ( $this- > getTemplateName ());
270 // this is mostly useful for Twig_Error_Loader exceptions
271 // see Twig_Error_Loader
272 if ( false === $e- > getTemplateLine ()) {
273 $e- > setTemplateLine (- 1 );
278 } catch ( Exception
$e ) {
279 throw new Twig_Error_Runtime ( sprintf ( 'An exception has been thrown during the rendering of a template ("%s").' , $e- > getMessage ()), - 1 , null , $e );
284 * Auto-generated method to display the template with the given context.
286 * @param array $context An array of parameters to pass to the template
287 * @param array $blocks An array of blocks to pass to the template
289 abstract protected function doDisplay ( array $context , array $blocks = array ());
292 * Returns a variable from the context.
294 * This method is for internal use only and should never be called
297 * This method should not be overridden in a sub-class as this is an
298 * implementation detail that has been introduced to optimize variable
299 * access for versions of PHP before 5.4. This is not a way to override
300 * the way to get a variable value.
302 * @param array $context The context
303 * @param string $item The variable to return from the context
304 * @param Boolean $ignoreStrictCheck Whether to ignore the strict variable check or not
306 * @return The content of the context variable
308 * @throws Twig_Error_Runtime if the variable does not exist and Twig is running in strict mode
310 final protected function getContext ( $context , $item , $ignoreStrictCheck = false )
312 if (! array_key_exists ( $item , $context )) {
313 if ( $ignoreStrictCheck || ! $this- > env
-> isStrictVariables ()) {
317 throw new Twig_Error_Runtime ( sprintf ( 'Variable "%s" does not exist' , $item ), - 1 , $this- > getTemplateName ());
320 return $context [ $item ];
324 * Returns the attribute value for a given array/object.
326 * @param mixed $object The object or array from where to get the item
327 * @param mixed $item The item to get from the array or object
328 * @param array $arguments An array of arguments to pass if the item is an object method
329 * @param string $type The type of attribute (@see Twig_TemplateInterface)
330 * @param Boolean $isDefinedTest Whether this is only a defined check
331 * @param Boolean $ignoreStrictCheck Whether to ignore the strict attribute check or not
333 * @return mixed The attribute value, or a Boolean when $isDefinedTest is true, or null when the attribute is not set and $ignoreStrictCheck is true
335 * @throws Twig_Error_Runtime if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false
337 protected function getAttribute ( $object , $item , array $arguments = array (), $type = Twig_TemplateInterface
:: ANY_CALL
, $isDefinedTest = false , $ignoreStrictCheck = false )
340 if ( Twig_TemplateInterface
:: METHOD_CALL
!== $type ) {
341 $arrayItem = is_bool ( $item ) || is_float ( $item ) ? ( int ) $item : $item ;
343 if (( is_array ( $object ) && array_key_exists ( $arrayItem , $object ))
344 || ( $object instanceof ArrayAccess
&& isset ( $object [ $arrayItem ]))
346 if ( $isDefinedTest ) {
350 return $object [ $arrayItem ];
353 if ( Twig_TemplateInterface
:: ARRAY_CALL
=== $type || ! is_object ( $object )) {
354 if ( $isDefinedTest ) {
358 if ( $ignoreStrictCheck || ! $this- > env
-> isStrictVariables ()) {
362 if ( is_object ( $object )) {
363 throw new Twig_Error_Runtime ( sprintf ( 'Key "%s" in object (with ArrayAccess) of type "%s" does not exist' , $arrayItem , get_class ( $object )), - 1 , $this- > getTemplateName ());
364 } elseif ( is_array ( $object )) {
365 throw new Twig_Error_Runtime ( sprintf ( 'Key "%s" for array with keys "%s" does not exist' , $arrayItem , implode ( ', ' , array_keys ( $object ))), - 1 , $this- > getTemplateName ());
366 } elseif ( Twig_TemplateInterface
:: ARRAY_CALL
=== $type ) {
367 throw new Twig_Error_Runtime ( sprintf ( 'Impossible to access a key ("%s") on a %s variable ("%s")' , $item , gettype ( $object ), $object ), - 1 , $this- > getTemplateName ());
369 throw new Twig_Error_Runtime ( sprintf ( 'Impossible to access an attribute ("%s") on a %s variable ("%s")' , $item , gettype ( $object ), $object ), - 1 , $this- > getTemplateName ());
374 if (! is_object ( $object )) {
375 if ( $isDefinedTest ) {
379 if ( $ignoreStrictCheck || ! $this- > env
-> isStrictVariables ()) {
383 throw new Twig_Error_Runtime ( sprintf ( 'Impossible to invoke a method ("%s") on a %s variable ("%s")' , $item , gettype ( $object ), $object ), - 1 , $this- > getTemplateName ());
386 $class = get_class ( $object );
389 if ( Twig_TemplateInterface
:: METHOD_CALL
!== $type ) {
390 if ( isset ( $object- > $item ) || array_key_exists (( string ) $item , $object )) {
391 if ( $isDefinedTest ) {
395 if ( $this- > env
-> hasExtension ( 'sandbox' )) {
396 $this- > env
-> getExtension ( 'sandbox' )-> checkPropertyAllowed ( $object , $item );
399 return $object- > $item ;
404 if (! isset ( self
:: $cache [ $class ][ 'methods' ])) {
405 self
:: $cache [ $class ][ 'methods' ] = array_change_key_case ( array_flip ( get_class_methods ( $object )));
408 $lcItem = strtolower ( $item );
409 if ( isset ( self
:: $cache [ $class ][ 'methods' ][ $lcItem ])) {
410 $method = ( string ) $item ;
411 } elseif ( isset ( self
:: $cache [ $class ][ 'methods' ][ 'get' . $lcItem ])) {
412 $method = 'get' . $item ;
413 } elseif ( isset ( self
:: $cache [ $class ][ 'methods' ][ 'is' . $lcItem ])) {
414 $method = 'is' . $item ;
415 } elseif ( isset ( self
:: $cache [ $class ][ 'methods' ][ '__call' ])) {
416 $method = ( string ) $item ;
418 if ( $isDefinedTest ) {
422 if ( $ignoreStrictCheck || ! $this- > env
-> isStrictVariables ()) {
426 throw new Twig_Error_Runtime ( sprintf ( 'Method "%s" for object "%s" does not exist' , $item , get_class ( $object )), - 1 , $this- > getTemplateName ());
429 if ( $isDefinedTest ) {
433 if ( $this- > env
-> hasExtension ( 'sandbox' )) {
434 $this- > env
-> getExtension ( 'sandbox' )-> checkMethodAllowed ( $object , $method );
437 $ret = call_user_func_array ( array ( $object , $method ), $arguments );
439 // useful when calling a template method from a template
440 // this is not supported but unfortunately heavily used in the Symfony profiler
441 if ( $object instanceof Twig_TemplateInterface
) {
442 return $ret === '' ? '' : new Twig_Markup ( $ret , $this- > env
-> getCharset ());
449 * This method is only useful when testing Twig. Do not use it.
451 public static function clearCache ()
453 self
:: $cache = array ();