Michael Foster
11 years ago
133 changed files with 5041 additions and 1347 deletions
@ -0,0 +1,28 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2009 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Adds an exists() method for loaders. |
|||
* |
|||
* @author Florin Patan <florinpatan@gmail.com> |
|||
* @deprecated since 1.12 (to be removed in 2.0) |
|||
*/ |
|||
interface Twig_ExistsLoaderInterface |
|||
{ |
|||
/** |
|||
* Check if we have the source code of a template, given its name. |
|||
* |
|||
* @param string $name The name of the template to check if we can load |
|||
* |
|||
* @return boolean If the template source code is handled by this loader or not |
|||
*/ |
|||
public function exists($name); |
|||
} |
File diff suppressed because it is too large
@ -0,0 +1,71 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
class Twig_Extension_Debug extends Twig_Extension |
|||
{ |
|||
/** |
|||
* Returns a list of global functions to add to the existing list. |
|||
* |
|||
* @return array An array of global functions |
|||
*/ |
|||
public function getFunctions() |
|||
{ |
|||
// dump is safe if var_dump is overridden by xdebug |
|||
$isDumpOutputHtmlSafe = extension_loaded('xdebug') |
|||
// false means that it was not set (and the default is on) or it explicitly enabled |
|||
&& (false === ini_get('xdebug.overload_var_dump') || ini_get('xdebug.overload_var_dump')) |
|||
// false means that it was not set (and the default is on) or it explicitly enabled |
|||
// xdebug.overload_var_dump produces HTML only when html_errors is also enabled |
|||
&& (false === ini_get('html_errors') || ini_get('html_errors')) |
|||
|| 'cli' === php_sapi_name() |
|||
; |
|||
|
|||
return array( |
|||
new Twig_SimpleFunction('dump', 'twig_var_dump', array('is_safe' => $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true, 'needs_environment' => true)), |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* Returns the name of the extension. |
|||
* |
|||
* @return string The extension name |
|||
*/ |
|||
public function getName() |
|||
{ |
|||
return 'debug'; |
|||
} |
|||
} |
|||
|
|||
function twig_var_dump(Twig_Environment $env, $context) |
|||
{ |
|||
if (!$env->isDebug()) { |
|||
return; |
|||
} |
|||
|
|||
ob_start(); |
|||
|
|||
$count = func_num_args(); |
|||
if (2 === $count) { |
|||
$vars = array(); |
|||
foreach ($context as $key => $value) { |
|||
if (!$value instanceof Twig_Template) { |
|||
$vars[$key] = $value; |
|||
} |
|||
} |
|||
|
|||
var_dump($vars); |
|||
} else { |
|||
for ($i = 2; $i < $count; $i++) { |
|||
var_dump(func_get_arg($i)); |
|||
} |
|||
} |
|||
|
|||
return ob_get_clean(); |
|||
} |
@ -0,0 +1,113 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2012 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Internal class. |
|||
* |
|||
* This class is used by Twig_Environment as a staging area and must not be used directly. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Extension_Staging extends Twig_Extension |
|||
{ |
|||
protected $functions = array(); |
|||
protected $filters = array(); |
|||
protected $visitors = array(); |
|||
protected $tokenParsers = array(); |
|||
protected $globals = array(); |
|||
protected $tests = array(); |
|||
|
|||
public function addFunction($name, $function) |
|||
{ |
|||
$this->functions[$name] = $function; |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function getFunctions() |
|||
{ |
|||
return $this->functions; |
|||
} |
|||
|
|||
public function addFilter($name, $filter) |
|||
{ |
|||
$this->filters[$name] = $filter; |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function getFilters() |
|||
{ |
|||
return $this->filters; |
|||
} |
|||
|
|||
public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) |
|||
{ |
|||
$this->visitors[] = $visitor; |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function getNodeVisitors() |
|||
{ |
|||
return $this->visitors; |
|||
} |
|||
|
|||
public function addTokenParser(Twig_TokenParserInterface $parser) |
|||
{ |
|||
$this->tokenParsers[] = $parser; |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function getTokenParsers() |
|||
{ |
|||
return $this->tokenParsers; |
|||
} |
|||
|
|||
public function addGlobal($name, $value) |
|||
{ |
|||
$this->globals[$name] = $value; |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function getGlobals() |
|||
{ |
|||
return $this->globals; |
|||
} |
|||
|
|||
public function addTest($name, $test) |
|||
{ |
|||
$this->tests[$name] = $test; |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function getTests() |
|||
{ |
|||
return $this->tests; |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function getName() |
|||
{ |
|||
return 'staging'; |
|||
} |
|||
} |
@ -0,0 +1,64 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2012 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
class Twig_Extension_StringLoader extends Twig_Extension |
|||
{ |
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function getFunctions() |
|||
{ |
|||
return array( |
|||
new Twig_SimpleFunction('template_from_string', 'twig_template_from_string', array('needs_environment' => true)), |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* {@inheritdoc} |
|||
*/ |
|||
public function getName() |
|||
{ |
|||
return 'string_loader'; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Loads a template from a string. |
|||
* |
|||
* <pre> |
|||
* {{ include(template_from_string("Hello {{ name }}")) }} |
|||
* </pre> |
|||
* |
|||
* @param Twig_Environment $env A Twig_Environment instance |
|||
* @param string $template A template as a string |
|||
* |
|||
* @return Twig_Template A Twig_Template instance |
|||
*/ |
|||
function twig_template_from_string(Twig_Environment $env, $template) |
|||
{ |
|||
static $loader; |
|||
|
|||
if (null === $loader) { |
|||
$loader = new Twig_Loader_String(); |
|||
} |
|||
|
|||
$current = $env->getLoader(); |
|||
$env->setLoader($loader); |
|||
try { |
|||
$template = $env->loadTemplate($template); |
|||
} catch (Exception $e) { |
|||
$env->setLoader($current); |
|||
|
|||
throw $e; |
|||
} |
|||
$env->setLoader($current); |
|||
|
|||
return $template; |
|||
} |
@ -0,0 +1,39 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Represents a template filter as a node. |
|||
* |
|||
* Use Twig_SimpleFilter instead. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
* @deprecated since 1.12 (to be removed in 2.0) |
|||
*/ |
|||
class Twig_Filter_Node extends Twig_Filter |
|||
{ |
|||
protected $class; |
|||
|
|||
public function __construct($class, array $options = array()) |
|||
{ |
|||
parent::__construct($options); |
|||
|
|||
$this->class = $class; |
|||
} |
|||
|
|||
public function getClass() |
|||
{ |
|||
return $this->class; |
|||
} |
|||
|
|||
public function compile() |
|||
{ |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2012 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Represents a callable template filter. |
|||
* |
|||
* Use Twig_SimpleFilter instead. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
* @deprecated since 1.12 (to be removed in 2.0) |
|||
*/ |
|||
interface Twig_FilterCallableInterface |
|||
{ |
|||
public function getCallable(); |
|||
} |
@ -0,0 +1,39 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Represents a template function as a node. |
|||
* |
|||
* Use Twig_SimpleFunction instead. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
* @deprecated since 1.12 (to be removed in 2.0) |
|||
*/ |
|||
class Twig_Function_Node extends Twig_Function |
|||
{ |
|||
protected $class; |
|||
|
|||
public function __construct($class, array $options = array()) |
|||
{ |
|||
parent::__construct($options); |
|||
|
|||
$this->class = $class; |
|||
} |
|||
|
|||
public function getClass() |
|||
{ |
|||
return $this->class; |
|||
} |
|||
|
|||
public function compile() |
|||
{ |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2012 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Represents a callable template function. |
|||
* |
|||
* Use Twig_SimpleFunction instead. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
* @deprecated since 1.12 (to be removed in 2.0) |
|||
*/ |
|||
interface Twig_FunctionCallableInterface |
|||
{ |
|||
public function getCallable(); |
|||
} |
@ -0,0 +1,19 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Represents a body node. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Body extends Twig_Node |
|||
{ |
|||
} |
@ -0,0 +1,38 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Represents a do node. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Do extends Twig_Node |
|||
{ |
|||
public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null) |
|||
{ |
|||
parent::__construct(array('expr' => $expr), array(), $lineno, $tag); |
|||
} |
|||
|
|||
/** |
|||
* Compiles the node to PHP. |
|||
* |
|||
* @param Twig_Compiler A Twig_Compiler instance |
|||
*/ |
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler |
|||
->addDebugInfo($this) |
|||
->write('') |
|||
->subcompile($this->getNode('expr')) |
|||
->raw(";\n") |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,38 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2012 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Represents an embed node. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Embed extends Twig_Node_Include |
|||
{ |
|||
// we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module) |
|||
public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) |
|||
{ |
|||
parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag); |
|||
|
|||
$this->setAttribute('filename', $filename); |
|||
$this->setAttribute('index', $index); |
|||
} |
|||
|
|||
protected function addGetTemplate(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler |
|||
->write("\$this->env->loadTemplate(") |
|||
->string($this->getAttribute('filename')) |
|||
->raw(', ') |
|||
->string($this->getAttribute('index')) |
|||
->raw(")") |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,178 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2012 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
abstract class Twig_Node_Expression_Call extends Twig_Node_Expression |
|||
{ |
|||
protected function compileCallable(Twig_Compiler $compiler) |
|||
{ |
|||
$callable = $this->getAttribute('callable'); |
|||
|
|||
$closingParenthesis = false; |
|||
if ($callable) { |
|||
if (is_string($callable)) { |
|||
$compiler->raw($callable); |
|||
} elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) { |
|||
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', $callable[0]->getName(), $callable[1])); |
|||
} else { |
|||
$type = ucfirst($this->getAttribute('type')); |
|||
$compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name'))); |
|||
$closingParenthesis = true; |
|||
} |
|||
} else { |
|||
$compiler->raw($this->getAttribute('thing')->compile()); |
|||
} |
|||
|
|||
$this->compileArguments($compiler); |
|||
|
|||
if ($closingParenthesis) { |
|||
$compiler->raw(')'); |
|||
} |
|||
} |
|||
|
|||
protected function compileArguments(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler->raw('('); |
|||
|
|||
$first = true; |
|||
|
|||
if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) { |
|||
$compiler->raw('$this->env'); |
|||
$first = false; |
|||
} |
|||
|
|||
if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) { |
|||
if (!$first) { |
|||
$compiler->raw(', '); |
|||
} |
|||
$compiler->raw('$context'); |
|||
$first = false; |
|||
} |
|||
|
|||
if ($this->hasAttribute('arguments')) { |
|||
foreach ($this->getAttribute('arguments') as $argument) { |
|||
if (!$first) { |
|||
$compiler->raw(', '); |
|||
} |
|||
$compiler->string($argument); |
|||
$first = false; |
|||
} |
|||
} |
|||
|
|||
if ($this->hasNode('node')) { |
|||
if (!$first) { |
|||
$compiler->raw(', '); |
|||
} |
|||
$compiler->subcompile($this->getNode('node')); |
|||
$first = false; |
|||
} |
|||
|
|||
if ($this->hasNode('arguments') && null !== $this->getNode('arguments')) { |
|||
$callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null; |
|||
|
|||
$arguments = $this->getArguments($callable, $this->getNode('arguments')); |
|||
|
|||
foreach ($arguments as $node) { |
|||
if (!$first) { |
|||
$compiler->raw(', '); |
|||
} |
|||
$compiler->subcompile($node); |
|||
$first = false; |
|||
} |
|||
} |
|||
|
|||
$compiler->raw(')'); |
|||
} |
|||
|
|||
protected function getArguments($callable, $arguments) |
|||
{ |
|||
$parameters = array(); |
|||
$named = false; |
|||
foreach ($arguments as $name => $node) { |
|||
if (!is_int($name)) { |
|||
$named = true; |
|||
$name = $this->normalizeName($name); |
|||
} elseif ($named) { |
|||
throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name'))); |
|||
} |
|||
|
|||
$parameters[$name] = $node; |
|||
} |
|||
|
|||
if (!$named) { |
|||
return $parameters; |
|||
} |
|||
|
|||
if (!$callable) { |
|||
throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name'))); |
|||
} |
|||
|
|||
// manage named arguments |
|||
if (is_array($callable)) { |
|||
$r = new ReflectionMethod($callable[0], $callable[1]); |
|||
} elseif (is_object($callable) && !$callable instanceof Closure) { |
|||
$r = new ReflectionObject($callable); |
|||
$r = $r->getMethod('__invoke'); |
|||
} else { |
|||
$r = new ReflectionFunction($callable); |
|||
} |
|||
|
|||
$definition = $r->getParameters(); |
|||
if ($this->hasNode('node')) { |
|||
array_shift($definition); |
|||
} |
|||
if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) { |
|||
array_shift($definition); |
|||
} |
|||
if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) { |
|||
array_shift($definition); |
|||
} |
|||
if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) { |
|||
foreach ($this->getAttribute('arguments') as $argument) { |
|||
array_shift($definition); |
|||
} |
|||
} |
|||
|
|||
$arguments = array(); |
|||
$pos = 0; |
|||
foreach ($definition as $param) { |
|||
$name = $this->normalizeName($param->name); |
|||
|
|||
if (array_key_exists($name, $parameters)) { |
|||
if (array_key_exists($pos, $parameters)) { |
|||
throw new Twig_Error_Syntax(sprintf('Arguments "%s" is defined twice for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name'))); |
|||
} |
|||
|
|||
$arguments[] = $parameters[$name]; |
|||
unset($parameters[$name]); |
|||
} elseif (array_key_exists($pos, $parameters)) { |
|||
$arguments[] = $parameters[$pos]; |
|||
unset($parameters[$pos]); |
|||
++$pos; |
|||
} elseif ($param->isDefaultValueAvailable()) { |
|||
$arguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1); |
|||
} elseif ($param->isOptional()) { |
|||
break; |
|||
} else { |
|||
throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name'))); |
|||
} |
|||
} |
|||
|
|||
foreach (array_keys($parameters) as $name) { |
|||
throw new Twig_Error_Syntax(sprintf('Unknown argument "%s" for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name'))); |
|||
} |
|||
|
|||
return $arguments; |
|||
} |
|||
|
|||
protected function normalizeName($name) |
|||
{ |
|||
return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $name)); |
|||
} |
|||
} |
@ -0,0 +1,43 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Returns the value or the default value when it is undefined or empty. |
|||
* |
|||
* <pre> |
|||
* {{ var.foo|default('foo item on var is not defined') }} |
|||
* </pre> |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter |
|||
{ |
|||
public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) |
|||
{ |
|||
$default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getLine()), $arguments, $node->getLine()); |
|||
|
|||
if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) { |
|||
$test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getLine()); |
|||
$false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getLine()); |
|||
|
|||
$node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getLine()); |
|||
} else { |
|||
$node = $default; |
|||
} |
|||
|
|||
parent::__construct($node, $filterName, $arguments, $lineno, $tag); |
|||
} |
|||
|
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler->subcompile($this->getNode('node')); |
|||
} |
|||
} |
@ -0,0 +1,41 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2012 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
class Twig_Node_Expression_MethodCall extends Twig_Node_Expression |
|||
{ |
|||
public function __construct(Twig_Node_Expression $node, $method, Twig_Node_Expression_Array $arguments, $lineno) |
|||
{ |
|||
parent::__construct(array('node' => $node, 'arguments' => $arguments), array('method' => $method, 'safe' => false), $lineno); |
|||
|
|||
if ($node instanceof Twig_Node_Expression_Name) { |
|||
$node->setAttribute('always_defined', true); |
|||
} |
|||
} |
|||
|
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler |
|||
->subcompile($this->getNode('node')) |
|||
->raw('->') |
|||
->raw($this->getAttribute('method')) |
|||
->raw('(') |
|||
; |
|||
$first = true; |
|||
foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) { |
|||
if (!$first) { |
|||
$compiler->raw(', '); |
|||
} |
|||
$first = false; |
|||
|
|||
$compiler->subcompile($pair['value']); |
|||
} |
|||
$compiler->raw(')'); |
|||
} |
|||
} |
@ -0,0 +1,26 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
class Twig_Node_Expression_TempName extends Twig_Node_Expression |
|||
{ |
|||
public function __construct($name, $lineno) |
|||
{ |
|||
parent::__construct(array(), array('name' => $name), $lineno); |
|||
} |
|||
|
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler |
|||
->raw('$_') |
|||
->raw($this->getAttribute('name')) |
|||
->raw('_') |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,46 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Checks if a variable is the exact same value as a constant. |
|||
* |
|||
* <pre> |
|||
* {% if post.status is constant('Post::PUBLISHED') %} |
|||
* the status attribute is exactly the same as Post::PUBLISHED |
|||
* {% endif %} |
|||
* </pre> |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Expression_Test_Constant extends Twig_Node_Expression_Test |
|||
{ |
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler |
|||
->raw('(') |
|||
->subcompile($this->getNode('node')) |
|||
->raw(' === constant(') |
|||
; |
|||
|
|||
if ($this->getNode('arguments')->hasNode(1)) { |
|||
$compiler |
|||
->raw('get_class(') |
|||
->subcompile($this->getNode('arguments')->getNode(1)) |
|||
->raw(')."::".') |
|||
; |
|||
} |
|||
|
|||
$compiler |
|||
->subcompile($this->getNode('arguments')->getNode(0)) |
|||
->raw('))') |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,54 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Checks if a variable is defined in the current context. |
|||
* |
|||
* <pre> |
|||
* {# defined works with variable names and variable attributes #} |
|||
* {% if foo is defined %} |
|||
* {# ... #} |
|||
* {% endif %} |
|||
* </pre> |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test |
|||
{ |
|||
public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno) |
|||
{ |
|||
parent::__construct($node, $name, $arguments, $lineno); |
|||
|
|||
if ($node instanceof Twig_Node_Expression_Name) { |
|||
$node->setAttribute('is_defined_test', true); |
|||
} elseif ($node instanceof Twig_Node_Expression_GetAttr) { |
|||
$node->setAttribute('is_defined_test', true); |
|||
|
|||
$this->changeIgnoreStrictCheck($node); |
|||
} else { |
|||
throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine()); |
|||
} |
|||
} |
|||
|
|||
protected function changeIgnoreStrictCheck(Twig_Node_Expression_GetAttr $node) |
|||
{ |
|||
$node->setAttribute('ignore_strict_check', true); |
|||
|
|||
if ($node->getNode('node') instanceof Twig_Node_Expression_GetAttr) { |
|||
$this->changeIgnoreStrictCheck($node->getNode('node')); |
|||
} |
|||
} |
|||
|
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler->subcompile($this->getNode('node')); |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Checks if a variable is divisible by a number. |
|||
* |
|||
* <pre> |
|||
* {% if loop.index is divisibleby(3) %} |
|||
* </pre> |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Expression_Test_Divisibleby extends Twig_Node_Expression_Test |
|||
{ |
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler |
|||
->raw('(0 == ') |
|||
->subcompile($this->getNode('node')) |
|||
->raw(' % ') |
|||
->subcompile($this->getNode('arguments')->getNode(0)) |
|||
->raw(')') |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Checks if a number is even. |
|||
* |
|||
* <pre> |
|||
* {{ var is even }} |
|||
* </pre> |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Expression_Test_Even extends Twig_Node_Expression_Test |
|||
{ |
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler |
|||
->raw('(') |
|||
->subcompile($this->getNode('node')) |
|||
->raw(' % 2 == 0') |
|||
->raw(')') |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Checks that a variable is null. |
|||
* |
|||
* <pre> |
|||
* {{ var is none }} |
|||
* </pre> |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Expression_Test_Null extends Twig_Node_Expression_Test |
|||
{ |
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler |
|||
->raw('(null === ') |
|||
->subcompile($this->getNode('node')) |
|||
->raw(')') |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Checks if a number is odd. |
|||
* |
|||
* <pre> |
|||
* {{ var is odd }} |
|||
* </pre> |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test |
|||
{ |
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler |
|||
->raw('(') |
|||
->subcompile($this->getNode('node')) |
|||
->raw(' % 2 == 1') |
|||
->raw(')') |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,29 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Checks if a variable is the same as another one (=== in PHP). |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Expression_Test_Sameas extends Twig_Node_Expression_Test |
|||
{ |
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler |
|||
->raw('(') |
|||
->subcompile($this->getNode('node')) |
|||
->raw(' === ') |
|||
->subcompile($this->getNode('arguments')->getNode(0)) |
|||
->raw(')') |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,36 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Represents a flush node. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_Flush extends Twig_Node |
|||
{ |
|||
public function __construct($lineno, $tag) |
|||
{ |
|||
parent::__construct(array(), array(), $lineno, $tag); |
|||
} |
|||
|
|||
/** |
|||
* Compiles the node to PHP. |
|||
* |
|||
* @param Twig_Compiler A Twig_Compiler instance |
|||
*/ |
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$compiler |
|||
->addDebugInfo($this) |
|||
->write("flush();\n") |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,55 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Internal node used by the for node. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_Node_ForLoop extends Twig_Node |
|||
{ |
|||
public function __construct($lineno, $tag = null) |
|||
{ |
|||
parent::__construct(array(), array('with_loop' => false, 'ifexpr' => false, 'else' => false), $lineno, $tag); |
|||
} |
|||
|
|||
/** |
|||
* Compiles the node to PHP. |
|||
* |
|||
* @param Twig_Compiler A Twig_Compiler instance |
|||
*/ |
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
if ($this->getAttribute('else')) { |
|||
$compiler->write("\$context['_iterated'] = true;\n"); |
|||
} |
|||
|
|||
if ($this->getAttribute('with_loop')) { |
|||
$compiler |
|||
->write("++\$context['loop']['index0'];\n") |
|||
->write("++\$context['loop']['index'];\n") |
|||
->write("\$context['loop']['first'] = false;\n") |
|||
; |
|||
|
|||
if (!$this->getAttribute('ifexpr')) { |
|||
$compiler |
|||
->write("if (isset(\$context['loop']['length'])) {\n") |
|||
->indent() |
|||
->write("--\$context['loop']['revindex0'];\n") |
|||
->write("--\$context['loop']['revindex'];\n") |
|||
->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n") |
|||
->outdent() |
|||
->write("}\n") |
|||
; |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,35 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2011 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
class Twig_Node_SetTemp extends Twig_Node |
|||
{ |
|||
public function __construct($name, $lineno) |
|||
{ |
|||
parent::__construct(array(), array('name' => $name), $lineno); |
|||
} |
|||
|
|||
public function compile(Twig_Compiler $compiler) |
|||
{ |
|||
$name = $this->getAttribute('name'); |
|||
$compiler |
|||
->addDebugInfo($this) |
|||
->write('if (isset($context[') |
|||
->string($name) |
|||
->raw('])) { $_') |
|||
->raw($name) |
|||
->raw('_ = $context[') |
|||
->repr($name) |
|||
->raw(']; } else { $_') |
|||
->raw($name) |
|||
->raw("_ = null; }\n") |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,94 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2009-2012 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Represents a template filter. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_SimpleFilter |
|||
{ |
|||
protected $name; |
|||
protected $callable; |
|||
protected $options; |
|||
protected $arguments = array(); |
|||
|
|||
public function __construct($name, $callable, array $options = array()) |
|||
{ |
|||
$this->name = $name; |
|||
$this->callable = $callable; |
|||
$this->options = array_merge(array( |
|||
'needs_environment' => false, |
|||
'needs_context' => false, |
|||
'is_safe' => null, |
|||
'is_safe_callback' => null, |
|||
'pre_escape' => null, |
|||
'preserves_safety' => null, |
|||
'node_class' => 'Twig_Node_Expression_Filter', |
|||
), $options); |
|||
} |
|||
|
|||
public function getName() |
|||
{ |
|||
return $this->name; |
|||
} |
|||
|
|||
public function getCallable() |
|||
{ |
|||
return $this->callable; |
|||
} |
|||
|
|||
public function getNodeClass() |
|||
{ |
|||
return $this->options['node_class']; |
|||
} |
|||
|
|||
public function setArguments($arguments) |
|||
{ |
|||
$this->arguments = $arguments; |
|||
} |
|||
|
|||
public function getArguments() |
|||
{ |
|||
return $this->arguments; |
|||
} |
|||
|
|||
public function needsEnvironment() |
|||
{ |
|||
return $this->options['needs_environment']; |
|||
} |
|||
|
|||
public function needsContext() |
|||
{ |
|||
return $this->options['needs_context']; |
|||
} |
|||
|
|||
public function getSafe(Twig_Node $filterArgs) |
|||
{ |
|||
if (null !== $this->options['is_safe']) { |
|||
return $this->options['is_safe']; |
|||
} |
|||
|
|||
if (null !== $this->options['is_safe_callback']) { |
|||
return call_user_func($this->options['is_safe_callback'], $filterArgs); |
|||
} |
|||
} |
|||
|
|||
public function getPreservesSafety() |
|||
{ |
|||
return $this->options['preserves_safety']; |
|||
} |
|||
|
|||
public function getPreEscape() |
|||
{ |
|||
return $this->options['pre_escape']; |
|||
} |
|||
} |
@ -0,0 +1,84 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2010-2012 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Represents a template function. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_SimpleFunction |
|||
{ |
|||
protected $name; |
|||
protected $callable; |
|||
protected $options; |
|||
protected $arguments = array(); |
|||
|
|||
public function __construct($name, $callable, array $options = array()) |
|||
{ |
|||
$this->name = $name; |
|||
$this->callable = $callable; |
|||
$this->options = array_merge(array( |
|||
'needs_environment' => false, |
|||
'needs_context' => false, |
|||
'is_safe' => null, |
|||
'is_safe_callback' => null, |
|||
'node_class' => 'Twig_Node_Expression_Function', |
|||
), $options); |
|||
} |
|||
|
|||
public function getName() |
|||
{ |
|||
return $this->name; |
|||
} |
|||
|
|||
public function getCallable() |
|||
{ |
|||
return $this->callable; |
|||
} |
|||
|
|||
public function getNodeClass() |
|||
{ |
|||
return $this->options['node_class']; |
|||
} |
|||
|
|||
public function setArguments($arguments) |
|||
{ |
|||
$this->arguments = $arguments; |
|||
} |
|||
|
|||
public function getArguments() |
|||
{ |
|||
return $this->arguments; |
|||
} |
|||
|
|||
public function needsEnvironment() |
|||
{ |
|||
return $this->options['needs_environment']; |
|||
} |
|||
|
|||
public function needsContext() |
|||
{ |
|||
return $this->options['needs_context']; |
|||
} |
|||
|
|||
public function getSafe(Twig_Node $functionArgs) |
|||
{ |
|||
if (null !== $this->options['is_safe']) { |
|||
return $this->options['is_safe']; |
|||
} |
|||
|
|||
if (null !== $this->options['is_safe_callback']) { |
|||
return call_user_func($this->options['is_safe_callback'], $functionArgs); |
|||
} |
|||
|
|||
return array(); |
|||
} |
|||
} |
@ -0,0 +1,46 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* This file is part of Twig. |
|||
* |
|||
* (c) 2010-2012 Fabien Potencier |
|||
* |
|||
* For the full copyright and license information, please view the LICENSE |
|||
* file that was distributed with this source code. |
|||
*/ |
|||
|
|||
/** |
|||
* Represents a template test. |
|||
* |
|||
* @author Fabien Potencier <fabien@symfony.com> |
|||
*/ |
|||
class Twig_SimpleTest |
|||
{ |
|||
protected $name; |
|||
protected $callable; |
|||
protected $options; |
|||
|
|||
public function __construct($name, $callable, array $options = array()) |
|||
{ |
|||
$this->name = $name; |
|||
$this->callable = $callable; |
|||
$this->options = array_merge(array( |
|||
'node_class' => 'Twig_Node_Expression_Test', |
|||
), $options); |
|||
} |
|||
|
|||
public function getName() |
|||
{ |
|||
return $this->name; |
|||
} |
|||
|
|||
public function getCallable() |
|||
{ |
|||
return $this->callable; |
|||
} |
|||
|
|||
public function getNodeClass() |
|||
{ |
|||
return $this->options['node_class']; |
|||
} |
|||
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue