diff --git a/lib/Twig/Environment.php b/lib/Twig/Environment.php index 766d0a9f2..c7795dd84 100644 --- a/lib/Twig/Environment.php +++ b/lib/Twig/Environment.php @@ -829,7 +829,7 @@ class Twig_Environment return false; } - public function registerUndefinedFilterCallback($callable) + public function registerUndefinedFilterCallback(callable $callable) { $this->filterCallbacks[] = $callable; } @@ -956,7 +956,7 @@ class Twig_Environment return false; } - public function registerUndefinedFunctionCallback($callable) + public function registerUndefinedFunctionCallback(callable $callable) { $this->functionCallbacks[] = $callable; } diff --git a/lib/Twig/Extension/Core.php b/lib/Twig/Extension/Core.php index f070e5284..01a5d5608 100644 --- a/lib/Twig/Extension/Core.php +++ b/lib/Twig/Extension/Core.php @@ -26,7 +26,7 @@ class Twig_Extension_Core extends Twig_Extension * @param string $strategy The strategy name that should be used as a strategy in the escape call * @param callable $callable A valid PHP callable */ - public function setEscaper($strategy, $callable) + public function setEscaper($strategy, callable $callable) { $this->escapers[$strategy] = $callable; } @@ -34,7 +34,7 @@ class Twig_Extension_Core extends Twig_Extension /** * Gets all defined escapers. * - * @return array An array of escapers + * @return callable[] An array of escapers */ public function getEscapers() { diff --git a/lib/Twig/Filter.php b/lib/Twig/Filter.php index 3bb2c5f1b..a984e2e34 100644 --- a/lib/Twig/Filter.php +++ b/lib/Twig/Filter.php @@ -13,6 +13,8 @@ * Represents a template filter. * * @author Fabien Potencier + * + * @see http://twig.sensiolabs.org/doc/templates.html#filters */ class Twig_Filter { @@ -21,7 +23,14 @@ class Twig_Filter private $options; private $arguments = array(); - public function __construct($name, $callable, array $options = array()) + /** + * Creates a template filter. + * + * @param string $name Name of this filter + * @param callable|null $callable A callable implementing the filter. If null, you need to overwrite the "node_class" option to customize compilation. + * @param array $options Options array + */ + public function __construct($name, callable $callable = null, array $options = array()) { $this->name = $name; $this->callable = $callable; @@ -44,6 +53,11 @@ class Twig_Filter return $this->name; } + /** + * Returns the callable to execute for this filter. + * + * @return callable|null + */ public function getCallable() { return $this->callable; diff --git a/lib/Twig/Function.php b/lib/Twig/Function.php index d673a2940..09ddc4cf1 100644 --- a/lib/Twig/Function.php +++ b/lib/Twig/Function.php @@ -13,6 +13,8 @@ * Represents a template function. * * @author Fabien Potencier + * + * @see http://twig.sensiolabs.org/doc/templates.html#functions */ class Twig_Function { @@ -21,7 +23,14 @@ class Twig_Function private $options; private $arguments = array(); - public function __construct($name, $callable, array $options = array()) + /** + * Creates a template function. + * + * @param string $name Name of this function + * @param callable|null $callable A callable implementing the function. If null, you need to overwrite the "node_class" option to customize compilation. + * @param array $options Options array + */ + public function __construct($name, callable $callable = null, array $options = array()) { $this->name = $name; $this->callable = $callable; @@ -42,6 +51,11 @@ class Twig_Function return $this->name; } + /** + * Returns the callable to execute for this function. + * + * @return callable|null + */ public function getCallable() { return $this->callable; diff --git a/lib/Twig/Node/Expression/Call.php b/lib/Twig/Node/Expression/Call.php index 20c4c3e63..f0269d121 100644 --- a/lib/Twig/Node/Expression/Call.php +++ b/lib/Twig/Node/Expression/Call.php @@ -19,9 +19,15 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression $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 { + } elseif (null !== $callable) { $closingParenthesis = true; $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', ucfirst($this->getAttribute('type')), $this->getAttribute('name'))); + } else { + throw new LogicException(sprintf( + '%s "%s" cannot be compiled because it does not define a callable to execute. Maybe you want to change compilation with a custom node class.', + ucfirst($this->getAttribute('type')), + $this->getAttribute('name') + )); } $this->compileArguments($compiler); @@ -83,7 +89,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression $compiler->raw(')'); } - protected function getArguments($callable, $arguments) + protected function getArguments(callable $callable = null, $arguments) { $callType = $this->getAttribute('type'); $callName = $this->getAttribute('name'); diff --git a/lib/Twig/Test.php b/lib/Twig/Test.php index 44e109d28..a39d922d8 100644 --- a/lib/Twig/Test.php +++ b/lib/Twig/Test.php @@ -13,6 +13,8 @@ * Represents a template test. * * @author Fabien Potencier + * + * @see http://twig.sensiolabs.org/doc/templates.html#test-operator */ class Twig_Test { @@ -20,7 +22,14 @@ class Twig_Test private $callable; private $options; - public function __construct($name, $callable, array $options = array()) + /** + * Creates a template test. + * + * @param string $name Name of this test + * @param callable|null $callable A callable implementing the test. If null, you need to overwrite the "node_class" option to customize compilation. + * @param array $options Options array + */ + public function __construct($name, callable $callable = null, array $options = array()) { $this->name = $name; $this->callable = $callable; @@ -37,6 +46,11 @@ class Twig_Test return $this->name; } + /** + * Returns the callable to execute for this test. + * + * @return callable|null + */ public function getCallable() { return $this->callable; diff --git a/test/Twig/Tests/EnvironmentTest.php b/test/Twig/Tests/EnvironmentTest.php index 00c32de6b..df7426c52 100644 --- a/test/Twig/Tests/EnvironmentTest.php +++ b/test/Twig/Tests/EnvironmentTest.php @@ -190,21 +190,21 @@ class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension public function getFilters() { return array( - new Twig_Filter('foo_filter', 'foo_filter'), + new Twig_Filter('foo_filter'), ); } public function getTests() { return array( - new Twig_Test('foo_test', 'foo_test'), + new Twig_Test('foo_test'), ); } public function getFunctions() { return array( - new Twig_Function('foo_function', 'foo_function'), + new Twig_Function('foo_function'), ); } diff --git a/test/Twig/Tests/Node/Expression/FilterTest.php b/test/Twig/Tests/Node/Expression/FilterTest.php index 48f929bda..0482daca3 100644 --- a/test/Twig/Tests/Node/Expression/FilterTest.php +++ b/test/Twig/Tests/Node/Expression/FilterTest.php @@ -26,7 +26,7 @@ class Twig_Tests_Node_Expression_FilterTest extends Twig_Test_NodeTestCase public function getTests() { $environment = new Twig_Environment($this->getMock('Twig_LoaderInterface')); - $environment->addFilter(new Twig_SimpleFilter('bar', 'bar', array('needs_environment' => true))); + $environment->addFilter(new Twig_SimpleFilter('bar', 'twig_tests_filter_dummy', array('needs_environment' => true))); $environment->addFilter(new Twig_SimpleFilter('barbar', 'twig_tests_filter_barbar', array('needs_context' => true, 'is_variadic' => true))); $tests = array(); @@ -73,10 +73,10 @@ class Twig_Tests_Node_Expression_FilterTest extends Twig_Test_NodeTestCase // needs environment $node = $this->createFilter($string, 'bar'); - $tests[] = array($node, 'bar($this->env, "abc")', $environment); + $tests[] = array($node, 'twig_tests_filter_dummy($this->env, "abc")', $environment); $node = $this->createFilter($string, 'bar', array(new Twig_Node_Expression_Constant('bar', 1))); - $tests[] = array($node, 'bar($this->env, "abc", "bar")', $environment); + $tests[] = array($node, 'twig_tests_filter_dummy($this->env, "abc", "bar")', $environment); // arbitrary named arguments $node = $this->createFilter($string, 'barbar'); @@ -146,6 +146,10 @@ class Twig_Tests_Node_Expression_FilterTest extends Twig_Test_NodeTestCase } } +function twig_tests_filter_dummy() +{ +} + function twig_tests_filter_barbar($context, $string, $arg1 = null, $arg2 = null, array $args = array()) { } diff --git a/test/Twig/Tests/Node/Expression/FunctionTest.php b/test/Twig/Tests/Node/Expression/FunctionTest.php index f13c3b6c2..b0c259d67 100644 --- a/test/Twig/Tests/Node/Expression/FunctionTest.php +++ b/test/Twig/Tests/Node/Expression/FunctionTest.php @@ -24,37 +24,37 @@ class Twig_Tests_Node_Expression_FunctionTest extends Twig_Test_NodeTestCase public function getTests() { $environment = new Twig_Environment($this->getMock('Twig_LoaderInterface')); - $environment->addFunction(new Twig_Function('foo', 'foo', array())); - $environment->addFunction(new Twig_Function('bar', 'bar', array('needs_environment' => true))); - $environment->addFunction(new Twig_Function('foofoo', 'foofoo', array('needs_context' => true))); - $environment->addFunction(new Twig_Function('foobar', 'foobar', array('needs_environment' => true, 'needs_context' => true))); + $environment->addFunction(new Twig_Function('foo', 'twig_tests_function_dummy', array())); + $environment->addFunction(new Twig_Function('bar', 'twig_tests_function_dummy', array('needs_environment' => true))); + $environment->addFunction(new Twig_Function('foofoo', 'twig_tests_function_dummy', array('needs_context' => true))); + $environment->addFunction(new Twig_Function('foobar', 'twig_tests_function_dummy', array('needs_environment' => true, 'needs_context' => true))); $environment->addFunction(new Twig_Function('barbar', 'twig_tests_function_barbar', array('is_variadic' => true))); $tests = array(); $node = $this->createFunction('foo'); - $tests[] = array($node, 'foo()', $environment); + $tests[] = array($node, 'twig_tests_function_dummy()', $environment); $node = $this->createFunction('foo', array(new Twig_Node_Expression_Constant('bar', 1), new Twig_Node_Expression_Constant('foobar', 1))); - $tests[] = array($node, 'foo("bar", "foobar")', $environment); + $tests[] = array($node, 'twig_tests_function_dummy("bar", "foobar")', $environment); $node = $this->createFunction('bar'); - $tests[] = array($node, 'bar($this->env)', $environment); + $tests[] = array($node, 'twig_tests_function_dummy($this->env)', $environment); $node = $this->createFunction('bar', array(new Twig_Node_Expression_Constant('bar', 1))); - $tests[] = array($node, 'bar($this->env, "bar")', $environment); + $tests[] = array($node, 'twig_tests_function_dummy($this->env, "bar")', $environment); $node = $this->createFunction('foofoo'); - $tests[] = array($node, 'foofoo($context)', $environment); + $tests[] = array($node, 'twig_tests_function_dummy($context)', $environment); $node = $this->createFunction('foofoo', array(new Twig_Node_Expression_Constant('bar', 1))); - $tests[] = array($node, 'foofoo($context, "bar")', $environment); + $tests[] = array($node, 'twig_tests_function_dummy($context, "bar")', $environment); $node = $this->createFunction('foobar'); - $tests[] = array($node, 'foobar($this->env, $context)', $environment); + $tests[] = array($node, 'twig_tests_function_dummy($this->env, $context)', $environment); $node = $this->createFunction('foobar', array(new Twig_Node_Expression_Constant('bar', 1))); - $tests[] = array($node, 'foobar($this->env, $context, "bar")', $environment); + $tests[] = array($node, 'twig_tests_function_dummy($this->env, $context, "bar")', $environment); // named arguments $node = $this->createFunction('date', array( @@ -102,6 +102,10 @@ class Twig_Tests_Node_Expression_FunctionTest extends Twig_Test_NodeTestCase } } +function twig_tests_function_dummy() +{ +} + function twig_tests_function_barbar($arg1 = null, $arg2 = null, array $args = array()) { }