├── .editorconfig ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── doc ├── errors.md ├── functions.md ├── guide.md ├── kirby-twig.png ├── options.md └── plugins.md ├── lib └── Twig │ ├── CHANGELOG │ ├── LICENSE │ ├── README.rst │ └── lib │ └── Twig │ ├── Autoloader.php │ ├── BaseNodeVisitor.php │ ├── Cache │ ├── Filesystem.php │ └── Null.php │ ├── CacheInterface.php │ ├── Compiler.php │ ├── CompilerInterface.php │ ├── ContainerRuntimeLoader.php │ ├── Environment.php │ ├── Error.php │ ├── Error │ ├── Loader.php │ ├── Runtime.php │ └── Syntax.php │ ├── ExistsLoaderInterface.php │ ├── ExpressionParser.php │ ├── Extension.php │ ├── Extension │ ├── Core.php │ ├── Debug.php │ ├── Escaper.php │ ├── GlobalsInterface.php │ ├── InitRuntimeInterface.php │ ├── Optimizer.php │ ├── Profiler.php │ ├── Sandbox.php │ ├── Staging.php │ └── StringLoader.php │ ├── ExtensionInterface.php │ ├── FactoryRuntimeLoader.php │ ├── FileExtensionEscapingStrategy.php │ ├── Filter.php │ ├── Filter │ ├── Function.php │ ├── Method.php │ └── Node.php │ ├── FilterCallableInterface.php │ ├── FilterInterface.php │ ├── Function.php │ ├── Function │ ├── Function.php │ ├── Method.php │ └── Node.php │ ├── FunctionCallableInterface.php │ ├── FunctionInterface.php │ ├── Lexer.php │ ├── LexerInterface.php │ ├── Loader │ ├── Array.php │ ├── Chain.php │ ├── Filesystem.php │ └── String.php │ ├── LoaderInterface.php │ ├── Markup.php │ ├── Node.php │ ├── Node │ ├── AutoEscape.php │ ├── Block.php │ ├── BlockReference.php │ ├── Body.php │ ├── CheckSecurity.php │ ├── Do.php │ ├── Embed.php │ ├── Expression.php │ ├── Expression │ │ ├── Array.php │ │ ├── AssignName.php │ │ ├── Binary.php │ │ ├── Binary │ │ │ ├── Add.php │ │ │ ├── And.php │ │ │ ├── BitwiseAnd.php │ │ │ ├── BitwiseOr.php │ │ │ ├── BitwiseXor.php │ │ │ ├── Concat.php │ │ │ ├── Div.php │ │ │ ├── EndsWith.php │ │ │ ├── Equal.php │ │ │ ├── FloorDiv.php │ │ │ ├── Greater.php │ │ │ ├── GreaterEqual.php │ │ │ ├── In.php │ │ │ ├── Less.php │ │ │ ├── LessEqual.php │ │ │ ├── Matches.php │ │ │ ├── Mod.php │ │ │ ├── Mul.php │ │ │ ├── NotEqual.php │ │ │ ├── NotIn.php │ │ │ ├── Or.php │ │ │ ├── Power.php │ │ │ ├── Range.php │ │ │ ├── StartsWith.php │ │ │ └── Sub.php │ │ ├── BlockReference.php │ │ ├── Call.php │ │ ├── Conditional.php │ │ ├── Constant.php │ │ ├── ExtensionReference.php │ │ ├── Filter.php │ │ ├── Filter │ │ │ └── Default.php │ │ ├── Function.php │ │ ├── GetAttr.php │ │ ├── MethodCall.php │ │ ├── Name.php │ │ ├── NullCoalesce.php │ │ ├── Parent.php │ │ ├── TempName.php │ │ ├── Test.php │ │ ├── Test │ │ │ ├── Constant.php │ │ │ ├── Defined.php │ │ │ ├── Divisibleby.php │ │ │ ├── Even.php │ │ │ ├── Null.php │ │ │ ├── Odd.php │ │ │ └── Sameas.php │ │ ├── Unary.php │ │ └── Unary │ │ │ ├── Neg.php │ │ │ ├── Not.php │ │ │ └── Pos.php │ ├── Flush.php │ ├── For.php │ ├── ForLoop.php │ ├── If.php │ ├── Import.php │ ├── Include.php │ ├── Macro.php │ ├── Module.php │ ├── Print.php │ ├── Sandbox.php │ ├── SandboxedPrint.php │ ├── Set.php │ ├── SetTemp.php │ ├── Spaceless.php │ ├── Text.php │ └── With.php │ ├── NodeCaptureInterface.php │ ├── NodeInterface.php │ ├── NodeOutputInterface.php │ ├── NodeTraverser.php │ ├── NodeVisitor │ ├── Escaper.php │ ├── Optimizer.php │ ├── SafeAnalysis.php │ └── Sandbox.php │ ├── NodeVisitorInterface.php │ ├── Parser.php │ ├── ParserInterface.php │ ├── Profiler │ ├── Dumper │ │ ├── Base.php │ │ ├── Blackfire.php │ │ ├── Html.php │ │ └── Text.php │ ├── Node │ │ ├── EnterProfile.php │ │ └── LeaveProfile.php │ ├── NodeVisitor │ │ └── Profiler.php │ └── Profile.php │ ├── RuntimeLoaderInterface.php │ ├── Sandbox │ ├── SecurityError.php │ ├── SecurityNotAllowedFilterError.php │ ├── SecurityNotAllowedFunctionError.php │ ├── SecurityNotAllowedMethodError.php │ ├── SecurityNotAllowedPropertyError.php │ ├── SecurityNotAllowedTagError.php │ ├── SecurityPolicy.php │ └── SecurityPolicyInterface.php │ ├── SimpleFilter.php │ ├── SimpleFunction.php │ ├── SimpleTest.php │ ├── Source.php │ ├── SourceContextLoaderInterface.php │ ├── Template.php │ ├── TemplateInterface.php │ ├── TemplateWrapper.php │ ├── Test.php │ ├── Test │ ├── Function.php │ ├── IntegrationTestCase.php │ ├── Method.php │ ├── Node.php │ └── NodeTestCase.php │ ├── TestCallableInterface.php │ ├── TestInterface.php │ ├── Token.php │ ├── TokenParser.php │ ├── TokenParser │ ├── AutoEscape.php │ ├── Block.php │ ├── Do.php │ ├── Embed.php │ ├── Extends.php │ ├── Filter.php │ ├── Flush.php │ ├── For.php │ ├── From.php │ ├── If.php │ ├── Import.php │ ├── Include.php │ ├── Macro.php │ ├── Sandbox.php │ ├── Set.php │ ├── Spaceless.php │ ├── Use.php │ └── With.php │ ├── TokenParserBroker.php │ ├── TokenParserBrokerInterface.php │ ├── TokenParserInterface.php │ ├── TokenStream.php │ └── Util │ ├── DeprecationCollector.php │ └── TemplateDirIterator.php ├── package.json ├── src ├── Plugin.php ├── TwigComponent.php ├── TwigEnv.php ├── errorpage.php └── helpers.php └── twig.php /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 4 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Kirby Twig Plugin: Change log 2 | ============================= 3 | 4 | ## v3.0.2 5 | 6 | - #29 Fix loading some templates on Windows 7 | 8 | ## v3.0.1 9 | 10 | - #25 Can't register namespaces, functions & filters in plugins 11 | - #26 Somehow allow adding safe functions 12 | 13 | ## v3.0.0 14 | 15 | **Breaking changes:** 16 | 17 | - Removed the `twig` boolean option. The plugin is now active if it’s installed (classical installation). For Composer installs, there is a separate registering step. 18 | - Removed the `twig.env.classes` option and `new()` Twig function. 19 | - Twig’s template cache is now disabled by default (enable with `c::set('twig.cache', true);`). 20 | - Error reporting: the `twig.error` config key is now ignored. Instead, the site’s main error page (whose URI is `error` by default) will be used in some specific situations. See `doc/errors.md` for details. 21 | - Namespace and class names (and sometimes methods) have changed (again); there is now a `Kirby\Twig\Plugin` class which will act as a stable API, while other implementation details may change. 22 | 23 | Deprecated (still working): 24 | 25 | - `twig.env.functions` in favor of `twig.function.myFunction`; 26 | - `twig.env.filters` in favor of `twig.filter.myFilter`; 27 | - `twig.env.namespace.xyz` in favor of `twig.namespace.xyz`. 28 | 29 | ## v2.x 30 | 31 | See on GitHub: 32 | 33 | - [v2.1.2](https://github.com/fvsch/kirby-twig/releases/tag/v2.1.2) 34 | - [v2.1.1](https://github.com/fvsch/kirby-twig/releases/tag/v2.1.1) 35 | - [v2.1.0](https://github.com/fvsch/kirby-twig/releases/tag/v2.1.0) 36 | - [v2.0.2](https://github.com/fvsch/kirby-twig/releases/tag/v2.0.2) 37 | - [v2.0.1](https://github.com/fvsch/kirby-twig/releases/tag/v2.0.1) 38 | - [v2.0.0](https://github.com/fvsch/kirby-twig/releases/tag/v2.0.0) 39 | 40 | ## v1.x 41 | 42 | - [v1.3.0](https://github.com/fvsch/kirby-twig/releases/tag/v1.3.0) 43 | - [v1.2.0](https://github.com/fvsch/kirby-twig/releases/tag/v1.2.0) 44 | - [v1.0.0](https://github.com/fvsch/kirby-twig/releases/tag/v1.0.0) 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /doc/kirby-twig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fvsch/kirby-twig/a5f78973720f18626d0e65e57be9199786b6f03f/doc/kirby-twig.png -------------------------------------------------------------------------------- /doc/options.md: -------------------------------------------------------------------------------- 1 | Options documentation 2 | ===================== 3 | 4 | 5 | Customizing the Twig environment 6 | -------------------------------- 7 | 8 | ```php 9 | // Define a directory as a Twig namespace, that can be used as: 10 | // {% include '@mynamespace/something.twig' %} 11 | c::set('twig.namespace.mynamespace', kirby()->roots()->index().'/mydirectory'); 12 | 13 | // Expose an existing function in templates 14 | c::set('twig.function.myfunction', 'myCustomFunction'); 15 | 16 | // Expose an existing function in templates as a filter 17 | c::set('twig.filter.myfilter', 'myCustomFilter'); 18 | ``` 19 | 20 | See [Using your own functions in templates](functions.md) for details about Twig functions and filters. 21 | 22 | Note: Kirby Twig 2.x used a `twig.env.functions` config, accepting an array of function names. This option is deprecated, but will still work in Kirby Twig 3.x. 23 | 24 | 25 | Advanced 26 | -------- 27 | 28 | ```php 29 | // Should we use .php templates as fallback when .twig 30 | // templates don't exist? Set to false to only allow Twig templates 31 | c::set('twig.usephp', true); 32 | 33 | // Use Twig’s PHP cache? 34 | // Disabled by default (starting from 2.2). 35 | // Enabling Twig's cache can give a speed boost to pages with changing 36 | // content (e.g. a search result page), because Twig will use a compiled 37 | // version of the template when building the response. 38 | // But if you have static text content in your Twig templates, you won’t 39 | // see content changes until you manually remove the `site/cache/twig` folder. 40 | c::set('twig.cache', false); 41 | 42 | // Disable autoescaping or specify autoescaping type 43 | // http://twig.sensiolabs.org/doc/api.html#environment-options 44 | c::set('twig.autoescape', true); 45 | 46 | // Should Twig throw errors when using undefined variables or methods? 47 | // Defaults to the value of the 'debug' option 48 | c::set('twig.strict', c::get('debug', false)); 49 | ``` 50 | -------------------------------------------------------------------------------- /doc/plugins.md: -------------------------------------------------------------------------------- 1 | Using Kirby Twig with other plugins 2 | =================================== 3 | 4 | 5 | Kirby Modules and Kirby Patterns 6 | -------------------------------- 7 | 8 | Using Twig templates with the Patterns or Modules plugins requires a few steps. 9 | 10 | First, you should declare Twig namespaces for the `patterns` and `modules` folders in your config: 11 | 12 | ```php 13 | c::set('twig.namespace.modules', dirname(__DIR__) . '/modules'); 14 | c::set('twig.namespace.patterns', dirname(__DIR__) . '/patterns'); 15 | ``` 16 | 17 | Now let’s say you’re using the Patterns plugin. You could have a file structure like this: 18 | 19 | ``` 20 | site/ 21 | patterns/ 22 | mypattern/ 23 | mypattern.html.php 24 | mypattern.html.twig 25 | ``` 26 | 27 | In the `mypattern.html.php` script, use the `twig()` helper function: 28 | 29 | ```php 30 | echo twig('@patterns/mypattern/mypattern.html.twig'); 31 | ``` 32 | 33 | The Twig template will have access to the `kirby`, `site` and `page` variables, and to any variable defined in the page’s controller. But if you defined other variables for your Module or Pattern, they won’t be automatically passed to the Twig template. Two solutions: 34 | 35 | ```php 36 | 18 | * 19 | * @deprecated since 1.21 and will be removed in 2.0. Use Composer instead. 2.0. 20 | */ 21 | class Twig_Autoloader 22 | { 23 | /** 24 | * Registers Twig_Autoloader as an SPL autoloader. 25 | * 26 | * @param bool $prepend whether to prepend the autoloader or not 27 | */ 28 | public static function register($prepend = false) 29 | { 30 | @trigger_error('Using Twig_Autoloader is deprecated since version 1.21. Use Composer instead.', E_USER_DEPRECATED); 31 | 32 | if (PHP_VERSION_ID < 50300) { 33 | spl_autoload_register(array(__CLASS__, 'autoload')); 34 | } else { 35 | spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend); 36 | } 37 | } 38 | 39 | /** 40 | * Handles autoloading of classes. 41 | * 42 | * @param string $class a class name 43 | */ 44 | public static function autoload($class) 45 | { 46 | if (0 !== strpos($class, 'Twig')) { 47 | return; 48 | } 49 | 50 | if (is_file($file = dirname(__FILE__).'/../'.str_replace(array('_', "\0"), array('/', ''), $class).'.php')) { 51 | require $file; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/BaseNodeVisitor.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface 18 | { 19 | final public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) 20 | { 21 | if (!$node instanceof Twig_Node) { 22 | throw new LogicException('Twig_BaseNodeVisitor only supports Twig_Node instances.'); 23 | } 24 | 25 | return $this->doEnterNode($node, $env); 26 | } 27 | 28 | final public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) 29 | { 30 | if (!$node instanceof Twig_Node) { 31 | throw new LogicException('Twig_BaseNodeVisitor only supports Twig_Node instances.'); 32 | } 33 | 34 | return $this->doLeaveNode($node, $env); 35 | } 36 | 37 | /** 38 | * Called before child nodes are visited. 39 | * 40 | * @return Twig_Node The modified node 41 | */ 42 | abstract protected function doEnterNode(Twig_Node $node, Twig_Environment $env); 43 | 44 | /** 45 | * Called after child nodes are visited. 46 | * 47 | * @return Twig_Node|false The modified node or false if the node must be removed 48 | */ 49 | abstract protected function doLeaveNode(Twig_Node $node, Twig_Environment $env); 50 | } 51 | 52 | class_alias('Twig_BaseNodeVisitor', 'Twig\NodeVisitor\AbstractNodeVisitor', false); 53 | class_exists('Twig_Environment'); 54 | class_exists('Twig_Node'); 55 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Cache/Null.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class Twig_Cache_Null implements Twig_CacheInterface 20 | { 21 | public function generateKey($name, $className) 22 | { 23 | return ''; 24 | } 25 | 26 | public function write($key, $content) 27 | { 28 | } 29 | 30 | public function load($key) 31 | { 32 | } 33 | 34 | public function getTimestamp($key) 35 | { 36 | return 0; 37 | } 38 | } 39 | 40 | class_alias('Twig_Cache_Null', 'Twig\Cache\NullCache', false); 41 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/CacheInterface.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | interface Twig_CacheInterface 22 | { 23 | /** 24 | * Generates a cache key for the given template class name. 25 | * 26 | * @param string $name The template name 27 | * @param string $className The template class name 28 | * 29 | * @return string 30 | */ 31 | public function generateKey($name, $className); 32 | 33 | /** 34 | * Writes the compiled template to cache. 35 | * 36 | * @param string $key The cache key 37 | * @param string $content The template representation as a PHP class 38 | */ 39 | public function write($key, $content); 40 | 41 | /** 42 | * Loads a template from the cache. 43 | * 44 | * @param string $key The cache key 45 | */ 46 | public function load($key); 47 | 48 | /** 49 | * Returns the modification timestamp of a key. 50 | * 51 | * @param string $key The cache key 52 | * 53 | * @return int 54 | */ 55 | public function getTimestamp($key); 56 | } 57 | 58 | class_alias('Twig_CacheInterface', 'Twig\Cache\CacheInterface', false); 59 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/CompilerInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * 17 | * @deprecated since 1.12 (to be removed in 3.0) 18 | */ 19 | interface Twig_CompilerInterface 20 | { 21 | /** 22 | * Compiles a node. 23 | * 24 | * @return $this 25 | */ 26 | public function compile(Twig_NodeInterface $node); 27 | 28 | /** 29 | * Gets the current PHP code after compilation. 30 | * 31 | * @return string The PHP code 32 | */ 33 | public function getSource(); 34 | } 35 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/ContainerRuntimeLoader.php: -------------------------------------------------------------------------------- 1 | 20 | * @author Robin Chalas 21 | */ 22 | class Twig_ContainerRuntimeLoader implements Twig_RuntimeLoaderInterface 23 | { 24 | private $container; 25 | 26 | public function __construct(ContainerInterface $container) 27 | { 28 | $this->container = $container; 29 | } 30 | 31 | public function load($class) 32 | { 33 | if ($this->container->has($class)) { 34 | return $this->container->get($class); 35 | } 36 | } 37 | } 38 | 39 | class_alias('Twig_ContainerRuntimeLoader', 'Twig\RuntimeLoader\ContainerRuntimeLoader', false); 40 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Error/Loader.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Twig_Error_Loader extends Twig_Error 26 | { 27 | public function __construct($message, $lineno = -1, $source = null, Exception $previous = null) 28 | { 29 | if (PHP_VERSION_ID < 50300) { 30 | $this->previous = $previous; 31 | Exception::__construct(''); 32 | } else { 33 | Exception::__construct('', 0, $previous); 34 | } 35 | $this->appendMessage($message); 36 | $this->setTemplateLine(false); 37 | } 38 | } 39 | 40 | class_alias('Twig_Error_Loader', 'Twig\Error\LoaderError', false); 41 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Error/Runtime.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class Twig_Error_Runtime extends Twig_Error 19 | { 20 | } 21 | 22 | class_alias('Twig_Error_Runtime', 'Twig\Error\RuntimeError', false); 23 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Error/Syntax.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class Twig_Error_Syntax extends Twig_Error 19 | { 20 | /** 21 | * Tweaks the error message to include suggestions. 22 | * 23 | * @param string $name The original name of the item that does not exist 24 | * @param array $items An array of possible items 25 | */ 26 | public function addSuggestions($name, array $items) 27 | { 28 | if (!$alternatives = self::computeAlternatives($name, $items)) { 29 | return; 30 | } 31 | 32 | $this->appendMessage(sprintf(' Did you mean "%s"?', implode('", "', $alternatives))); 33 | } 34 | 35 | /** 36 | * @internal 37 | * 38 | * To be merged with the addSuggestions() method in 2.0. 39 | */ 40 | public static function computeAlternatives($name, $items) 41 | { 42 | $alternatives = array(); 43 | foreach ($items as $item) { 44 | $lev = levenshtein($name, $item); 45 | if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { 46 | $alternatives[$item] = $lev; 47 | } 48 | } 49 | asort($alternatives); 50 | 51 | return array_keys($alternatives); 52 | } 53 | } 54 | 55 | class_alias('Twig_Error_Syntax', 'Twig\Error\SyntaxError', false); 56 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/ExistsLoaderInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * 17 | * @deprecated since 1.12 (to be removed in 3.0) 18 | */ 19 | interface Twig_ExistsLoaderInterface 20 | { 21 | /** 22 | * Check if we have the source code of a template, given its name. 23 | * 24 | * @param string $name The name of the template to check if we can load 25 | * 26 | * @return bool If the template source code is handled by this loader or not 27 | */ 28 | public function exists($name); 29 | } 30 | 31 | class_alias('Twig_ExistsLoaderInterface', 'Twig\Loader\ExistsLoaderInterface', false); 32 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Extension.php: -------------------------------------------------------------------------------- 1 | $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true, 'needs_environment' => true)), 31 | ); 32 | } 33 | 34 | public function getName() 35 | { 36 | return 'debug'; 37 | } 38 | } 39 | 40 | function twig_var_dump(Twig_Environment $env, $context) 41 | { 42 | if (!$env->isDebug()) { 43 | return; 44 | } 45 | 46 | ob_start(); 47 | 48 | $count = func_num_args(); 49 | if (2 === $count) { 50 | $vars = array(); 51 | foreach ($context as $key => $value) { 52 | if (!$value instanceof Twig_Template) { 53 | $vars[$key] = $value; 54 | } 55 | } 56 | 57 | var_dump($vars); 58 | } else { 59 | for ($i = 2; $i < $count; ++$i) { 60 | var_dump(func_get_arg($i)); 61 | } 62 | } 63 | 64 | return ob_get_clean(); 65 | } 66 | 67 | class_alias('Twig_Extension_Debug', 'Twig\Extension\DebugExtension', false); 68 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Extension/GlobalsInterface.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | interface Twig_Extension_GlobalsInterface 21 | { 22 | } 23 | 24 | class_alias('Twig_Extension_GlobalsInterface', 'Twig\Extension\GlobalsInterface', false); 25 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Extension/InitRuntimeInterface.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | interface Twig_Extension_InitRuntimeInterface 21 | { 22 | } 23 | 24 | class_alias('Twig_Extension_InitRuntimeInterface', 'Twig\Extension\InitRuntimeInterface', false); 25 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Extension/Optimizer.php: -------------------------------------------------------------------------------- 1 | optimizers = $optimizers; 22 | } 23 | 24 | public function getNodeVisitors() 25 | { 26 | return array(new Twig_NodeVisitor_Optimizer($this->optimizers)); 27 | } 28 | 29 | public function getName() 30 | { 31 | return 'optimizer'; 32 | } 33 | } 34 | 35 | class_alias('Twig_Extension_Optimizer', 'Twig\Extension\OptimizerExtension', false); 36 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Extension/Profiler.php: -------------------------------------------------------------------------------- 1 | actives[] = $profile; 19 | } 20 | 21 | public function enter(Twig_Profiler_Profile $profile) 22 | { 23 | $this->actives[0]->addProfile($profile); 24 | array_unshift($this->actives, $profile); 25 | } 26 | 27 | public function leave(Twig_Profiler_Profile $profile) 28 | { 29 | $profile->leave(); 30 | array_shift($this->actives); 31 | 32 | if (1 === count($this->actives)) { 33 | $this->actives[0]->leave(); 34 | } 35 | } 36 | 37 | public function getNodeVisitors() 38 | { 39 | return array(new Twig_Profiler_NodeVisitor_Profiler(get_class($this))); 40 | } 41 | 42 | public function getName() 43 | { 44 | return 'profiler'; 45 | } 46 | } 47 | 48 | class_alias('Twig_Extension_Profiler', 'Twig\Extension\ProfilerExtension', false); 49 | class_exists('Twig_Profiler_Profile'); 50 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Extension/StringLoader.php: -------------------------------------------------------------------------------- 1 | true)), 21 | ); 22 | } 23 | 24 | public function getName() 25 | { 26 | return 'string_loader'; 27 | } 28 | } 29 | 30 | /** 31 | * Loads a template from a string. 32 | * 33 | *
34 |  * {{ include(template_from_string("Hello {{ name }}")) }}
35 |  * 
36 | * 37 | * @param Twig_Environment $env A Twig_Environment instance 38 | * @param string $template A template as a string or object implementing __toString() 39 | * 40 | * @return Twig_Template 41 | */ 42 | function twig_template_from_string(Twig_Environment $env, $template) 43 | { 44 | return $env->createTemplate((string) $template); 45 | } 46 | 47 | class_alias('Twig_Extension_StringLoader', 'Twig\Extension\StringLoaderExtension', false); 48 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/FactoryRuntimeLoader.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_FactoryRuntimeLoader implements Twig_RuntimeLoaderInterface 18 | { 19 | private $map; 20 | 21 | /** 22 | * @param array $map An array where keys are class names and values factory callables 23 | */ 24 | public function __construct($map = array()) 25 | { 26 | $this->map = $map; 27 | } 28 | 29 | public function load($class) 30 | { 31 | if (isset($this->map[$class])) { 32 | $runtimeFactory = $this->map[$class]; 33 | 34 | return $runtimeFactory(); 35 | } 36 | } 37 | } 38 | 39 | class_alias('Twig_FactoryRuntimeLoader', 'Twig\RuntimeLoader\FactoryRuntimeLoader', false); 40 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/FileExtensionEscapingStrategy.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class Twig_FileExtensionEscapingStrategy 24 | { 25 | /** 26 | * Guesses the best autoescaping strategy based on the file name. 27 | * 28 | * @param string $name The template name 29 | * 30 | * @return string|false The escaping strategy name to use or false to disable 31 | */ 32 | public static function guess($name) 33 | { 34 | if (in_array(substr($name, -1), array('/', '\\'))) { 35 | return 'html'; // return html for directories 36 | } 37 | 38 | if ('.twig' === substr($name, -5)) { 39 | $name = substr($name, 0, -5); 40 | } 41 | 42 | $extension = pathinfo($name, PATHINFO_EXTENSION); 43 | 44 | switch ($extension) { 45 | case 'js': 46 | return 'js'; 47 | 48 | case 'css': 49 | return 'css'; 50 | 51 | case 'txt': 52 | return false; 53 | 54 | default: 55 | return 'html'; 56 | } 57 | } 58 | } 59 | 60 | class_alias('Twig_FileExtensionEscapingStrategy', 'Twig\FileExtensionEscapingStrategy', false); 61 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Filter.php: -------------------------------------------------------------------------------- 1 | 20 | * 21 | * @deprecated since 1.12 (to be removed in 2.0) 22 | */ 23 | abstract class Twig_Filter implements Twig_FilterInterface, Twig_FilterCallableInterface 24 | { 25 | protected $options; 26 | protected $arguments = array(); 27 | 28 | public function __construct(array $options = array()) 29 | { 30 | $this->options = array_merge(array( 31 | 'needs_environment' => false, 32 | 'needs_context' => false, 33 | 'pre_escape' => null, 34 | 'preserves_safety' => null, 35 | 'callable' => null, 36 | ), $options); 37 | } 38 | 39 | public function setArguments($arguments) 40 | { 41 | $this->arguments = $arguments; 42 | } 43 | 44 | public function getArguments() 45 | { 46 | return $this->arguments; 47 | } 48 | 49 | public function needsEnvironment() 50 | { 51 | return $this->options['needs_environment']; 52 | } 53 | 54 | public function needsContext() 55 | { 56 | return $this->options['needs_context']; 57 | } 58 | 59 | public function getSafe(Twig_Node $filterArgs) 60 | { 61 | if (isset($this->options['is_safe'])) { 62 | return $this->options['is_safe']; 63 | } 64 | 65 | if (isset($this->options['is_safe_callback'])) { 66 | return call_user_func($this->options['is_safe_callback'], $filterArgs); 67 | } 68 | } 69 | 70 | public function getPreservesSafety() 71 | { 72 | return $this->options['preserves_safety']; 73 | } 74 | 75 | public function getPreEscape() 76 | { 77 | return $this->options['pre_escape']; 78 | } 79 | 80 | public function getCallable() 81 | { 82 | return $this->options['callable']; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Filter/Function.php: -------------------------------------------------------------------------------- 1 | 20 | * 21 | * @deprecated since 1.12 (to be removed in 2.0) 22 | */ 23 | class Twig_Filter_Function extends Twig_Filter 24 | { 25 | protected $function; 26 | 27 | public function __construct($function, array $options = array()) 28 | { 29 | $options['callable'] = $function; 30 | 31 | parent::__construct($options); 32 | 33 | $this->function = $function; 34 | } 35 | 36 | public function compile() 37 | { 38 | return $this->function; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Filter/Method.php: -------------------------------------------------------------------------------- 1 | 20 | * 21 | * @deprecated since 1.12 (to be removed in 2.0) 22 | */ 23 | class Twig_Filter_Method extends Twig_Filter 24 | { 25 | protected $extension; 26 | protected $method; 27 | 28 | public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) 29 | { 30 | $options['callable'] = array($extension, $method); 31 | 32 | parent::__construct($options); 33 | 34 | $this->extension = $extension; 35 | $this->method = $method; 36 | } 37 | 38 | public function compile() 39 | { 40 | return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Filter/Node.php: -------------------------------------------------------------------------------- 1 | 20 | * 21 | * @deprecated since 1.12 (to be removed in 2.0) 22 | */ 23 | class Twig_Filter_Node extends Twig_Filter 24 | { 25 | protected $class; 26 | 27 | public function __construct($class, array $options = array()) 28 | { 29 | parent::__construct($options); 30 | 31 | $this->class = $class; 32 | } 33 | 34 | public function getClass() 35 | { 36 | return $this->class; 37 | } 38 | 39 | public function compile() 40 | { 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/FilterCallableInterface.php: -------------------------------------------------------------------------------- 1 | 18 | * 19 | * @deprecated since 1.12 (to be removed in 2.0) 20 | */ 21 | interface Twig_FilterCallableInterface 22 | { 23 | public function getCallable(); 24 | } 25 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/FilterInterface.php: -------------------------------------------------------------------------------- 1 | 18 | * 19 | * @deprecated since 1.12 (to be removed in 2.0) 20 | */ 21 | interface Twig_FilterInterface 22 | { 23 | /** 24 | * Compiles a filter. 25 | * 26 | * @return string The PHP code for the filter 27 | */ 28 | public function compile(); 29 | 30 | public function needsEnvironment(); 31 | 32 | public function needsContext(); 33 | 34 | public function getSafe(Twig_Node $filterArgs); 35 | 36 | public function getPreservesSafety(); 37 | 38 | public function getPreEscape(); 39 | 40 | public function setArguments($arguments); 41 | 42 | public function getArguments(); 43 | } 44 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Function.php: -------------------------------------------------------------------------------- 1 | 20 | * 21 | * @deprecated since 1.12 (to be removed in 2.0) 22 | */ 23 | abstract class Twig_Function implements Twig_FunctionInterface, Twig_FunctionCallableInterface 24 | { 25 | protected $options; 26 | protected $arguments = array(); 27 | 28 | public function __construct(array $options = array()) 29 | { 30 | $this->options = array_merge(array( 31 | 'needs_environment' => false, 32 | 'needs_context' => false, 33 | 'callable' => null, 34 | ), $options); 35 | } 36 | 37 | public function setArguments($arguments) 38 | { 39 | $this->arguments = $arguments; 40 | } 41 | 42 | public function getArguments() 43 | { 44 | return $this->arguments; 45 | } 46 | 47 | public function needsEnvironment() 48 | { 49 | return $this->options['needs_environment']; 50 | } 51 | 52 | public function needsContext() 53 | { 54 | return $this->options['needs_context']; 55 | } 56 | 57 | public function getSafe(Twig_Node $functionArgs) 58 | { 59 | if (isset($this->options['is_safe'])) { 60 | return $this->options['is_safe']; 61 | } 62 | 63 | if (isset($this->options['is_safe_callback'])) { 64 | return call_user_func($this->options['is_safe_callback'], $functionArgs); 65 | } 66 | 67 | return array(); 68 | } 69 | 70 | public function getCallable() 71 | { 72 | return $this->options['callable']; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Function/Function.php: -------------------------------------------------------------------------------- 1 | 21 | * 22 | * @deprecated since 1.12 (to be removed in 2.0) 23 | */ 24 | class Twig_Function_Function extends Twig_Function 25 | { 26 | protected $function; 27 | 28 | public function __construct($function, array $options = array()) 29 | { 30 | $options['callable'] = $function; 31 | 32 | parent::__construct($options); 33 | 34 | $this->function = $function; 35 | } 36 | 37 | public function compile() 38 | { 39 | return $this->function; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Function/Method.php: -------------------------------------------------------------------------------- 1 | 21 | * 22 | * @deprecated since 1.12 (to be removed in 2.0) 23 | */ 24 | class Twig_Function_Method extends Twig_Function 25 | { 26 | protected $extension; 27 | protected $method; 28 | 29 | public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) 30 | { 31 | $options['callable'] = array($extension, $method); 32 | 33 | parent::__construct($options); 34 | 35 | $this->extension = $extension; 36 | $this->method = $method; 37 | } 38 | 39 | public function compile() 40 | { 41 | return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Function/Node.php: -------------------------------------------------------------------------------- 1 | 20 | * 21 | * @deprecated since 1.12 (to be removed in 2.0) 22 | */ 23 | class Twig_Function_Node extends Twig_Function 24 | { 25 | protected $class; 26 | 27 | public function __construct($class, array $options = array()) 28 | { 29 | parent::__construct($options); 30 | 31 | $this->class = $class; 32 | } 33 | 34 | public function getClass() 35 | { 36 | return $this->class; 37 | } 38 | 39 | public function compile() 40 | { 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/FunctionCallableInterface.php: -------------------------------------------------------------------------------- 1 | 18 | * 19 | * @deprecated since 1.12 (to be removed in 2.0) 20 | */ 21 | interface Twig_FunctionCallableInterface 22 | { 23 | public function getCallable(); 24 | } 25 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/FunctionInterface.php: -------------------------------------------------------------------------------- 1 | 19 | * 20 | * @deprecated since 1.12 (to be removed in 2.0) 21 | */ 22 | interface Twig_FunctionInterface 23 | { 24 | /** 25 | * Compiles a function. 26 | * 27 | * @return string The PHP code for the function 28 | */ 29 | public function compile(); 30 | 31 | public function needsEnvironment(); 32 | 33 | public function needsContext(); 34 | 35 | public function getSafe(Twig_Node $filterArgs); 36 | 37 | public function setArguments($arguments); 38 | 39 | public function getArguments(); 40 | } 41 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/LexerInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * 17 | * @deprecated since 1.12 (to be removed in 3.0) 18 | */ 19 | interface Twig_LexerInterface 20 | { 21 | /** 22 | * Tokenizes a source code. 23 | * 24 | * @param string|Twig_Source $code The source code 25 | * @param string $name A unique identifier for the source code 26 | * 27 | * @return Twig_TokenStream 28 | * 29 | * @throws Twig_Error_Syntax When the code is syntactically wrong 30 | */ 31 | public function tokenize($code, $name = null); 32 | } 33 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Loader/String.php: -------------------------------------------------------------------------------- 1 | 29 | */ 30 | class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface 31 | { 32 | public function getSource($name) 33 | { 34 | @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED); 35 | 36 | return $name; 37 | } 38 | 39 | public function getSourceContext($name) 40 | { 41 | return new Twig_Source($name, $name); 42 | } 43 | 44 | public function exists($name) 45 | { 46 | return true; 47 | } 48 | 49 | public function getCacheKey($name) 50 | { 51 | return $name; 52 | } 53 | 54 | public function isFresh($name, $time) 55 | { 56 | return true; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/LoaderInterface.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | interface Twig_LoaderInterface 18 | { 19 | /** 20 | * Gets the source code of a template, given its name. 21 | * 22 | * @param string $name The name of the template to load 23 | * 24 | * @return string The template source code 25 | * 26 | * @throws Twig_Error_Loader When $name is not found 27 | * 28 | * @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface 29 | */ 30 | public function getSource($name); 31 | 32 | /** 33 | * Gets the cache key to use for the cache for a given template name. 34 | * 35 | * @param string $name The name of the template to load 36 | * 37 | * @return string The cache key 38 | * 39 | * @throws Twig_Error_Loader When $name is not found 40 | */ 41 | public function getCacheKey($name); 42 | 43 | /** 44 | * Returns true if the template is still fresh. 45 | * 46 | * @param string $name The template name 47 | * @param int $time Timestamp of the last modification time of the 48 | * cached template 49 | * 50 | * @return bool true if the template is fresh, false otherwise 51 | * 52 | * @throws Twig_Error_Loader When $name is not found 53 | */ 54 | public function isFresh($name, $time); 55 | } 56 | 57 | class_alias('Twig_LoaderInterface', 'Twig\Loader\LoaderInterface', false); 58 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Markup.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Markup implements Countable 18 | { 19 | protected $content; 20 | protected $charset; 21 | 22 | public function __construct($content, $charset) 23 | { 24 | $this->content = (string) $content; 25 | $this->charset = $charset; 26 | } 27 | 28 | public function __toString() 29 | { 30 | return $this->content; 31 | } 32 | 33 | public function count() 34 | { 35 | return function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : strlen($this->content); 36 | } 37 | } 38 | 39 | class_alias('Twig_Markup', 'Twig\Markup', false); 40 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/AutoEscape.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class Twig_Node_AutoEscape extends Twig_Node 24 | { 25 | public function __construct($value, Twig_NodeInterface $body, $lineno, $tag = 'autoescape') 26 | { 27 | parent::__construct(array('body' => $body), array('value' => $value), $lineno, $tag); 28 | } 29 | 30 | public function compile(Twig_Compiler $compiler) 31 | { 32 | $compiler->subcompile($this->getNode('body')); 33 | } 34 | } 35 | 36 | class_alias('Twig_Node_AutoEscape', 'Twig\Node\AutoEscapeNode', false); 37 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Block.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class Twig_Node_Block extends Twig_Node 19 | { 20 | public function __construct($name, Twig_NodeInterface $body, $lineno, $tag = null) 21 | { 22 | parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag); 23 | } 24 | 25 | public function compile(Twig_Compiler $compiler) 26 | { 27 | $compiler 28 | ->addDebugInfo($this) 29 | ->write(sprintf("public function block_%s(\$context, array \$blocks = array())\n", $this->getAttribute('name')), "{\n") 30 | ->indent() 31 | ; 32 | 33 | $compiler 34 | ->subcompile($this->getNode('body')) 35 | ->outdent() 36 | ->write("}\n\n") 37 | ; 38 | } 39 | } 40 | 41 | class_alias('Twig_Node_Block', 'Twig\Node\BlockNode', false); 42 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/BlockReference.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInterface 19 | { 20 | public function __construct($name, $lineno, $tag = null) 21 | { 22 | parent::__construct(array(), array('name' => $name), $lineno, $tag); 23 | } 24 | 25 | public function compile(Twig_Compiler $compiler) 26 | { 27 | $compiler 28 | ->addDebugInfo($this) 29 | ->write(sprintf("\$this->displayBlock('%s', \$context, \$blocks);\n", $this->getAttribute('name'))) 30 | ; 31 | } 32 | } 33 | 34 | class_alias('Twig_Node_BlockReference', 'Twig\Node\BlockReferenceNode', false); 35 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Body.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Node_Body extends Twig_Node 18 | { 19 | } 20 | 21 | class_alias('Twig_Node_Body', 'Twig\Node\BodyNode', false); 22 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Do.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Node_Do extends Twig_Node 18 | { 19 | public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null) 20 | { 21 | parent::__construct(array('expr' => $expr), array(), $lineno, $tag); 22 | } 23 | 24 | public function compile(Twig_Compiler $compiler) 25 | { 26 | $compiler 27 | ->addDebugInfo($this) 28 | ->write('') 29 | ->subcompile($this->getNode('expr')) 30 | ->raw(";\n") 31 | ; 32 | } 33 | } 34 | 35 | class_alias('Twig_Node_Do', 'Twig\Node\DoNode', false); 36 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Embed.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Node_Embed extends Twig_Node_Include 18 | { 19 | // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module) 20 | public function __construct($name, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) 21 | { 22 | parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag); 23 | 24 | $this->setAttribute('name', $name); 25 | // to be removed in 2.0, used name instead 26 | $this->setAttribute('filename', $name); 27 | $this->setAttribute('index', $index); 28 | } 29 | 30 | protected function addGetTemplate(Twig_Compiler $compiler) 31 | { 32 | $compiler 33 | ->write('$this->loadTemplate(') 34 | ->string($this->getAttribute('name')) 35 | ->raw(', ') 36 | ->repr($this->getTemplateName()) 37 | ->raw(', ') 38 | ->repr($this->getTemplateLine()) 39 | ->raw(', ') 40 | ->string($this->getAttribute('index')) 41 | ->raw(')') 42 | ; 43 | } 44 | } 45 | 46 | class_alias('Twig_Node_Embed', 'Twig\Node\EmbedNode', false); 47 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | abstract class Twig_Node_Expression extends Twig_Node 19 | { 20 | } 21 | 22 | class_alias('Twig_Node_Expression', 'Twig\Node\Expression\AbstractExpression', false); 23 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Array.php: -------------------------------------------------------------------------------- 1 | index = -1; 20 | foreach ($this->getKeyValuePairs() as $pair) { 21 | if ($pair['key'] instanceof Twig_Node_Expression_Constant && ctype_digit((string) $pair['key']->getAttribute('value')) && $pair['key']->getAttribute('value') > $this->index) { 22 | $this->index = $pair['key']->getAttribute('value'); 23 | } 24 | } 25 | } 26 | 27 | public function getKeyValuePairs() 28 | { 29 | $pairs = array(); 30 | 31 | foreach (array_chunk($this->nodes, 2) as $pair) { 32 | $pairs[] = array( 33 | 'key' => $pair[0], 34 | 'value' => $pair[1], 35 | ); 36 | } 37 | 38 | return $pairs; 39 | } 40 | 41 | public function hasElement(Twig_Node_Expression $key) 42 | { 43 | foreach ($this->getKeyValuePairs() as $pair) { 44 | // we compare the string representation of the keys 45 | // to avoid comparing the line numbers which are not relevant here. 46 | if ((string) $key === (string) $pair['key']) { 47 | return true; 48 | } 49 | } 50 | 51 | return false; 52 | } 53 | 54 | public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null) 55 | { 56 | if (null === $key) { 57 | $key = new Twig_Node_Expression_Constant(++$this->index, $value->getTemplateLine()); 58 | } 59 | 60 | array_push($this->nodes, $key, $value); 61 | } 62 | 63 | public function compile(Twig_Compiler $compiler) 64 | { 65 | $compiler->raw('array('); 66 | $first = true; 67 | foreach ($this->getKeyValuePairs() as $pair) { 68 | if (!$first) { 69 | $compiler->raw(', '); 70 | } 71 | $first = false; 72 | 73 | $compiler 74 | ->subcompile($pair['key']) 75 | ->raw(' => ') 76 | ->subcompile($pair['value']) 77 | ; 78 | } 79 | $compiler->raw(')'); 80 | } 81 | } 82 | 83 | class_alias('Twig_Node_Expression_Array', 'Twig\Node\Expression\ArrayExpression', false); 84 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/AssignName.php: -------------------------------------------------------------------------------- 1 | raw('$context[') 19 | ->string($this->getAttribute('name')) 20 | ->raw(']') 21 | ; 22 | } 23 | } 24 | 25 | class_alias('Twig_Node_Expression_AssignName', 'Twig\Node\Expression\AssignNameExpression', false); 26 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary.php: -------------------------------------------------------------------------------- 1 | $left, 'right' => $right), array(), $lineno); 17 | } 18 | 19 | public function compile(Twig_Compiler $compiler) 20 | { 21 | $compiler 22 | ->raw('(') 23 | ->subcompile($this->getNode('left')) 24 | ->raw(' ') 25 | ; 26 | $this->operator($compiler); 27 | $compiler 28 | ->raw(' ') 29 | ->subcompile($this->getNode('right')) 30 | ->raw(')') 31 | ; 32 | } 33 | 34 | abstract public function operator(Twig_Compiler $compiler); 35 | } 36 | 37 | class_alias('Twig_Node_Expression_Binary', 'Twig\Node\Expression\Binary\AbstractBinary', false); 38 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Add.php: -------------------------------------------------------------------------------- 1 | raw('+'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Binary_Add', 'Twig\Node\Expression\Binary\AddBinary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/And.php: -------------------------------------------------------------------------------- 1 | raw('&&'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Binary_And', 'Twig\Node\Expression\Binary\AndBinary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php: -------------------------------------------------------------------------------- 1 | raw('&'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Binary_BitwiseAnd', 'Twig\Node\Expression\Binary\BitwiseAndBinary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php: -------------------------------------------------------------------------------- 1 | raw('|'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Binary_BitwiseOr', 'Twig\Node\Expression\Binary\BitwiseOrBinary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php: -------------------------------------------------------------------------------- 1 | raw('^'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Binary_BitwiseXor', 'Twig\Node\Expression\Binary\BitwiseXorBinary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Concat.php: -------------------------------------------------------------------------------- 1 | raw('.'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Binary_Concat', 'Twig\Node\Expression\Binary\ConcatBinary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Div.php: -------------------------------------------------------------------------------- 1 | raw('/'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Binary_Div', 'Twig\Node\Expression\Binary\DivBinary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/EndsWith.php: -------------------------------------------------------------------------------- 1 | getVarName(); 16 | $right = $compiler->getVarName(); 17 | $compiler 18 | ->raw(sprintf('(is_string($%s = ', $left)) 19 | ->subcompile($this->getNode('left')) 20 | ->raw(sprintf(') && is_string($%s = ', $right)) 21 | ->subcompile($this->getNode('right')) 22 | ->raw(sprintf(') && (\'\' === $%2$s || $%2$s === substr($%1$s, -strlen($%2$s))))', $left, $right)) 23 | ; 24 | } 25 | 26 | public function operator(Twig_Compiler $compiler) 27 | { 28 | return $compiler->raw(''); 29 | } 30 | } 31 | 32 | class_alias('Twig_Node_Expression_Binary_EndsWith', 'Twig\Node\Expression\Binary\EndsWithBinary', false); 33 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Equal.php: -------------------------------------------------------------------------------- 1 | raw('=='); 16 | } 17 | } 18 | 19 | class_alias('Twig_Node_Expression_Binary_Equal', 'Twig\Node\Expression\Binary\EqualBinary', false); 20 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/FloorDiv.php: -------------------------------------------------------------------------------- 1 | raw('(int) floor('); 16 | parent::compile($compiler); 17 | $compiler->raw(')'); 18 | } 19 | 20 | public function operator(Twig_Compiler $compiler) 21 | { 22 | return $compiler->raw('/'); 23 | } 24 | } 25 | 26 | class_alias('Twig_Node_Expression_Binary_FloorDiv', 'Twig\Node\Expression\Binary\FloorDivBinary', false); 27 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Greater.php: -------------------------------------------------------------------------------- 1 | raw('>'); 16 | } 17 | } 18 | 19 | class_alias('Twig_Node_Expression_Binary_Greater', 'Twig\Node\Expression\Binary\GreaterBinary', false); 20 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php: -------------------------------------------------------------------------------- 1 | raw('>='); 16 | } 17 | } 18 | 19 | class_alias('Twig_Node_Expression_Binary_GreaterEqual', 'Twig\Node\Expression\Binary\GreaterEqualBinary', false); 20 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/In.php: -------------------------------------------------------------------------------- 1 | raw('twig_in_filter(') 17 | ->subcompile($this->getNode('left')) 18 | ->raw(', ') 19 | ->subcompile($this->getNode('right')) 20 | ->raw(')') 21 | ; 22 | } 23 | 24 | public function operator(Twig_Compiler $compiler) 25 | { 26 | return $compiler->raw('in'); 27 | } 28 | } 29 | 30 | class_alias('Twig_Node_Expression_Binary_In', 'Twig\Node\Expression\Binary\InBinary', false); 31 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Less.php: -------------------------------------------------------------------------------- 1 | raw('<'); 16 | } 17 | } 18 | 19 | class_alias('Twig_Node_Expression_Binary_Less', 'Twig\Node\Expression\Binary\LessBinary', false); 20 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/LessEqual.php: -------------------------------------------------------------------------------- 1 | raw('<='); 16 | } 17 | } 18 | 19 | class_alias('Twig_Node_Expression_Binary_LessEqual', 'Twig\Node\Expression\Binary\LessEqualBinary', false); 20 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Matches.php: -------------------------------------------------------------------------------- 1 | raw('preg_match(') 17 | ->subcompile($this->getNode('right')) 18 | ->raw(', ') 19 | ->subcompile($this->getNode('left')) 20 | ->raw(')') 21 | ; 22 | } 23 | 24 | public function operator(Twig_Compiler $compiler) 25 | { 26 | return $compiler->raw(''); 27 | } 28 | } 29 | 30 | class_alias('Twig_Node_Expression_Binary_Matches', 'Twig\Node\Expression\Binary\MatchesBinary', false); 31 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Mod.php: -------------------------------------------------------------------------------- 1 | raw('%'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Binary_Mod', 'Twig\Node\Expression\Binary\ModBinary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Mul.php: -------------------------------------------------------------------------------- 1 | raw('*'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Binary_Mul', 'Twig\Node\Expression\Binary\MulBinary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/NotEqual.php: -------------------------------------------------------------------------------- 1 | raw('!='); 16 | } 17 | } 18 | 19 | class_alias('Twig_Node_Expression_Binary_NotEqual', 'Twig\Node\Expression\Binary\NotEqualBinary', false); 20 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/NotIn.php: -------------------------------------------------------------------------------- 1 | raw('!twig_in_filter(') 17 | ->subcompile($this->getNode('left')) 18 | ->raw(', ') 19 | ->subcompile($this->getNode('right')) 20 | ->raw(')') 21 | ; 22 | } 23 | 24 | public function operator(Twig_Compiler $compiler) 25 | { 26 | return $compiler->raw('not in'); 27 | } 28 | } 29 | 30 | class_alias('Twig_Node_Expression_Binary_NotIn', 'Twig\Node\Expression\Binary\NotInBinary', false); 31 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Or.php: -------------------------------------------------------------------------------- 1 | raw('||'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Binary_Or', 'Twig\Node\Expression\Binary\OrBinary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Power.php: -------------------------------------------------------------------------------- 1 | = 50600) { 16 | return parent::compile($compiler); 17 | } 18 | 19 | $compiler 20 | ->raw('pow(') 21 | ->subcompile($this->getNode('left')) 22 | ->raw(', ') 23 | ->subcompile($this->getNode('right')) 24 | ->raw(')') 25 | ; 26 | } 27 | 28 | public function operator(Twig_Compiler $compiler) 29 | { 30 | return $compiler->raw('**'); 31 | } 32 | } 33 | 34 | class_alias('Twig_Node_Expression_Binary_Power', 'Twig\Node\Expression\Binary\PowerBinary', false); 35 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Range.php: -------------------------------------------------------------------------------- 1 | raw('range(') 17 | ->subcompile($this->getNode('left')) 18 | ->raw(', ') 19 | ->subcompile($this->getNode('right')) 20 | ->raw(')') 21 | ; 22 | } 23 | 24 | public function operator(Twig_Compiler $compiler) 25 | { 26 | return $compiler->raw('..'); 27 | } 28 | } 29 | 30 | class_alias('Twig_Node_Expression_Binary_Range', 'Twig\Node\Expression\Binary\RangeBinary', false); 31 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/StartsWith.php: -------------------------------------------------------------------------------- 1 | getVarName(); 16 | $right = $compiler->getVarName(); 17 | $compiler 18 | ->raw(sprintf('(is_string($%s = ', $left)) 19 | ->subcompile($this->getNode('left')) 20 | ->raw(sprintf(') && is_string($%s = ', $right)) 21 | ->subcompile($this->getNode('right')) 22 | ->raw(sprintf(') && (\'\' === $%2$s || 0 === strpos($%1$s, $%2$s)))', $left, $right)) 23 | ; 24 | } 25 | 26 | public function operator(Twig_Compiler $compiler) 27 | { 28 | return $compiler->raw(''); 29 | } 30 | } 31 | 32 | class_alias('Twig_Node_Expression_Binary_StartsWith', 'Twig\Node\Expression\Binary\StartsWithBinary', false); 33 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Binary/Sub.php: -------------------------------------------------------------------------------- 1 | raw('-'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Binary_Sub', 'Twig\Node\Expression\Binary\SubBinary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Conditional.php: -------------------------------------------------------------------------------- 1 | $expr1, 'expr2' => $expr2, 'expr3' => $expr3), array(), $lineno); 17 | } 18 | 19 | public function compile(Twig_Compiler $compiler) 20 | { 21 | $compiler 22 | ->raw('((') 23 | ->subcompile($this->getNode('expr1')) 24 | ->raw(') ? (') 25 | ->subcompile($this->getNode('expr2')) 26 | ->raw(') : (') 27 | ->subcompile($this->getNode('expr3')) 28 | ->raw('))') 29 | ; 30 | } 31 | } 32 | 33 | class_alias('Twig_Node_Expression_Conditional', 'Twig\Node\Expression\ConditionalExpression', false); 34 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Constant.php: -------------------------------------------------------------------------------- 1 | $value), $lineno); 17 | } 18 | 19 | public function compile(Twig_Compiler $compiler) 20 | { 21 | $compiler->repr($this->getAttribute('value')); 22 | } 23 | } 24 | 25 | class_alias('Twig_Node_Expression_Constant', 'Twig\Node\Expression\ConstantExpression', false); 26 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/ExtensionReference.php: -------------------------------------------------------------------------------- 1 | 18 | * 19 | * @deprecated since 1.23 and will be removed in 2.0. 20 | */ 21 | class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression 22 | { 23 | public function __construct($name, $lineno, $tag = null) 24 | { 25 | parent::__construct(array(), array('name' => $name), $lineno, $tag); 26 | } 27 | 28 | public function compile(Twig_Compiler $compiler) 29 | { 30 | $compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name'))); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Filter.php: -------------------------------------------------------------------------------- 1 | $node, 'filter' => $filterName, 'arguments' => $arguments), array(), $lineno, $tag); 17 | } 18 | 19 | public function compile(Twig_Compiler $compiler) 20 | { 21 | $name = $this->getNode('filter')->getAttribute('value'); 22 | $filter = $compiler->getEnvironment()->getFilter($name); 23 | 24 | $this->setAttribute('name', $name); 25 | $this->setAttribute('type', 'filter'); 26 | $this->setAttribute('thing', $filter); 27 | $this->setAttribute('needs_environment', $filter->needsEnvironment()); 28 | $this->setAttribute('needs_context', $filter->needsContext()); 29 | $this->setAttribute('arguments', $filter->getArguments()); 30 | if ($filter instanceof Twig_FilterCallableInterface || $filter instanceof Twig_SimpleFilter) { 31 | $this->setAttribute('callable', $filter->getCallable()); 32 | } 33 | if ($filter instanceof Twig_SimpleFilter) { 34 | $this->setAttribute('is_variadic', $filter->isVariadic()); 35 | } 36 | 37 | $this->compileCallable($compiler); 38 | } 39 | } 40 | 41 | class_alias('Twig_Node_Expression_Filter', 'Twig\Node\Expression\FilterExpression', false); 42 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Filter/Default.php: -------------------------------------------------------------------------------- 1 | 16 | * {{ var.foo|default('foo item on var is not defined') }} 17 | * 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter 22 | { 23 | public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) 24 | { 25 | $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine()); 26 | 27 | if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) { 28 | $test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getTemplateLine()); 29 | $false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getTemplateLine()); 30 | 31 | $node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getTemplateLine()); 32 | } else { 33 | $node = $default; 34 | } 35 | 36 | parent::__construct($node, $filterName, $arguments, $lineno, $tag); 37 | } 38 | 39 | public function compile(Twig_Compiler $compiler) 40 | { 41 | $compiler->subcompile($this->getNode('node')); 42 | } 43 | } 44 | 45 | class_alias('Twig_Node_Expression_Filter_Default', 'Twig\Node\Expression\Filter\DefaultFilter', false); 46 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Function.php: -------------------------------------------------------------------------------- 1 | $arguments), array('name' => $name, 'is_defined_test' => false), $lineno); 16 | } 17 | 18 | public function compile(Twig_Compiler $compiler) 19 | { 20 | $name = $this->getAttribute('name'); 21 | $function = $compiler->getEnvironment()->getFunction($name); 22 | 23 | $this->setAttribute('name', $name); 24 | $this->setAttribute('type', 'function'); 25 | $this->setAttribute('thing', $function); 26 | $this->setAttribute('needs_environment', $function->needsEnvironment()); 27 | $this->setAttribute('needs_context', $function->needsContext()); 28 | $this->setAttribute('arguments', $function->getArguments()); 29 | if ($function instanceof Twig_FunctionCallableInterface || $function instanceof Twig_SimpleFunction) { 30 | $callable = $function->getCallable(); 31 | if ('constant' === $name && $this->getAttribute('is_defined_test')) { 32 | $callable = 'twig_constant_is_defined'; 33 | } 34 | 35 | $this->setAttribute('callable', $callable); 36 | } 37 | if ($function instanceof Twig_SimpleFunction) { 38 | $this->setAttribute('is_variadic', $function->isVariadic()); 39 | } 40 | 41 | $this->compileCallable($compiler); 42 | } 43 | } 44 | 45 | class_alias('Twig_Node_Expression_Function', 'Twig\Node\Expression\FunctionExpression', false); 46 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/MethodCall.php: -------------------------------------------------------------------------------- 1 | $node, 'arguments' => $arguments), array('method' => $method, 'safe' => false), $lineno); 16 | 17 | if ($node instanceof Twig_Node_Expression_Name) { 18 | $node->setAttribute('always_defined', true); 19 | } 20 | } 21 | 22 | public function compile(Twig_Compiler $compiler) 23 | { 24 | $compiler 25 | ->subcompile($this->getNode('node')) 26 | ->raw('->') 27 | ->raw($this->getAttribute('method')) 28 | ->raw('(') 29 | ; 30 | $first = true; 31 | foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) { 32 | if (!$first) { 33 | $compiler->raw(', '); 34 | } 35 | $first = false; 36 | 37 | $compiler->subcompile($pair['value']); 38 | } 39 | $compiler->raw(')'); 40 | } 41 | } 42 | 43 | class_alias('Twig_Node_Expression_MethodCall', 'Twig\Node\Expression\MethodCallExpression', false); 44 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/NullCoalesce.php: -------------------------------------------------------------------------------- 1 | getTemplateLine()), 17 | new Twig_Node_Expression_Unary_Not(new Twig_Node_Expression_Test_Null($left, 'null', new Twig_Node(), $left->getTemplateLine()), $left->getTemplateLine()), 18 | $left->getTemplateLine() 19 | ); 20 | 21 | parent::__construct($test, $left, $right, $lineno); 22 | } 23 | 24 | public function compile(Twig_Compiler $compiler) 25 | { 26 | /* 27 | * This optimizes only one case. PHP 7 also supports more complex expressions 28 | * that can return null. So, for instance, if log is defined, log("foo") ?? "..." works, 29 | * but log($a["foo"]) ?? "..." does not if $a["foo"] is not defined. More advanced 30 | * cases might be implemented as an optimizer node visitor, but has not been done 31 | * as benefits are probably not worth the added complexity. 32 | */ 33 | if (PHP_VERSION_ID >= 70000 && $this->getNode('expr2') instanceof Twig_Node_Expression_Name) { 34 | $this->getNode('expr2')->setAttribute('always_defined', true); 35 | $compiler 36 | ->raw('((') 37 | ->subcompile($this->getNode('expr2')) 38 | ->raw(') ?? (') 39 | ->subcompile($this->getNode('expr3')) 40 | ->raw('))') 41 | ; 42 | } else { 43 | parent::compile($compiler); 44 | } 45 | } 46 | } 47 | 48 | class_alias('Twig_Node_Expression_NullCoalesce', 'Twig\Node\Expression\NullCoalesceExpression', false); 49 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Parent.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class Twig_Node_Expression_Parent extends Twig_Node_Expression 19 | { 20 | public function __construct($name, $lineno, $tag = null) 21 | { 22 | parent::__construct(array(), array('output' => false, 'name' => $name), $lineno, $tag); 23 | } 24 | 25 | public function compile(Twig_Compiler $compiler) 26 | { 27 | if ($this->getAttribute('output')) { 28 | $compiler 29 | ->addDebugInfo($this) 30 | ->write('$this->displayParentBlock(') 31 | ->string($this->getAttribute('name')) 32 | ->raw(", \$context, \$blocks);\n") 33 | ; 34 | } else { 35 | $compiler 36 | ->raw('$this->renderParentBlock(') 37 | ->string($this->getAttribute('name')) 38 | ->raw(', $context, $blocks)') 39 | ; 40 | } 41 | } 42 | } 43 | 44 | class_alias('Twig_Node_Expression_Parent', 'Twig\Node\Expression\ParentExpression', false); 45 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/TempName.php: -------------------------------------------------------------------------------- 1 | $name), $lineno); 16 | } 17 | 18 | public function compile(Twig_Compiler $compiler) 19 | { 20 | $compiler 21 | ->raw('$_') 22 | ->raw($this->getAttribute('name')) 23 | ->raw('_') 24 | ; 25 | } 26 | } 27 | 28 | class_alias('Twig_Node_Expression_TempName', 'Twig\Node\Expression\TempNameExpression', false); 29 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Test.php: -------------------------------------------------------------------------------- 1 | $node); 16 | if (null !== $arguments) { 17 | $nodes['arguments'] = $arguments; 18 | } 19 | 20 | parent::__construct($nodes, array('name' => $name), $lineno); 21 | } 22 | 23 | public function compile(Twig_Compiler $compiler) 24 | { 25 | $name = $this->getAttribute('name'); 26 | $test = $compiler->getEnvironment()->getTest($name); 27 | 28 | $this->setAttribute('name', $name); 29 | $this->setAttribute('type', 'test'); 30 | $this->setAttribute('thing', $test); 31 | if ($test instanceof Twig_TestCallableInterface || $test instanceof Twig_SimpleTest) { 32 | $this->setAttribute('callable', $test->getCallable()); 33 | } 34 | if ($test instanceof Twig_SimpleTest) { 35 | $this->setAttribute('is_variadic', $test->isVariadic()); 36 | } 37 | 38 | $this->compileCallable($compiler); 39 | } 40 | } 41 | 42 | class_alias('Twig_Node_Expression_Test', 'Twig\Node\Expression\TestExpression', false); 43 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Test/Constant.php: -------------------------------------------------------------------------------- 1 | 16 | * {% if post.status is constant('Post::PUBLISHED') %} 17 | * the status attribute is exactly the same as Post::PUBLISHED 18 | * {% endif %} 19 | * 20 | * 21 | * @author Fabien Potencier 22 | */ 23 | class Twig_Node_Expression_Test_Constant extends Twig_Node_Expression_Test 24 | { 25 | public function compile(Twig_Compiler $compiler) 26 | { 27 | $compiler 28 | ->raw('(') 29 | ->subcompile($this->getNode('node')) 30 | ->raw(' === constant(') 31 | ; 32 | 33 | if ($this->getNode('arguments')->hasNode(1)) { 34 | $compiler 35 | ->raw('get_class(') 36 | ->subcompile($this->getNode('arguments')->getNode(1)) 37 | ->raw(')."::".') 38 | ; 39 | } 40 | 41 | $compiler 42 | ->subcompile($this->getNode('arguments')->getNode(0)) 43 | ->raw('))') 44 | ; 45 | } 46 | } 47 | 48 | class_alias('Twig_Node_Expression_Test_Constant', 'Twig\Node\Expression\Test\ConstantTest', false); 49 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Test/Defined.php: -------------------------------------------------------------------------------- 1 | 16 | * {# defined works with variable names and variable attributes #} 17 | * {% if foo is defined %} 18 | * {# ... #} 19 | * {% endif %} 20 | * 21 | * 22 | * @author Fabien Potencier 23 | */ 24 | class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test 25 | { 26 | public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno) 27 | { 28 | if ($node instanceof Twig_Node_Expression_Name) { 29 | $node->setAttribute('is_defined_test', true); 30 | } elseif ($node instanceof Twig_Node_Expression_GetAttr) { 31 | $node->setAttribute('is_defined_test', true); 32 | $this->changeIgnoreStrictCheck($node); 33 | } elseif ($node instanceof Twig_Node_Expression_BlockReference) { 34 | $node->setAttribute('is_defined_test', true); 35 | } elseif ($node instanceof Twig_Node_Expression_Function && 'constant' === $node->getAttribute('name')) { 36 | $node->setAttribute('is_defined_test', true); 37 | } elseif ($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array) { 38 | $node = new Twig_Node_Expression_Constant(true, $node->getTemplateLine()); 39 | } else { 40 | throw new Twig_Error_Syntax('The "defined" test only works with simple variables.', $this->getTemplateLine()); 41 | } 42 | 43 | parent::__construct($node, $name, $arguments, $lineno); 44 | } 45 | 46 | protected function changeIgnoreStrictCheck(Twig_Node_Expression_GetAttr $node) 47 | { 48 | $node->setAttribute('ignore_strict_check', true); 49 | 50 | if ($node->getNode('node') instanceof Twig_Node_Expression_GetAttr) { 51 | $this->changeIgnoreStrictCheck($node->getNode('node')); 52 | } 53 | } 54 | 55 | public function compile(Twig_Compiler $compiler) 56 | { 57 | $compiler->subcompile($this->getNode('node')); 58 | } 59 | } 60 | 61 | class_alias('Twig_Node_Expression_Test_Defined', 'Twig\Node\Expression\Test\DefinedTest', false); 62 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Test/Divisibleby.php: -------------------------------------------------------------------------------- 1 | 16 | * {% if loop.index is divisible by(3) %} 17 | * 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | class Twig_Node_Expression_Test_Divisibleby extends Twig_Node_Expression_Test 22 | { 23 | public function compile(Twig_Compiler $compiler) 24 | { 25 | $compiler 26 | ->raw('(0 == ') 27 | ->subcompile($this->getNode('node')) 28 | ->raw(' % ') 29 | ->subcompile($this->getNode('arguments')->getNode(0)) 30 | ->raw(')') 31 | ; 32 | } 33 | } 34 | 35 | class_alias('Twig_Node_Expression_Test_Divisibleby', 'Twig\Node\Expression\Test\DivisiblebyTest', false); 36 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Test/Even.php: -------------------------------------------------------------------------------- 1 | 16 | * {{ var is even }} 17 | * 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | class Twig_Node_Expression_Test_Even extends Twig_Node_Expression_Test 22 | { 23 | public function compile(Twig_Compiler $compiler) 24 | { 25 | $compiler 26 | ->raw('(') 27 | ->subcompile($this->getNode('node')) 28 | ->raw(' % 2 == 0') 29 | ->raw(')') 30 | ; 31 | } 32 | } 33 | 34 | class_alias('Twig_Node_Expression_Test_Even', 'Twig\Node\Expression\Test\EvenTest', false); 35 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Test/Null.php: -------------------------------------------------------------------------------- 1 | 16 | * {{ var is none }} 17 | * 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | class Twig_Node_Expression_Test_Null extends Twig_Node_Expression_Test 22 | { 23 | public function compile(Twig_Compiler $compiler) 24 | { 25 | $compiler 26 | ->raw('(null === ') 27 | ->subcompile($this->getNode('node')) 28 | ->raw(')') 29 | ; 30 | } 31 | } 32 | 33 | class_alias('Twig_Node_Expression_Test_Null', 'Twig\Node\Expression\Test\NullTest', false); 34 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Test/Odd.php: -------------------------------------------------------------------------------- 1 | 16 | * {{ var is odd }} 17 | * 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test 22 | { 23 | public function compile(Twig_Compiler $compiler) 24 | { 25 | $compiler 26 | ->raw('(') 27 | ->subcompile($this->getNode('node')) 28 | ->raw(' % 2 == 1') 29 | ->raw(')') 30 | ; 31 | } 32 | } 33 | 34 | class_alias('Twig_Node_Expression_Test_Odd', 'Twig\Node\Expression\Test\OddTest', false); 35 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Test/Sameas.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Node_Expression_Test_Sameas extends Twig_Node_Expression_Test 18 | { 19 | public function compile(Twig_Compiler $compiler) 20 | { 21 | $compiler 22 | ->raw('(') 23 | ->subcompile($this->getNode('node')) 24 | ->raw(' === ') 25 | ->subcompile($this->getNode('arguments')->getNode(0)) 26 | ->raw(')') 27 | ; 28 | } 29 | } 30 | 31 | class_alias('Twig_Node_Expression_Test_Sameas', 'Twig\Node\Expression\Test\SameasTest', false); 32 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Unary.php: -------------------------------------------------------------------------------- 1 | $node), array(), $lineno); 17 | } 18 | 19 | public function compile(Twig_Compiler $compiler) 20 | { 21 | $compiler->raw(' '); 22 | $this->operator($compiler); 23 | $compiler->subcompile($this->getNode('node')); 24 | } 25 | 26 | abstract public function operator(Twig_Compiler $compiler); 27 | } 28 | 29 | class_alias('Twig_Node_Expression_Unary', 'Twig\Node\Expression\Unary\AbstractUnary', false); 30 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Unary/Neg.php: -------------------------------------------------------------------------------- 1 | raw('-'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Unary_Neg', 'Twig\Node\Expression\Unary\NegUnary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Unary/Not.php: -------------------------------------------------------------------------------- 1 | raw('!'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Unary_Not', 'Twig\Node\Expression\Unary\NotUnary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Expression/Unary/Pos.php: -------------------------------------------------------------------------------- 1 | raw('+'); 17 | } 18 | } 19 | 20 | class_alias('Twig_Node_Expression_Unary_Pos', 'Twig\Node\Expression\Unary\PosUnary', false); 21 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Flush.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Node_Flush extends Twig_Node 18 | { 19 | public function __construct($lineno, $tag) 20 | { 21 | parent::__construct(array(), array(), $lineno, $tag); 22 | } 23 | 24 | public function compile(Twig_Compiler $compiler) 25 | { 26 | $compiler 27 | ->addDebugInfo($this) 28 | ->write("flush();\n") 29 | ; 30 | } 31 | } 32 | 33 | class_alias('Twig_Node_Flush', 'Twig\Node\FlushNode', false); 34 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/ForLoop.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Node_ForLoop extends Twig_Node 18 | { 19 | public function __construct($lineno, $tag = null) 20 | { 21 | parent::__construct(array(), array('with_loop' => false, 'ifexpr' => false, 'else' => false), $lineno, $tag); 22 | } 23 | 24 | public function compile(Twig_Compiler $compiler) 25 | { 26 | if ($this->getAttribute('else')) { 27 | $compiler->write("\$context['_iterated'] = true;\n"); 28 | } 29 | 30 | if ($this->getAttribute('with_loop')) { 31 | $compiler 32 | ->write("++\$context['loop']['index0'];\n") 33 | ->write("++\$context['loop']['index'];\n") 34 | ->write("\$context['loop']['first'] = false;\n") 35 | ; 36 | 37 | if (!$this->getAttribute('ifexpr')) { 38 | $compiler 39 | ->write("if (isset(\$context['loop']['length'])) {\n") 40 | ->indent() 41 | ->write("--\$context['loop']['revindex0'];\n") 42 | ->write("--\$context['loop']['revindex'];\n") 43 | ->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n") 44 | ->outdent() 45 | ->write("}\n") 46 | ; 47 | } 48 | } 49 | } 50 | } 51 | 52 | class_alias('Twig_Node_ForLoop', 'Twig\Node\ForLoopNode', false); 53 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/If.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class Twig_Node_If extends Twig_Node 19 | { 20 | public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null) 21 | { 22 | $nodes = array('tests' => $tests); 23 | if (null !== $else) { 24 | $nodes['else'] = $else; 25 | } 26 | 27 | parent::__construct($nodes, array(), $lineno, $tag); 28 | } 29 | 30 | public function compile(Twig_Compiler $compiler) 31 | { 32 | $compiler->addDebugInfo($this); 33 | for ($i = 0, $count = count($this->getNode('tests')); $i < $count; $i += 2) { 34 | if ($i > 0) { 35 | $compiler 36 | ->outdent() 37 | ->write('} elseif (') 38 | ; 39 | } else { 40 | $compiler 41 | ->write('if (') 42 | ; 43 | } 44 | 45 | $compiler 46 | ->subcompile($this->getNode('tests')->getNode($i)) 47 | ->raw(") {\n") 48 | ->indent() 49 | ->subcompile($this->getNode('tests')->getNode($i + 1)) 50 | ; 51 | } 52 | 53 | if ($this->hasNode('else')) { 54 | $compiler 55 | ->outdent() 56 | ->write("} else {\n") 57 | ->indent() 58 | ->subcompile($this->getNode('else')) 59 | ; 60 | } 61 | 62 | $compiler 63 | ->outdent() 64 | ->write("}\n"); 65 | } 66 | } 67 | 68 | class_alias('Twig_Node_If', 'Twig\Node\IfNode', false); 69 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Import.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Node_Import extends Twig_Node 18 | { 19 | public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $var, $lineno, $tag = null) 20 | { 21 | parent::__construct(array('expr' => $expr, 'var' => $var), array(), $lineno, $tag); 22 | } 23 | 24 | public function compile(Twig_Compiler $compiler) 25 | { 26 | $compiler 27 | ->addDebugInfo($this) 28 | ->write('') 29 | ->subcompile($this->getNode('var')) 30 | ->raw(' = ') 31 | ; 32 | 33 | if ($this->getNode('expr') instanceof Twig_Node_Expression_Name && '_self' === $this->getNode('expr')->getAttribute('name')) { 34 | $compiler->raw('$this'); 35 | } else { 36 | $compiler 37 | ->raw('$this->loadTemplate(') 38 | ->subcompile($this->getNode('expr')) 39 | ->raw(', ') 40 | ->repr($this->getTemplateName()) 41 | ->raw(', ') 42 | ->repr($this->getTemplateLine()) 43 | ->raw(')') 44 | ; 45 | } 46 | 47 | $compiler->raw(";\n"); 48 | } 49 | } 50 | 51 | class_alias('Twig_Node_Import', 'Twig\Node\ImportNode', false); 52 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Print.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface 19 | { 20 | public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null) 21 | { 22 | parent::__construct(array('expr' => $expr), array(), $lineno, $tag); 23 | } 24 | 25 | public function compile(Twig_Compiler $compiler) 26 | { 27 | $compiler 28 | ->addDebugInfo($this) 29 | ->write('echo ') 30 | ->subcompile($this->getNode('expr')) 31 | ->raw(";\n") 32 | ; 33 | } 34 | } 35 | 36 | class_alias('Twig_Node_Print', 'Twig\Node\PrintNode', false); 37 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Sandbox.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Node_Sandbox extends Twig_Node 18 | { 19 | public function __construct(Twig_NodeInterface $body, $lineno, $tag = null) 20 | { 21 | parent::__construct(array('body' => $body), array(), $lineno, $tag); 22 | } 23 | 24 | public function compile(Twig_Compiler $compiler) 25 | { 26 | $compiler 27 | ->addDebugInfo($this) 28 | ->write("\$sandbox = \$this->env->getExtension('Twig_Extension_Sandbox');\n") 29 | ->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n") 30 | ->indent() 31 | ->write("\$sandbox->enableSandbox();\n") 32 | ->outdent() 33 | ->write("}\n") 34 | ->subcompile($this->getNode('body')) 35 | ->write("if (!\$alreadySandboxed) {\n") 36 | ->indent() 37 | ->write("\$sandbox->disableSandbox();\n") 38 | ->outdent() 39 | ->write("}\n") 40 | ; 41 | } 42 | } 43 | 44 | class_alias('Twig_Node_Sandbox', 'Twig\Node\SandboxNode', false); 45 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/SandboxedPrint.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class Twig_Node_SandboxedPrint extends Twig_Node_Print 23 | { 24 | public function compile(Twig_Compiler $compiler) 25 | { 26 | $compiler 27 | ->addDebugInfo($this) 28 | ->write('echo $this->env->getExtension(\'Twig_Extension_Sandbox\')->ensureToStringAllowed(') 29 | ->subcompile($this->getNode('expr')) 30 | ->raw(");\n") 31 | ; 32 | } 33 | 34 | /** 35 | * Removes node filters. 36 | * 37 | * This is mostly needed when another visitor adds filters (like the escaper one). 38 | * 39 | * @return Twig_Node 40 | */ 41 | protected function removeNodeFilter(Twig_Node $node) 42 | { 43 | if ($node instanceof Twig_Node_Expression_Filter) { 44 | return $this->removeNodeFilter($node->getNode('node')); 45 | } 46 | 47 | return $node; 48 | } 49 | } 50 | 51 | class_alias('Twig_Node_SandboxedPrint', 'Twig\Node\SandboxedPrintNode', false); 52 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/SetTemp.php: -------------------------------------------------------------------------------- 1 | $name), $lineno); 20 | } 21 | 22 | public function compile(Twig_Compiler $compiler) 23 | { 24 | $name = $this->getAttribute('name'); 25 | $compiler 26 | ->addDebugInfo($this) 27 | ->write('if (isset($context[') 28 | ->string($name) 29 | ->raw('])) { $_') 30 | ->raw($name) 31 | ->raw('_ = $context[') 32 | ->repr($name) 33 | ->raw(']; } else { $_') 34 | ->raw($name) 35 | ->raw("_ = null; }\n") 36 | ; 37 | } 38 | } 39 | 40 | class_alias('Twig_Node_SetTemp', 'Twig\Node\SetTempNode', false); 41 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Spaceless.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class Twig_Node_Spaceless extends Twig_Node 20 | { 21 | public function __construct(Twig_NodeInterface $body, $lineno, $tag = 'spaceless') 22 | { 23 | parent::__construct(array('body' => $body), array(), $lineno, $tag); 24 | } 25 | 26 | public function compile(Twig_Compiler $compiler) 27 | { 28 | $compiler 29 | ->addDebugInfo($this) 30 | ->write("ob_start();\n") 31 | ->subcompile($this->getNode('body')) 32 | ->write("echo trim(preg_replace('/>\s+<', ob_get_clean()));\n") 33 | ; 34 | } 35 | } 36 | 37 | class_alias('Twig_Node_Spaceless', 'Twig\Node\SpacelessNode', false); 38 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/Text.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface 19 | { 20 | public function __construct($data, $lineno) 21 | { 22 | parent::__construct(array(), array('data' => $data), $lineno); 23 | } 24 | 25 | public function compile(Twig_Compiler $compiler) 26 | { 27 | $compiler 28 | ->addDebugInfo($this) 29 | ->write('echo ') 30 | ->string($this->getAttribute('data')) 31 | ->raw(";\n") 32 | ; 33 | } 34 | } 35 | 36 | class_alias('Twig_Node_Text', 'Twig\Node\TextNode', false); 37 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Node/With.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Node_With extends Twig_Node 18 | { 19 | public function __construct(Twig_Node $body, Twig_Node $variables = null, $only = false, $lineno, $tag = null) 20 | { 21 | $nodes = array('body' => $body); 22 | if (null !== $variables) { 23 | $nodes['variables'] = $variables; 24 | } 25 | 26 | parent::__construct($nodes, array('only' => (bool) $only), $lineno, $tag); 27 | } 28 | 29 | public function compile(Twig_Compiler $compiler) 30 | { 31 | $compiler->addDebugInfo($this); 32 | 33 | if ($this->hasNode('variables')) { 34 | $varsName = $compiler->getVarName(); 35 | $compiler 36 | ->write(sprintf('$%s = ', $varsName)) 37 | ->subcompile($this->getNode('variables')) 38 | ->raw(";\n") 39 | ->write(sprintf("if (!is_array(\$%s)) {\n", $varsName)) 40 | ->indent() 41 | ->write("throw new Twig_Error_Runtime('Variables passed to the \"with\" tag must be a hash.');\n") 42 | ->outdent() 43 | ->write("}\n") 44 | ; 45 | 46 | if ($this->getAttribute('only')) { 47 | $compiler->write("\$context = array('_parent' => \$context);\n"); 48 | } else { 49 | $compiler->write("\$context['_parent'] = \$context;\n"); 50 | } 51 | 52 | $compiler->write(sprintf("\$context = array_merge(\$context, \$%s);\n", $varsName)); 53 | } else { 54 | $compiler->write("\$context['_parent'] = \$context;\n"); 55 | } 56 | 57 | $compiler 58 | ->subcompile($this->getNode('body')) 59 | ->write("\$context = \$context['_parent'];\n") 60 | ; 61 | } 62 | } 63 | 64 | class_alias('Twig_Node_With', 'Twig\Node\WithNode', false); 65 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/NodeCaptureInterface.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | interface Twig_NodeCaptureInterface 18 | { 19 | } 20 | 21 | class_alias('Twig_NodeCaptureInterface', 'Twig\Node\NodeCaptureInterface', false); 22 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/NodeInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * 17 | * @deprecated since 1.12 (to be removed in 3.0) 18 | */ 19 | interface Twig_NodeInterface extends Countable, IteratorAggregate 20 | { 21 | /** 22 | * Compiles the node to PHP. 23 | */ 24 | public function compile(Twig_Compiler $compiler); 25 | 26 | /** 27 | * @deprecated since 1.27 (to be removed in 2.0) 28 | */ 29 | public function getLine(); 30 | 31 | public function getNodeTag(); 32 | } 33 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/NodeOutputInterface.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | interface Twig_NodeOutputInterface 18 | { 19 | } 20 | 21 | class_alias('Twig_NodeOutputInterface', 'Twig\Node\NodeOutputInterface', false); 22 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/NodeTraverser.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | class Twig_NodeTraverser 22 | { 23 | protected $env; 24 | protected $visitors = array(); 25 | 26 | /** 27 | * @param Twig_Environment $env 28 | * @param Twig_NodeVisitorInterface[] $visitors 29 | */ 30 | public function __construct(Twig_Environment $env, array $visitors = array()) 31 | { 32 | $this->env = $env; 33 | foreach ($visitors as $visitor) { 34 | $this->addVisitor($visitor); 35 | } 36 | } 37 | 38 | public function addVisitor(Twig_NodeVisitorInterface $visitor) 39 | { 40 | if (!isset($this->visitors[$visitor->getPriority()])) { 41 | $this->visitors[$visitor->getPriority()] = array(); 42 | } 43 | 44 | $this->visitors[$visitor->getPriority()][] = $visitor; 45 | } 46 | 47 | /** 48 | * Traverses a node and calls the registered visitors. 49 | * 50 | * @return Twig_NodeInterface 51 | */ 52 | public function traverse(Twig_NodeInterface $node) 53 | { 54 | ksort($this->visitors); 55 | foreach ($this->visitors as $visitors) { 56 | foreach ($visitors as $visitor) { 57 | $node = $this->traverseForVisitor($visitor, $node); 58 | } 59 | } 60 | 61 | return $node; 62 | } 63 | 64 | protected function traverseForVisitor(Twig_NodeVisitorInterface $visitor, Twig_NodeInterface $node = null) 65 | { 66 | if (null === $node) { 67 | return; 68 | } 69 | 70 | $node = $visitor->enterNode($node, $this->env); 71 | 72 | foreach ($node as $k => $n) { 73 | if (false !== $m = $this->traverseForVisitor($visitor, $n)) { 74 | if ($m !== $n) { 75 | $node->setNode($k, $m); 76 | } 77 | } else { 78 | $node->removeNode($k); 79 | } 80 | } 81 | 82 | return $visitor->leaveNode($node, $this->env); 83 | } 84 | } 85 | 86 | class_alias('Twig_NodeTraverser', 'Twig\NodeTraverser', false); 87 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/NodeVisitorInterface.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | interface Twig_NodeVisitorInterface 18 | { 19 | /** 20 | * Called before child nodes are visited. 21 | * 22 | * @return Twig_NodeInterface The modified node 23 | */ 24 | public function enterNode(Twig_NodeInterface $node, Twig_Environment $env); 25 | 26 | /** 27 | * Called after child nodes are visited. 28 | * 29 | * @return Twig_NodeInterface|false The modified node or false if the node must be removed 30 | */ 31 | public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env); 32 | 33 | /** 34 | * Returns the priority for this visitor. 35 | * 36 | * Priority should be between -10 and 10 (0 is the default). 37 | * 38 | * @return int The priority level 39 | */ 40 | public function getPriority(); 41 | } 42 | 43 | class_alias('Twig_NodeVisitorInterface', 'Twig\NodeVisitor\NodeVisitorInterface', false); 44 | class_exists('Twig_Environment'); 45 | class_exists('Twig_Node'); 46 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/ParserInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * 17 | * @deprecated since 1.12 (to be removed in 3.0) 18 | */ 19 | interface Twig_ParserInterface 20 | { 21 | /** 22 | * Converts a token stream to a node tree. 23 | * 24 | * @return Twig_Node_Module 25 | * 26 | * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong 27 | */ 28 | public function parse(Twig_TokenStream $stream); 29 | } 30 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Profiler/Dumper/Base.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | abstract class Twig_Profiler_Dumper_Base 16 | { 17 | private $root; 18 | 19 | public function dump(Twig_Profiler_Profile $profile) 20 | { 21 | return $this->dumpProfile($profile); 22 | } 23 | 24 | abstract protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix); 25 | 26 | abstract protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix); 27 | 28 | abstract protected function formatTime(Twig_Profiler_Profile $profile, $percent); 29 | 30 | private function dumpProfile(Twig_Profiler_Profile $profile, $prefix = '', $sibling = false) 31 | { 32 | if ($profile->isRoot()) { 33 | $this->root = $profile->getDuration(); 34 | $start = $profile->getName(); 35 | } else { 36 | if ($profile->isTemplate()) { 37 | $start = $this->formatTemplate($profile, $prefix); 38 | } else { 39 | $start = $this->formatNonTemplate($profile, $prefix); 40 | } 41 | $prefix .= $sibling ? '│ ' : ' '; 42 | } 43 | 44 | $percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0; 45 | 46 | if ($profile->getDuration() * 1000 < 1) { 47 | $str = $start."\n"; 48 | } else { 49 | $str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent)); 50 | } 51 | 52 | $nCount = count($profile->getProfiles()); 53 | foreach ($profile as $i => $p) { 54 | $str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount); 55 | } 56 | 57 | return $str; 58 | } 59 | } 60 | 61 | class_alias('Twig_Profiler_Dumper_Base', 'Twig\Profiler\Dumper\BaseDumper', false); 62 | class_exists('Twig_Profiler_Profile'); 63 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Profiler/Dumper/Blackfire.php: -------------------------------------------------------------------------------- 1 | 14 | * 15 | * @final 16 | */ 17 | class Twig_Profiler_Dumper_Blackfire 18 | { 19 | public function dump(Twig_Profiler_Profile $profile) 20 | { 21 | $data = array(); 22 | $this->dumpProfile('main()', $profile, $data); 23 | $this->dumpChildren('main()', $profile, $data); 24 | 25 | $start = sprintf('%f', microtime(true)); 26 | $str = << $values) { 35 | $str .= "{$name}//{$values['ct']} {$values['wt']} {$values['mu']} {$values['pmu']}\n"; 36 | } 37 | 38 | return $str; 39 | } 40 | 41 | private function dumpChildren($parent, Twig_Profiler_Profile $profile, &$data) 42 | { 43 | foreach ($profile as $p) { 44 | if ($p->isTemplate()) { 45 | $name = $p->getTemplate(); 46 | } else { 47 | $name = sprintf('%s::%s(%s)', $p->getTemplate(), $p->getType(), $p->getName()); 48 | } 49 | $this->dumpProfile(sprintf('%s==>%s', $parent, $name), $p, $data); 50 | $this->dumpChildren($name, $p, $data); 51 | } 52 | } 53 | 54 | private function dumpProfile($edge, Twig_Profiler_Profile $profile, &$data) 55 | { 56 | if (isset($data[$edge])) { 57 | $data[$edge]['ct'] += 1; 58 | $data[$edge]['wt'] += floor($profile->getDuration() * 1000000); 59 | $data[$edge]['mu'] += $profile->getMemoryUsage(); 60 | $data[$edge]['pmu'] += $profile->getPeakMemoryUsage(); 61 | } else { 62 | $data[$edge] = array( 63 | 'ct' => 1, 64 | 'wt' => floor($profile->getDuration() * 1000000), 65 | 'mu' => $profile->getMemoryUsage(), 66 | 'pmu' => $profile->getPeakMemoryUsage(), 67 | ); 68 | } 69 | } 70 | } 71 | 72 | class_alias('Twig_Profiler_Dumper_Blackfire', 'Twig\Profiler\Dumper\BlackfireDumper', false); 73 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Profiler/Dumper/Html.php: -------------------------------------------------------------------------------- 1 | 14 | * 15 | * @final 16 | */ 17 | class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Base 18 | { 19 | private static $colors = array( 20 | 'block' => '#dfd', 21 | 'macro' => '#ddf', 22 | 'template' => '#ffd', 23 | 'big' => '#d44', 24 | ); 25 | 26 | public function dump(Twig_Profiler_Profile $profile) 27 | { 28 | return '
'.parent::dump($profile).'
'; 29 | } 30 | 31 | protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix) 32 | { 33 | return sprintf('%s└ %s', $prefix, self::$colors['template'], $profile->getTemplate()); 34 | } 35 | 36 | protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix) 37 | { 38 | return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), isset(self::$colors[$profile->getType()]) ? self::$colors[$profile->getType()] : 'auto', $profile->getName()); 39 | } 40 | 41 | protected function formatTime(Twig_Profiler_Profile $profile, $percent) 42 | { 43 | return sprintf('%.2fms/%.0f%%', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent); 44 | } 45 | } 46 | 47 | class_alias('Twig_Profiler_Dumper_Html', 'Twig\Profiler\Dumper\HtmlDumper', false); 48 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Profiler/Dumper/Text.php: -------------------------------------------------------------------------------- 1 | 14 | * 15 | * @final 16 | */ 17 | class Twig_Profiler_Dumper_Text extends Twig_Profiler_Dumper_Base 18 | { 19 | protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix) 20 | { 21 | return sprintf('%s└ %s', $prefix, $profile->getTemplate()); 22 | } 23 | 24 | protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix) 25 | { 26 | return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), $profile->getName()); 27 | } 28 | 29 | protected function formatTime(Twig_Profiler_Profile $profile, $percent) 30 | { 31 | return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent); 32 | } 33 | } 34 | 35 | class_alias('Twig_Profiler_Dumper_Text', 'Twig\Profiler\Dumper\TextDumper', false); 36 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Profiler/Node/EnterProfile.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Profiler_Node_EnterProfile extends Twig_Node 18 | { 19 | public function __construct($extensionName, $type, $name, $varName) 20 | { 21 | parent::__construct(array(), array('extension_name' => $extensionName, 'name' => $name, 'type' => $type, 'var_name' => $varName)); 22 | } 23 | 24 | public function compile(Twig_Compiler $compiler) 25 | { 26 | $compiler 27 | ->write(sprintf('$%s = $this->env->getExtension(', $this->getAttribute('var_name'))) 28 | ->repr($this->getAttribute('extension_name')) 29 | ->raw(");\n") 30 | ->write(sprintf('$%s->enter($%s = new Twig_Profiler_Profile($this->getTemplateName(), ', $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof')) 31 | ->repr($this->getAttribute('type')) 32 | ->raw(', ') 33 | ->repr($this->getAttribute('name')) 34 | ->raw("));\n\n") 35 | ; 36 | } 37 | } 38 | 39 | class_alias('Twig_Profiler_Node_EnterProfile', 'Twig\Profiler\Node\EnterProfileNode', false); 40 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Profiler/Node/LeaveProfile.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Profiler_Node_LeaveProfile extends Twig_Node 18 | { 19 | public function __construct($varName) 20 | { 21 | parent::__construct(array(), array('var_name' => $varName)); 22 | } 23 | 24 | public function compile(Twig_Compiler $compiler) 25 | { 26 | $compiler 27 | ->write("\n") 28 | ->write(sprintf("\$%s->leave(\$%s);\n\n", $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof')) 29 | ; 30 | } 31 | } 32 | 33 | class_alias('Twig_Profiler_Node_LeaveProfile', 'Twig\Profiler\Node\LeaveProfileNode', false); 34 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Profiler/NodeVisitor/Profiler.php: -------------------------------------------------------------------------------- 1 | 14 | * 15 | * @final 16 | */ 17 | class Twig_Profiler_NodeVisitor_Profiler extends Twig_BaseNodeVisitor 18 | { 19 | private $extensionName; 20 | 21 | public function __construct($extensionName) 22 | { 23 | $this->extensionName = $extensionName; 24 | } 25 | 26 | protected function doEnterNode(Twig_Node $node, Twig_Environment $env) 27 | { 28 | return $node; 29 | } 30 | 31 | protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) 32 | { 33 | if ($node instanceof Twig_Node_Module) { 34 | $varName = $this->getVarName(); 35 | $node->setNode('display_start', new Twig_Node(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::TEMPLATE, $node->getTemplateName(), $varName), $node->getNode('display_start')))); 36 | $node->setNode('display_end', new Twig_Node(array(new Twig_Profiler_Node_LeaveProfile($varName), $node->getNode('display_end')))); 37 | } elseif ($node instanceof Twig_Node_Block) { 38 | $varName = $this->getVarName(); 39 | $node->setNode('body', new Twig_Node_Body(array( 40 | new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::BLOCK, $node->getAttribute('name'), $varName), 41 | $node->getNode('body'), 42 | new Twig_Profiler_Node_LeaveProfile($varName), 43 | ))); 44 | } elseif ($node instanceof Twig_Node_Macro) { 45 | $varName = $this->getVarName(); 46 | $node->setNode('body', new Twig_Node_Body(array( 47 | new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::MACRO, $node->getAttribute('name'), $varName), 48 | $node->getNode('body'), 49 | new Twig_Profiler_Node_LeaveProfile($varName), 50 | ))); 51 | } 52 | 53 | return $node; 54 | } 55 | 56 | private function getVarName() 57 | { 58 | return sprintf('__internal_%s', hash('sha256', $this->extensionName)); 59 | } 60 | 61 | public function getPriority() 62 | { 63 | return 0; 64 | } 65 | } 66 | 67 | class_alias('Twig_Profiler_NodeVisitor_Profiler', 'Twig\Profiler\NodeVisitor\ProfilerNodeVisitor', false); 68 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/RuntimeLoaderInterface.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | interface Twig_RuntimeLoaderInterface 18 | { 19 | /** 20 | * Creates the runtime implementation of a Twig element (filter/function/test). 21 | * 22 | * @param string $class A runtime class 23 | * 24 | * @return object|null The runtime instance or null if the loader does not know how to create the runtime for this class 25 | */ 26 | public function load($class); 27 | } 28 | 29 | class_alias('Twig_RuntimeLoaderInterface', 'Twig\RuntimeLoader\RuntimeLoaderInterface', false); 30 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Sandbox/SecurityError.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Sandbox_SecurityError extends Twig_Error 18 | { 19 | } 20 | 21 | class_alias('Twig_Sandbox_SecurityError', 'Twig\Sandbox\SecurityError', false); 22 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Sandbox_SecurityNotAllowedFilterError extends Twig_Sandbox_SecurityError 18 | { 19 | private $filterName; 20 | 21 | public function __construct($message, $functionName, $lineno = -1, $filename = null, Exception $previous = null) 22 | { 23 | parent::__construct($message, $lineno, $filename, $previous); 24 | $this->filterName = $functionName; 25 | } 26 | 27 | public function getFilterName() 28 | { 29 | return $this->filterName; 30 | } 31 | } 32 | 33 | class_alias('Twig_Sandbox_SecurityNotAllowedFilterError', 'Twig\Sandbox\SecurityNotAllowedFilterError', false); 34 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Sandbox_SecurityNotAllowedFunctionError extends Twig_Sandbox_SecurityError 18 | { 19 | private $functionName; 20 | 21 | public function __construct($message, $functionName, $lineno = -1, $filename = null, Exception $previous = null) 22 | { 23 | parent::__construct($message, $lineno, $filename, $previous); 24 | $this->functionName = $functionName; 25 | } 26 | 27 | public function getFunctionName() 28 | { 29 | return $this->functionName; 30 | } 31 | } 32 | 33 | class_alias('Twig_Sandbox_SecurityNotAllowedFunctionError', 'Twig\Sandbox\SecurityNotAllowedFunctionError', false); 34 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Sandbox_SecurityNotAllowedMethodError extends Twig_Sandbox_SecurityError 18 | { 19 | private $className; 20 | private $methodName; 21 | 22 | public function __construct($message, $className, $methodName, $lineno = -1, $filename = null, Exception $previous = null) 23 | { 24 | parent::__construct($message, $lineno, $filename, $previous); 25 | $this->className = $className; 26 | $this->methodName = $methodName; 27 | } 28 | 29 | public function getClassName() 30 | { 31 | return $this->className; 32 | } 33 | 34 | public function getMethodName() 35 | { 36 | return $this->methodName; 37 | } 38 | } 39 | 40 | class_alias('Twig_Sandbox_SecurityNotAllowedMethodError', 'Twig\Sandbox\SecurityNotAllowedMethodError', false); 41 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Sandbox_SecurityNotAllowedPropertyError extends Twig_Sandbox_SecurityError 18 | { 19 | private $className; 20 | private $propertyName; 21 | 22 | public function __construct($message, $className, $propertyName, $lineno = -1, $filename = null, Exception $previous = null) 23 | { 24 | parent::__construct($message, $lineno, $filename, $previous); 25 | $this->className = $className; 26 | $this->propertyName = $propertyName; 27 | } 28 | 29 | public function getClassName() 30 | { 31 | return $this->className; 32 | } 33 | 34 | public function getPropertyName() 35 | { 36 | return $this->propertyName; 37 | } 38 | } 39 | 40 | class_alias('Twig_Sandbox_SecurityNotAllowedPropertyError', 'Twig\Sandbox\SecurityNotAllowedPropertyError', false); 41 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Twig_Sandbox_SecurityNotAllowedTagError extends Twig_Sandbox_SecurityError 18 | { 19 | private $tagName; 20 | 21 | public function __construct($message, $tagName, $lineno = -1, $filename = null, Exception $previous = null) 22 | { 23 | parent::__construct($message, $lineno, $filename, $previous); 24 | $this->tagName = $tagName; 25 | } 26 | 27 | public function getTagName() 28 | { 29 | return $this->tagName; 30 | } 31 | } 32 | 33 | class_alias('Twig_Sandbox_SecurityNotAllowedTagError', 'Twig\Sandbox\SecurityNotAllowedTagError', false); 34 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Sandbox/SecurityPolicyInterface.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | interface Twig_Sandbox_SecurityPolicyInterface 18 | { 19 | public function checkSecurity($tags, $filters, $functions); 20 | 21 | public function checkMethodAllowed($obj, $method); 22 | 23 | public function checkPropertyAllowed($obj, $method); 24 | } 25 | 26 | class_alias('Twig_Sandbox_SecurityPolicyInterface', 'Twig\Sandbox\SecurityPolicyInterface', false); 27 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/SimpleTest.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class Twig_SimpleTest 20 | { 21 | protected $name; 22 | protected $callable; 23 | protected $options; 24 | 25 | public function __construct($name, $callable, array $options = array()) 26 | { 27 | $this->name = $name; 28 | $this->callable = $callable; 29 | $this->options = array_merge(array( 30 | 'is_variadic' => false, 31 | 'node_class' => 'Twig_Node_Expression_Test', 32 | 'deprecated' => false, 33 | 'alternative' => null, 34 | ), $options); 35 | } 36 | 37 | public function getName() 38 | { 39 | return $this->name; 40 | } 41 | 42 | public function getCallable() 43 | { 44 | return $this->callable; 45 | } 46 | 47 | public function getNodeClass() 48 | { 49 | return $this->options['node_class']; 50 | } 51 | 52 | public function isVariadic() 53 | { 54 | return $this->options['is_variadic']; 55 | } 56 | 57 | public function isDeprecated() 58 | { 59 | return (bool) $this->options['deprecated']; 60 | } 61 | 62 | public function getDeprecatedVersion() 63 | { 64 | return $this->options['deprecated']; 65 | } 66 | 67 | public function getAlternative() 68 | { 69 | return $this->options['alternative']; 70 | } 71 | } 72 | 73 | class_alias('Twig_SimpleTest', 'Twig\TwigTest', false); 74 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Source.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class Twig_Source 20 | { 21 | private $code; 22 | private $name; 23 | private $path; 24 | 25 | /** 26 | * @param string $code The template source code 27 | * @param string $name The template logical name 28 | * @param string $path The filesystem path of the template if any 29 | */ 30 | public function __construct($code, $name, $path = '') 31 | { 32 | $this->code = $code; 33 | $this->name = $name; 34 | $this->path = $path; 35 | } 36 | 37 | public function getCode() 38 | { 39 | return $this->code; 40 | } 41 | 42 | public function getName() 43 | { 44 | return $this->name; 45 | } 46 | 47 | public function getPath() 48 | { 49 | return $this->path; 50 | } 51 | } 52 | 53 | class_alias('Twig_Source', 'Twig\Source', false); 54 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/SourceContextLoaderInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * 17 | * @deprecated since 1.27 (to be removed in 3.0) 18 | */ 19 | interface Twig_SourceContextLoaderInterface 20 | { 21 | /** 22 | * Returns the source context for a given template logical name. 23 | * 24 | * @param string $name The template logical name 25 | * 26 | * @return Twig_Source 27 | * 28 | * @throws Twig_Error_Loader When $name is not found 29 | */ 30 | public function getSourceContext($name); 31 | } 32 | 33 | class_alias('Twig_SourceContextLoaderInterface', 'Twig\Loader\SourceContextLoaderInterface', false); 34 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TemplateInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * 17 | * @deprecated since 1.12 (to be removed in 3.0) 18 | */ 19 | interface Twig_TemplateInterface 20 | { 21 | const ANY_CALL = 'any'; 22 | const ARRAY_CALL = 'array'; 23 | const METHOD_CALL = 'method'; 24 | 25 | /** 26 | * Renders the template with the given context and returns it as string. 27 | * 28 | * @param array $context An array of parameters to pass to the template 29 | * 30 | * @return string The rendered template 31 | */ 32 | public function render(array $context); 33 | 34 | /** 35 | * Displays the template with the given context. 36 | * 37 | * @param array $context An array of parameters to pass to the template 38 | * @param array $blocks An array of blocks to pass to the template 39 | */ 40 | public function display(array $context, array $blocks = array()); 41 | 42 | /** 43 | * Returns the bound environment for this template. 44 | * 45 | * @return Twig_Environment 46 | */ 47 | public function getEnvironment(); 48 | } 49 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Test.php: -------------------------------------------------------------------------------- 1 | 18 | * 19 | * @deprecated since 1.12 (to be removed in 2.0) 20 | */ 21 | abstract class Twig_Test implements Twig_TestInterface, Twig_TestCallableInterface 22 | { 23 | protected $options; 24 | protected $arguments = array(); 25 | 26 | public function __construct(array $options = array()) 27 | { 28 | $this->options = array_merge(array( 29 | 'callable' => null, 30 | ), $options); 31 | } 32 | 33 | public function getCallable() 34 | { 35 | return $this->options['callable']; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Test/Function.php: -------------------------------------------------------------------------------- 1 | 18 | * 19 | * @deprecated since 1.12 (to be removed in 2.0) 20 | */ 21 | class Twig_Test_Function extends Twig_Test 22 | { 23 | protected $function; 24 | 25 | public function __construct($function, array $options = array()) 26 | { 27 | $options['callable'] = $function; 28 | 29 | parent::__construct($options); 30 | 31 | $this->function = $function; 32 | } 33 | 34 | public function compile() 35 | { 36 | return $this->function; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Test/Method.php: -------------------------------------------------------------------------------- 1 | 18 | * 19 | * @deprecated since 1.12 (to be removed in 2.0) 20 | */ 21 | class Twig_Test_Method extends Twig_Test 22 | { 23 | protected $extension; 24 | protected $method; 25 | 26 | public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) 27 | { 28 | $options['callable'] = array($extension, $method); 29 | 30 | parent::__construct($options); 31 | 32 | $this->extension = $extension; 33 | $this->method = $method; 34 | } 35 | 36 | public function compile() 37 | { 38 | return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Test/Node.php: -------------------------------------------------------------------------------- 1 | 18 | * 19 | * @deprecated since 1.12 (to be removed in 2.0) 20 | */ 21 | class Twig_Test_Node extends Twig_Test 22 | { 23 | protected $class; 24 | 25 | public function __construct($class, array $options = array()) 26 | { 27 | parent::__construct($options); 28 | 29 | $this->class = $class; 30 | } 31 | 32 | public function getClass() 33 | { 34 | return $this->class; 35 | } 36 | 37 | public function compile() 38 | { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Test/NodeTestCase.php: -------------------------------------------------------------------------------- 1 | assertNodeCompilation($source, $node, $environment, $isPattern); 24 | } 25 | 26 | public function assertNodeCompilation($source, Twig_Node $node, Twig_Environment $environment = null, $isPattern = false) 27 | { 28 | $compiler = $this->getCompiler($environment); 29 | $compiler->compile($node); 30 | 31 | if ($isPattern) { 32 | $this->assertStringMatchesFormat($source, trim($compiler->getSource())); 33 | } else { 34 | $this->assertEquals($source, trim($compiler->getSource())); 35 | } 36 | } 37 | 38 | protected function getCompiler(Twig_Environment $environment = null) 39 | { 40 | return new Twig_Compiler(null === $environment ? $this->getEnvironment() : $environment); 41 | } 42 | 43 | protected function getEnvironment() 44 | { 45 | return new Twig_Environment(new Twig_Loader_Array(array())); 46 | } 47 | 48 | protected function getVariableGetter($name, $line = false) 49 | { 50 | $line = $line > 0 ? "// line {$line}\n" : ''; 51 | 52 | if (PHP_VERSION_ID >= 70000) { 53 | return sprintf('%s($context["%s"] ?? null)', $line, $name, $name); 54 | } 55 | 56 | if (PHP_VERSION_ID >= 50400) { 57 | return sprintf('%s(isset($context["%s"]) ? $context["%s"] : null)', $line, $name, $name); 58 | } 59 | 60 | return sprintf('%s$this->getContext($context, "%s")', $line, $name); 61 | } 62 | 63 | protected function getAttributeGetter() 64 | { 65 | if (function_exists('twig_template_get_attributes')) { 66 | return 'twig_template_get_attributes($this, '; 67 | } 68 | 69 | return '$this->getAttribute('; 70 | } 71 | } 72 | 73 | class_alias('Twig_Test_NodeTestCase', 'Twig\Test\NodeTestCase', false); 74 | class_exists('Twig_Environment'); 75 | class_exists('Twig_Node'); 76 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TestCallableInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * 17 | * @deprecated since 1.12 (to be removed in 2.0) 18 | */ 19 | interface Twig_TestCallableInterface 20 | { 21 | public function getCallable(); 22 | } 23 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TestInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * 17 | * @deprecated since 1.12 (to be removed in 2.0) 18 | */ 19 | interface Twig_TestInterface 20 | { 21 | /** 22 | * Compiles a test. 23 | * 24 | * @return string The PHP code for the test 25 | */ 26 | public function compile(); 27 | } 28 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | abstract class Twig_TokenParser implements Twig_TokenParserInterface 18 | { 19 | /** 20 | * @var Twig_Parser 21 | */ 22 | protected $parser; 23 | 24 | /** 25 | * Sets the parser associated with this token parser. 26 | */ 27 | public function setParser(Twig_Parser $parser) 28 | { 29 | $this->parser = $parser; 30 | } 31 | } 32 | 33 | class_alias('Twig_TokenParser', 'Twig\TokenParser\AbstractTokenParser', false); 34 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Block.php: -------------------------------------------------------------------------------- 1 | 17 | * {% block head %} 18 | * 19 | * {% block title %}{% endblock %} - My Webpage 20 | * {% endblock %} 21 | * 22 | * 23 | * @final 24 | */ 25 | class Twig_TokenParser_Block extends Twig_TokenParser 26 | { 27 | public function parse(Twig_Token $token) 28 | { 29 | $lineno = $token->getLine(); 30 | $stream = $this->parser->getStream(); 31 | $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); 32 | if ($this->parser->hasBlock($name)) { 33 | throw new Twig_Error_Syntax(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext()); 34 | } 35 | $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno)); 36 | $this->parser->pushLocalScope(); 37 | $this->parser->pushBlockStack($name); 38 | 39 | if ($stream->nextIf(Twig_Token::BLOCK_END_TYPE)) { 40 | $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); 41 | if ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) { 42 | $value = $token->getValue(); 43 | 44 | if ($value != $name) { 45 | throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()); 46 | } 47 | } 48 | } else { 49 | $body = new Twig_Node(array( 50 | new Twig_Node_Print($this->parser->getExpressionParser()->parseExpression(), $lineno), 51 | )); 52 | } 53 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 54 | 55 | $block->setNode('body', $body); 56 | $this->parser->popBlockStack(); 57 | $this->parser->popLocalScope(); 58 | 59 | return new Twig_Node_BlockReference($name, $lineno, $this->getTag()); 60 | } 61 | 62 | public function decideBlockEnd(Twig_Token $token) 63 | { 64 | return $token->test('endblock'); 65 | } 66 | 67 | public function getTag() 68 | { 69 | return 'block'; 70 | } 71 | } 72 | 73 | class_alias('Twig_TokenParser_Block', 'Twig\TokenParser\BlockTokenParser', false); 74 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Do.php: -------------------------------------------------------------------------------- 1 | parser->getExpressionParser()->parseExpression(); 22 | 23 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 24 | 25 | return new Twig_Node_Do($expr, $token->getLine(), $this->getTag()); 26 | } 27 | 28 | public function getTag() 29 | { 30 | return 'do'; 31 | } 32 | } 33 | 34 | class_alias('Twig_TokenParser_Do', 'Twig\TokenParser\DoTokenParser', false); 35 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Embed.php: -------------------------------------------------------------------------------- 1 | parser->getStream(); 22 | 23 | $parent = $this->parser->getExpressionParser()->parseExpression(); 24 | 25 | list($variables, $only, $ignoreMissing) = $this->parseArguments(); 26 | 27 | $parentToken = $fakeParentToken = new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine()); 28 | if ($parent instanceof Twig_Node_Expression_Constant) { 29 | $parentToken = new Twig_Token(Twig_Token::STRING_TYPE, $parent->getAttribute('value'), $token->getLine()); 30 | } elseif ($parent instanceof Twig_Node_Expression_Name) { 31 | $parentToken = new Twig_Token(Twig_Token::NAME_TYPE, $parent->getAttribute('name'), $token->getLine()); 32 | } 33 | 34 | // inject a fake parent to make the parent() function work 35 | $stream->injectTokens(array( 36 | new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()), 37 | new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()), 38 | $parentToken, 39 | new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()), 40 | )); 41 | 42 | $module = $this->parser->parse($stream, array($this, 'decideBlockEnd'), true); 43 | 44 | // override the parent with the correct one 45 | if ($fakeParentToken === $parentToken) { 46 | $module->setNode('parent', $parent); 47 | } 48 | 49 | $this->parser->embedTemplate($module); 50 | 51 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 52 | 53 | return new Twig_Node_Embed($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); 54 | } 55 | 56 | public function decideBlockEnd(Twig_Token $token) 57 | { 58 | return $token->test('endembed'); 59 | } 60 | 61 | public function getTag() 62 | { 63 | return 'embed'; 64 | } 65 | } 66 | 67 | class_alias('Twig_TokenParser_Embed', 'Twig\TokenParser\EmbedTokenParser', false); 68 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Extends.php: -------------------------------------------------------------------------------- 1 | 17 | * {% extends "base.html" %} 18 | * 19 | * 20 | * @final 21 | */ 22 | class Twig_TokenParser_Extends extends Twig_TokenParser 23 | { 24 | public function parse(Twig_Token $token) 25 | { 26 | $stream = $this->parser->getStream(); 27 | 28 | if (!$this->parser->isMainScope()) { 29 | throw new Twig_Error_Syntax('Cannot extend from a block.', $token->getLine(), $stream->getSourceContext()); 30 | } 31 | 32 | if (null !== $this->parser->getParent()) { 33 | throw new Twig_Error_Syntax('Multiple extends tags are forbidden.', $token->getLine(), $stream->getSourceContext()); 34 | } 35 | $this->parser->setParent($this->parser->getExpressionParser()->parseExpression()); 36 | 37 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 38 | } 39 | 40 | public function getTag() 41 | { 42 | return 'extends'; 43 | } 44 | } 45 | 46 | class_alias('Twig_TokenParser_Extends', 'Twig\TokenParser\ExtendsTokenParser', false); 47 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Filter.php: -------------------------------------------------------------------------------- 1 | 16 | * {% filter upper %} 17 | * This text becomes uppercase 18 | * {% endfilter %} 19 | * 20 | * 21 | * @final 22 | */ 23 | class Twig_TokenParser_Filter extends Twig_TokenParser 24 | { 25 | public function parse(Twig_Token $token) 26 | { 27 | $name = $this->parser->getVarName(); 28 | $ref = new Twig_Node_Expression_BlockReference(new Twig_Node_Expression_Constant($name, $token->getLine()), null, $token->getLine(), $this->getTag()); 29 | 30 | $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag()); 31 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 32 | 33 | $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); 34 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 35 | 36 | $block = new Twig_Node_Block($name, $body, $token->getLine()); 37 | $this->parser->setBlock($name, $block); 38 | 39 | return new Twig_Node_Print($filter, $token->getLine(), $this->getTag()); 40 | } 41 | 42 | public function decideBlockEnd(Twig_Token $token) 43 | { 44 | return $token->test('endfilter'); 45 | } 46 | 47 | public function getTag() 48 | { 49 | return 'filter'; 50 | } 51 | } 52 | 53 | class_alias('Twig_TokenParser_Filter', 'Twig\TokenParser\FilterTokenParser', false); 54 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Flush.php: -------------------------------------------------------------------------------- 1 | parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 24 | 25 | return new Twig_Node_Flush($token->getLine(), $this->getTag()); 26 | } 27 | 28 | public function getTag() 29 | { 30 | return 'flush'; 31 | } 32 | } 33 | 34 | class_alias('Twig_TokenParser_Flush', 'Twig\TokenParser\FlushTokenParser', false); 35 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/From.php: -------------------------------------------------------------------------------- 1 | 16 | * {% from 'forms.html' import forms %} 17 | * 18 | * 19 | * @final 20 | */ 21 | class Twig_TokenParser_From extends Twig_TokenParser 22 | { 23 | public function parse(Twig_Token $token) 24 | { 25 | $macro = $this->parser->getExpressionParser()->parseExpression(); 26 | $stream = $this->parser->getStream(); 27 | $stream->expect('import'); 28 | 29 | $targets = array(); 30 | do { 31 | $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); 32 | 33 | $alias = $name; 34 | if ($stream->nextIf('as')) { 35 | $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); 36 | } 37 | 38 | $targets[$name] = $alias; 39 | 40 | if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) { 41 | break; 42 | } 43 | } while (true); 44 | 45 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 46 | 47 | $node = new Twig_Node_Import($macro, new Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag()); 48 | 49 | foreach ($targets as $name => $alias) { 50 | if ($this->parser->isReservedMacroName($name)) { 51 | throw new Twig_Error_Syntax(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext()); 52 | } 53 | 54 | $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var')); 55 | } 56 | 57 | return $node; 58 | } 59 | 60 | public function getTag() 61 | { 62 | return 'from'; 63 | } 64 | } 65 | 66 | class_alias('Twig_TokenParser_From', 'Twig\TokenParser\FromTokenParser', false); 67 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Import.php: -------------------------------------------------------------------------------- 1 | 16 | * {% import 'forms.html' as forms %} 17 | * 18 | * 19 | * @final 20 | */ 21 | class Twig_TokenParser_Import extends Twig_TokenParser 22 | { 23 | public function parse(Twig_Token $token) 24 | { 25 | $macro = $this->parser->getExpressionParser()->parseExpression(); 26 | $this->parser->getStream()->expect('as'); 27 | $var = new Twig_Node_Expression_AssignName($this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(), $token->getLine()); 28 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 29 | 30 | $this->parser->addImportedSymbol('template', $var->getAttribute('name')); 31 | 32 | return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag()); 33 | } 34 | 35 | public function getTag() 36 | { 37 | return 'import'; 38 | } 39 | } 40 | 41 | class_alias('Twig_TokenParser_Import', 'Twig\TokenParser\ImportTokenParser', false); 42 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Include.php: -------------------------------------------------------------------------------- 1 | 17 | * {% include 'header.html' %} 18 | * Body 19 | * {% include 'footer.html' %} 20 | * 21 | */ 22 | class Twig_TokenParser_Include extends Twig_TokenParser 23 | { 24 | public function parse(Twig_Token $token) 25 | { 26 | $expr = $this->parser->getExpressionParser()->parseExpression(); 27 | 28 | list($variables, $only, $ignoreMissing) = $this->parseArguments(); 29 | 30 | return new Twig_Node_Include($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); 31 | } 32 | 33 | protected function parseArguments() 34 | { 35 | $stream = $this->parser->getStream(); 36 | 37 | $ignoreMissing = false; 38 | if ($stream->nextIf(Twig_Token::NAME_TYPE, 'ignore')) { 39 | $stream->expect(Twig_Token::NAME_TYPE, 'missing'); 40 | 41 | $ignoreMissing = true; 42 | } 43 | 44 | $variables = null; 45 | if ($stream->nextIf(Twig_Token::NAME_TYPE, 'with')) { 46 | $variables = $this->parser->getExpressionParser()->parseExpression(); 47 | } 48 | 49 | $only = false; 50 | if ($stream->nextIf(Twig_Token::NAME_TYPE, 'only')) { 51 | $only = true; 52 | } 53 | 54 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 55 | 56 | return array($variables, $only, $ignoreMissing); 57 | } 58 | 59 | public function getTag() 60 | { 61 | return 'include'; 62 | } 63 | } 64 | 65 | class_alias('Twig_TokenParser_Include', 'Twig\TokenParser\IncludeTokenParser', false); 66 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Macro.php: -------------------------------------------------------------------------------- 1 | 16 | * {% macro input(name, value, type, size) %} 17 | * 18 | * {% endmacro %} 19 | * 20 | * 21 | * @final 22 | */ 23 | class Twig_TokenParser_Macro extends Twig_TokenParser 24 | { 25 | public function parse(Twig_Token $token) 26 | { 27 | $lineno = $token->getLine(); 28 | $stream = $this->parser->getStream(); 29 | $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); 30 | 31 | $arguments = $this->parser->getExpressionParser()->parseArguments(true, true); 32 | 33 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 34 | $this->parser->pushLocalScope(); 35 | $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); 36 | if ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) { 37 | $value = $token->getValue(); 38 | 39 | if ($value != $name) { 40 | throw new Twig_Error_Syntax(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()); 41 | } 42 | } 43 | $this->parser->popLocalScope(); 44 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 45 | 46 | $this->parser->setMacro($name, new Twig_Node_Macro($name, new Twig_Node_Body(array($body)), $arguments, $lineno, $this->getTag())); 47 | } 48 | 49 | public function decideBlockEnd(Twig_Token $token) 50 | { 51 | return $token->test('endmacro'); 52 | } 53 | 54 | public function getTag() 55 | { 56 | return 'macro'; 57 | } 58 | } 59 | 60 | class_alias('Twig_TokenParser_Macro', 'Twig\TokenParser\MacroTokenParser', false); 61 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Sandbox.php: -------------------------------------------------------------------------------- 1 | 16 | * {% sandbox %} 17 | * {% include 'user.html' %} 18 | * {% endsandbox %} 19 | * 20 | * 21 | * @see https://twig.symfony.com/doc/api.html#sandbox-extension for details 22 | * 23 | * @final 24 | */ 25 | class Twig_TokenParser_Sandbox extends Twig_TokenParser 26 | { 27 | public function parse(Twig_Token $token) 28 | { 29 | $stream = $this->parser->getStream(); 30 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 31 | $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); 32 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 33 | 34 | // in a sandbox tag, only include tags are allowed 35 | if (!$body instanceof Twig_Node_Include) { 36 | foreach ($body as $node) { 37 | if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) { 38 | continue; 39 | } 40 | 41 | if (!$node instanceof Twig_Node_Include) { 42 | throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section.', $node->getTemplateLine(), $stream->getSourceContext()); 43 | } 44 | } 45 | } 46 | 47 | return new Twig_Node_Sandbox($body, $token->getLine(), $this->getTag()); 48 | } 49 | 50 | public function decideBlockEnd(Twig_Token $token) 51 | { 52 | return $token->test('endsandbox'); 53 | } 54 | 55 | public function getTag() 56 | { 57 | return 'sandbox'; 58 | } 59 | } 60 | 61 | class_alias('Twig_TokenParser_Sandbox', 'Twig\TokenParser\SandboxTokenParser', false); 62 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Set.php: -------------------------------------------------------------------------------- 1 | 16 | * {% set foo = 'foo' %} 17 | * 18 | * {% set foo = [1, 2] %} 19 | * 20 | * {% set foo = {'foo': 'bar'} %} 21 | * 22 | * {% set foo = 'foo' ~ 'bar' %} 23 | * 24 | * {% set foo, bar = 'foo', 'bar' %} 25 | * 26 | * {% set foo %}Some content{% endset %} 27 | * 28 | * 29 | * @final 30 | */ 31 | class Twig_TokenParser_Set extends Twig_TokenParser 32 | { 33 | public function parse(Twig_Token $token) 34 | { 35 | $lineno = $token->getLine(); 36 | $stream = $this->parser->getStream(); 37 | $names = $this->parser->getExpressionParser()->parseAssignmentExpression(); 38 | 39 | $capture = false; 40 | if ($stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) { 41 | $values = $this->parser->getExpressionParser()->parseMultitargetExpression(); 42 | 43 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 44 | 45 | if (count($names) !== count($values)) { 46 | throw new Twig_Error_Syntax('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); 47 | } 48 | } else { 49 | $capture = true; 50 | 51 | if (count($names) > 1) { 52 | throw new Twig_Error_Syntax('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); 53 | } 54 | 55 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 56 | 57 | $values = $this->parser->subparse(array($this, 'decideBlockEnd'), true); 58 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 59 | } 60 | 61 | return new Twig_Node_Set($capture, $names, $values, $lineno, $this->getTag()); 62 | } 63 | 64 | public function decideBlockEnd(Twig_Token $token) 65 | { 66 | return $token->test('endset'); 67 | } 68 | 69 | public function getTag() 70 | { 71 | return 'set'; 72 | } 73 | } 74 | 75 | class_alias('Twig_TokenParser_Set', 'Twig\TokenParser\SetTokenParser', false); 76 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Spaceless.php: -------------------------------------------------------------------------------- 1 | 16 | * {% spaceless %} 17 | *
18 | * foo 19 | *
20 | * {% endspaceless %} 21 | * 22 | * {# output will be
foo
#} 23 | * 24 | * 25 | * @final 26 | */ 27 | class Twig_TokenParser_Spaceless extends Twig_TokenParser 28 | { 29 | public function parse(Twig_Token $token) 30 | { 31 | $lineno = $token->getLine(); 32 | 33 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 34 | $body = $this->parser->subparse(array($this, 'decideSpacelessEnd'), true); 35 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 36 | 37 | return new Twig_Node_Spaceless($body, $lineno, $this->getTag()); 38 | } 39 | 40 | public function decideSpacelessEnd(Twig_Token $token) 41 | { 42 | return $token->test('endspaceless'); 43 | } 44 | 45 | public function getTag() 46 | { 47 | return 'spaceless'; 48 | } 49 | } 50 | 51 | class_alias('Twig_TokenParser_Spaceless', 'Twig\TokenParser\SpacelessTokenParser', false); 52 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/Use.php: -------------------------------------------------------------------------------- 1 | 16 | * {% extends "base.html" %} 17 | * 18 | * {% use "blocks.html" %} 19 | * 20 | * {% block title %}{% endblock %} 21 | * {% block content %}{% endblock %} 22 | * 23 | * 24 | * @see https://twig.symfony.com/doc/templates.html#horizontal-reuse for details. 25 | * 26 | * @final 27 | */ 28 | class Twig_TokenParser_Use extends Twig_TokenParser 29 | { 30 | public function parse(Twig_Token $token) 31 | { 32 | $template = $this->parser->getExpressionParser()->parseExpression(); 33 | $stream = $this->parser->getStream(); 34 | 35 | if (!$template instanceof Twig_Node_Expression_Constant) { 36 | throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); 37 | } 38 | 39 | $targets = array(); 40 | if ($stream->nextIf('with')) { 41 | do { 42 | $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); 43 | 44 | $alias = $name; 45 | if ($stream->nextIf('as')) { 46 | $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); 47 | } 48 | 49 | $targets[$name] = new Twig_Node_Expression_Constant($alias, -1); 50 | 51 | if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) { 52 | break; 53 | } 54 | } while (true); 55 | } 56 | 57 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 58 | 59 | $this->parser->addTrait(new Twig_Node(array('template' => $template, 'targets' => new Twig_Node($targets)))); 60 | 61 | return new Twig_Node(); 62 | } 63 | 64 | public function getTag() 65 | { 66 | return 'use'; 67 | } 68 | } 69 | 70 | class_alias('Twig_TokenParser_Use', 'Twig\TokenParser\UseTokenParser', false); 71 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParser/With.php: -------------------------------------------------------------------------------- 1 | 16 | * 17 | * @final 18 | */ 19 | class Twig_TokenParser_With extends Twig_TokenParser 20 | { 21 | public function parse(Twig_Token $token) 22 | { 23 | $stream = $this->parser->getStream(); 24 | 25 | $variables = null; 26 | $only = false; 27 | if (!$stream->test(Twig_Token::BLOCK_END_TYPE)) { 28 | $variables = $this->parser->getExpressionParser()->parseExpression(); 29 | $only = $stream->nextIf(Twig_Token::NAME_TYPE, 'only'); 30 | } 31 | 32 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 33 | 34 | $body = $this->parser->subparse(array($this, 'decideWithEnd'), true); 35 | 36 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 37 | 38 | return new Twig_Node_With($body, $variables, $only, $token->getLine(), $this->getTag()); 39 | } 40 | 41 | public function decideWithEnd(Twig_Token $token) 42 | { 43 | return $token->test('endwith'); 44 | } 45 | 46 | public function getTag() 47 | { 48 | return 'with'; 49 | } 50 | } 51 | 52 | class_alias('Twig_TokenParser_With', 'Twig\TokenParser\WithTokenParser', false); 53 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParserBrokerInterface.php: -------------------------------------------------------------------------------- 1 | 19 | * 20 | * @deprecated since 1.12 (to be removed in 2.0) 21 | */ 22 | interface Twig_TokenParserBrokerInterface 23 | { 24 | /** 25 | * Gets a TokenParser suitable for a tag. 26 | * 27 | * @param string $tag A tag name 28 | * 29 | * @return Twig_TokenParserInterface|null A Twig_TokenParserInterface or null if no suitable TokenParser was found 30 | */ 31 | public function getTokenParser($tag); 32 | 33 | /** 34 | * Calls Twig_TokenParserInterface::setParser on all parsers the implementation knows of. 35 | */ 36 | public function setParser(Twig_ParserInterface $parser); 37 | 38 | /** 39 | * Gets the Twig_ParserInterface. 40 | * 41 | * @return null|Twig_ParserInterface A Twig_ParserInterface instance or null 42 | */ 43 | public function getParser(); 44 | } 45 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/TokenParserInterface.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | interface Twig_TokenParserInterface 18 | { 19 | /** 20 | * Sets the parser associated with this token parser. 21 | */ 22 | public function setParser(Twig_Parser $parser); 23 | 24 | /** 25 | * Parses a token and returns a node. 26 | * 27 | * @return Twig_NodeInterface 28 | * 29 | * @throws Twig_Error_Syntax 30 | */ 31 | public function parse(Twig_Token $token); 32 | 33 | /** 34 | * Gets the tag name associated with this token parser. 35 | * 36 | * @return string The tag name 37 | */ 38 | public function getTag(); 39 | } 40 | 41 | class_alias('Twig_TokenParserInterface', 'Twig\TokenParser\TokenParserInterface', false); 42 | class_exists('Twig_Parser'); 43 | class_exists('Twig_Token'); 44 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Util/DeprecationCollector.php: -------------------------------------------------------------------------------- 1 | 14 | * 15 | * @final 16 | */ 17 | class Twig_Util_DeprecationCollector 18 | { 19 | private $twig; 20 | private $deprecations; 21 | 22 | public function __construct(Twig_Environment $twig) 23 | { 24 | $this->twig = $twig; 25 | } 26 | 27 | /** 28 | * Returns deprecations for templates contained in a directory. 29 | * 30 | * @param string $dir A directory where templates are stored 31 | * @param string $ext Limit the loaded templates by extension 32 | * 33 | * @return array An array of deprecations 34 | */ 35 | public function collectDir($dir, $ext = '.twig') 36 | { 37 | $iterator = new RegexIterator( 38 | new RecursiveIteratorIterator( 39 | new RecursiveDirectoryIterator($dir), RecursiveIteratorIterator::LEAVES_ONLY 40 | ), '{'.preg_quote($ext).'$}' 41 | ); 42 | 43 | return $this->collect(new Twig_Util_TemplateDirIterator($iterator)); 44 | } 45 | 46 | /** 47 | * Returns deprecations for passed templates. 48 | * 49 | * @param Traversable $iterator An iterator of templates (where keys are template names and values the contents of the template) 50 | * 51 | * @return array An array of deprecations 52 | */ 53 | public function collect(Traversable $iterator) 54 | { 55 | $this->deprecations = array(); 56 | 57 | set_error_handler(array($this, 'errorHandler')); 58 | 59 | foreach ($iterator as $name => $contents) { 60 | try { 61 | $this->twig->parse($this->twig->tokenize(new Twig_Source($contents, $name))); 62 | } catch (Twig_Error_Syntax $e) { 63 | // ignore templates containing syntax errors 64 | } 65 | } 66 | 67 | restore_error_handler(); 68 | 69 | $deprecations = $this->deprecations; 70 | $this->deprecations = array(); 71 | 72 | return $deprecations; 73 | } 74 | 75 | /** 76 | * @internal 77 | */ 78 | public function errorHandler($type, $msg) 79 | { 80 | if (E_USER_DEPRECATED === $type) { 81 | $this->deprecations[] = $msg; 82 | } 83 | } 84 | } 85 | 86 | class_alias('Twig_Util_DeprecationCollector', 'Twig\Util\DeprecationCollector', false); 87 | -------------------------------------------------------------------------------- /lib/Twig/lib/Twig/Util/TemplateDirIterator.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | class Twig_Util_TemplateDirIterator extends IteratorIterator 16 | { 17 | public function current() 18 | { 19 | return file_get_contents(parent::current()); 20 | } 21 | 22 | public function key() 23 | { 24 | return (string) parent::key(); 25 | } 26 | } 27 | 28 | class_alias('Twig_Util_TemplateDirIterator', 'Twig\Util\TemplateDirIterator', false); 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twig", 3 | "description": "Kirby Twig Plugin", 4 | "author": "Florens Verschelde ", 5 | "license": "MIT", 6 | "type": "kirby-plugin", 7 | "version": "3.0.1" 8 | } 9 | -------------------------------------------------------------------------------- /src/Plugin.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class Plugin 17 | { 18 | /** @var bool - flag to make sure we only register once */ 19 | static private $registered = false; 20 | 21 | /** 22 | * Register the template component and load the `twig` helper function 23 | * @return bool 24 | * @throws Exception 25 | */ 26 | static public function register() 27 | { 28 | // only register once 29 | if (static::$registered === true) { 30 | return true; 31 | } 32 | $kirby = kirby(); 33 | if (!class_exists('Kirby\Component\Template')) { 34 | throw new Exception('The Kirby Twig plugin requires Kirby 2.3 or higher. Current version: ' . $kirby->version()); 35 | } 36 | if (!class_exists('Twig_Environment')) { 37 | require_once __DIR__.'/../lib/Twig/lib/Twig/Autoloader.php'; 38 | \Twig_Autoloader::register(); 39 | } 40 | $kirby->set('component', 'template', 'Kirby\Twig\TwigComponent'); 41 | if (is_executable('twig') === false) { 42 | require_once __DIR__ . '/helpers.php'; 43 | } 44 | return static::$registered = true; 45 | } 46 | 47 | /** 48 | * Renders a Twig template string or template file 49 | * Can be used in Kirby controllers and PHP templates 50 | * 51 | * * Example usage: 52 | * 53 | * 'World']) ?> 54 | * 'Home page']) ?> 55 | * 56 | * Note: in Twig templates, you should use the `include` tag or function instead. 57 | * 58 | * @param string $template - path or template string to render 59 | * @param array $userData - data to pass as variables to the template 60 | * @return string 61 | */ 62 | static public function render($template, $userData) 63 | { 64 | if (!is_string($template)) return ''; 65 | $path = strlen($template) <= 256 ? trim($template) : ''; 66 | $data = array_merge(Tpl::$data, is_array($userData) ? $userData : []); 67 | $twig = TwigEnv::instance(); 68 | 69 | // treat template as a path only if it *looks like* a Twig template path 70 | if (Str::startsWith($path, '@') || Str::endsWith(strtolower($path), '.twig')) { 71 | return $twig->renderPath($path, $data); 72 | } 73 | return $twig->renderString($template, $data); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/TwigComponent.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class TwigComponent extends Template 23 | { 24 | /** 25 | * Returns a template file path by name 26 | * @param string $name 27 | * @return string 28 | */ 29 | public function file($name) 30 | { 31 | $usephp = c::get('twig.usephp', true); 32 | $base = str_replace('\\', '/', $this->kirby->roots()->templates().'/'.$name); 33 | $twig = $base . '.twig'; 34 | $php = $base . '.php'; 35 | 36 | // only check existing files if PHP template support is active 37 | if ($usephp and !is_file($twig) and is_file($php)) { 38 | return $php; 39 | } else { 40 | return $twig; 41 | } 42 | } 43 | 44 | /** 45 | * Renders the template by page with the additional data 46 | * @param Page|string $template 47 | * @param array $data 48 | * @param boolean $return 49 | * @return string 50 | * @throws Exception 51 | */ 52 | public function render($template, $data = [], $return = true) 53 | { 54 | if ($template instanceof Page) { 55 | $page = $template; 56 | $file = $page->templateFile(); 57 | $data = $this->data($page, $data); 58 | } else { 59 | $file = $template; 60 | $data = $this->data(null, $data); 61 | } 62 | 63 | // check for an existing template 64 | if (!file_exists($file)) { 65 | throw new Exception('The template could not be found'); 66 | } 67 | 68 | // merge and register the template data globally 69 | $startData = Tpl::$data; 70 | Tpl::$data = array_merge(Tpl::$data, $data); 71 | 72 | // load the template 73 | if (pathinfo($file, PATHINFO_EXTENSION) === 'twig') { 74 | $twig = TwigEnv::instance(); 75 | $result = $twig->renderPath($file, Tpl::$data, $return, true); 76 | } else { 77 | $result = Tpl::load($file, [], $return); 78 | } 79 | 80 | // reset the template data 81 | Tpl::$data = $startData; 82 | 83 | return $result; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/helpers.php: -------------------------------------------------------------------------------- 1 | 8 | * @param string $template 9 | * @param array $userData 10 | * @return string 11 | */ 12 | function twig($template='', $userData=[]) 13 | { 14 | return Kirby\Twig\Plugin::render($template, $userData); 15 | } 16 | -------------------------------------------------------------------------------- /twig.php: -------------------------------------------------------------------------------- 1 | __DIR__.'/src/Plugin.php', 10 | 'kirby\twig\twigcomponent' => __DIR__.'/src/TwigComponent.php', 11 | 'kirby\twig\twigenv' => __DIR__.'/src/TwigEnv.php' 12 | ]); 13 | 14 | Kirby\Twig\Plugin::register(); 15 | --------------------------------------------------------------------------------