Updating Twig to version v1.16.0 moving to vendor folder see #7320
	
		
	
				
					
				
			
							parent
							
								
									ed2d3f0f7d
								
							
						
					
					
						commit
						b1d261db6f
					
				@ -1,176 +0,0 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2009 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Twig base exception. | 
				
			||||
 * | 
				
			||||
 * @package    twig | 
				
			||||
 * @author     Fabien Potencier <fabien@symfony.com> | 
				
			||||
 */ | 
				
			||||
class Twig_Error extends Exception | 
				
			||||
{ | 
				
			||||
    protected $lineno; | 
				
			||||
    protected $filename; | 
				
			||||
    protected $rawMessage; | 
				
			||||
    protected $previous; | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Constructor. | 
				
			||||
     * | 
				
			||||
     * @param string    $message  The error message | 
				
			||||
     * @param integer   $lineno   The template line where the error occurred | 
				
			||||
     * @param string    $filename The template file name where the error occurred | 
				
			||||
     * @param Exception $previous The previous exception | 
				
			||||
     */ | 
				
			||||
    public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) | 
				
			||||
    { | 
				
			||||
        if (-1 === $lineno || null === $filename) { | 
				
			||||
            if ($trace = $this->getTemplateTrace()) { | 
				
			||||
                if (-1 === $lineno) { | 
				
			||||
                    $lineno = $this->guessTemplateLine($trace); | 
				
			||||
                } | 
				
			||||
 | 
				
			||||
                if (null === $filename) { | 
				
			||||
                    $filename = $trace['object']->getTemplateName(); | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->lineno = $lineno; | 
				
			||||
        $this->filename = $filename; | 
				
			||||
        $this->rawMessage = $message; | 
				
			||||
 | 
				
			||||
        $this->updateRepr(); | 
				
			||||
 | 
				
			||||
        if (version_compare(PHP_VERSION, '5.3.0', '<')) { | 
				
			||||
            $this->previous = $previous; | 
				
			||||
            parent::__construct($this->message); | 
				
			||||
        } else { | 
				
			||||
            parent::__construct($this->message, 0, $previous); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the raw message. | 
				
			||||
     * | 
				
			||||
     * @return string The raw message | 
				
			||||
     */ | 
				
			||||
    public function getRawMessage() | 
				
			||||
    { | 
				
			||||
        return $this->rawMessage; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the filename where the error occurred. | 
				
			||||
     * | 
				
			||||
     * @return string The filename | 
				
			||||
     */ | 
				
			||||
    public function getTemplateFile() | 
				
			||||
    { | 
				
			||||
        return $this->filename; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Sets the filename where the error occurred. | 
				
			||||
     * | 
				
			||||
     * @param string $filename The filename | 
				
			||||
     */ | 
				
			||||
    public function setTemplateFile($filename) | 
				
			||||
    { | 
				
			||||
        $this->filename = $filename; | 
				
			||||
 | 
				
			||||
        $this->updateRepr(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the template line where the error occurred. | 
				
			||||
     * | 
				
			||||
     * @return integer The template line | 
				
			||||
     */ | 
				
			||||
    public function getTemplateLine() | 
				
			||||
    { | 
				
			||||
        return $this->lineno; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Sets the template line where the error occurred. | 
				
			||||
     * | 
				
			||||
     * @param integer $lineno The template line | 
				
			||||
     */ | 
				
			||||
    public function setTemplateLine($lineno) | 
				
			||||
    { | 
				
			||||
        $this->lineno = $lineno; | 
				
			||||
 | 
				
			||||
        $this->updateRepr(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * For PHP < 5.3.0, provides access to the getPrevious() method. | 
				
			||||
     * | 
				
			||||
     * @param  string $method    The method name | 
				
			||||
     * @param  array  $arguments The parameters to be passed to the method | 
				
			||||
     * | 
				
			||||
     * @return Exception The previous exception or null | 
				
			||||
     */ | 
				
			||||
    public function __call($method, $arguments) | 
				
			||||
    { | 
				
			||||
        if ('getprevious' == strtolower($method)) { | 
				
			||||
            return $this->previous; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method)); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function updateRepr() | 
				
			||||
    { | 
				
			||||
        $this->message = $this->rawMessage; | 
				
			||||
 | 
				
			||||
        $dot = false; | 
				
			||||
        if ('.' === substr($this->message, -1)) { | 
				
			||||
            $this->message = substr($this->message, 0, -1); | 
				
			||||
            $dot = true; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (null !== $this->filename) { | 
				
			||||
            $this->message .= sprintf(' in %s', is_string($this->filename) ? '"'.$this->filename.'"' : json_encode($this->filename)); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if ($this->lineno >= 0) { | 
				
			||||
            $this->message .= sprintf(' at line %d', $this->lineno); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if ($dot) { | 
				
			||||
            $this->message .= '.'; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function getTemplateTrace() | 
				
			||||
    { | 
				
			||||
        foreach (debug_backtrace() as $trace) { | 
				
			||||
            if (isset($trace['object']) && $trace['object'] instanceof Twig_Template) { | 
				
			||||
                return $trace; | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function guessTemplateLine($trace) | 
				
			||||
    { | 
				
			||||
        if (isset($trace['line'])) { | 
				
			||||
            foreach ($trace['object']->getDebugInfo() as $codeLine => $templateLine) { | 
				
			||||
                if ($codeLine <= $trace['line']) { | 
				
			||||
                    return $templateLine; | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return -1; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -1,20 +0,0 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2010 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Exception thrown when an error occurs during template loading. | 
				
			||||
 * | 
				
			||||
 * @package    twig | 
				
			||||
 * @author     Fabien Potencier <fabien@symfony.com> | 
				
			||||
 */ | 
				
			||||
class Twig_Error_Loader extends Twig_Error | 
				
			||||
{ | 
				
			||||
} | 
				
			||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -1,77 +0,0 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2009 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
class Twig_Extension_Escaper extends Twig_Extension | 
				
			||||
{ | 
				
			||||
    protected $autoescape; | 
				
			||||
 | 
				
			||||
    public function __construct($autoescape = true) | 
				
			||||
    { | 
				
			||||
        $this->autoescape = $autoescape; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns the token parser instances to add to the existing list. | 
				
			||||
     * | 
				
			||||
     * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances | 
				
			||||
     */ | 
				
			||||
    public function getTokenParsers() | 
				
			||||
    { | 
				
			||||
        return array(new Twig_TokenParser_AutoEscape()); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns the node visitor instances to add to the existing list. | 
				
			||||
     * | 
				
			||||
     * @return array An array of Twig_NodeVisitorInterface instances | 
				
			||||
     */ | 
				
			||||
    public function getNodeVisitors() | 
				
			||||
    { | 
				
			||||
        return array(new Twig_NodeVisitor_Escaper()); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns a list of filters to add to the existing list. | 
				
			||||
     * | 
				
			||||
     * @return array An array of filters | 
				
			||||
     */ | 
				
			||||
    public function getFilters() | 
				
			||||
    { | 
				
			||||
        return array( | 
				
			||||
            'raw' => new Twig_Filter_Function('twig_raw_filter', array('is_safe' => array('all'))), | 
				
			||||
        ); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function isGlobal() | 
				
			||||
    { | 
				
			||||
        return $this->autoescape; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns the name of the extension. | 
				
			||||
     * | 
				
			||||
     * @return string The extension name | 
				
			||||
     */ | 
				
			||||
    public function getName() | 
				
			||||
    { | 
				
			||||
        return 'escaper'; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Marks a variable as being safe. | 
				
			||||
 * | 
				
			||||
 * @param string $string A PHP variable | 
				
			||||
 */ | 
				
			||||
function twig_raw_filter($string) | 
				
			||||
{ | 
				
			||||
    return $string; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
@ -1,38 +0,0 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2010 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Represents a template filter. | 
				
			||||
 * | 
				
			||||
 * @package    twig | 
				
			||||
 * @author     Fabien Potencier <fabien@symfony.com> | 
				
			||||
 */ | 
				
			||||
interface Twig_FilterInterface | 
				
			||||
{ | 
				
			||||
    /** | 
				
			||||
     * Compiles a filter. | 
				
			||||
     * | 
				
			||||
     * @return string The PHP code for the filter | 
				
			||||
     */ | 
				
			||||
    function compile(); | 
				
			||||
 | 
				
			||||
    function needsEnvironment(); | 
				
			||||
 | 
				
			||||
    function needsContext(); | 
				
			||||
 | 
				
			||||
    function getSafe(Twig_Node $filterArgs); | 
				
			||||
 | 
				
			||||
    function getPreEscape(); | 
				
			||||
 | 
				
			||||
    function setArguments($arguments); | 
				
			||||
 | 
				
			||||
    function getArguments(); | 
				
			||||
} | 
				
			||||
@ -1,100 +0,0 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2011 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Loads templates from other loaders. | 
				
			||||
 * | 
				
			||||
 * @package twig | 
				
			||||
 * @author  Fabien Potencier <fabien@symfony.com> | 
				
			||||
 */ | 
				
			||||
class Twig_Loader_Chain implements Twig_LoaderInterface | 
				
			||||
{ | 
				
			||||
    protected $loaders; | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Constructor. | 
				
			||||
     * | 
				
			||||
     * @param Twig_LoaderInterface[] $loaders An array of loader instances | 
				
			||||
     */ | 
				
			||||
    public function __construct(array $loaders = array()) | 
				
			||||
    { | 
				
			||||
        $this->loaders = array(); | 
				
			||||
        foreach ($loaders as $loader) { | 
				
			||||
            $this->addLoader($loader); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Adds a loader instance. | 
				
			||||
     * | 
				
			||||
     * @param Twig_LoaderInterface $loader A Loader instance | 
				
			||||
     */ | 
				
			||||
    public function addLoader(Twig_LoaderInterface $loader) | 
				
			||||
    { | 
				
			||||
        $this->loaders[] = $loader; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the source code of a template, given its name. | 
				
			||||
     * | 
				
			||||
     * @param  string $name The name of the template to load | 
				
			||||
     * | 
				
			||||
     * @return string The template source code | 
				
			||||
     */ | 
				
			||||
    public function getSource($name) | 
				
			||||
    { | 
				
			||||
        foreach ($this->loaders as $loader) { | 
				
			||||
            try { | 
				
			||||
                return $loader->getSource($name); | 
				
			||||
            } catch (Twig_Error_Loader $e) { | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the cache key to use for the cache for a given template name. | 
				
			||||
     * | 
				
			||||
     * @param  string $name The name of the template to load | 
				
			||||
     * | 
				
			||||
     * @return string The cache key | 
				
			||||
     */ | 
				
			||||
    public function getCacheKey($name) | 
				
			||||
    { | 
				
			||||
        foreach ($this->loaders as $loader) { | 
				
			||||
            try { | 
				
			||||
                return $loader->getCacheKey($name); | 
				
			||||
            } catch (Twig_Error_Loader $e) { | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns true if the template is still fresh. | 
				
			||||
     * | 
				
			||||
     * @param string    $name The template name | 
				
			||||
     * @param timestamp $time The last modification time of the cached template | 
				
			||||
     */ | 
				
			||||
    public function isFresh($name, $time) | 
				
			||||
    { | 
				
			||||
        foreach ($this->loaders as $loader) { | 
				
			||||
            try { | 
				
			||||
                return $loader->isFresh($name, $time); | 
				
			||||
            } catch (Twig_Error_Loader $e) { | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -1,152 +0,0 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2009 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Loads template from the filesystem. | 
				
			||||
 * | 
				
			||||
 * @package    twig | 
				
			||||
 * @author     Fabien Potencier <fabien@symfony.com> | 
				
			||||
 */ | 
				
			||||
class Twig_Loader_Filesystem implements Twig_LoaderInterface | 
				
			||||
{ | 
				
			||||
    protected $paths; | 
				
			||||
    protected $cache; | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Constructor. | 
				
			||||
     * | 
				
			||||
     * @param string|array $paths A path or an array of paths where to look for templates | 
				
			||||
     */ | 
				
			||||
    public function __construct($paths) | 
				
			||||
    { | 
				
			||||
        $this->setPaths($paths); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns the paths to the templates. | 
				
			||||
     * | 
				
			||||
     * @return array The array of paths where to look for templates | 
				
			||||
     */ | 
				
			||||
    public function getPaths() | 
				
			||||
    { | 
				
			||||
        return $this->paths; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Sets the paths where templates are stored. | 
				
			||||
     * | 
				
			||||
     * @param string|array $paths A path or an array of paths where to look for templates | 
				
			||||
     */ | 
				
			||||
    public function setPaths($paths) | 
				
			||||
    { | 
				
			||||
        if (!is_array($paths)) { | 
				
			||||
            $paths = array($paths); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->paths = array(); | 
				
			||||
        foreach ($paths as $path) { | 
				
			||||
            $this->addPath($path); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Adds a path where templates are stored. | 
				
			||||
     * | 
				
			||||
     * @param string $path A path where to look for templates | 
				
			||||
     */ | 
				
			||||
    public function addPath($path) | 
				
			||||
    { | 
				
			||||
        // invalidate the cache | 
				
			||||
        $this->cache = array(); | 
				
			||||
 | 
				
			||||
        if (!is_dir($path)) { | 
				
			||||
            throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->paths[] = $path; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the source code of a template, given its name. | 
				
			||||
     * | 
				
			||||
     * @param  string $name The name of the template to load | 
				
			||||
     * | 
				
			||||
     * @return string The template source code | 
				
			||||
     */ | 
				
			||||
    public function getSource($name) | 
				
			||||
    { | 
				
			||||
        return file_get_contents($this->findTemplate($name)); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the cache key to use for the cache for a given template name. | 
				
			||||
     * | 
				
			||||
     * @param  string $name The name of the template to load | 
				
			||||
     * | 
				
			||||
     * @return string The cache key | 
				
			||||
     */ | 
				
			||||
    public function getCacheKey($name) | 
				
			||||
    { | 
				
			||||
        return $this->findTemplate($name); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns true if the template is still fresh. | 
				
			||||
     * | 
				
			||||
     * @param string    $name The template name | 
				
			||||
     * @param timestamp $time The last modification time of the cached template | 
				
			||||
     */ | 
				
			||||
    public function isFresh($name, $time) | 
				
			||||
    { | 
				
			||||
        return filemtime($this->findTemplate($name)) < $time; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function findTemplate($name) | 
				
			||||
    { | 
				
			||||
        // normalize name | 
				
			||||
        $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')); | 
				
			||||
 | 
				
			||||
        if (isset($this->cache[$name])) { | 
				
			||||
            return $this->cache[$name]; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->validateName($name); | 
				
			||||
 | 
				
			||||
        foreach ($this->paths as $path) { | 
				
			||||
            if (is_file($path.'/'.$name)) { | 
				
			||||
                return $this->cache[$name] = $path.'/'.$name; | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths))); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function validateName($name) | 
				
			||||
    { | 
				
			||||
        if (false !== strpos($name, "\0")) { | 
				
			||||
            throw new Twig_Error_Loader('A template name cannot contain NUL bytes.'); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $parts = explode('/', $name); | 
				
			||||
        $level = 0; | 
				
			||||
        foreach ($parts as $part) { | 
				
			||||
            if ('..' === $part) { | 
				
			||||
                --$level; | 
				
			||||
            } elseif ('.' !== $part) { | 
				
			||||
                ++$level; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            if ($level < 0) { | 
				
			||||
                throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name)); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -1,61 +0,0 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2009 Fabien Potencier | 
				
			||||
 * (c) 2009 Armin Ronacher | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
class Twig_Node_Expression_Filter extends Twig_Node_Expression | 
				
			||||
{ | 
				
			||||
    public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) | 
				
			||||
    { | 
				
			||||
        parent::__construct(array('node' => $node, 'filter' => $filterName, 'arguments' => $arguments), array(), $lineno, $tag); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function compile(Twig_Compiler $compiler) | 
				
			||||
    { | 
				
			||||
        $name = $this->getNode('filter')->getAttribute('value'); | 
				
			||||
 | 
				
			||||
        if (false === $filter = $compiler->getEnvironment()->getFilter($name)) { | 
				
			||||
            $message = sprintf('The filter "%s" does not exist', $name); | 
				
			||||
            if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFilters()))) { | 
				
			||||
                $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            throw new Twig_Error_Syntax($message, $this->getLine()); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->compileFilter($compiler, $filter); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function compileFilter(Twig_Compiler $compiler, Twig_FilterInterface $filter) | 
				
			||||
    { | 
				
			||||
        $compiler | 
				
			||||
            ->raw($filter->compile().'(') | 
				
			||||
            ->raw($filter->needsEnvironment() ? '$this->env, ' : '') | 
				
			||||
            ->raw($filter->needsContext() ? '$context, ' : '') | 
				
			||||
        ; | 
				
			||||
 | 
				
			||||
        foreach ($filter->getArguments() as $argument) { | 
				
			||||
            $compiler | 
				
			||||
                ->string($argument) | 
				
			||||
                ->raw(', ') | 
				
			||||
            ; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $compiler->subcompile($this->getNode('node')); | 
				
			||||
 | 
				
			||||
        foreach ($this->getNode('arguments') as $node) { | 
				
			||||
            $compiler | 
				
			||||
                ->raw(', ') | 
				
			||||
                ->subcompile($node) | 
				
			||||
            ; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $compiler->raw(')'); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -1,66 +0,0 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2010 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
class Twig_Node_Expression_Function extends Twig_Node_Expression | 
				
			||||
{ | 
				
			||||
    public function __construct($name, Twig_NodeInterface $arguments, $lineno) | 
				
			||||
    { | 
				
			||||
        parent::__construct(array('arguments' => $arguments), array('name' => $name), $lineno); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function compile(Twig_Compiler $compiler) | 
				
			||||
    { | 
				
			||||
        $name = $this->getAttribute('name'); | 
				
			||||
 | 
				
			||||
        if (false === $function = $compiler->getEnvironment()->getFunction($name)) { | 
				
			||||
            $message = sprintf('The function "%s" does not exist', $name); | 
				
			||||
            if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFunctions()))) { | 
				
			||||
                $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            throw new Twig_Error_Syntax($message, $this->getLine()); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $compiler->raw($function->compile().'('); | 
				
			||||
 | 
				
			||||
        $first = true; | 
				
			||||
 | 
				
			||||
        if ($function->needsEnvironment()) { | 
				
			||||
            $compiler->raw('$this->env'); | 
				
			||||
            $first = false; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if ($function->needsContext()) { | 
				
			||||
            if (!$first) { | 
				
			||||
                $compiler->raw(', '); | 
				
			||||
            } | 
				
			||||
            $compiler->raw('$context'); | 
				
			||||
            $first = false; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        foreach ($function->getArguments() as $argument) { | 
				
			||||
            if (!$first) { | 
				
			||||
                $compiler->raw(', '); | 
				
			||||
            } | 
				
			||||
            $compiler->string($argument); | 
				
			||||
            $first = false; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        foreach ($this->getNode('arguments') as $node) { | 
				
			||||
            if (!$first) { | 
				
			||||
                $compiler->raw(', '); | 
				
			||||
            } | 
				
			||||
            $compiler->subcompile($node); | 
				
			||||
            $first = false; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $compiler->raw(')'); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -1,54 +0,0 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2010 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
class Twig_Node_Expression_Test extends Twig_Node_Expression | 
				
			||||
{ | 
				
			||||
    public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno) | 
				
			||||
    { | 
				
			||||
        parent::__construct(array('node' => $node, 'arguments' => $arguments), array('name' => $name), $lineno); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function compile(Twig_Compiler $compiler) | 
				
			||||
    { | 
				
			||||
        $name = $this->getAttribute('name'); | 
				
			||||
        $testMap = $compiler->getEnvironment()->getTests(); | 
				
			||||
        if (!isset($testMap[$name])) { | 
				
			||||
            $message = sprintf('The test "%s" does not exist', $name); | 
				
			||||
            if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getTests()))) { | 
				
			||||
                $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            throw new Twig_Error_Syntax($message, $this->getLine()); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $name = $this->getAttribute('name'); | 
				
			||||
        $node = $this->getNode('node'); | 
				
			||||
 | 
				
			||||
        $compiler | 
				
			||||
            ->raw($testMap[$name]->compile().'(') | 
				
			||||
            ->subcompile($node) | 
				
			||||
        ; | 
				
			||||
 | 
				
			||||
        if (null !== $this->getNode('arguments')) { | 
				
			||||
            $compiler->raw(', '); | 
				
			||||
 | 
				
			||||
            $max = count($this->getNode('arguments')) - 1; | 
				
			||||
            foreach ($this->getNode('arguments') as $i => $arg) { | 
				
			||||
                $compiler->subcompile($arg); | 
				
			||||
 | 
				
			||||
                if ($i != $max) { | 
				
			||||
                    $compiler->raw(', '); | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $compiler->raw(')'); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -1,89 +0,0 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2009 Fabien Potencier | 
				
			||||
 * (c) 2009 Armin Ronacher | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Loops over each item of a sequence. | 
				
			||||
 * | 
				
			||||
 * <pre> | 
				
			||||
 * <ul> | 
				
			||||
 *  {% for user in users %} | 
				
			||||
 *    <li>{{ user.username|e }}</li> | 
				
			||||
 *  {% endfor %} | 
				
			||||
 * </ul> | 
				
			||||
 * </pre> | 
				
			||||
 */ | 
				
			||||
class Twig_TokenParser_For extends Twig_TokenParser | 
				
			||||
{ | 
				
			||||
    /** | 
				
			||||
     * Parses a token and returns a node. | 
				
			||||
     * | 
				
			||||
     * @param Twig_Token $token A Twig_Token instance | 
				
			||||
     * | 
				
			||||
     * @return Twig_NodeInterface A Twig_NodeInterface instance | 
				
			||||
     */ | 
				
			||||
    public function parse(Twig_Token $token) | 
				
			||||
    { | 
				
			||||
        $lineno = $token->getLine(); | 
				
			||||
        $targets = $this->parser->getExpressionParser()->parseAssignmentExpression(); | 
				
			||||
        $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, 'in'); | 
				
			||||
        $seq = $this->parser->getExpressionParser()->parseExpression(); | 
				
			||||
 | 
				
			||||
        $ifexpr = null; | 
				
			||||
        if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'if')) { | 
				
			||||
            $this->parser->getStream()->next(); | 
				
			||||
            $ifexpr = $this->parser->getExpressionParser()->parseExpression(); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | 
				
			||||
        $body = $this->parser->subparse(array($this, 'decideForFork')); | 
				
			||||
        if ($this->parser->getStream()->next()->getValue() == 'else') { | 
				
			||||
            $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | 
				
			||||
            $else = $this->parser->subparse(array($this, 'decideForEnd'), true); | 
				
			||||
        } else { | 
				
			||||
            $else = null; | 
				
			||||
        } | 
				
			||||
        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | 
				
			||||
 | 
				
			||||
        if (count($targets) > 1) { | 
				
			||||
            $keyTarget = $targets->getNode(0); | 
				
			||||
            $keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->getLine()); | 
				
			||||
            $valueTarget = $targets->getNode(1); | 
				
			||||
            $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); | 
				
			||||
        } else { | 
				
			||||
            $keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno); | 
				
			||||
            $valueTarget = $targets->getNode(0); | 
				
			||||
            $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag()); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function decideForFork(Twig_Token $token) | 
				
			||||
    { | 
				
			||||
        return $token->test(array('else', 'endfor')); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function decideForEnd(Twig_Token $token) | 
				
			||||
    { | 
				
			||||
        return $token->test('endfor'); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the tag name associated with this token parser. | 
				
			||||
     * | 
				
			||||
     * @return string The tag name | 
				
			||||
     */ | 
				
			||||
    public function getTag() | 
				
			||||
    { | 
				
			||||
        return 'for'; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,18 @@ | 
				
			||||
; top-most EditorConfig file | 
				
			||||
root = true | 
				
			||||
 | 
				
			||||
; Unix-style newlines | 
				
			||||
[*] | 
				
			||||
end_of_line = LF | 
				
			||||
 | 
				
			||||
[*.php] | 
				
			||||
indent_style = space | 
				
			||||
indent_size = 4 | 
				
			||||
 | 
				
			||||
[*.test] | 
				
			||||
indent_style = space | 
				
			||||
indent_size = 4 | 
				
			||||
 | 
				
			||||
[*.rst] | 
				
			||||
indent_style = space | 
				
			||||
indent_size = 4 | 
				
			||||
@ -0,0 +1,2 @@ | 
				
			||||
/ext/twig/autom4te.cache/ | 
				
			||||
 | 
				
			||||
@ -0,0 +1,21 @@ | 
				
			||||
language: php | 
				
			||||
 | 
				
			||||
php: | 
				
			||||
  - 5.2 | 
				
			||||
  - 5.3 | 
				
			||||
  - 5.4 | 
				
			||||
  - 5.5 | 
				
			||||
  - hhvm | 
				
			||||
 | 
				
			||||
env: | 
				
			||||
  - TWIG_EXT=no | 
				
			||||
  - TWIG_EXT=yes | 
				
			||||
 | 
				
			||||
before_script: | 
				
			||||
  - if [ "$TWIG_EXT" == "yes" ]; then sh -c "cd ext/twig && phpize && ./configure --enable-twig && make && sudo make install"; fi | 
				
			||||
  - if [ "$TWIG_EXT" == "yes" ]; then echo "extension=twig.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi | 
				
			||||
 | 
				
			||||
matrix: | 
				
			||||
  exclude: | 
				
			||||
    - php: hhvm | 
				
			||||
      env: TWIG_EXT=yes | 
				
			||||
@ -0,0 +1,684 @@ | 
				
			||||
* 1.16.0 (2014-07-05) | 
				
			||||
 | 
				
			||||
 * changed url_encode to always encode according to RFC 3986 | 
				
			||||
 * fixed inheritance in a 'use'-hierarchy | 
				
			||||
 * removed the __toString policy check when the sandbox is disabled | 
				
			||||
 * fixed recursively calling blocks in templates with inheritance | 
				
			||||
 | 
				
			||||
* 1.15.1 (2014-02-13) | 
				
			||||
 | 
				
			||||
 * fixed the conversion of the special '0000-00-00 00:00' date | 
				
			||||
 * added an error message when trying to import an undefined block from a trait | 
				
			||||
 * fixed a C extension crash when accessing defined but uninitialized property. | 
				
			||||
 | 
				
			||||
* 1.15.0 (2013-12-06) | 
				
			||||
 | 
				
			||||
 * made ignoreStrictCheck in Template::getAttribute() works with __call() methods throwing BadMethodCallException | 
				
			||||
 * added min and max functions | 
				
			||||
 * added the round filter | 
				
			||||
 * fixed a bug that prevented the optimizers to be enabled/disabled selectively | 
				
			||||
 * fixed first and last filters for UTF-8 strings | 
				
			||||
 * added a source function to include the content of a template without rendering it | 
				
			||||
 * fixed the C extension sandbox behavior when get or set is prepend to method name | 
				
			||||
 | 
				
			||||
* 1.14.2 (2013-10-30) | 
				
			||||
 | 
				
			||||
 * fixed error filename/line when an error occurs in an included file | 
				
			||||
 * allowed operators that contain whitespaces to have more than one whitespace | 
				
			||||
 * allowed tests to be made of 1 or 2 words (like "same as" or "divisible by") | 
				
			||||
 | 
				
			||||
* 1.14.1 (2013-10-15) | 
				
			||||
 | 
				
			||||
 * made it possible to use named operators as variables | 
				
			||||
 * fixed the possibility to have a variable named 'matches' | 
				
			||||
 * added support for PHP 5.5 DateTimeInterface | 
				
			||||
 | 
				
			||||
* 1.14.0 (2013-10-03) | 
				
			||||
 | 
				
			||||
 * fixed usage of the html_attr escaping strategy to avoid double-escaping with the html strategy | 
				
			||||
 * added new operators: ends with, starts with, and matches | 
				
			||||
 * fixed some compatibility issues with HHVM | 
				
			||||
 * added a way to add custom escaping strategies | 
				
			||||
 * fixed the C extension compilation on Windows | 
				
			||||
 * fixed the batch filter when using a fill argument with an exact match of elements to batch | 
				
			||||
 * fixed the filesystem loader cache when a template name exists in several namespaces | 
				
			||||
 * fixed template_from_string when the template includes or extends other ones | 
				
			||||
 * fixed a crash of the C extension on an edge case | 
				
			||||
 | 
				
			||||
* 1.13.2 (2013-08-03) | 
				
			||||
 | 
				
			||||
 * fixed the error line number for an error occurs in and embedded template | 
				
			||||
 * fixed crashes of the C extension on some edge cases | 
				
			||||
 | 
				
			||||
* 1.13.1 (2013-06-06) | 
				
			||||
 | 
				
			||||
 * added the possibility to ignore the filesystem constructor argument in Twig_Loader_Filesystem | 
				
			||||
 * fixed Twig_Loader_Chain::exists() for a loader which implements Twig_ExistsLoaderInterface | 
				
			||||
 * adjusted backtrace call to reduce memory usage when an error occurs | 
				
			||||
 * added support for object instances as the second argument of the constant test | 
				
			||||
 * fixed the include function when used in an assignment | 
				
			||||
 | 
				
			||||
* 1.13.0 (2013-05-10) | 
				
			||||
 | 
				
			||||
 * fixed getting a numeric-like item on a variable ('09' for instance) | 
				
			||||
 * fixed getting a boolean or float key on an array, so it is consistent with PHP's array access: | 
				
			||||
   `{{ array[false] }}` behaves the same as `echo $array[false];` (equals `$array[0]`) | 
				
			||||
 * made the escape filter 20% faster for happy path (escaping string for html with UTF-8) | 
				
			||||
 * changed ☃ to § in tests | 
				
			||||
 * enforced usage of named arguments after positional ones | 
				
			||||
 | 
				
			||||
* 1.12.3 (2013-04-08) | 
				
			||||
 | 
				
			||||
 * fixed a security issue in the filesystem loader where it was possible to include a template one | 
				
			||||
   level above the configured path | 
				
			||||
 * fixed fatal error that should be an exception when adding a filter/function/test too late | 
				
			||||
 * added a batch filter | 
				
			||||
 * added support for encoding an array as query string in the url_encode filter | 
				
			||||
 | 
				
			||||
* 1.12.2 (2013-02-09) | 
				
			||||
 | 
				
			||||
 * fixed the timezone used by the date filter and function when the given date contains a timezone (like 2010-01-28T15:00:00+02:00) | 
				
			||||
 * fixed globals when getGlobals is called early on | 
				
			||||
 * added the first and last filter | 
				
			||||
 | 
				
			||||
* 1.12.1 (2013-01-15) | 
				
			||||
 | 
				
			||||
 * added support for object instances as the second argument of the constant function | 
				
			||||
 * relaxed globals management to avoid a BC break | 
				
			||||
 * added support for {{ some_string[:2] }} | 
				
			||||
 | 
				
			||||
* 1.12.0 (2013-01-08) | 
				
			||||
 | 
				
			||||
 * added verbatim as an alias for the raw tag to avoid confusion with the raw filter | 
				
			||||
 * fixed registration of tests and functions as anonymous functions | 
				
			||||
 * fixed globals management | 
				
			||||
 | 
				
			||||
* 1.12.0-RC1 (2012-12-29) | 
				
			||||
 | 
				
			||||
 * added an include function (does the same as the include tag but in a more flexible way) | 
				
			||||
 * added the ability to use any PHP callable to define filters, functions, and tests | 
				
			||||
 * added a syntax error when using a loop variable that is not defined | 
				
			||||
 * added the ability to set default values for macro arguments | 
				
			||||
 * added support for named arguments for filters, tests, and functions | 
				
			||||
 * moved filters/functions/tests syntax errors to the parser | 
				
			||||
 * added support for extended ternary operator syntaxes | 
				
			||||
 | 
				
			||||
* 1.11.1 (2012-11-11) | 
				
			||||
 | 
				
			||||
 * fixed debug info line numbering (was off by 2) | 
				
			||||
 * fixed escaping when calling a macro inside another one (regression introduced in 1.9.1) | 
				
			||||
 * optimized variable access on PHP 5.4 | 
				
			||||
 * fixed a crash of the C extension when an exception was thrown from a macro called without being imported (using _self.XXX) | 
				
			||||
 | 
				
			||||
* 1.11.0 (2012-11-07) | 
				
			||||
 | 
				
			||||
 * fixed macro compilation when a variable name is a PHP reserved keyword | 
				
			||||
 * changed the date filter behavior to always apply the default timezone, except if false is passed as the timezone | 
				
			||||
 * fixed bitwise operator precedences | 
				
			||||
 * added the template_from_string function | 
				
			||||
 * fixed default timezone usage for the date function | 
				
			||||
 * optimized the way Twig exceptions are managed (to make them faster) | 
				
			||||
 * added Twig_ExistsLoaderInterface (implementing this interface in your loader make the chain loader much faster) | 
				
			||||
 | 
				
			||||
* 1.10.3 (2012-10-19) | 
				
			||||
 | 
				
			||||
 * fixed wrong template location in some error messages | 
				
			||||
 * reverted a BC break introduced in 1.10.2 | 
				
			||||
 * added a split filter | 
				
			||||
 | 
				
			||||
* 1.10.2 (2012-10-15) | 
				
			||||
 | 
				
			||||
 * fixed macro calls on PHP 5.4 | 
				
			||||
 | 
				
			||||
* 1.10.1 (2012-10-15) | 
				
			||||
 | 
				
			||||
 * made a speed optimization to macro calls when imported via the "import" tag | 
				
			||||
 * fixed C extension compilation on Windows | 
				
			||||
 * fixed a segfault in the C extension when using DateTime objects | 
				
			||||
 | 
				
			||||
* 1.10.0 (2012-09-28) | 
				
			||||
 | 
				
			||||
 * extracted functional tests framework to make it reusable for third-party extensions | 
				
			||||
 * added namespaced templates support in Twig_Loader_Filesystem | 
				
			||||
 * added Twig_Loader_Filesystem::prependPath() | 
				
			||||
 * fixed an error when a token parser pass a closure as a test to the subparse() method | 
				
			||||
 | 
				
			||||
* 1.9.2 (2012-08-25) | 
				
			||||
 | 
				
			||||
 * fixed the in operator for objects that contain circular references | 
				
			||||
 * fixed the C extension when accessing a public property of an object implementing the \ArrayAccess interface | 
				
			||||
 | 
				
			||||
* 1.9.1 (2012-07-22) | 
				
			||||
 | 
				
			||||
 * optimized macro calls when auto-escaping is on | 
				
			||||
 * fixed wrong parent class for Twig_Function_Node | 
				
			||||
 * made Twig_Loader_Chain more explicit about problems | 
				
			||||
 | 
				
			||||
* 1.9.0 (2012-07-13) | 
				
			||||
 | 
				
			||||
 * made the parsing independent of the template loaders | 
				
			||||
 * fixed exception trace when an error occurs when rendering a child template | 
				
			||||
 * added escaping strategies for CSS, URL, and HTML attributes | 
				
			||||
 * fixed nested embed tag calls | 
				
			||||
 * added the date_modify filter | 
				
			||||
 | 
				
			||||
* 1.8.3 (2012-06-17) | 
				
			||||
 | 
				
			||||
 * fixed paths in the filesystem loader when passing a path that ends with a slash or a backslash | 
				
			||||
 * fixed escaping when a project defines a function named html or js | 
				
			||||
 * fixed chmod mode to apply the umask correctly | 
				
			||||
 | 
				
			||||
* 1.8.2 (2012-05-30) | 
				
			||||
 | 
				
			||||
 * added the abs filter | 
				
			||||
 * fixed a regression when using a number in template attributes | 
				
			||||
 * fixed compiler when mbstring.func_overload is set to 2 | 
				
			||||
 * fixed DateTimeZone support in date filter | 
				
			||||
 | 
				
			||||
* 1.8.1 (2012-05-17) | 
				
			||||
 | 
				
			||||
 * fixed a regression when dealing with SimpleXMLElement instances in templates | 
				
			||||
 * fixed "is_safe" value for the "dump" function when "html_errors" is not defined in php.ini | 
				
			||||
 * switched to use mbstring whenever possible instead of iconv (you might need to update your encoding as mbstring and iconv encoding names sometimes differ) | 
				
			||||
 | 
				
			||||
* 1.8.0 (2012-05-08) | 
				
			||||
 | 
				
			||||
 * enforced interface when adding tests, filters, functions, and node visitors from extensions | 
				
			||||
 * fixed a side-effect of the date filter where the timezone might be changed | 
				
			||||
 * simplified usage of the autoescape tag; the only (optional) argument is now the escaping strategy or false (with a BC layer) | 
				
			||||
 * added a way to dynamically change the auto-escaping strategy according to the template "filename" | 
				
			||||
 * changed the autoescape option to also accept a supported escaping strategy (for BC, true is equivalent to html) | 
				
			||||
 * added an embed tag | 
				
			||||
 | 
				
			||||
* 1.7.0 (2012-04-24) | 
				
			||||
 | 
				
			||||
 * fixed a PHP warning when using CIFS | 
				
			||||
 * fixed template line number in some exceptions | 
				
			||||
 * added an iterable test | 
				
			||||
 * added an error when defining two blocks with the same name in a template | 
				
			||||
 * added the preserves_safety option for filters | 
				
			||||
 * fixed a PHP notice when trying to access a key on a non-object/array variable | 
				
			||||
 * enhanced error reporting when the template file is an instance of SplFileInfo | 
				
			||||
 * added Twig_Environment::mergeGlobals() | 
				
			||||
 * added compilation checks to avoid misuses of the sandbox tag | 
				
			||||
 * fixed filesystem loader freshness logic for high traffic websites | 
				
			||||
 * fixed random function when charset is null | 
				
			||||
 | 
				
			||||
* 1.6.5 (2012-04-11) | 
				
			||||
 | 
				
			||||
 * fixed a regression when a template only extends another one without defining any blocks | 
				
			||||
 | 
				
			||||
* 1.6.4 (2012-04-02) | 
				
			||||
 | 
				
			||||
 * fixed PHP notice in Twig_Error::guessTemplateLine() introduced in 1.6.3 | 
				
			||||
 * fixed performance when compiling large files | 
				
			||||
 * optimized parent template creation when the template does not use dynamic inheritance | 
				
			||||
 | 
				
			||||
* 1.6.3 (2012-03-22) | 
				
			||||
 | 
				
			||||
 * fixed usage of Z_ADDREF_P for PHP 5.2 in the C extension | 
				
			||||
 * fixed compilation of numeric values used in templates when using a locale where the decimal separator is not a dot | 
				
			||||
 * made the strategy used to guess the real template file name and line number in exception messages much faster and more accurate | 
				
			||||
 | 
				
			||||
* 1.6.2 (2012-03-18) | 
				
			||||
 | 
				
			||||
 * fixed sandbox mode when used with inheritance | 
				
			||||
 * added preserveKeys support for the slice filter | 
				
			||||
 * fixed the date filter when a DateTime instance is passed with a specific timezone | 
				
			||||
 * added a trim filter | 
				
			||||
 | 
				
			||||
* 1.6.1 (2012-02-29) | 
				
			||||
 | 
				
			||||
 * fixed Twig C extension | 
				
			||||
 * removed the creation of Twig_Markup instances when not needed | 
				
			||||
 * added a way to set the default global timezone for dates | 
				
			||||
 * fixed the slice filter on strings when the length is not specified | 
				
			||||
 * fixed the creation of the cache directory in case of a race condition | 
				
			||||
 | 
				
			||||
* 1.6.0 (2012-02-04) | 
				
			||||
 | 
				
			||||
 * fixed raw blocks when used with the whitespace trim option | 
				
			||||
 * made a speed optimization to macro calls when imported via the "from" tag | 
				
			||||
 * fixed globals, parsers, visitors, filters, tests, and functions management in Twig_Environment when a new one or new extension is added | 
				
			||||
 * fixed the attribute function when passing arguments | 
				
			||||
 * added slice notation support for the [] operator (syntactic sugar for the slice operator) | 
				
			||||
 * added a slice filter | 
				
			||||
 * added string support for the reverse filter | 
				
			||||
 * fixed the empty test and the length filter for Twig_Markup instances | 
				
			||||
 * added a date function to ease date comparison | 
				
			||||
 * fixed unary operators precedence | 
				
			||||
 * added recursive parsing support in the parser | 
				
			||||
 * added string and integer handling for the random function | 
				
			||||
 | 
				
			||||
* 1.5.1 (2012-01-05) | 
				
			||||
 | 
				
			||||
 * fixed a regression when parsing strings | 
				
			||||
 | 
				
			||||
* 1.5.0 (2012-01-04) | 
				
			||||
 | 
				
			||||
 * added Traversable objects support for the join filter | 
				
			||||
 | 
				
			||||
* 1.5.0-RC2 (2011-12-30) | 
				
			||||
 | 
				
			||||
 * added a way to set the default global date interval format | 
				
			||||
 * fixed the date filter for DateInterval instances (setTimezone() does not exist for them) | 
				
			||||
 * refactored Twig_Template::display() to ease its extension | 
				
			||||
 * added a number_format filter | 
				
			||||
 | 
				
			||||
* 1.5.0-RC1 (2011-12-26) | 
				
			||||
 | 
				
			||||
 * removed the need to quote hash keys | 
				
			||||
 * allowed hash keys to be any expression | 
				
			||||
 * added a do tag | 
				
			||||
 * added a flush tag | 
				
			||||
 * added support for dynamically named filters and functions | 
				
			||||
 * added a dump function to help debugging templates | 
				
			||||
 * added a nl2br filter | 
				
			||||
 * added a random function | 
				
			||||
 * added a way to change the default format for the date filter | 
				
			||||
 * fixed the lexer when an operator ending with a letter ends a line | 
				
			||||
 * added string interpolation support | 
				
			||||
 * enhanced exceptions for unknown filters, functions, tests, and tags | 
				
			||||
 | 
				
			||||
* 1.4.0 (2011-12-07) | 
				
			||||
 | 
				
			||||
 * fixed lexer when using big numbers (> PHP_INT_MAX) | 
				
			||||
 * added missing preserveKeys argument to the reverse filter | 
				
			||||
 * fixed macros containing filter tag calls | 
				
			||||
 | 
				
			||||
* 1.4.0-RC2 (2011-11-27) | 
				
			||||
 | 
				
			||||
 * removed usage of Reflection in Twig_Template::getAttribute() | 
				
			||||
 * added a C extension that can optionally replace Twig_Template::getAttribute() | 
				
			||||
 * added negative timestamp support to the date filter | 
				
			||||
 | 
				
			||||
* 1.4.0-RC1 (2011-11-20) | 
				
			||||
 | 
				
			||||
 * optimized variable access when using PHP 5.4 | 
				
			||||
 * changed the precedence of the .. operator to be more consistent with languages that implements such a feature like Ruby | 
				
			||||
 * added an Exception to Twig_Loader_Array::isFresh() method when the template does not exist to be consistent with other loaders | 
				
			||||
 * added Twig_Function_Node to allow more complex functions to have their own Node class | 
				
			||||
 * added Twig_Filter_Node to allow more complex filters to have their own Node class | 
				
			||||
 * added Twig_Test_Node to allow more complex tests to have their own Node class | 
				
			||||
 * added a better error message when a template is empty but contain a BOM | 
				
			||||
 * fixed "in" operator for empty strings | 
				
			||||
 * fixed the "defined" test and the "default" filter (now works with more than one call (foo.bar.foo) and for both values of the strict_variables option) | 
				
			||||
 * changed the way extensions are loaded (addFilter/addFunction/addGlobal/addTest/addNodeVisitor/addTokenParser/addExtension can now be called in any order) | 
				
			||||
 * added Twig_Environment::display() | 
				
			||||
 * made the escape filter smarter when the encoding is not supported by PHP | 
				
			||||
 * added a convert_encoding filter | 
				
			||||
 * moved all node manipulations outside the compile() Node method | 
				
			||||
 * made several speed optimizations | 
				
			||||
 | 
				
			||||
* 1.3.0 (2011-10-08) | 
				
			||||
 | 
				
			||||
no changes | 
				
			||||
 | 
				
			||||
* 1.3.0-RC1 (2011-10-04) | 
				
			||||
 | 
				
			||||
 * added an optimization for the parent() function | 
				
			||||
 * added cache reloading when auto_reload is true and an extension has been modified | 
				
			||||
 * added the possibility to force the escaping of a string already marked as safe (instance of Twig_Markup) | 
				
			||||
 * allowed empty templates to be used as traits | 
				
			||||
 * added traits support for the "parent" function | 
				
			||||
 | 
				
			||||
* 1.2.0 (2011-09-13) | 
				
			||||
 | 
				
			||||
no changes | 
				
			||||
 | 
				
			||||
* 1.2.0-RC1 (2011-09-10) | 
				
			||||
 | 
				
			||||
 * enhanced the exception when a tag remains unclosed | 
				
			||||
 * added support for empty Countable objects for the "empty" test | 
				
			||||
 * fixed algorithm that determines if a template using inheritance is valid (no output between block definitions) | 
				
			||||
 * added better support for encoding problems when escaping a string (available as of PHP 5.4) | 
				
			||||
 * added a way to ignore a missing template when using the "include" tag ({% include "foo" ignore missing %}) | 
				
			||||
 * added support for an array of templates to the "include" and "extends" tags ({% include ['foo', 'bar'] %}) | 
				
			||||
 * added support for bitwise operators in expressions | 
				
			||||
 * added the "attribute" function to allow getting dynamic attributes on variables | 
				
			||||
 * added Twig_Loader_Chain | 
				
			||||
 * added Twig_Loader_Array::setTemplate() | 
				
			||||
 * added an optimization for the set tag when used to capture a large chunk of static text | 
				
			||||
 * changed name regex to match PHP one "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" (works for blocks, tags, functions, filters, and macros) | 
				
			||||
 * removed the possibility to use the "extends" tag from a block | 
				
			||||
 * added "if" modifier support to "for" loops | 
				
			||||
 | 
				
			||||
* 1.1.2 (2011-07-30) | 
				
			||||
 | 
				
			||||
 * fixed json_encode filter on PHP 5.2 | 
				
			||||
 * fixed regression introduced in 1.1.1 ({{ block(foo|lower) }}) | 
				
			||||
 * fixed inheritance when using conditional parents | 
				
			||||
 * fixed compilation of templates when the body of a child template is not empty | 
				
			||||
 * fixed output when a macro throws an exception | 
				
			||||
 * fixed a parsing problem when a large chunk of text is enclosed in a comment tag | 
				
			||||
 * added PHPDoc for all Token parsers and Core extension functions | 
				
			||||
 | 
				
			||||
* 1.1.1 (2011-07-17) | 
				
			||||
 | 
				
			||||
 * added a performance optimization in the Optimizer (also helps to lower the number of nested level calls) | 
				
			||||
 * made some performance improvement for some edge cases | 
				
			||||
 | 
				
			||||
* 1.1.0 (2011-06-28) | 
				
			||||
 | 
				
			||||
 * fixed json_encode filter | 
				
			||||
 | 
				
			||||
* 1.1.0-RC3 (2011-06-24) | 
				
			||||
 | 
				
			||||
 * fixed method case-sensitivity when using the sandbox mode | 
				
			||||
 * added timezone support for the date filter | 
				
			||||
 * fixed possible security problems with NUL bytes | 
				
			||||
 | 
				
			||||
* 1.1.0-RC2 (2011-06-16) | 
				
			||||
 | 
				
			||||
 * added an exception when the template passed to "use" is not a string | 
				
			||||
 * made 'a.b is defined' not throw an exception if a is not defined (in strict mode) | 
				
			||||
 * added {% line \d+ %} directive | 
				
			||||
 | 
				
			||||
* 1.1.0-RC1 (2011-05-28) | 
				
			||||
 | 
				
			||||
Flush your cache after upgrading. | 
				
			||||
 | 
				
			||||
 * fixed date filter when using a timestamp | 
				
			||||
 * fixed the defined test for some cases | 
				
			||||
 * fixed a parsing problem when a large chunk of text is enclosed in a raw tag | 
				
			||||
 * added support for horizontal reuse of template blocks (see docs for more information) | 
				
			||||
 * added whitespace control modifier to all tags (see docs for more information) | 
				
			||||
 * added null as an alias for none (the null test is also an alias for the none test now) | 
				
			||||
 * made TRUE, FALSE, NONE equivalent to their lowercase counterparts | 
				
			||||
 * wrapped all compilation and runtime exceptions with Twig_Error_Runtime and added logic to guess the template name and line | 
				
			||||
 * moved display() method to Twig_Template (generated templates should now use doDisplay() instead) | 
				
			||||
 | 
				
			||||
* 1.0.0 (2011-03-27) | 
				
			||||
 | 
				
			||||
 * fixed output when using mbstring | 
				
			||||
 * fixed duplicate call of methods when using the sandbox | 
				
			||||
 * made the charset configurable for the escape filter | 
				
			||||
 | 
				
			||||
* 1.0.0-RC2 (2011-02-21) | 
				
			||||
 | 
				
			||||
 * changed the way {% set %} works when capturing (the content is now marked as safe) | 
				
			||||
 * added support for macro name in the endmacro tag | 
				
			||||
 * make Twig_Error compatible with PHP 5.3.0 > | 
				
			||||
 * fixed an infinite loop on some Windows configurations | 
				
			||||
 * fixed the "length" filter for numbers | 
				
			||||
 * fixed Template::getAttribute() as properties in PHP are case sensitive | 
				
			||||
 * removed coupling between Twig_Node and Twig_Template | 
				
			||||
 * fixed the ternary operator precedence rule | 
				
			||||
 | 
				
			||||
* 1.0.0-RC1 (2011-01-09) | 
				
			||||
 | 
				
			||||
Backward incompatibilities: | 
				
			||||
 | 
				
			||||
 * the "items" filter, which has been deprecated for quite a long time now, has been removed | 
				
			||||
 * the "range" filter has been converted to a function: 0|range(10) -> range(0, 10) | 
				
			||||
 * the "constant" filter has been converted to a function: {{ some_date|date('DATE_W3C'|constant) }} -> {{ some_date|date(constant('DATE_W3C')) }} | 
				
			||||
 * the "cycle" filter has been converted to a function: {{ ['odd', 'even']|cycle(i) }} -> {{ cycle(['odd', 'even'], i) }} | 
				
			||||
 * the "for" tag does not support "joined by" anymore | 
				
			||||
 * the "autoescape" first argument is now "true"/"false" (instead of "on"/"off") | 
				
			||||
 * the "parent" tag has been replaced by a "parent" function ({{ parent() }} instead of {% parent %}) | 
				
			||||
 * the "display" tag has been replaced by a "block" function ({{ block('title') }} instead of {% display title %}) | 
				
			||||
 * removed the grammar and simple token parser (moved to the Twig Extensions repository) | 
				
			||||
 | 
				
			||||
Changes: | 
				
			||||
 | 
				
			||||
 * added "needs_context" option for filters and functions (the context is then passed as a first argument) | 
				
			||||
 * added global variables support | 
				
			||||
 * made macros return their value instead of echoing directly (fixes calling a macro in sandbox mode) | 
				
			||||
 * added the "from" tag to import macros as functions | 
				
			||||
 * added support for functions (a function is just syntactic sugar for a getAttribute() call) | 
				
			||||
 * made macros callable when sandbox mode is enabled | 
				
			||||
 * added an exception when a macro uses a reserved name | 
				
			||||
 * the "default" filter now uses the "empty" test instead of just checking for null | 
				
			||||
 * added the "empty" test | 
				
			||||
 | 
				
			||||
* 0.9.10 (2010-12-16) | 
				
			||||
 | 
				
			||||
Backward incompatibilities: | 
				
			||||
 | 
				
			||||
 * The Escaper extension is enabled by default, which means that all displayed | 
				
			||||
   variables are now automatically escaped. You can revert to the previous | 
				
			||||
   behavior by removing the extension via $env->removeExtension('escaper') | 
				
			||||
   or just set the 'autoescape' option to 'false'. | 
				
			||||
 * removed the "without loop" attribute for the "for" tag (not needed anymore | 
				
			||||
   as the Optimizer take care of that for most cases) | 
				
			||||
 * arrays and hashes have now a different syntax | 
				
			||||
     * arrays keep the same syntax with square brackets: [1, 2] | 
				
			||||
     * hashes now use curly braces (["a": "b"] should now be written as {"a": "b"}) | 
				
			||||
     * support for "arrays with keys" and "hashes without keys" is not supported anymore ([1, "foo": "bar"] or {"foo": "bar", 1}) | 
				
			||||
 * the i18n extension is now part of the Twig Extensions repository | 
				
			||||
 | 
				
			||||
Changes: | 
				
			||||
 | 
				
			||||
 * added the merge filter | 
				
			||||
 * removed 'is_escaper' option for filters (a left over from the previous version) -- you must use 'is_safe' now instead | 
				
			||||
 * fixed usage of operators as method names (like is, in, and not) | 
				
			||||
 * changed the order of execution for node visitors | 
				
			||||
 * fixed default() filter behavior when used with strict_variables set to on | 
				
			||||
 * fixed filesystem loader compatibility with PHAR files | 
				
			||||
 * enhanced error messages when an unexpected token is parsed in an expression | 
				
			||||
 * fixed filename not being added to syntax error messages | 
				
			||||
 * added the autoescape option to enable/disable autoescaping | 
				
			||||
 * removed the newline after a comment (mimics PHP behavior) | 
				
			||||
 * added a syntax error exception when parent block is used on a template that does not extend another one | 
				
			||||
 * made the Escaper extension enabled by default | 
				
			||||
 * fixed sandbox extension when used with auto output escaping | 
				
			||||
 * fixed escaper when wrapping a Twig_Node_Print (the original class must be preserved) | 
				
			||||
 * added an Optimizer extension (enabled by default; optimizes "for" loops and "raw" filters) | 
				
			||||
 * added priority to node visitors | 
				
			||||
 | 
				
			||||
* 0.9.9 (2010-11-28) | 
				
			||||
 | 
				
			||||
Backward incompatibilities: | 
				
			||||
 * the self special variable has been renamed to _self | 
				
			||||
 * the odd and even filters are now tests: | 
				
			||||
     {{ foo|odd }} must now be written {{ foo is odd }} | 
				
			||||
 * the "safe" filter has been renamed to "raw" | 
				
			||||
 * in Node classes, | 
				
			||||
        sub-nodes are now accessed via getNode() (instead of property access) | 
				
			||||
        attributes via getAttribute() (instead of array access) | 
				
			||||
 * the urlencode filter had been renamed to url_encode | 
				
			||||
 * the include tag now merges the passed variables with the current context by default | 
				
			||||
   (the old behavior is still possible by adding the "only" keyword) | 
				
			||||
 * moved Exceptions to Twig_Error_* (Twig_SyntaxError/Twig_RuntimeError are now Twig_Error_Syntax/Twig_Error_Runtime) | 
				
			||||
 * removed support for {{ 1 < i < 3 }} (use {{ i > 1 and i < 3 }} instead) | 
				
			||||
 * the "in" filter has been removed ({{ a|in(b) }} should now be written {{ a in b }}) | 
				
			||||
 | 
				
			||||
Changes: | 
				
			||||
 * added file and line to Twig_Error_Runtime exceptions thrown from Twig_Template | 
				
			||||
 * changed trans tag to accept any variable for the plural count | 
				
			||||
 * fixed sandbox mode (__toString() method check was not enforced if called implicitly from complex statements) | 
				
			||||
 * added the ** (power) operator | 
				
			||||
 * changed the algorithm used for parsing expressions | 
				
			||||
 * added the spaceless tag | 
				
			||||
 * removed trim_blocks option | 
				
			||||
 * added support for is*() methods for attributes (foo.bar now looks for foo->getBar() or foo->isBar()) | 
				
			||||
 * changed all exceptions to extend Twig_Error | 
				
			||||
 * fixed unary expressions ({{ not(1 or 0) }}) | 
				
			||||
 * fixed child templates (with an extend tag) that uses one or more imports | 
				
			||||
 * added support for {{ 1 not in [2, 3] }} (more readable than the current {{ not (1 in [2, 3]) }}) | 
				
			||||
 * escaping has been rewritten | 
				
			||||
 * the implementation of template inheritance has been rewritten | 
				
			||||
   (blocks can now be called individually and still work with inheritance) | 
				
			||||
 * fixed error handling for if tag when a syntax error occurs within a subparse process | 
				
			||||
 * added a way to implement custom logic for resolving token parsers given a tag name | 
				
			||||
 * fixed js escaper to be stricter (now uses a whilelist-based js escaper) | 
				
			||||
 * added the following filers: "constant", "trans", "replace", "json_encode" | 
				
			||||
 * added a "constant" test | 
				
			||||
 * fixed objects with __toString() not being autoescaped | 
				
			||||
 * fixed subscript expressions when calling __call() (methods now keep the case) | 
				
			||||
 * added "test" feature (accessible via the "is" operator) | 
				
			||||
 * removed the debug tag (should be done in an extension) | 
				
			||||
 * fixed trans tag when no vars are used in plural form | 
				
			||||
 * fixed race condition when writing template cache | 
				
			||||
 * added the special _charset variable to reference the current charset | 
				
			||||
 * added the special _context variable to reference the current context | 
				
			||||
 * renamed self to _self (to avoid conflict) | 
				
			||||
 * fixed Twig_Template::getAttribute() for protected properties | 
				
			||||
 | 
				
			||||
* 0.9.8 (2010-06-28) | 
				
			||||
 | 
				
			||||
Backward incompatibilities: | 
				
			||||
 * the trans tag plural count is now attached to the plural tag: | 
				
			||||
    old: `{% trans count %}...{% plural %}...{% endtrans %}` | 
				
			||||
    new: `{% trans %}...{% plural count %}...{% endtrans %}` | 
				
			||||
 | 
				
			||||
 * added a way to translate strings coming from a variable ({% trans var %}) | 
				
			||||
 * fixed trans tag when used with the Escaper extension | 
				
			||||
 * fixed default cache umask | 
				
			||||
 * removed Twig_Template instances from the debug tag output | 
				
			||||
 * fixed objects with __isset() defined | 
				
			||||
 * fixed set tag when used with a capture | 
				
			||||
 * fixed type hinting for Twig_Environment::addFilter() method | 
				
			||||
 | 
				
			||||
* 0.9.7 (2010-06-12) | 
				
			||||
 | 
				
			||||
Backward incompatibilities: | 
				
			||||
 * changed 'as' to '=' for the set tag ({% set title as "Title" %} must now be {% set title = "Title" %}) | 
				
			||||
 * removed the sandboxed attribute of the include tag (use the new sandbox tag instead) | 
				
			||||
 * refactored the Node system (if you have custom nodes, you will have to update them to use the new API) | 
				
			||||
 | 
				
			||||
 * added self as a special variable that refers to the current template (useful for importing macros from the current template) | 
				
			||||
 * added Twig_Template instance support to the include tag | 
				
			||||
 * added support for dynamic and conditional inheritance ({% extends some_var %} and {% extends standalone ? "minimum" : "base" %}) | 
				
			||||
 * added a grammar sub-framework to ease the creation of custom tags | 
				
			||||
 * fixed the for tag for large arrays (some loop variables are now only available for arrays and objects that implement the Countable interface) | 
				
			||||
 * removed the Twig_Resource::resolveMissingFilter() method | 
				
			||||
 * fixed the filter tag which did not apply filtering to included files | 
				
			||||
 * added a bunch of unit tests | 
				
			||||
 * added a bunch of phpdoc | 
				
			||||
 * added a sandbox tag in the sandbox extension | 
				
			||||
 * changed the date filter to support any date format supported by DateTime | 
				
			||||
 * added strict_variable setting to throw an exception when an invalid variable is used in a template (disabled by default) | 
				
			||||
 * added the lexer, parser, and compiler as arguments to the Twig_Environment constructor | 
				
			||||
 * changed the cache option to only accepts an explicit path to a cache directory or false | 
				
			||||
 * added a way to add token parsers, filters, and visitors without creating an extension | 
				
			||||
 * added three interfaces: Twig_NodeInterface, Twig_TokenParserInterface, and Twig_FilterInterface | 
				
			||||
 * changed the generated code to match the new coding standards | 
				
			||||
 * fixed sandbox mode (__toString() method check was not enforced if called implicitly from a simple statement like {{ article }}) | 
				
			||||
 * added an exception when a child template has a non-empty body (as it is always ignored when rendering) | 
				
			||||
 | 
				
			||||
* 0.9.6 (2010-05-12) | 
				
			||||
 | 
				
			||||
 * fixed variables defined outside a loop and for which the value changes in a for loop | 
				
			||||
 * fixed the test suite for PHP 5.2 and older versions of PHPUnit | 
				
			||||
 * added support for __call() in expression resolution | 
				
			||||
 * fixed node visiting for macros (macros are now visited by visitors as any other node) | 
				
			||||
 * fixed nested block definitions with a parent call (rarely useful but nonetheless supported now) | 
				
			||||
 * added the cycle filter | 
				
			||||
 * fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII | 
				
			||||
 * added a long-syntax for the set tag ({% set foo %}...{% endset %}) | 
				
			||||
 * unit tests are now powered by PHPUnit | 
				
			||||
 * added support for gettext via the `i18n` extension | 
				
			||||
 * fixed twig_capitalize_string_filter() and fixed twig_length_filter() when used with UTF-8 values | 
				
			||||
 * added a more useful exception if an if tag is not closed properly | 
				
			||||
 * added support for escaping strategy in the autoescape tag | 
				
			||||
 * fixed lexer when a template has a big chunk of text between/in a block | 
				
			||||
 | 
				
			||||
* 0.9.5 (2010-01-20) | 
				
			||||
 | 
				
			||||
As for any new release, don't forget to remove all cached templates after | 
				
			||||
upgrading. | 
				
			||||
 | 
				
			||||
If you have defined custom filters, you MUST upgrade them for this release. To | 
				
			||||
upgrade, replace "array" with "new Twig_Filter_Function", and replace the | 
				
			||||
environment constant by the "needs_environment" option: | 
				
			||||
 | 
				
			||||
  // before | 
				
			||||
  'even'   => array('twig_is_even_filter', false), | 
				
			||||
  'escape' => array('twig_escape_filter', true), | 
				
			||||
 | 
				
			||||
  // after | 
				
			||||
  'even'   => new Twig_Filter_Function('twig_is_even_filter'), | 
				
			||||
  'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)), | 
				
			||||
 | 
				
			||||
If you have created NodeTransformer classes, you will need to upgrade them to | 
				
			||||
the new interface (please note that the interface is not yet considered | 
				
			||||
stable). | 
				
			||||
 | 
				
			||||
 * fixed list nodes that did not extend the Twig_NodeListInterface | 
				
			||||
 * added the "without loop" option to the for tag (it disables the generation of the loop variable) | 
				
			||||
 * refactored node transformers to node visitors | 
				
			||||
 * fixed automatic-escaping for blocks | 
				
			||||
 * added a way to specify variables to pass to an included template | 
				
			||||
 * changed the automatic-escaping rules to be more sensible and more configurable in custom filters (the documentation lists all the rules) | 
				
			||||
 * improved the filter system to allow object methods to be used as filters | 
				
			||||
 * changed the Array and String loaders to actually make use of the cache mechanism | 
				
			||||
 * included the default filter function definitions in the extension class files directly (Core, Escaper) | 
				
			||||
 * added the // operator (like the floor() PHP function) | 
				
			||||
 * added the .. operator (as a syntactic sugar for the range filter when the step is 1) | 
				
			||||
 * added the in operator (as a syntactic sugar for the in filter) | 
				
			||||
 * added the following filters in the Core extension: in, range | 
				
			||||
 * added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes) | 
				
			||||
 * enhanced some error messages to provide better feedback in case of parsing errors | 
				
			||||
 | 
				
			||||
* 0.9.4 (2009-12-02) | 
				
			||||
 | 
				
			||||
If you have custom loaders, you MUST upgrade them for this release: The | 
				
			||||
Twig_Loader base class has been removed, and the Twig_LoaderInterface has also | 
				
			||||
been changed (see the source code for more information or the documentation). | 
				
			||||
 | 
				
			||||
 * added support for DateTime instances for the date filter | 
				
			||||
 * fixed loop.last when the array only has one item | 
				
			||||
 * made it possible to insert newlines in tag and variable blocks | 
				
			||||
 * fixed a bug when a literal '\n' were present in a template text | 
				
			||||
 * fixed bug when the filename of a template contains */ | 
				
			||||
 * refactored loaders | 
				
			||||
 | 
				
			||||
* 0.9.3 (2009-11-11) | 
				
			||||
 | 
				
			||||
This release is NOT backward compatible with the previous releases. | 
				
			||||
 | 
				
			||||
  The loaders do not take the cache and autoReload arguments anymore. Instead, | 
				
			||||
  the Twig_Environment class has two new options: cache and auto_reload. | 
				
			||||
  Upgrading your code means changing this kind of code: | 
				
			||||
 | 
				
			||||
      $loader = new Twig_Loader_Filesystem('/path/to/templates', '/path/to/compilation_cache', true); | 
				
			||||
      $twig = new Twig_Environment($loader); | 
				
			||||
 | 
				
			||||
  to something like this: | 
				
			||||
 | 
				
			||||
      $loader = new Twig_Loader_Filesystem('/path/to/templates'); | 
				
			||||
      $twig = new Twig_Environment($loader, array( | 
				
			||||
        'cache' => '/path/to/compilation_cache', | 
				
			||||
        'auto_reload' => true, | 
				
			||||
      )); | 
				
			||||
 | 
				
			||||
 * deprecated the "items" filter as it is not needed anymore | 
				
			||||
 * made cache and auto_reload options of Twig_Environment instead of arguments of Twig_Loader | 
				
			||||
 * optimized template loading speed | 
				
			||||
 * removed output when an error occurs in a template and render() is used | 
				
			||||
 * made major speed improvements for loops (up to 300% on even the smallest loops) | 
				
			||||
 * added properties as part of the sandbox mode | 
				
			||||
 * added public properties support (obj.item can now be the item property on the obj object) | 
				
			||||
 * extended set tag to support expression as value ({% set foo as 'foo' ~ 'bar' %} ) | 
				
			||||
 * fixed bug when \ was used in HTML | 
				
			||||
 | 
				
			||||
* 0.9.2 (2009-10-29) | 
				
			||||
 | 
				
			||||
 * made some speed optimizations | 
				
			||||
 * changed the cache extension to .php | 
				
			||||
 * added a js escaping strategy | 
				
			||||
 * added support for short block tag | 
				
			||||
 * changed the filter tag to allow chained filters | 
				
			||||
 * made lexer more flexible as you can now change the default delimiters | 
				
			||||
 * added set tag | 
				
			||||
 * changed default directory permission when cache dir does not exist (more secure) | 
				
			||||
 * added macro support | 
				
			||||
 * changed filters first optional argument to be a Twig_Environment instance instead of a Twig_Template instance | 
				
			||||
 * made Twig_Autoloader::autoload() a static method | 
				
			||||
 * avoid writing template file if an error occurs | 
				
			||||
 * added $ escaping when outputting raw strings | 
				
			||||
 * enhanced some error messages to ease debugging | 
				
			||||
 * fixed empty cache files when the template contains an error | 
				
			||||
 | 
				
			||||
* 0.9.1 (2009-10-14) | 
				
			||||
 | 
				
			||||
  * fixed a bug in PHP 5.2.6 | 
				
			||||
  * fixed numbers with one than one decimal | 
				
			||||
  * added support for method calls with arguments ({{ foo.bar('a', 43) }}) | 
				
			||||
  * made small speed optimizations | 
				
			||||
  * made minor tweaks to allow better extensibility and flexibility | 
				
			||||
 | 
				
			||||
* 0.9.0 (2009-10-12) | 
				
			||||
 | 
				
			||||
 * Initial release | 
				
			||||
@ -0,0 +1,31 @@ | 
				
			||||
Copyright (c) 2009-2014 by the Twig Team. | 
				
			||||
 | 
				
			||||
Some rights reserved. | 
				
			||||
 | 
				
			||||
Redistribution and use in source and binary forms, with or without | 
				
			||||
modification, are permitted provided that the following conditions are | 
				
			||||
met: | 
				
			||||
 | 
				
			||||
    * Redistributions of source code must retain the above copyright | 
				
			||||
      notice, this list of conditions and the following disclaimer. | 
				
			||||
 | 
				
			||||
    * Redistributions in binary form must reproduce the above | 
				
			||||
      copyright notice, this list of conditions and the following | 
				
			||||
      disclaimer in the documentation and/or other materials provided | 
				
			||||
      with the distribution. | 
				
			||||
 | 
				
			||||
    * The names of the contributors may not be used to endorse or | 
				
			||||
      promote products derived from this software without specific | 
				
			||||
      prior written permission. | 
				
			||||
 | 
				
			||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
				
			||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
				
			||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
				
			||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
				
			||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
				
			||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
				
			||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
				
			||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
				
			||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
				
			||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
				
			||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
				
			||||
@ -0,0 +1,15 @@ | 
				
			||||
Twig, the flexible, fast, and secure template language for PHP | 
				
			||||
============================================================== | 
				
			||||
 | 
				
			||||
Twig is a template language for PHP, released under the new BSD license (code | 
				
			||||
and documentation). | 
				
			||||
 | 
				
			||||
Twig uses a syntax similar to the Django and Jinja template languages which | 
				
			||||
inspired the Twig runtime environment. | 
				
			||||
 | 
				
			||||
More Information | 
				
			||||
---------------- | 
				
			||||
 | 
				
			||||
Read the `documentation`_ for more information. | 
				
			||||
 | 
				
			||||
.. _documentation: http://twig.sensiolabs.org/documentation | 
				
			||||
@ -0,0 +1,42 @@ | 
				
			||||
{ | 
				
			||||
    "name": "twig/twig", | 
				
			||||
    "type": "library", | 
				
			||||
    "description": "Twig, the flexible, fast, and secure template language for PHP", | 
				
			||||
    "keywords": ["templating"], | 
				
			||||
    "homepage": "http://twig.sensiolabs.org", | 
				
			||||
    "license": "BSD-3-Clause", | 
				
			||||
    "authors": [ | 
				
			||||
        { | 
				
			||||
            "name": "Fabien Potencier", | 
				
			||||
            "email": "fabien@symfony.com", | 
				
			||||
            "homepage": "http://fabien.potencier.org", | 
				
			||||
            "role": "Lead Developer" | 
				
			||||
        }, | 
				
			||||
        { | 
				
			||||
            "name": "Twig Team", | 
				
			||||
            "homepage": "https://github.com/fabpot/Twig/graphs/contributors", | 
				
			||||
            "role": "Contributors" | 
				
			||||
        }, | 
				
			||||
        { | 
				
			||||
            "name": "Armin Ronacher", | 
				
			||||
            "email": "armin.ronacher@active-4.com", | 
				
			||||
            "role": "Project Founder" | 
				
			||||
        } | 
				
			||||
    ], | 
				
			||||
    "support": { | 
				
			||||
        "forum": "https://groups.google.com/forum/#!forum/twig-users" | 
				
			||||
    }, | 
				
			||||
    "require": { | 
				
			||||
        "php": ">=5.2.4" | 
				
			||||
    }, | 
				
			||||
    "autoload": { | 
				
			||||
        "psr-0" : { | 
				
			||||
            "Twig_" : "lib/" | 
				
			||||
        } | 
				
			||||
    }, | 
				
			||||
    "extra": { | 
				
			||||
        "branch-alias": { | 
				
			||||
            "dev-master": "1.16-dev" | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,30 @@ | 
				
			||||
*.sw* | 
				
			||||
.deps | 
				
			||||
Makefile | 
				
			||||
Makefile.fragments | 
				
			||||
Makefile.global | 
				
			||||
Makefile.objects | 
				
			||||
acinclude.m4 | 
				
			||||
aclocal.m4 | 
				
			||||
build/ | 
				
			||||
config.cache | 
				
			||||
config.guess | 
				
			||||
config.h | 
				
			||||
config.h.in | 
				
			||||
config.log | 
				
			||||
config.nice | 
				
			||||
config.status | 
				
			||||
config.sub | 
				
			||||
configure | 
				
			||||
configure.in | 
				
			||||
install-sh | 
				
			||||
libtool | 
				
			||||
ltmain.sh | 
				
			||||
missing | 
				
			||||
mkinstalldirs | 
				
			||||
run-tests.php | 
				
			||||
twig.loT | 
				
			||||
.libs/ | 
				
			||||
modules/ | 
				
			||||
twig.la | 
				
			||||
twig.lo | 
				
			||||
@ -0,0 +1,31 @@ | 
				
			||||
Copyright (c) 2009-2013 by the Twig Team, see AUTHORS for more details. | 
				
			||||
 | 
				
			||||
Some rights reserved. | 
				
			||||
 | 
				
			||||
Redistribution and use in source and binary forms, with or without | 
				
			||||
modification, are permitted provided that the following conditions are | 
				
			||||
met: | 
				
			||||
 | 
				
			||||
    * Redistributions of source code must retain the above copyright | 
				
			||||
      notice, this list of conditions and the following disclaimer. | 
				
			||||
 | 
				
			||||
    * Redistributions in binary form must reproduce the above | 
				
			||||
      copyright notice, this list of conditions and the following | 
				
			||||
      disclaimer in the documentation and/or other materials provided | 
				
			||||
      with the distribution. | 
				
			||||
 | 
				
			||||
    * The names of the contributors may not be used to endorse or | 
				
			||||
      promote products derived from this software without specific | 
				
			||||
      prior written permission. | 
				
			||||
 | 
				
			||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
				
			||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
				
			||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
				
			||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
				
			||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
				
			||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
				
			||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
				
			||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
				
			||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
				
			||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
				
			||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
				
			||||
@ -0,0 +1,8 @@ | 
				
			||||
dnl config.m4 for extension twig | 
				
			||||
 | 
				
			||||
PHP_ARG_ENABLE(twig, whether to enable twig support, | 
				
			||||
[  --enable-twig           Enable twig support]) | 
				
			||||
 | 
				
			||||
if test "$PHP_TWIG" != "no"; then | 
				
			||||
  PHP_NEW_EXTENSION(twig, twig.c, $ext_shared) | 
				
			||||
fi | 
				
			||||
@ -0,0 +1,8 @@ | 
				
			||||
// vim:ft=javascript | 
				
			||||
 | 
				
			||||
ARG_ENABLE("twig", "Twig support", "no"); | 
				
			||||
 | 
				
			||||
if (PHP_TWIG != "no") { | 
				
			||||
	AC_DEFINE('HAVE_TWIG', 1); | 
				
			||||
	EXTENSION('twig', 'twig.c'); | 
				
			||||
} | 
				
			||||
@ -0,0 +1,31 @@ | 
				
			||||
/*
 | 
				
			||||
   +----------------------------------------------------------------------+ | 
				
			||||
   | Twig Extension                                                       | | 
				
			||||
   +----------------------------------------------------------------------+ | 
				
			||||
   | Copyright (c) 2011 Derick Rethans                                    | | 
				
			||||
   +----------------------------------------------------------------------+ | 
				
			||||
   | Redistribution and use in source and binary forms, with or without   | | 
				
			||||
   | modification, are permitted provided that the conditions mentioned   | | 
				
			||||
   | in the accompanying LICENSE file are met (BSD-3-Clause).             | | 
				
			||||
   +----------------------------------------------------------------------+ | 
				
			||||
   | Author: Derick Rethans <derick@derickrethans.nl>                     | | 
				
			||||
   +----------------------------------------------------------------------+ | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
#ifndef PHP_TWIG_H | 
				
			||||
#define PHP_TWIG_H | 
				
			||||
 | 
				
			||||
#define PHP_TWIG_VERSION "1.16.0" | 
				
			||||
 | 
				
			||||
#include "php.h" | 
				
			||||
 | 
				
			||||
extern zend_module_entry twig_module_entry; | 
				
			||||
#define phpext_twig_ptr &twig_module_entry | 
				
			||||
 | 
				
			||||
#ifdef ZTS | 
				
			||||
#include "TSRM.h" | 
				
			||||
#endif | 
				
			||||
 | 
				
			||||
PHP_FUNCTION(twig_template_get_attributes); | 
				
			||||
 | 
				
			||||
#endif | 
				
			||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -0,0 +1,248 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2009 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Twig base exception. | 
				
			||||
 * | 
				
			||||
 * This exception class and its children must only be used when | 
				
			||||
 * an error occurs during the loading of a template, when a syntax error | 
				
			||||
 * is detected in a template, or when rendering a template. Other | 
				
			||||
 * errors must use regular PHP exception classes (like when the template | 
				
			||||
 * cache directory is not writable for instance). | 
				
			||||
 * | 
				
			||||
 * To help debugging template issues, this class tracks the original template | 
				
			||||
 * name and line where the error occurred. | 
				
			||||
 * | 
				
			||||
 * Whenever possible, you must set these information (original template name | 
				
			||||
 * and line number) yourself by passing them to the constructor. If some or all | 
				
			||||
 * these information are not available from where you throw the exception, then | 
				
			||||
 * this class will guess them automatically (when the line number is set to -1 | 
				
			||||
 * and/or the filename is set to null). As this is a costly operation, this | 
				
			||||
 * can be disabled by passing false for both the filename and the line number | 
				
			||||
 * when creating a new instance of this class. | 
				
			||||
 * | 
				
			||||
 * @author Fabien Potencier <fabien@symfony.com> | 
				
			||||
 */ | 
				
			||||
class Twig_Error extends Exception | 
				
			||||
{ | 
				
			||||
    protected $lineno; | 
				
			||||
    protected $filename; | 
				
			||||
    protected $rawMessage; | 
				
			||||
    protected $previous; | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Constructor. | 
				
			||||
     * | 
				
			||||
     * Set both the line number and the filename to false to | 
				
			||||
     * disable automatic guessing of the original template name | 
				
			||||
     * and line number. | 
				
			||||
     * | 
				
			||||
     * Set the line number to -1 to enable its automatic guessing. | 
				
			||||
     * Set the filename to null to enable its automatic guessing. | 
				
			||||
     * | 
				
			||||
     * By default, automatic guessing is enabled. | 
				
			||||
     * | 
				
			||||
     * @param string    $message  The error message | 
				
			||||
     * @param int       $lineno   The template line where the error occurred | 
				
			||||
     * @param string    $filename The template file name where the error occurred | 
				
			||||
     * @param Exception $previous The previous exception | 
				
			||||
     */ | 
				
			||||
    public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) | 
				
			||||
    { | 
				
			||||
        if (version_compare(PHP_VERSION, '5.3.0', '<')) { | 
				
			||||
            $this->previous = $previous; | 
				
			||||
            parent::__construct(''); | 
				
			||||
        } else { | 
				
			||||
            parent::__construct('', 0, $previous); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->lineno = $lineno; | 
				
			||||
        $this->filename = $filename; | 
				
			||||
 | 
				
			||||
        if (-1 === $this->lineno || null === $this->filename) { | 
				
			||||
            $this->guessTemplateInfo(); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->rawMessage = $message; | 
				
			||||
 | 
				
			||||
        $this->updateRepr(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the raw message. | 
				
			||||
     * | 
				
			||||
     * @return string The raw message | 
				
			||||
     */ | 
				
			||||
    public function getRawMessage() | 
				
			||||
    { | 
				
			||||
        return $this->rawMessage; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the filename where the error occurred. | 
				
			||||
     * | 
				
			||||
     * @return string The filename | 
				
			||||
     */ | 
				
			||||
    public function getTemplateFile() | 
				
			||||
    { | 
				
			||||
        return $this->filename; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Sets the filename where the error occurred. | 
				
			||||
     * | 
				
			||||
     * @param string $filename The filename | 
				
			||||
     */ | 
				
			||||
    public function setTemplateFile($filename) | 
				
			||||
    { | 
				
			||||
        $this->filename = $filename; | 
				
			||||
 | 
				
			||||
        $this->updateRepr(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the template line where the error occurred. | 
				
			||||
     * | 
				
			||||
     * @return int     The template line | 
				
			||||
     */ | 
				
			||||
    public function getTemplateLine() | 
				
			||||
    { | 
				
			||||
        return $this->lineno; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Sets the template line where the error occurred. | 
				
			||||
     * | 
				
			||||
     * @param int     $lineno The template line | 
				
			||||
     */ | 
				
			||||
    public function setTemplateLine($lineno) | 
				
			||||
    { | 
				
			||||
        $this->lineno = $lineno; | 
				
			||||
 | 
				
			||||
        $this->updateRepr(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function guess() | 
				
			||||
    { | 
				
			||||
        $this->guessTemplateInfo(); | 
				
			||||
        $this->updateRepr(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * For PHP < 5.3.0, provides access to the getPrevious() method. | 
				
			||||
     * | 
				
			||||
     * @param string $method    The method name | 
				
			||||
     * @param array  $arguments The parameters to be passed to the method | 
				
			||||
     * | 
				
			||||
     * @return Exception The previous exception or null | 
				
			||||
     * | 
				
			||||
     * @throws BadMethodCallException | 
				
			||||
     */ | 
				
			||||
    public function __call($method, $arguments) | 
				
			||||
    { | 
				
			||||
        if ('getprevious' == strtolower($method)) { | 
				
			||||
            return $this->previous; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method)); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function updateRepr() | 
				
			||||
    { | 
				
			||||
        $this->message = $this->rawMessage; | 
				
			||||
 | 
				
			||||
        $dot = false; | 
				
			||||
        if ('.' === substr($this->message, -1)) { | 
				
			||||
            $this->message = substr($this->message, 0, -1); | 
				
			||||
            $dot = true; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if ($this->filename) { | 
				
			||||
            if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) { | 
				
			||||
                $filename = sprintf('"%s"', $this->filename); | 
				
			||||
            } else { | 
				
			||||
                $filename = json_encode($this->filename); | 
				
			||||
            } | 
				
			||||
            $this->message .= sprintf(' in %s', $filename); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if ($this->lineno && $this->lineno >= 0) { | 
				
			||||
            $this->message .= sprintf(' at line %d', $this->lineno); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if ($dot) { | 
				
			||||
            $this->message .= '.'; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function guessTemplateInfo() | 
				
			||||
    { | 
				
			||||
        $template = null; | 
				
			||||
        $templateClass = null; | 
				
			||||
 | 
				
			||||
        if (version_compare(phpversion(), '5.3.6', '>=')) { | 
				
			||||
            $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT); | 
				
			||||
        } else { | 
				
			||||
            $backtrace = debug_backtrace(); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        foreach ($backtrace as $trace) { | 
				
			||||
            if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) { | 
				
			||||
                $currentClass = get_class($trace['object']); | 
				
			||||
                $isEmbedContainer = 0 === strpos($templateClass, $currentClass); | 
				
			||||
                if (null === $this->filename || ($this->filename == $trace['object']->getTemplateName() && !$isEmbedContainer)) { | 
				
			||||
                    $template = $trace['object']; | 
				
			||||
                    $templateClass = get_class($trace['object']); | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // update template filename | 
				
			||||
        if (null !== $template && null === $this->filename) { | 
				
			||||
            $this->filename = $template->getTemplateName(); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (null === $template || $this->lineno > -1) { | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $r = new ReflectionObject($template); | 
				
			||||
        $file = $r->getFileName(); | 
				
			||||
 | 
				
			||||
        // hhvm has a bug where eval'ed files comes out as the current directory | 
				
			||||
        if (is_dir($file)) { | 
				
			||||
            $file = ''; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $exceptions = array($e = $this); | 
				
			||||
        while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) { | 
				
			||||
            $exceptions[] = $e; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        while ($e = array_pop($exceptions)) { | 
				
			||||
            $traces = $e->getTrace(); | 
				
			||||
            while ($trace = array_shift($traces)) { | 
				
			||||
                if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) { | 
				
			||||
                    continue; | 
				
			||||
                } | 
				
			||||
 | 
				
			||||
                foreach ($template->getDebugInfo() as $codeLine => $templateLine) { | 
				
			||||
                    if ($codeLine <= $trace['line']) { | 
				
			||||
                        // update template line | 
				
			||||
                        $this->lineno = $templateLine; | 
				
			||||
 | 
				
			||||
                        return; | 
				
			||||
                    } | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,31 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2010 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Exception thrown when an error occurs during template loading. | 
				
			||||
 * | 
				
			||||
 * Automatic template information guessing is always turned off as | 
				
			||||
 * if a template cannot be loaded, there is nothing to guess. | 
				
			||||
 * However, when a template is loaded from another one, then, we need | 
				
			||||
 * to find the current context and this is automatically done by | 
				
			||||
 * Twig_Template::displayWithErrorHandling(). | 
				
			||||
 * | 
				
			||||
 * This strategy makes Twig_Environment::resolveTemplate() much faster. | 
				
			||||
 * | 
				
			||||
 * @author Fabien Potencier <fabien@symfony.com> | 
				
			||||
 */ | 
				
			||||
class Twig_Error_Loader extends Twig_Error | 
				
			||||
{ | 
				
			||||
    public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) | 
				
			||||
    { | 
				
			||||
        parent::__construct($message, false, false, $previous); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,29 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2009 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Adds an exists() method for loaders. | 
				
			||||
 * | 
				
			||||
 * @author Florin Patan <florinpatan@gmail.com> | 
				
			||||
 * | 
				
			||||
 * @deprecated since 1.12 (to be removed in 3.0) | 
				
			||||
 */ | 
				
			||||
interface Twig_ExistsLoaderInterface | 
				
			||||
{ | 
				
			||||
    /** | 
				
			||||
     * Check if we have the source code of a template, given its name. | 
				
			||||
     * | 
				
			||||
     * @param string $name The name of the template to check if we can load | 
				
			||||
     * | 
				
			||||
     * @return bool    If the template source code is handled by this loader or not | 
				
			||||
     */ | 
				
			||||
    public function exists($name); | 
				
			||||
} | 
				
			||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -0,0 +1,107 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2009 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
class Twig_Extension_Escaper extends Twig_Extension | 
				
			||||
{ | 
				
			||||
    protected $defaultStrategy; | 
				
			||||
 | 
				
			||||
    public function __construct($defaultStrategy = 'html') | 
				
			||||
    { | 
				
			||||
        $this->setDefaultStrategy($defaultStrategy); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns the token parser instances to add to the existing list. | 
				
			||||
     * | 
				
			||||
     * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances | 
				
			||||
     */ | 
				
			||||
    public function getTokenParsers() | 
				
			||||
    { | 
				
			||||
        return array(new Twig_TokenParser_AutoEscape()); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns the node visitor instances to add to the existing list. | 
				
			||||
     * | 
				
			||||
     * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances | 
				
			||||
     */ | 
				
			||||
    public function getNodeVisitors() | 
				
			||||
    { | 
				
			||||
        return array(new Twig_NodeVisitor_Escaper()); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns a list of filters to add to the existing list. | 
				
			||||
     * | 
				
			||||
     * @return array An array of filters | 
				
			||||
     */ | 
				
			||||
    public function getFilters() | 
				
			||||
    { | 
				
			||||
        return array( | 
				
			||||
            new Twig_SimpleFilter('raw', 'twig_raw_filter', array('is_safe' => array('all'))), | 
				
			||||
        ); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Sets the default strategy to use when not defined by the user. | 
				
			||||
     * | 
				
			||||
     * The strategy can be a valid PHP callback that takes the template | 
				
			||||
     * "filename" as an argument and returns the strategy to use. | 
				
			||||
     * | 
				
			||||
     * @param mixed $defaultStrategy An escaping strategy | 
				
			||||
     */ | 
				
			||||
    public function setDefaultStrategy($defaultStrategy) | 
				
			||||
    { | 
				
			||||
        // for BC | 
				
			||||
        if (true === $defaultStrategy) { | 
				
			||||
            $defaultStrategy = 'html'; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->defaultStrategy = $defaultStrategy; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Gets the default strategy to use when not defined by the user. | 
				
			||||
     * | 
				
			||||
     * @param string $filename The template "filename" | 
				
			||||
     * | 
				
			||||
     * @return string The default strategy to use for the template | 
				
			||||
     */ | 
				
			||||
    public function getDefaultStrategy($filename) | 
				
			||||
    { | 
				
			||||
        // disable string callables to avoid calling a function named html or js, | 
				
			||||
        // or any other upcoming escaping strategy | 
				
			||||
        if (!is_string($this->defaultStrategy) && is_callable($this->defaultStrategy)) { | 
				
			||||
            return call_user_func($this->defaultStrategy, $filename); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return $this->defaultStrategy; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns the name of the extension. | 
				
			||||
     * | 
				
			||||
     * @return string The extension name | 
				
			||||
     */ | 
				
			||||
    public function getName() | 
				
			||||
    { | 
				
			||||
        return 'escaper'; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Marks a variable as being safe. | 
				
			||||
 * | 
				
			||||
 * @param string $string A PHP variable | 
				
			||||
 */ | 
				
			||||
function twig_raw_filter($string) | 
				
			||||
{ | 
				
			||||
    return $string; | 
				
			||||
} | 
				
			||||
@ -0,0 +1,113 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2012 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Internal class. | 
				
			||||
 * | 
				
			||||
 * This class is used by Twig_Environment as a staging area and must not be used directly. | 
				
			||||
 * | 
				
			||||
 * @author Fabien Potencier <fabien@symfony.com> | 
				
			||||
 */ | 
				
			||||
class Twig_Extension_Staging extends Twig_Extension | 
				
			||||
{ | 
				
			||||
    protected $functions = array(); | 
				
			||||
    protected $filters = array(); | 
				
			||||
    protected $visitors = array(); | 
				
			||||
    protected $tokenParsers = array(); | 
				
			||||
    protected $globals = array(); | 
				
			||||
    protected $tests = array(); | 
				
			||||
 | 
				
			||||
    public function addFunction($name, $function) | 
				
			||||
    { | 
				
			||||
        $this->functions[$name] = $function; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getFunctions() | 
				
			||||
    { | 
				
			||||
        return $this->functions; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function addFilter($name, $filter) | 
				
			||||
    { | 
				
			||||
        $this->filters[$name] = $filter; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getFilters() | 
				
			||||
    { | 
				
			||||
        return $this->filters; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) | 
				
			||||
    { | 
				
			||||
        $this->visitors[] = $visitor; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getNodeVisitors() | 
				
			||||
    { | 
				
			||||
        return $this->visitors; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function addTokenParser(Twig_TokenParserInterface $parser) | 
				
			||||
    { | 
				
			||||
        $this->tokenParsers[] = $parser; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getTokenParsers() | 
				
			||||
    { | 
				
			||||
        return $this->tokenParsers; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function addGlobal($name, $value) | 
				
			||||
    { | 
				
			||||
        $this->globals[$name] = $value; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getGlobals() | 
				
			||||
    { | 
				
			||||
        return $this->globals; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function addTest($name, $test) | 
				
			||||
    { | 
				
			||||
        $this->tests[$name] = $test; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getTests() | 
				
			||||
    { | 
				
			||||
        return $this->tests; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getName() | 
				
			||||
    { | 
				
			||||
        return 'staging'; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,64 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2012 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
class Twig_Extension_StringLoader extends Twig_Extension | 
				
			||||
{ | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getFunctions() | 
				
			||||
    { | 
				
			||||
        return array( | 
				
			||||
            new Twig_SimpleFunction('template_from_string', 'twig_template_from_string', array('needs_environment' => true)), | 
				
			||||
        ); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getName() | 
				
			||||
    { | 
				
			||||
        return 'string_loader'; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Loads a template from a string. | 
				
			||||
 * | 
				
			||||
 * <pre> | 
				
			||||
 * {{ include(template_from_string("Hello {{ name }}")) }} | 
				
			||||
 * </pre> | 
				
			||||
 * | 
				
			||||
 * @param Twig_Environment $env      A Twig_Environment instance | 
				
			||||
 * @param string           $template A template as a string | 
				
			||||
 * | 
				
			||||
 * @return Twig_Template A Twig_Template instance | 
				
			||||
 */ | 
				
			||||
function twig_template_from_string(Twig_Environment $env, $template) | 
				
			||||
{ | 
				
			||||
    $name = sprintf('__string_template__%s', hash('sha256', uniqid(mt_rand(), true), false)); | 
				
			||||
 | 
				
			||||
    $loader = new Twig_Loader_Chain(array( | 
				
			||||
        new Twig_Loader_Array(array($name => $template)), | 
				
			||||
        $current = $env->getLoader(), | 
				
			||||
    )); | 
				
			||||
 | 
				
			||||
    $env->setLoader($loader); | 
				
			||||
    try { | 
				
			||||
        $template = $env->loadTemplate($name); | 
				
			||||
    } catch (Exception $e) { | 
				
			||||
        $env->setLoader($current); | 
				
			||||
 | 
				
			||||
        throw $e; | 
				
			||||
    } | 
				
			||||
    $env->setLoader($current); | 
				
			||||
 | 
				
			||||
    return $template; | 
				
			||||
} | 
				
			||||
@ -0,0 +1,23 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2012 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Represents a callable template filter. | 
				
			||||
 * | 
				
			||||
 * Use Twig_SimpleFilter instead. | 
				
			||||
 * | 
				
			||||
 * @author Fabien Potencier <fabien@symfony.com> | 
				
			||||
 * @deprecated since 1.12 (to be removed in 2.0) | 
				
			||||
 */ | 
				
			||||
interface Twig_FilterCallableInterface | 
				
			||||
{ | 
				
			||||
    public function getCallable(); | 
				
			||||
} | 
				
			||||
@ -0,0 +1,42 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2010 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Represents a template filter. | 
				
			||||
 * | 
				
			||||
 * Use Twig_SimpleFilter instead. | 
				
			||||
 * | 
				
			||||
 * @author Fabien Potencier <fabien@symfony.com> | 
				
			||||
 * @deprecated since 1.12 (to be removed in 2.0) | 
				
			||||
 */ | 
				
			||||
interface Twig_FilterInterface | 
				
			||||
{ | 
				
			||||
    /** | 
				
			||||
     * Compiles a filter. | 
				
			||||
     * | 
				
			||||
     * @return string The PHP code for the filter | 
				
			||||
     */ | 
				
			||||
    public function compile(); | 
				
			||||
 | 
				
			||||
    public function needsEnvironment(); | 
				
			||||
 | 
				
			||||
    public function needsContext(); | 
				
			||||
 | 
				
			||||
    public function getSafe(Twig_Node $filterArgs); | 
				
			||||
 | 
				
			||||
    public function getPreservesSafety(); | 
				
			||||
 | 
				
			||||
    public function getPreEscape(); | 
				
			||||
 | 
				
			||||
    public function setArguments($arguments); | 
				
			||||
 | 
				
			||||
    public function getArguments(); | 
				
			||||
} | 
				
			||||
@ -0,0 +1,23 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2012 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Represents a callable template function. | 
				
			||||
 * | 
				
			||||
 * Use Twig_SimpleFunction instead. | 
				
			||||
 * | 
				
			||||
 * @author Fabien Potencier <fabien@symfony.com> | 
				
			||||
 * @deprecated since 1.12 (to be removed in 2.0) | 
				
			||||
 */ | 
				
			||||
interface Twig_FunctionCallableInterface | 
				
			||||
{ | 
				
			||||
    public function getCallable(); | 
				
			||||
} | 
				
			||||
@ -0,0 +1,138 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2011 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Loads templates from other loaders. | 
				
			||||
 * | 
				
			||||
 * @author Fabien Potencier <fabien@symfony.com> | 
				
			||||
 */ | 
				
			||||
class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface | 
				
			||||
{ | 
				
			||||
    private $hasSourceCache = array(); | 
				
			||||
    protected $loaders = array(); | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Constructor. | 
				
			||||
     * | 
				
			||||
     * @param Twig_LoaderInterface[] $loaders An array of loader instances | 
				
			||||
     */ | 
				
			||||
    public function __construct(array $loaders = array()) | 
				
			||||
    { | 
				
			||||
        foreach ($loaders as $loader) { | 
				
			||||
            $this->addLoader($loader); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Adds a loader instance. | 
				
			||||
     * | 
				
			||||
     * @param Twig_LoaderInterface $loader A Loader instance | 
				
			||||
     */ | 
				
			||||
    public function addLoader(Twig_LoaderInterface $loader) | 
				
			||||
    { | 
				
			||||
        $this->loaders[] = $loader; | 
				
			||||
        $this->hasSourceCache = array(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getSource($name) | 
				
			||||
    { | 
				
			||||
        $exceptions = array(); | 
				
			||||
        foreach ($this->loaders as $loader) { | 
				
			||||
            if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { | 
				
			||||
                continue; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            try { | 
				
			||||
                return $loader->getSource($name); | 
				
			||||
            } catch (Twig_Error_Loader $e) { | 
				
			||||
                $exceptions[] = $e->getMessage(); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(', ', $exceptions))); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function exists($name) | 
				
			||||
    { | 
				
			||||
        $name = (string) $name; | 
				
			||||
 | 
				
			||||
        if (isset($this->hasSourceCache[$name])) { | 
				
			||||
            return $this->hasSourceCache[$name]; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        foreach ($this->loaders as $loader) { | 
				
			||||
            if ($loader instanceof Twig_ExistsLoaderInterface) { | 
				
			||||
                if ($loader->exists($name)) { | 
				
			||||
                    return $this->hasSourceCache[$name] = true; | 
				
			||||
                } | 
				
			||||
 | 
				
			||||
                continue; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            try { | 
				
			||||
                $loader->getSource($name); | 
				
			||||
 | 
				
			||||
                return $this->hasSourceCache[$name] = true; | 
				
			||||
            } catch (Twig_Error_Loader $e) { | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return $this->hasSourceCache[$name] = false; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getCacheKey($name) | 
				
			||||
    { | 
				
			||||
        $exceptions = array(); | 
				
			||||
        foreach ($this->loaders as $loader) { | 
				
			||||
            if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { | 
				
			||||
                continue; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            try { | 
				
			||||
                return $loader->getCacheKey($name); | 
				
			||||
            } catch (Twig_Error_Loader $e) { | 
				
			||||
                $exceptions[] = get_class($loader).': '.$e->getMessage(); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions))); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function isFresh($name, $time) | 
				
			||||
    { | 
				
			||||
        $exceptions = array(); | 
				
			||||
        foreach ($this->loaders as $loader) { | 
				
			||||
            if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { | 
				
			||||
                continue; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            try { | 
				
			||||
                return $loader->isFresh($name, $time); | 
				
			||||
            } catch (Twig_Error_Loader $e) { | 
				
			||||
                $exceptions[] = get_class($loader).': '.$e->getMessage(); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions))); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,236 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2009 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Loads template from the filesystem. | 
				
			||||
 * | 
				
			||||
 * @author Fabien Potencier <fabien@symfony.com> | 
				
			||||
 */ | 
				
			||||
class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface | 
				
			||||
{ | 
				
			||||
    /** Identifier of the main namespace. */ | 
				
			||||
    const MAIN_NAMESPACE = '__main__'; | 
				
			||||
 | 
				
			||||
    protected $paths = array(); | 
				
			||||
    protected $cache = array(); | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Constructor. | 
				
			||||
     * | 
				
			||||
     * @param string|array $paths A path or an array of paths where to look for templates | 
				
			||||
     */ | 
				
			||||
    public function __construct($paths = array()) | 
				
			||||
    { | 
				
			||||
        if ($paths) { | 
				
			||||
            $this->setPaths($paths); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns the paths to the templates. | 
				
			||||
     * | 
				
			||||
     * @param string $namespace A path namespace | 
				
			||||
     * | 
				
			||||
     * @return array The array of paths where to look for templates | 
				
			||||
     */ | 
				
			||||
    public function getPaths($namespace = self::MAIN_NAMESPACE) | 
				
			||||
    { | 
				
			||||
        return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns the path namespaces. | 
				
			||||
     * | 
				
			||||
     * The main namespace is always defined. | 
				
			||||
     * | 
				
			||||
     * @return array The array of defined namespaces | 
				
			||||
     */ | 
				
			||||
    public function getNamespaces() | 
				
			||||
    { | 
				
			||||
        return array_keys($this->paths); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Sets the paths where templates are stored. | 
				
			||||
     * | 
				
			||||
     * @param string|array $paths     A path or an array of paths where to look for templates | 
				
			||||
     * @param string       $namespace A path namespace | 
				
			||||
     */ | 
				
			||||
    public function setPaths($paths, $namespace = self::MAIN_NAMESPACE) | 
				
			||||
    { | 
				
			||||
        if (!is_array($paths)) { | 
				
			||||
            $paths = array($paths); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->paths[$namespace] = array(); | 
				
			||||
        foreach ($paths as $path) { | 
				
			||||
            $this->addPath($path, $namespace); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Adds a path where templates are stored. | 
				
			||||
     * | 
				
			||||
     * @param string $path      A path where to look for templates | 
				
			||||
     * @param string $namespace A path name | 
				
			||||
     * | 
				
			||||
     * @throws Twig_Error_Loader | 
				
			||||
     */ | 
				
			||||
    public function addPath($path, $namespace = self::MAIN_NAMESPACE) | 
				
			||||
    { | 
				
			||||
        // invalidate the cache | 
				
			||||
        $this->cache = array(); | 
				
			||||
 | 
				
			||||
        if (!is_dir($path)) { | 
				
			||||
            throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->paths[$namespace][] = rtrim($path, '/\\'); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Prepends a path where templates are stored. | 
				
			||||
     * | 
				
			||||
     * @param string $path      A path where to look for templates | 
				
			||||
     * @param string $namespace A path name | 
				
			||||
     * | 
				
			||||
     * @throws Twig_Error_Loader | 
				
			||||
     */ | 
				
			||||
    public function prependPath($path, $namespace = self::MAIN_NAMESPACE) | 
				
			||||
    { | 
				
			||||
        // invalidate the cache | 
				
			||||
        $this->cache = array(); | 
				
			||||
 | 
				
			||||
        if (!is_dir($path)) { | 
				
			||||
            throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $path = rtrim($path, '/\\'); | 
				
			||||
 | 
				
			||||
        if (!isset($this->paths[$namespace])) { | 
				
			||||
            $this->paths[$namespace][] = $path; | 
				
			||||
        } else { | 
				
			||||
            array_unshift($this->paths[$namespace], $path); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getSource($name) | 
				
			||||
    { | 
				
			||||
        return file_get_contents($this->findTemplate($name)); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function getCacheKey($name) | 
				
			||||
    { | 
				
			||||
        return $this->findTemplate($name); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function exists($name) | 
				
			||||
    { | 
				
			||||
        $name = $this->normalizeName($name); | 
				
			||||
 | 
				
			||||
        if (isset($this->cache[$name])) { | 
				
			||||
            return true; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            $this->findTemplate($name); | 
				
			||||
 | 
				
			||||
            return true; | 
				
			||||
        } catch (Twig_Error_Loader $exception) { | 
				
			||||
            return false; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * {@inheritdoc} | 
				
			||||
     */ | 
				
			||||
    public function isFresh($name, $time) | 
				
			||||
    { | 
				
			||||
        return filemtime($this->findTemplate($name)) <= $time; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function findTemplate($name) | 
				
			||||
    { | 
				
			||||
        $name = $this->normalizeName($name); | 
				
			||||
 | 
				
			||||
        if (isset($this->cache[$name])) { | 
				
			||||
            return $this->cache[$name]; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $this->validateName($name); | 
				
			||||
 | 
				
			||||
        list($namespace, $shortname) = $this->parseName($name); | 
				
			||||
 | 
				
			||||
        if (!isset($this->paths[$namespace])) { | 
				
			||||
            throw new Twig_Error_Loader(sprintf('There are no registered paths for namespace "%s".', $namespace)); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        foreach ($this->paths[$namespace] as $path) { | 
				
			||||
            if (is_file($path.'/'.$shortname)) { | 
				
			||||
                return $this->cache[$name] = $path.'/'.$shortname; | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]))); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function parseName($name, $default = self::MAIN_NAMESPACE) | 
				
			||||
    { | 
				
			||||
        if (isset($name[0]) && '@' == $name[0]) { | 
				
			||||
            if (false === $pos = strpos($name, '/')) { | 
				
			||||
                throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name)); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            $namespace = substr($name, 1, $pos - 1); | 
				
			||||
            $shortname = substr($name, $pos + 1); | 
				
			||||
 | 
				
			||||
            return array($namespace, $shortname); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return array($default, $name); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function normalizeName($name) | 
				
			||||
    { | 
				
			||||
        return preg_replace('#/{2,}#', '/', strtr((string) $name, '\\', '/')); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function validateName($name) | 
				
			||||
    { | 
				
			||||
        if (false !== strpos($name, "\0")) { | 
				
			||||
            throw new Twig_Error_Loader('A template name cannot contain NUL bytes.'); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $name = ltrim($name, '/'); | 
				
			||||
        $parts = explode('/', $name); | 
				
			||||
        $level = 0; | 
				
			||||
        foreach ($parts as $part) { | 
				
			||||
            if ('..' === $part) { | 
				
			||||
                --$level; | 
				
			||||
            } elseif ('.' !== $part) { | 
				
			||||
                ++$level; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            if ($level < 0) { | 
				
			||||
                throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name)); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,38 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2012 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Represents an embed node. | 
				
			||||
 * | 
				
			||||
 * @author Fabien Potencier <fabien@symfony.com> | 
				
			||||
 */ | 
				
			||||
class Twig_Node_Embed extends Twig_Node_Include | 
				
			||||
{ | 
				
			||||
    // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module) | 
				
			||||
    public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) | 
				
			||||
    { | 
				
			||||
        parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag); | 
				
			||||
 | 
				
			||||
        $this->setAttribute('filename', $filename); | 
				
			||||
        $this->setAttribute('index', $index); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function addGetTemplate(Twig_Compiler $compiler) | 
				
			||||
    { | 
				
			||||
        $compiler | 
				
			||||
            ->write("\$this->env->loadTemplate(") | 
				
			||||
            ->string($this->getAttribute('filename')) | 
				
			||||
            ->raw(', ') | 
				
			||||
            ->string($this->getAttribute('index')) | 
				
			||||
            ->raw(")") | 
				
			||||
        ; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,30 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2013 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary | 
				
			||||
{ | 
				
			||||
    public function compile(Twig_Compiler $compiler) | 
				
			||||
    { | 
				
			||||
        $compiler | 
				
			||||
            ->raw('(0 === substr_compare(') | 
				
			||||
            ->subcompile($this->getNode('left')) | 
				
			||||
            ->raw(', ') | 
				
			||||
            ->subcompile($this->getNode('right')) | 
				
			||||
            ->raw(', -strlen(') | 
				
			||||
            ->subcompile($this->getNode('right')) | 
				
			||||
            ->raw(')))') | 
				
			||||
        ; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function operator(Twig_Compiler $compiler) | 
				
			||||
    { | 
				
			||||
        return $compiler->raw(''); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,28 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This file is part of Twig. | 
				
			||||
 * | 
				
			||||
 * (c) 2013 Fabien Potencier | 
				
			||||
 * | 
				
			||||
 * For the full copyright and license information, please view the LICENSE | 
				
			||||
 * file that was distributed with this source code. | 
				
			||||
 */ | 
				
			||||
class Twig_Node_Expression_Binary_Matches extends Twig_Node_Expression_Binary | 
				
			||||
{ | 
				
			||||
    public function compile(Twig_Compiler $compiler) | 
				
			||||
    { | 
				
			||||
        $compiler | 
				
			||||
            ->raw('preg_match(') | 
				
			||||
            ->subcompile($this->getNode('right')) | 
				
			||||
            ->raw(', ') | 
				
			||||
            ->subcompile($this->getNode('left')) | 
				
			||||
            ->raw(')') | 
				
			||||
        ; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public function operator(Twig_Compiler $compiler) | 
				
			||||
    { | 
				
			||||
        return $compiler->raw(''); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in new issue