Changeset 1101:7273894e61b8
- Timestamp:
- 02/15/13 08:35:19 (12 years ago)
- Branch:
- twig
- Children:
- 1106:a4487f3ca4b4, 1147:2e5cb79e4782
- Location:
- inc/libs/twig
- Files:
-
- 9 added
- 41 edited
Legend:
- Unmodified
- Added
- Removed
-
inc/libs/twig/CHANGELOG
r991 r1101 1 * 1.12.2 (2013-02-09) 2 3 * fixed the timezone used by the date filter and function when the given date contains a timezone (like 2010-01-28T15:00:00+02:00) 4 * fixed globals when getGlobals is called early on 5 * added the first and last filter 6 7 * 1.12.1 (2013-01-15) 8 9 * added support for object instances as the second argument of the constant function 10 * relaxed globals management to avoid a BC break 11 * added support for {{ some_string[:2] }} 12 13 * 1.12.0 (2013-01-08) 14 15 * added verbatim as an alias for the raw tag to avoid confusion with the raw filter 16 * fixed registration of tests and functions as anonymous functions 17 * fixed globals management 18 19 * 1.12.0-RC1 (2012-12-29) 20 21 * added an include function (does the same as the include tag but in a more flexible way) 22 * added the ability to use any PHP callable to define filters, functions, and tests 23 * added a syntax error when using a loop variable that is not defined 24 * added the ability to set default values for macro arguments 25 * added support for named arguments for filters, tests, and functions 26 * moved filters/functions/tests syntax errors to the parser 27 * added support for extended ternary operator syntaxes 28 1 29 * 1.11.1 (2012-11-11) 2 30 -
inc/libs/twig/Compiler.php
r991 r1101 257 257 public function outdent($step = 1) 258 258 { 259 // can't outdent by more steps tha tthe current indentation level259 // can't outdent by more steps than the current indentation level 260 260 if ($this->indentation < $step) { 261 261 throw new LogicException('Unable to call outdent() as the indentation would become negative'); -
inc/libs/twig/CompilerInterface.php
r991 r1101 15 15 * @package twig 16 16 * @author Fabien Potencier <fabien@symfony.com> 17 * @deprecated since 1.12 (to be removed in 2.0) 17 18 */ 18 19 interface Twig_CompilerInterface -
inc/libs/twig/Environment.php
r991 r1101 18 18 class Twig_Environment 19 19 { 20 const VERSION = '1.1 1.1';20 const VERSION = '1.12.2'; 21 21 22 22 protected $charset; … … 37 37 protected $globals; 38 38 protected $runtimeInitialized; 39 protected $extensionInitialized; 39 40 protected $loadedTemplates; 40 41 protected $strictVariables; … … 103 104 $this->baseTemplateClass = $options['base_template_class']; 104 105 $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload']; 105 $this->extensions = array(106 'core' => new Twig_Extension_Core(),107 'escaper' => new Twig_Extension_Escaper($options['autoescape']),108 'optimizer' => new Twig_Extension_Optimizer($options['optimizations']),109 );110 106 $this->strictVariables = (bool) $options['strict_variables']; 111 107 $this->runtimeInitialized = false; … … 113 109 $this->functionCallbacks = array(); 114 110 $this->filterCallbacks = array(); 115 $this->staging = array( 116 'functions' => array(), 117 'filters' => array(), 118 'tests' => array(), 119 'token_parsers' => array(), 120 'visitors' => array(), 121 'globals' => array(), 122 ); 111 112 $this->addExtension(new Twig_Extension_Core()); 113 $this->addExtension(new Twig_Extension_Escaper($options['autoescape'])); 114 $this->addExtension(new Twig_Extension_Optimizer($options['optimizations'])); 115 $this->extensionInitialized = false; 116 $this->staging = new Twig_Extension_Staging(); 123 117 } 124 118 … … 270 264 public function getTemplateClass($name, $index = null) 271 265 { 272 return $this->templateClassPrefix.md5($this-> loader->getCacheKey($name)).(null === $index ? '' : '_'.$index);266 return $this->templateClassPrefix.md5($this->getLoader()->getCacheKey($name)).(null === $index ? '' : '_'.$index); 273 267 } 274 268 … … 325 319 if (!class_exists($cls, false)) { 326 320 if (false === $cache = $this->getCacheFilename($name)) { 327 eval('?>'.$this->compileSource($this-> loader->getSource($name), $name));321 eval('?>'.$this->compileSource($this->getLoader()->getSource($name), $name)); 328 322 } else { 329 323 if (!is_file($cache) || ($this->isAutoReload() && !$this->isTemplateFresh($name, filemtime($cache)))) { 330 $this->writeCacheFile($cache, $this->compileSource($this-> loader->getSource($name), $name));324 $this->writeCacheFile($cache, $this->compileSource($this->getLoader()->getSource($name), $name)); 331 325 } 332 326 … … 363 357 } 364 358 365 return $this-> loader->isFresh($name, $time);359 return $this->getLoader()->isFresh($name, $time); 366 360 } 367 361 … … 560 554 public function getLoader() 561 555 { 556 if (null === $this->loader) { 557 throw new LogicException('You must set a loader first.'); 558 } 559 562 560 return $this->loader; 563 561 } … … 630 628 public function addExtension(Twig_ExtensionInterface $extension) 631 629 { 630 if ($this->extensionInitialized) { 631 throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName())); 632 } 633 632 634 $this->extensions[$extension->getName()] = $extension; 633 $this->parsers = null;634 $this->visitors = null;635 $this->filters = null;636 $this->tests = null;637 $this->functions = null;638 $this->globals = null;639 635 } 640 636 … … 642 638 * Removes an extension by name. 643 639 * 640 * This method is deprecated and you should not use it. 641 * 644 642 * @param string $name The extension name 643 * 644 * @deprecated since 1.12 (to be removed in 2.0) 645 645 */ 646 646 public function removeExtension($name) 647 647 { 648 if ($this->extensionInitialized) { 649 throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name)); 650 } 651 648 652 unset($this->extensions[$name]); 649 $this->parsers = null;650 $this->visitors = null;651 $this->filters = null;652 $this->tests = null;653 $this->functions = null;654 $this->globals = null;655 653 } 656 654 … … 684 682 public function addTokenParser(Twig_TokenParserInterface $parser) 685 683 { 686 $this->staging['token_parsers'][] = $parser; 687 $this->parsers = null; 684 if ($this->extensionInitialized) { 685 throw new LogicException('Unable to add a token parser as extensions have already been initialized.'); 686 } 687 688 $this->staging->addTokenParser($parser); 688 689 } 689 690 … … 695 696 public function getTokenParsers() 696 697 { 697 if (null === $this->parsers) { 698 $this->parsers = new Twig_TokenParserBroker(); 699 700 if (isset($this->staging['token_parsers'])) { 701 foreach ($this->staging['token_parsers'] as $parser) { 702 $this->parsers->addTokenParser($parser); 703 } 704 } 705 706 foreach ($this->getExtensions() as $extension) { 707 $parsers = $extension->getTokenParsers(); 708 foreach ($parsers as $parser) { 709 if ($parser instanceof Twig_TokenParserInterface) { 710 $this->parsers->addTokenParser($parser); 711 } elseif ($parser instanceof Twig_TokenParserBrokerInterface) { 712 $this->parsers->addTokenParserBroker($parser); 713 } else { 714 throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances'); 715 } 716 } 717 } 698 if (!$this->extensionInitialized) { 699 $this->initExtensions(); 718 700 } 719 701 … … 747 729 public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) 748 730 { 749 $this->staging['visitors'][] = $visitor; 750 $this->visitors = null; 731 if ($this->extensionInitialized) { 732 throw new LogicException('Unable to add a node visitor as extensions have already been initialized.', $extension->getName()); 733 } 734 735 $this->staging->addNodeVisitor($visitor); 751 736 } 752 737 … … 758 743 public function getNodeVisitors() 759 744 { 760 if (null === $this->visitors) { 761 foreach ($this->getExtensions() as $extension) { 762 foreach ($extension->getNodeVisitors() as $visitor) { 763 $this->addNodeVisitor($visitor); 764 } 765 } 766 767 $this->visitors = $this->staging['visitors']; 745 if (!$this->extensionInitialized) { 746 $this->initExtensions(); 768 747 } 769 748 … … 774 753 * Registers a Filter. 775 754 * 776 * @param string $name The filter name 777 * @param Twig_FilterInterface $filter A Twig_FilterInterface instance 778 */ 779 public function addFilter($name, Twig_FilterInterface $filter) 780 { 781 $this->staging['filters'][$name] = $filter; 782 $this->filters = null; 755 * @param string|Twig_SimpleFilter $name The filter name or a Twig_SimpleFilter instance 756 * @param Twig_FilterInterface|Twig_SimpleFilter $filter A Twig_FilterInterface instance or a Twig_SimpleFilter instance 757 */ 758 public function addFilter($name, $filter = null) 759 { 760 if ($this->extensionInitialized) { 761 throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name)); 762 } 763 764 if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) { 765 throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter'); 766 } 767 768 if ($name instanceof Twig_SimpleFilter) { 769 $filter = $name; 770 $name = $filter->getName(); 771 } 772 773 $this->staging->addFilter($name, $filter); 783 774 } 784 775 … … 791 782 * @param string $name The filter name 792 783 * 793 * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exist s784 * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exist 794 785 */ 795 786 public function getFilter($name) 796 787 { 797 if ( null === $this->filters) {798 $this-> getFilters();788 if (!$this->extensionInitialized) { 789 $this->initExtensions(); 799 790 } 800 791 … … 841 832 public function getFilters() 842 833 { 843 if (null === $this->filters) { 844 foreach ($this->getExtensions() as $extension) { 845 foreach ($extension->getFilters() as $name => $filter) { 846 $this->addFilter($name, $filter); 847 } 848 } 849 850 $this->filters = $this->staging['filters']; 834 if (!$this->extensionInitialized) { 835 $this->initExtensions(); 851 836 } 852 837 … … 857 842 * Registers a Test. 858 843 * 859 * @param string $name The test name 860 * @param Twig_TestInterface $test A Twig_TestInterface instance 861 */ 862 public function addTest($name, Twig_TestInterface $test) 863 { 864 $this->staging['tests'][$name] = $test; 865 $this->tests = null; 844 * @param string|Twig_SimpleTest $name The test name or a Twig_SimpleTest instance 845 * @param Twig_TestInterface|Twig_SimpleTest $test A Twig_TestInterface instance or a Twig_SimpleTest instance 846 */ 847 public function addTest($name, $test = null) 848 { 849 if ($this->extensionInitialized) { 850 throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name)); 851 } 852 853 if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) { 854 throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest'); 855 } 856 857 if ($name instanceof Twig_SimpleTest) { 858 $test = $name; 859 $name = $test->getName(); 860 } 861 862 $this->staging->addTest($name, $test); 866 863 } 867 864 … … 873 870 public function getTests() 874 871 { 875 if (null === $this->tests) { 876 foreach ($this->getExtensions() as $extension) { 877 foreach ($extension->getTests() as $name => $test) { 878 $this->addTest($name, $test); 879 } 880 } 881 882 $this->tests = $this->staging['tests']; 872 if (!$this->extensionInitialized) { 873 $this->initExtensions(); 883 874 } 884 875 … … 887 878 888 879 /** 880 * Gets a test by name. 881 * 882 * @param string $name The test name 883 * 884 * @return Twig_Test|false A Twig_Test instance or false if the test does not exist 885 */ 886 public function getTest($name) 887 { 888 if (!$this->extensionInitialized) { 889 $this->initExtensions(); 890 } 891 892 if (isset($this->tests[$name])) { 893 return $this->tests[$name]; 894 } 895 896 return false; 897 } 898 899 /** 889 900 * Registers a Function. 890 901 * 891 * @param string $name The function name 892 * @param Twig_FunctionInterface $function A Twig_FunctionInterface instance 893 */ 894 public function addFunction($name, Twig_FunctionInterface $function) 895 { 896 $this->staging['functions'][$name] = $function; 897 $this->functions = null; 902 * @param string|Twig_SimpleFunction $name The function name or a Twig_SimpleFunction instance 903 * @param Twig_FunctionInterface|Twig_SimpleFunction $function A Twig_FunctionInterface instance or a Twig_SimpleFunction instance 904 */ 905 public function addFunction($name, $function = null) 906 { 907 if ($this->extensionInitialized) { 908 throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name)); 909 } 910 911 if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) { 912 throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction'); 913 } 914 915 if ($name instanceof Twig_SimpleFunction) { 916 $function = $name; 917 $name = $function->getName(); 918 } 919 920 $this->staging->addFunction($name, $function); 898 921 } 899 922 … … 906 929 * @param string $name function name 907 930 * 908 * @return Twig_Function|false A Twig_Function instance or false if the function does not exist s931 * @return Twig_Function|false A Twig_Function instance or false if the function does not exist 909 932 */ 910 933 public function getFunction($name) 911 934 { 912 if ( null === $this->functions) {913 $this-> getFunctions();935 if (!$this->extensionInitialized) { 936 $this->initExtensions(); 914 937 } 915 938 … … 956 979 public function getFunctions() 957 980 { 958 if (null === $this->functions) { 959 foreach ($this->getExtensions() as $extension) { 960 foreach ($extension->getFunctions() as $name => $function) { 961 $this->addFunction($name, $function); 962 } 963 } 964 965 $this->functions = $this->staging['functions']; 981 if (!$this->extensionInitialized) { 982 $this->initExtensions(); 966 983 } 967 984 … … 971 988 /** 972 989 * Registers a Global. 990 * 991 * New globals can be added before compiling or rendering a template; 992 * but after, you can only update existing globals. 973 993 * 974 994 * @param string $name The global name … … 977 997 public function addGlobal($name, $value) 978 998 { 979 $this->staging['globals'][$name] = $value; 980 $this->globals = null; 999 if ($this->extensionInitialized || $this->runtimeInitialized) { 1000 if (null === $this->globals) { 1001 $this->globals = $this->initGlobals(); 1002 } 1003 1004 /* This condition must be uncommented in Twig 2.0 1005 if (!array_key_exists($name, $this->globals)) { 1006 throw new LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name)); 1007 } 1008 */ 1009 } 1010 1011 if ($this->extensionInitialized || $this->runtimeInitialized) { 1012 // update the value 1013 $this->globals[$name] = $value; 1014 } else { 1015 $this->staging->addGlobal($name, $value); 1016 } 981 1017 } 982 1018 … … 988 1024 public function getGlobals() 989 1025 { 1026 if (!$this->runtimeInitialized && !$this->extensionInitialized) { 1027 return $this->initGlobals(); 1028 } 1029 990 1030 if (null === $this->globals) { 991 $this->globals = isset($this->staging['globals']) ? $this->staging['globals'] : array(); 992 foreach ($this->getExtensions() as $extension) { 993 $this->globals = array_merge($this->globals, $extension->getGlobals()); 994 } 1031 $this->globals = $this->initGlobals(); 995 1032 } 996 1033 … … 1025 1062 public function getUnaryOperators() 1026 1063 { 1027 if ( null === $this->unaryOperators) {1028 $this->init Operators();1064 if (!$this->extensionInitialized) { 1065 $this->initExtensions(); 1029 1066 } 1030 1067 … … 1039 1076 public function getBinaryOperators() 1040 1077 { 1041 if ( null === $this->binaryOperators) {1042 $this->init Operators();1078 if (!$this->extensionInitialized) { 1079 $this->initExtensions(); 1043 1080 } 1044 1081 … … 1060 1097 } 1061 1098 1062 protected function initOperators() 1063 { 1099 protected function initGlobals() 1100 { 1101 $globals = array(); 1102 foreach ($this->extensions as $extension) { 1103 $globals = array_merge($globals, $extension->getGlobals()); 1104 } 1105 1106 return array_merge($globals, $this->staging->getGlobals()); 1107 } 1108 1109 protected function initExtensions() 1110 { 1111 if ($this->extensionInitialized) { 1112 return; 1113 } 1114 1115 $this->extensionInitialized = true; 1116 $this->parsers = new Twig_TokenParserBroker(); 1117 $this->filters = array(); 1118 $this->functions = array(); 1119 $this->tests = array(); 1120 $this->visitors = array(); 1064 1121 $this->unaryOperators = array(); 1065 1122 $this->binaryOperators = array(); 1066 foreach ($this->getExtensions() as $extension) { 1067 $operators = $extension->getOperators(); 1068 1069 if (!$operators) { 1070 continue; 1071 } 1072 1123 1124 foreach ($this->extensions as $extension) { 1125 $this->initExtension($extension); 1126 } 1127 $this->initExtension($this->staging); 1128 } 1129 1130 protected function initExtension(Twig_ExtensionInterface $extension) 1131 { 1132 // filters 1133 foreach ($extension->getFilters() as $name => $filter) { 1134 if ($name instanceof Twig_SimpleFilter) { 1135 $filter = $name; 1136 $name = $filter->getName(); 1137 } elseif ($filter instanceof Twig_SimpleFilter) { 1138 $name = $filter->getName(); 1139 } 1140 1141 $this->filters[$name] = $filter; 1142 } 1143 1144 // functions 1145 foreach ($extension->getFunctions() as $name => $function) { 1146 if ($name instanceof Twig_SimpleFunction) { 1147 $function = $name; 1148 $name = $function->getName(); 1149 } elseif ($function instanceof Twig_SimpleFunction) { 1150 $name = $function->getName(); 1151 } 1152 1153 $this->functions[$name] = $function; 1154 } 1155 1156 // tests 1157 foreach ($extension->getTests() as $name => $test) { 1158 if ($name instanceof Twig_SimpleTest) { 1159 $test = $name; 1160 $name = $test->getName(); 1161 } elseif ($test instanceof Twig_SimpleTest) { 1162 $name = $test->getName(); 1163 } 1164 1165 $this->tests[$name] = $test; 1166 } 1167 1168 // token parsers 1169 foreach ($extension->getTokenParsers() as $parser) { 1170 if ($parser instanceof Twig_TokenParserInterface) { 1171 $this->parsers->addTokenParser($parser); 1172 } elseif ($parser instanceof Twig_TokenParserBrokerInterface) { 1173 $this->parsers->addTokenParserBroker($parser); 1174 } else { 1175 throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances'); 1176 } 1177 } 1178 1179 // node visitors 1180 foreach ($extension->getNodeVisitors() as $visitor) { 1181 $this->visitors[] = $visitor; 1182 } 1183 1184 // operators 1185 if ($operators = $extension->getOperators()) { 1073 1186 if (2 !== count($operators)) { 1074 1187 throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension))); -
inc/libs/twig/ExistsLoaderInterface.php
r991 r1101 15 15 * @package twig 16 16 * @author Florin Patan <florinpatan@gmail.com> 17 * @deprecated since 1.12 (to be removed in 2.0) 17 18 */ 18 19 interface Twig_ExistsLoaderInterface -
inc/libs/twig/ExpressionParser.php
r991 r1101 90 90 while ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '?')) { 91 91 $this->parser->getStream()->next(); 92 $expr2 = $this->parseExpression(); 93 $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'The ternary operator must have a default value'); 94 $expr3 = $this->parseExpression(); 92 if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) { 93 $expr2 = $this->parseExpression(); 94 if ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) { 95 $this->parser->getStream()->next(); 96 $expr3 = $this->parseExpression(); 97 } else { 98 $expr3 = new Twig_Node_Expression_Constant('', $this->parser->getCurrentToken()->getLine()); 99 } 100 } else { 101 $this->parser->getStream()->next(); 102 $expr2 = $expr; 103 $expr3 = $this->parseExpression(); 104 } 95 105 96 106 $expr = new Twig_Node_Expression_Conditional($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine()); … … 288 298 public function getFunctionNode($name, $line) 289 299 { 290 $args = $this->parseArguments();291 300 switch ($name) { 292 301 case 'parent': 302 $args = $this->parseArguments(); 293 303 if (!count($this->parser->getBlockStack())) { 294 304 throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line, $this->parser->getFilename()); … … 301 311 return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line); 302 312 case 'block': 303 return new Twig_Node_Expression_BlockReference($ args->getNode(0), false, $line);313 return new Twig_Node_Expression_BlockReference($this->parseArguments()->getNode(0), false, $line); 304 314 case 'attribute': 315 $args = $this->parseArguments(); 305 316 if (count($args) < 2) { 306 317 throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line, $this->parser->getFilename()); … … 311 322 if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) { 312 323 $arguments = new Twig_Node_Expression_Array(array(), $line); 313 foreach ($ argsas $n) {324 foreach ($this->parseArguments() as $n) { 314 325 $arguments->addElement($n); 315 326 } … … 321 332 } 322 333 323 $class = $this->getFunctionNodeClass($name); 334 $args = $this->parseArguments(true); 335 $class = $this->getFunctionNodeClass($name, $line); 324 336 325 337 return new $class($name, $args, $line); … … 354 366 throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename()); 355 367 } 368 369 if ($node instanceof Twig_Node_Expression_Name && null !== $alias = $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) { 370 if (!$arg instanceof Twig_Node_Expression_Constant) { 371 throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s")', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename()); 372 } 373 374 $node = new Twig_Node_Expression_MethodCall($node, 'get'.$arg->getAttribute('value'), $arguments, $lineno); 375 $node->setAttribute('safe', true); 376 377 return $node; 378 } 356 379 } else { 357 380 $type = Twig_TemplateInterface::ARRAY_CALL; 358 381 359 $arg = $this->parseExpression();360 361 382 // slice? 383 $slice = false; 362 384 if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) { 385 $slice = true; 386 $arg = new Twig_Node_Expression_Constant(0, $token->getLine()); 387 } else { 388 $arg = $this->parseExpression(); 389 } 390 391 if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) { 392 $slice = true; 363 393 $stream->next(); 364 394 } 395 396 if ($slice) { 365 397 if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) { 366 398 $length = new Twig_Node_Expression_Constant(null, $token->getLine()); … … 369 401 } 370 402 371 $class = $this->getFilterNodeClass('slice' );403 $class = $this->getFilterNodeClass('slice', $token->getLine()); 372 404 $arguments = new Twig_Node(array($arg, $length)); 373 405 $filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine()); … … 379 411 380 412 $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']'); 381 }382 383 if ($node instanceof Twig_Node_Expression_Name && null !== $alias = $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {384 $node = new Twig_Node_Expression_MethodCall($node, 'get'.$arg->getAttribute('value'), $arguments, $lineno);385 $node->setAttribute('safe', true);386 387 return $node;388 413 } 389 414 … … 407 432 $arguments = new Twig_Node(); 408 433 } else { 409 $arguments = $this->parseArguments( );410 } 411 412 $class = $this->getFilterNodeClass($name->getAttribute('value') );434 $arguments = $this->parseArguments(true); 435 } 436 437 $class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine()); 413 438 414 439 $node = new $class($node, $name, $arguments, $token->getLine(), $tag); … … 424 449 } 425 450 426 public function parseArguments() 451 /** 452 * Parses arguments. 453 * 454 * @param Boolean $namedArguments Whether to allow named arguments or not 455 * @param Boolean $definition Whether we are parsing arguments for a function definition 456 */ 457 public function parseArguments($namedArguments = false, $definition = false) 427 458 { 428 459 $args = array(); 429 460 $stream = $this->parser->getStream(); 430 461 431 $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must be opened by aparenthesis');462 $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis'); 432 463 while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ')')) { 433 464 if (!empty($args)) { 434 465 $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma'); 435 466 } 436 $args[] = $this->parseExpression(); 467 468 if ($definition) { 469 $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'An argument must be a name'); 470 $value = new Twig_Node_Expression_Name($token->getValue(), $this->parser->getCurrentToken()->getLine()); 471 } else { 472 $value = $this->parseExpression(); 473 } 474 475 $name = null; 476 if ($namedArguments && $stream->test(Twig_Token::OPERATOR_TYPE, '=')) { 477 $token = $stream->next(); 478 if (!$value instanceof Twig_Node_Expression_Name) { 479 throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given', get_class($value)), $token->getLine(), $this->parser->getFilename()); 480 } 481 $name = $value->getAttribute('name'); 482 483 if ($definition) { 484 $value = $this->parsePrimaryExpression(); 485 486 if (!$this->checkConstantExpression($value)) { 487 throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $this->parser->getFilename()); 488 } 489 } else { 490 $value = $this->parseExpression(); 491 } 492 } 493 494 if ($definition) { 495 if (null === $name) { 496 $name = $value->getAttribute('name'); 497 $value = new Twig_Node_Expression_Constant(null, $this->parser->getCurrentToken()->getLine()); 498 } 499 $args[$name] = $value; 500 } else { 501 if (null === $name) { 502 $args[] = $value; 503 } else { 504 $args[$name] = $value; 505 } 506 } 437 507 } 438 508 $stream->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis'); … … 474 544 } 475 545 476 protected function getFunctionNodeClass($name) 477 { 478 $functionMap = $this->parser->getEnvironment()->getFunctions(); 479 if (isset($functionMap[$name]) && $functionMap[$name] instanceof Twig_Function_Node) { 480 return $functionMap[$name]->getClass(); 481 } 482 483 return 'Twig_Node_Expression_Function'; 484 } 485 486 protected function getFilterNodeClass($name) 487 { 488 $filterMap = $this->parser->getEnvironment()->getFilters(); 489 if (isset($filterMap[$name]) && $filterMap[$name] instanceof Twig_Filter_Node) { 490 return $filterMap[$name]->getClass(); 491 } 492 493 return 'Twig_Node_Expression_Filter'; 546 protected function getFunctionNodeClass($name, $line) 547 { 548 $env = $this->parser->getEnvironment(); 549 550 if (false === $function = $env->getFunction($name)) { 551 $message = sprintf('The function "%s" does not exist', $name); 552 if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFunctions()))) { 553 $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); 554 } 555 556 throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename()); 557 } 558 559 if ($function instanceof Twig_SimpleFunction) { 560 return $function->getNodeClass(); 561 } 562 563 return $function instanceof Twig_Function_Node ? $function->getClass() : 'Twig_Node_Expression_Function'; 564 } 565 566 protected function getFilterNodeClass($name, $line) 567 { 568 $env = $this->parser->getEnvironment(); 569 570 if (false === $filter = $env->getFilter($name)) { 571 $message = sprintf('The filter "%s" does not exist', $name); 572 if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFilters()))) { 573 $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); 574 } 575 576 throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename()); 577 } 578 579 if ($filter instanceof Twig_SimpleFilter) { 580 return $filter->getNodeClass(); 581 } 582 583 return $filter instanceof Twig_Filter_Node ? $filter->getClass() : 'Twig_Node_Expression_Filter'; 584 } 585 586 // checks that the node only contains "constant" elements 587 protected function checkConstantExpression(Twig_NodeInterface $node) 588 { 589 if (!($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array)) { 590 return false; 591 } 592 593 foreach ($node as $n) { 594 if (!$this->checkConstantExpression($n)) { 595 return false; 596 } 597 } 598 599 return true; 494 600 } 495 601 } -
inc/libs/twig/Extension/Core.php
r991 r1101 127 127 $filters = array( 128 128 // formatting filters 129 'date' => new Twig_Filter_Function('twig_date_format_filter', array('needs_environment' => true)),130 'date_modify' => new Twig_Filter_Function('twig_date_modify_filter', array('needs_environment' => true)),131 'format' => new Twig_Filter_Function('sprintf'),132 'replace' => new Twig_Filter_Function('strtr'),133 'number_format' => new Twig_Filter_Function('twig_number_format_filter', array('needs_environment' => true)),134 'abs' => new Twig_Filter_Function('abs'),129 new Twig_SimpleFilter('date', 'twig_date_format_filter', array('needs_environment' => true)), 130 new Twig_SimpleFilter('date_modify', 'twig_date_modify_filter', array('needs_environment' => true)), 131 new Twig_SimpleFilter('format', 'sprintf'), 132 new Twig_SimpleFilter('replace', 'strtr'), 133 new Twig_SimpleFilter('number_format', 'twig_number_format_filter', array('needs_environment' => true)), 134 new Twig_SimpleFilter('abs', 'abs'), 135 135 136 136 // encoding 137 'url_encode' => new Twig_Filter_Function('twig_urlencode_filter'),138 'json_encode' => new Twig_Filter_Function('twig_jsonencode_filter'),139 'convert_encoding' => new Twig_Filter_Function('twig_convert_encoding'),137 new Twig_SimpleFilter('url_encode', 'twig_urlencode_filter'), 138 new Twig_SimpleFilter('json_encode', 'twig_jsonencode_filter'), 139 new Twig_SimpleFilter('convert_encoding', 'twig_convert_encoding'), 140 140 141 141 // string filters 142 'title' => new Twig_Filter_Function('twig_title_string_filter', array('needs_environment' => true)),143 'capitalize' => new Twig_Filter_Function('twig_capitalize_string_filter', array('needs_environment' => true)),144 'upper' => new Twig_Filter_Function('strtoupper'),145 'lower' => new Twig_Filter_Function('strtolower'),146 'striptags' => new Twig_Filter_Function('strip_tags'),147 'trim' => new Twig_Filter_Function('trim'),148 'nl2br' => new Twig_Filter_Function('nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))),142 new Twig_SimpleFilter('title', 'twig_title_string_filter', array('needs_environment' => true)), 143 new Twig_SimpleFilter('capitalize', 'twig_capitalize_string_filter', array('needs_environment' => true)), 144 new Twig_SimpleFilter('upper', 'strtoupper'), 145 new Twig_SimpleFilter('lower', 'strtolower'), 146 new Twig_SimpleFilter('striptags', 'strip_tags'), 147 new Twig_SimpleFilter('trim', 'trim'), 148 new Twig_SimpleFilter('nl2br', 'nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))), 149 149 150 150 // array helpers 151 'join' => new Twig_Filter_Function('twig_join_filter'),152 'split' => new Twig_Filter_Function('twig_split_filter'),153 'sort' => new Twig_Filter_Function('twig_sort_filter'),154 'merge' => new Twig_Filter_Function('twig_array_merge'),151 new Twig_SimpleFilter('join', 'twig_join_filter'), 152 new Twig_SimpleFilter('split', 'twig_split_filter'), 153 new Twig_SimpleFilter('sort', 'twig_sort_filter'), 154 new Twig_SimpleFilter('merge', 'twig_array_merge'), 155 155 156 156 // string/array filters 157 'reverse' => new Twig_Filter_Function('twig_reverse_filter', array('needs_environment' => true)), 158 'length' => new Twig_Filter_Function('twig_length_filter', array('needs_environment' => true)), 159 'slice' => new Twig_Filter_Function('twig_slice', array('needs_environment' => true)), 157 new Twig_SimpleFilter('reverse', 'twig_reverse_filter', array('needs_environment' => true)), 158 new Twig_SimpleFilter('length', 'twig_length_filter', array('needs_environment' => true)), 159 new Twig_SimpleFilter('slice', 'twig_slice', array('needs_environment' => true)), 160 new Twig_SimpleFilter('first', 'twig_first', array('needs_environment' => true)), 161 new Twig_SimpleFilter('last', 'twig_last', array('needs_environment' => true)), 160 162 161 163 // iteration and runtime 162 'default' => new Twig_Filter_Node('Twig_Node_Expression_Filter_Default'), 163 '_default' => new Twig_Filter_Function('_twig_default_filter'), 164 165 'keys' => new Twig_Filter_Function('twig_get_array_keys_filter'), 164 new Twig_SimpleFilter('default', '_twig_default_filter', array('node_class' => 'Twig_Node_Expression_Filter_Default')), 165 new Twig_SimpleFilter('keys', 'twig_get_array_keys_filter'), 166 166 167 167 // escaping 168 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')),169 'e' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')),168 new Twig_SimpleFilter('escape', 'twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), 169 new Twig_SimpleFilter('e', 'twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), 170 170 ); 171 171 … … 186 186 { 187 187 return array( 188 'range' => new Twig_Function_Function('range'), 189 'constant' => new Twig_Function_Function('constant'), 190 'cycle' => new Twig_Function_Function('twig_cycle'), 191 'random' => new Twig_Function_Function('twig_random', array('needs_environment' => true)), 192 'date' => new Twig_Function_Function('twig_date_converter', array('needs_environment' => true)), 188 new Twig_SimpleFunction('range', 'range'), 189 new Twig_SimpleFunction('constant', 'twig_constant'), 190 new Twig_SimpleFunction('cycle', 'twig_cycle'), 191 new Twig_SimpleFunction('random', 'twig_random', array('needs_environment' => true)), 192 new Twig_SimpleFunction('date', 'twig_date_converter', array('needs_environment' => true)), 193 new Twig_SimpleFunction('include', 'twig_include', array('needs_environment' => true, 'needs_context' => true)), 193 194 ); 194 195 } … … 202 203 { 203 204 return array( 204 'even' => new Twig_Test_Node('Twig_Node_Expression_Test_Even'),205 'odd' => new Twig_Test_Node('Twig_Node_Expression_Test_Odd'),206 'defined' => new Twig_Test_Node('Twig_Node_Expression_Test_Defined'),207 'sameas' => new Twig_Test_Node('Twig_Node_Expression_Test_Sameas'),208 'none' => new Twig_Test_Node('Twig_Node_Expression_Test_Null'),209 'null' => new Twig_Test_Node('Twig_Node_Expression_Test_Null'),210 'divisibleby' => new Twig_Test_Node('Twig_Node_Expression_Test_Divisibleby'),211 'constant' => new Twig_Test_Node('Twig_Node_Expression_Test_Constant'),212 'empty' => new Twig_Test_Function('twig_test_empty'),213 'iterable' => new Twig_Test_Function('twig_test_iterable'),205 new Twig_SimpleTest('even', null, array('node_class' => 'Twig_Node_Expression_Test_Even')), 206 new Twig_SimpleTest('odd', null, array('node_class' => 'Twig_Node_Expression_Test_Odd')), 207 new Twig_SimpleTest('defined', null, array('node_class' => 'Twig_Node_Expression_Test_Defined')), 208 new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')), 209 new Twig_SimpleTest('none', null, array('node_class' => 'Twig_Node_Expression_Test_Null')), 210 new Twig_SimpleTest('null', null, array('node_class' => 'Twig_Node_Expression_Test_Null')), 211 new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')), 212 new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')), 213 new Twig_SimpleTest('empty', 'twig_test_empty'), 214 new Twig_SimpleTest('iterable', 'twig_test_iterable'), 214 215 ); 215 216 } … … 268 269 $arguments = null; 269 270 if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { 270 $arguments = $parser->getExpressionParser()->parseArguments( );271 } 272 273 $class = $this->getTestNodeClass($parser ->getEnvironment(), $name);271 $arguments = $parser->getExpressionParser()->parseArguments(true); 272 } 273 274 $class = $this->getTestNodeClass($parser, $name, $node->getLine()); 274 275 275 276 return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine()); 276 277 } 277 278 278 protected function getTestNodeClass(Twig_Environment $env, $name) 279 { 279 protected function getTestNodeClass(Twig_Parser $parser, $name, $line) 280 { 281 $env = $parser->getEnvironment(); 280 282 $testMap = $env->getTests(); 281 if (isset($testMap[$name]) && $testMap[$name] instanceof Twig_Test_Node) { 282 return $testMap[$name]->getClass(); 283 } 284 285 return 'Twig_Node_Expression_Test'; 283 if (!isset($testMap[$name])) { 284 $message = sprintf('The test "%s" does not exist', $name); 285 if ($alternatives = $env->computeAlternatives($name, array_keys($env->getTests()))) { 286 $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); 287 } 288 289 throw new Twig_Error_Syntax($message, $line, $parser->getFilename()); 290 } 291 292 if ($testMap[$name] instanceof Twig_SimpleTest) { 293 return $testMap[$name]->getNodeClass(); 294 } 295 296 return $testMap[$name] instanceof Twig_Test_Node ? $testMap[$name]->getClass() : 'Twig_Node_Expression_Test'; 286 297 } 287 298 … … 300 311 * Cycles over a value. 301 312 * 302 * @param ArrayAccess|array $values An array or an ArrayAccess instance303 * @param integer $ i The cycle value313 * @param ArrayAccess|array $values An array or an ArrayAccess instance 314 * @param integer $position The cycle position 304 315 * 305 316 * @return string The next value in the cycle 306 317 */ 307 function twig_cycle($values, $ i)318 function twig_cycle($values, $position) 308 319 { 309 320 if (!is_array($values) && !$values instanceof ArrayAccess) { … … 311 322 } 312 323 313 return $values[$ i% count($values)];324 return $values[$position % count($values)]; 314 325 } 315 326 … … 405 416 * 406 417 * <pre> 407 * {{ post.published_at| modify("-1day")|date("m/d/Y") }}418 * {{ post.published_at|date_modify("-1day")|date("m/d/Y") }} 408 419 * </pre> 409 420 * … … 459 470 $asString = (string) $date; 460 471 if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) { 461 $date = new DateTime('@'.$date); 472 $date = '@'.$date; 473 } 474 475 $date = new DateTime($date, $defaultTimezone); 476 if (false !== $timezone) { 462 477 $date->setTimezone($defaultTimezone); 463 464 return $date; 465 } 466 467 return new DateTime($date, $defaultTimezone); 478 } 479 480 return $date; 468 481 } 469 482 … … 621 634 622 635 /** 636 * Returns the first element of the item. 637 * 638 * @param Twig_Environment $env A Twig_Environment instance 639 * @param mixed $item A variable 640 * 641 * @return mixed The first element of the item 642 */ 643 function twig_first(Twig_Environment $env, $item) 644 { 645 $elements = twig_slice($env, $item, 0, 1, false); 646 647 return is_string($elements) ? $elements[0] : current($elements); 648 } 649 650 /** 651 * Returns the last element of the item. 652 * 653 * @param Twig_Environment $env A Twig_Environment instance 654 * @param mixed $item A variable 655 * 656 * @return mixed The last element of the item 657 */ 658 function twig_last(Twig_Environment $env, $item) 659 { 660 $elements = twig_slice($env, $item, -1, 1, false); 661 662 return is_string($elements) ? $elements[0] : current($elements); 663 } 664 665 /** 623 666 * Joins the values to a string. 624 667 * … … 774 817 function twig_in_filter($value, $compare) 775 818 { 776 $strict = is_object($value);777 778 819 if (is_array($compare)) { 779 return in_array($value, $compare, $strict);820 return in_array($value, $compare, is_object($value)); 780 821 } elseif (is_string($compare)) { 781 if (!strlen( (string)$value)) {822 if (!strlen($value)) { 782 823 return empty($compare); 783 824 } 784 825 785 826 return false !== strpos($compare, (string) $value); 786 } elseif ( is_object($compare) &&$compare instanceof Traversable) {787 return in_array($value, iterator_to_array($compare, false), $strict);827 } elseif ($compare instanceof Traversable) { 828 return in_array($value, iterator_to_array($compare, false), is_object($value)); 788 829 } 789 830 … … 1192 1233 } 1193 1234 1194 return false === $value || (empty($value) && '0' != $value);1235 return '' === $value || false === $value || null === $value || array() === $value; 1195 1236 } 1196 1237 … … 1213 1254 return $value instanceof Traversable || is_array($value); 1214 1255 } 1256 1257 /** 1258 * Renders a template. 1259 * 1260 * @param string template The template to render 1261 * @param array variables The variables to pass to the template 1262 * @param Boolean with_context Whether to pass the current context variables or not 1263 * @param Boolean ignore_missing Whether to ignore missing templates or not 1264 * @param Boolean sandboxed Whether to sandbox the template or not 1265 * 1266 * @return string The rendered template 1267 */ 1268 function twig_include(Twig_Environment $env, $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false) 1269 { 1270 if ($withContext) { 1271 $variables = array_merge($context, $variables); 1272 } 1273 1274 if ($isSandboxed = $sandboxed && $env->hasExtension('sandbox')) { 1275 $sandbox = $env->getExtension('sandbox'); 1276 if (!$alreadySandboxed = $sandbox->isSandboxed()) { 1277 $sandbox->enableSandbox(); 1278 } 1279 } 1280 1281 try { 1282 return $env->resolveTemplate($template)->display($variables); 1283 } catch (Twig_Error_Loader $e) { 1284 if (!$ignoreMissing) { 1285 throw $e; 1286 } 1287 } 1288 1289 if ($isSandboxed && !$alreadySandboxed) { 1290 $sandbox->disableSandbox(); 1291 } 1292 } 1293 1294 /** 1295 * Provides the ability to get constants from instances as well as class/global constants. 1296 * 1297 * @param string $constant The name of the constant 1298 * @param null|object $object The object to get the constant from 1299 * 1300 * @return string 1301 */ 1302 function twig_constant($constant, $object = null) 1303 { 1304 if (null !== $object) { 1305 $constant = get_class($object).'::'.$constant; 1306 } 1307 1308 return constant($constant); 1309 } -
inc/libs/twig/Extension/Debug.php
r991 r1101 28 28 29 29 return array( 30 'dump' => new Twig_Function_Function('twig_var_dump', array('is_safe' => $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true, 'needs_environment' => true)),30 new Twig_SimpleFunction('dump', 'twig_var_dump', array('is_safe' => $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true, 'needs_environment' => true)), 31 31 ); 32 32 } -
inc/libs/twig/Extension/Escaper.php
r991 r1101 46 46 { 47 47 return array( 48 'raw' => new Twig_Filter_Function('twig_raw_filter', array('is_safe' => array('all'))),48 new Twig_SimpleFilter('raw', 'twig_raw_filter', array('is_safe' => array('all'))), 49 49 ); 50 50 } -
inc/libs/twig/Extension/StringLoader.php
r991 r1101 17 17 { 18 18 return array( 19 'template_from_string' => new Twig_Function_Function('twig_template_from_string', array('needs_environment' => true)),19 new Twig_SimpleFunction('template_from_string', 'twig_template_from_string', array('needs_environment' => true)), 20 20 ); 21 21 } -
inc/libs/twig/Filter.php
r991 r1101 13 13 * Represents a template filter. 14 14 * 15 * Use Twig_SimpleFilter instead. 16 * 15 17 * @package twig 16 18 * @author Fabien Potencier <fabien@symfony.com> 19 * @deprecated since 1.12 (to be removed in 2.0) 17 20 */ 18 abstract class Twig_Filter implements Twig_FilterInterface 21 abstract class Twig_Filter implements Twig_FilterInterface, Twig_FilterCallableInterface 19 22 { 20 23 protected $options; … … 28 31 'pre_escape' => null, 29 32 'preserves_safety' => null, 33 'callable' => null, 30 34 ), $options); 31 35 } … … 73 77 return $this->options['pre_escape']; 74 78 } 79 80 public function getCallable() 81 { 82 return $this->options['callable']; 83 } 75 84 } -
inc/libs/twig/Filter/Function.php
r991 r1101 13 13 * Represents a function template filter. 14 14 * 15 * Use Twig_SimpleFilter instead. 16 * 15 17 * @package twig 16 18 * @author Fabien Potencier <fabien@symfony.com> 19 * @deprecated since 1.12 (to be removed in 2.0) 17 20 */ 18 21 class Twig_Filter_Function extends Twig_Filter … … 22 25 public function __construct($function, array $options = array()) 23 26 { 27 $options['callable'] = $function; 28 24 29 parent::__construct($options); 25 30 -
inc/libs/twig/Filter/Method.php
r991 r1101 13 13 * Represents a method template filter. 14 14 * 15 * Use Twig_SimpleFilter instead. 16 * 15 17 * @package twig 16 18 * @author Fabien Potencier <fabien@symfony.com> 19 * @deprecated since 1.12 (to be removed in 2.0) 17 20 */ 18 21 class Twig_Filter_Method extends Twig_Filter … … 23 26 public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) 24 27 { 28 $options['callable'] = array($extension, $method); 29 25 30 parent::__construct($options); 26 31 -
inc/libs/twig/Filter/Node.php
r991 r1101 13 13 * Represents a template filter as a node. 14 14 * 15 * Use Twig_SimpleFilter instead. 16 * 15 17 * @package twig 16 18 * @author Fabien Potencier <fabien@symfony.com> 19 * @deprecated since 1.12 (to be removed in 2.0) 17 20 */ 18 21 class Twig_Filter_Node extends Twig_Filter -
inc/libs/twig/FilterInterface.php
r991 r1101 13 13 * Represents a template filter. 14 14 * 15 * Use Twig_SimpleFilter instead. 16 * 15 17 * @package twig 16 18 * @author Fabien Potencier <fabien@symfony.com> 19 * @deprecated since 1.12 (to be removed in 2.0) 17 20 */ 18 21 interface Twig_FilterInterface -
inc/libs/twig/Function.php
r991 r1101 13 13 * Represents a template function. 14 14 * 15 * Use Twig_SimpleFunction instead. 16 * 15 17 * @package twig 16 18 * @author Fabien Potencier <fabien@symfony.com> 19 * @deprecated since 1.12 (to be removed in 2.0) 17 20 */ 18 abstract class Twig_Function implements Twig_FunctionInterface 21 abstract class Twig_Function implements Twig_FunctionInterface, Twig_FunctionCallableInterface 19 22 { 20 23 protected $options; … … 26 29 'needs_environment' => false, 27 30 'needs_context' => false, 31 'callable' => null, 28 32 ), $options); 29 33 } … … 61 65 return array(); 62 66 } 67 68 public function getCallable() 69 { 70 return $this->options['callable']; 71 } 63 72 } -
inc/libs/twig/Function/Function.php
r0 r1101 14 14 * Represents a function template function. 15 15 * 16 * Use Twig_SimpleFunction instead. 17 * 16 18 * @package twig 17 19 * @author Arnaud Le Blanc <arnaud.lb@gmail.com> 20 * @deprecated since 1.12 (to be removed in 2.0) 18 21 */ 19 22 class Twig_Function_Function extends Twig_Function … … 23 26 public function __construct($function, array $options = array()) 24 27 { 28 $options['callable'] = $function; 29 25 30 parent::__construct($options); 26 31 -
inc/libs/twig/Function/Method.php
r991 r1101 14 14 * Represents a method template function. 15 15 * 16 * Use Twig_SimpleFunction instead. 17 * 16 18 * @package twig 17 19 * @author Arnaud Le Blanc <arnaud.lb@gmail.com> 20 * @deprecated since 1.12 (to be removed in 2.0) 18 21 */ 19 22 class Twig_Function_Method extends Twig_Function … … 24 27 public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) 25 28 { 29 $options['callable'] = array($extension, $method); 30 26 31 parent::__construct($options); 27 32 -
inc/libs/twig/Function/Node.php
r991 r1101 13 13 * Represents a template function as a node. 14 14 * 15 * Use Twig_SimpleFunction instead. 16 * 15 17 * @package twig 16 18 * @author Fabien Potencier <fabien@symfony.com> 19 * @deprecated since 1.12 (to be removed in 2.0) 17 20 */ 18 21 class Twig_Function_Node extends Twig_Function -
inc/libs/twig/FunctionInterface.php
r991 r1101 14 14 * Represents a template function. 15 15 * 16 * Use Twig_SimpleFunction instead. 17 * 16 18 * @package twig 17 19 * @author Arnaud Le Blanc <arnaud.lb@gmail.com> 20 * @deprecated since 1.12 (to be removed in 2.0) 18 21 */ 19 22 interface Twig_FunctionInterface -
inc/libs/twig/LICENSE
r0 r1101 1 Copyright (c) 2009 by the Twig Team, see AUTHORS for more details.1 Copyright (c) 2009-2013 by the Twig Team, see AUTHORS for more details. 2 2 3 3 Some rights reserved. -
inc/libs/twig/Lexer.php
r991 r1101 62 62 'lex_var' => '/\s*'.preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_variable'][1], '/').'/A', 63 63 'lex_block' => '/\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')\n?/A', 64 'lex_raw_data' => '/('.preg_quote($this->options['tag_block'][0].$this->options['whitespace_trim'], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')\s* endraw\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/s',64 'lex_raw_data' => '/('.preg_quote($this->options['tag_block'][0].$this->options['whitespace_trim'], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')\s*(?:end%s)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/s', 65 65 'operator' => $this->getOperatorRegex(), 66 66 'lex_comment' => '/(?:'.preg_quote($this->options['whitespace_trim'], '/').preg_quote($this->options['tag_comment'][1], '/').'\s*|'.preg_quote($this->options['tag_comment'][1], '/').')\n?/s', 67 'lex_block_raw' => '/\s* raw\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/As',67 'lex_block_raw' => '/\s*(raw|verbatim)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/As', 68 68 'lex_block_line' => '/\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '/').'/As', 69 69 'lex_tokens_start' => '/('.preg_quote($this->options['tag_variable'][0], '/').'|'.preg_quote($this->options['tag_block'][0], '/').'|'.preg_quote($this->options['tag_comment'][0], '/').')('.preg_quote($this->options['whitespace_trim'], '/').')?/s', … … 179 179 if (preg_match($this->regexes['lex_block_raw'], $this->code, $match, null, $this->cursor)) { 180 180 $this->moveCursor($match[0]); 181 $this->lexRawData( );181 $this->lexRawData($match[1]); 182 182 // {% line \d+ %} 183 183 } elseif (preg_match($this->regexes['lex_block_line'], $this->code, $match, null, $this->cursor)) { … … 287 287 } 288 288 289 protected function lexRawData( )290 { 291 if (!preg_match( $this->regexes['lex_raw_data'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {292 throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed " block"'), $this->lineno, $this->filename);289 protected function lexRawData($tag) 290 { 291 if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { 292 throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s" block', $tag), $this->lineno, $this->filename); 293 293 } 294 294 -
inc/libs/twig/LexerInterface.php
r991 r1101 15 15 * @package twig 16 16 * @author Fabien Potencier <fabien@symfony.com> 17 * @deprecated since 1.12 (to be removed in 2.0) 17 18 */ 18 19 interface Twig_LexerInterface -
inc/libs/twig/Node/Expression/Filter.php
r991 r1101 10 10 * file that was distributed with this source code. 11 11 */ 12 class Twig_Node_Expression_Filter extends Twig_Node_Expression 12 class Twig_Node_Expression_Filter extends Twig_Node_Expression_Call 13 13 { 14 14 public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) … … 20 20 { 21 21 $name = $this->getNode('filter')->getAttribute('value'); 22 $filter = $compiler->getEnvironment()->getFilter($name); 22 23 23 if (false === $filter = $compiler->getEnvironment()->getFilter($name)) { 24 $message = sprintf('The filter "%s" does not exist', $name); 25 if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFilters()))) { 26 $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); 27 } 28 29 throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename()); 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()); 30 32 } 31 33 32 $this->compileFilter($compiler, $filter); 33 } 34 35 protected function compileFilter(Twig_Compiler $compiler, Twig_FilterInterface $filter) 36 { 37 $compiler 38 ->raw($filter->compile().'(') 39 ->raw($filter->needsEnvironment() ? '$this->env, ' : '') 40 ->raw($filter->needsContext() ? '$context, ' : '') 41 ; 42 43 foreach ($filter->getArguments() as $argument) { 44 $compiler 45 ->string($argument) 46 ->raw(', ') 47 ; 48 } 49 50 $compiler->subcompile($this->getNode('node')); 51 52 foreach ($this->getNode('arguments') as $node) { 53 $compiler 54 ->raw(', ') 55 ->subcompile($node) 56 ; 57 } 58 59 $compiler->raw(')'); 34 $this->compileCallable($compiler); 60 35 } 61 36 } -
inc/libs/twig/Node/Expression/Filter/Default.php
r991 r1101 24 24 public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) 25 25 { 26 $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant(' _default', $node->getLine()), $arguments, $node->getLine());26 $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getLine()), $arguments, $node->getLine()); 27 27 28 28 if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) { -
inc/libs/twig/Node/Expression/Function.php
r991 r1101 9 9 * file that was distributed with this source code. 10 10 */ 11 class Twig_Node_Expression_Function extends Twig_Node_Expression 11 class Twig_Node_Expression_Function extends Twig_Node_Expression_Call 12 12 { 13 13 public function __construct($name, Twig_NodeInterface $arguments, $lineno) … … 19 19 { 20 20 $name = $this->getAttribute('name'); 21 $function = $compiler->getEnvironment()->getFunction($name); 21 22 22 if (false === $function = $compiler->getEnvironment()->getFunction($name)) { 23 $message = sprintf('The function "%s" does not exist', $name); 24 if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFunctions()))) { 25 $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); 26 } 27 28 throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename()); 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 $this->setAttribute('callable', $function->getCallable()); 29 31 } 30 32 31 $compiler->raw($function->compile().'('); 32 33 $first = true; 34 35 if ($function->needsEnvironment()) { 36 $compiler->raw('$this->env'); 37 $first = false; 38 } 39 40 if ($function->needsContext()) { 41 if (!$first) { 42 $compiler->raw(', '); 43 } 44 $compiler->raw('$context'); 45 $first = false; 46 } 47 48 foreach ($function->getArguments() as $argument) { 49 if (!$first) { 50 $compiler->raw(', '); 51 } 52 $compiler->string($argument); 53 $first = false; 54 } 55 56 foreach ($this->getNode('arguments') as $node) { 57 if (!$first) { 58 $compiler->raw(', '); 59 } 60 $compiler->subcompile($node); 61 $first = false; 62 } 63 64 $compiler->raw(')'); 33 $this->compileCallable($compiler); 65 34 } 66 35 } -
inc/libs/twig/Node/Expression/Test.php
r991 r1101 9 9 * file that was distributed with this source code. 10 10 */ 11 class Twig_Node_Expression_Test extends Twig_Node_Expression 11 class Twig_Node_Expression_Test extends Twig_Node_Expression_Call 12 12 { 13 13 public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno) … … 19 19 { 20 20 $name = $this->getAttribute('name'); 21 $testMap = $compiler->getEnvironment()->getTests(); 22 if (!isset($testMap[$name])) { 23 $message = sprintf('The test "%s" does not exist', $name); 24 if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getTests()))) { 25 $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); 26 } 21 $test = $compiler->getEnvironment()->getTest($name); 27 22 28 throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename()); 23 $this->setAttribute('name', $name); 24 $this->setAttribute('type', 'test'); 25 $this->setAttribute('thing', $test); 26 if ($test instanceof Twig_TestCallableInterface || $test instanceof Twig_SimpleTest) { 27 $this->setAttribute('callable', $test->getCallable()); 29 28 } 30 29 31 $name = $this->getAttribute('name'); 32 $node = $this->getNode('node'); 33 34 $compiler 35 ->raw($testMap[$name]->compile().'(') 36 ->subcompile($node) 37 ; 38 39 if (null !== $this->getNode('arguments')) { 40 $compiler->raw(', '); 41 42 $max = count($this->getNode('arguments')) - 1; 43 foreach ($this->getNode('arguments') as $i => $arg) { 44 $compiler->subcompile($arg); 45 46 if ($i != $max) { 47 $compiler->raw(', '); 48 } 49 } 50 } 51 52 $compiler->raw(')'); 30 $this->compileCallable($compiler); 53 31 } 54 32 } -
inc/libs/twig/Node/Macro.php
r991 r1101 30 30 public function compile(Twig_Compiler $compiler) 31 31 { 32 $arguments = array(); 33 foreach ($this->getNode('arguments') as $argument) { 34 $arguments[] = '$_'.$argument->getAttribute('name').' = null'; 32 $compiler 33 ->addDebugInfo($this) 34 ->write(sprintf("public function get%s(", $this->getAttribute('name'))) 35 ; 36 37 $count = count($this->getNode('arguments')); 38 $pos = 0; 39 foreach ($this->getNode('arguments') as $name => $default) { 40 $compiler 41 ->raw('$_'.$name.' = ') 42 ->subcompile($default) 43 ; 44 45 if (++$pos < $count) { 46 $compiler->raw(', '); 47 } 35 48 } 36 49 37 50 $compiler 38 -> addDebugInfo($this)39 ->write( sprintf("public function get%s(%s)\n", $this->getAttribute('name'), implode(', ', $arguments)),"{\n")51 ->raw(")\n") 52 ->write("{\n") 40 53 ->indent() 41 54 ; … … 49 62 ; 50 63 51 foreach ($this->getNode('arguments') as $ argument) {64 foreach ($this->getNode('arguments') as $name => $default) { 52 65 $compiler 53 66 ->write('') 54 ->string($ argument->getAttribute('name'))55 ->raw(' => $_'.$ argument->getAttribute('name'))67 ->string($name) 68 ->raw(' => $_'.$name) 56 69 ->raw(",\n") 57 70 ; -
inc/libs/twig/NodeInterface.php
r991 r1101 15 15 * @package twig 16 16 * @author Fabien Potencier <fabien@symfony.com> 17 * @deprecated since 1.12 (to be removed in 2.0) 17 18 */ 18 19 interface Twig_NodeInterface extends Countable, IteratorAggregate -
inc/libs/twig/NodeVisitor/Escaper.php
r991 r1101 108 108 $name = $filter->getNode('filter')->getAttribute('value'); 109 109 110 if (false !== $f = $env->getFilter($name)) { 111 $type = $f->getPreEscape(); 112 if (null === $type) { 113 return $filter; 114 } 115 116 $node = $filter->getNode('node'); 117 if ($this->isSafeFor($type, $node, $env)) { 118 return $filter; 119 } 120 121 $filter->setNode('node', $this->getEscaperFilter($type, $node)); 122 110 $type = $env->getFilter($name)->getPreEscape(); 111 if (null === $type) { 123 112 return $filter; 124 113 } 114 115 $node = $filter->getNode('node'); 116 if ($this->isSafeFor($type, $node, $env)) { 117 return $filter; 118 } 119 120 $filter->setNode('node', $this->getEscaperFilter($type, $node)); 125 121 126 122 return $filter; -
inc/libs/twig/ParserInterface.php
r991 r1101 13 13 * Interface implemented by parser classes. 14 14 * 15 * @package twig 16 * @author Fabien Potencier <fabien@symfony.com> 15 * @package twig 16 * @author Fabien Potencier <fabien@symfony.com> 17 * @deprecated since 1.12 (to be removed in 2.0) 17 18 */ 18 19 interface Twig_ParserInterface -
inc/libs/twig/TemplateInterface.php
r991 r1101 13 13 * Interface implemented by all compiled templates. 14 14 * 15 * @package twig 16 * @author Fabien Potencier <fabien@symfony.com> 15 * @package twig 16 * @author Fabien Potencier <fabien@symfony.com> 17 * @deprecated since 1.12 (to be removed in 2.0) 17 18 */ 18 19 interface Twig_TemplateInterface -
inc/libs/twig/Test/Function.php
r991 r1101 15 15 * @package twig 16 16 * @author Fabien Potencier <fabien@symfony.com> 17 * @deprecated since 1.12 (to be removed in 2.0) 17 18 */ 18 class Twig_Test_Function implements Twig_TestInterface19 class Twig_Test_Function extends Twig_Test 19 20 { 20 21 protected $function; 21 22 22 public function __construct($function )23 public function __construct($function, array $options = array()) 23 24 { 25 $options['callable'] = $function; 26 27 parent::__construct($options); 28 24 29 $this->function = $function; 25 30 } -
inc/libs/twig/Test/Method.php
r991 r1101 15 15 * @package twig 16 16 * @author Fabien Potencier <fabien@symfony.com> 17 * @deprecated since 1.12 (to be removed in 2.0) 17 18 */ 18 class Twig_Test_Method implements Twig_TestInterface19 class Twig_Test_Method extends Twig_Test 19 20 { 20 21 protected $extension; 21 22 protected $method; 22 23 23 public function __construct(Twig_ExtensionInterface $extension, $method )24 public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) 24 25 { 26 $options['callable'] = array($extension, $method); 27 28 parent::__construct($options); 29 25 30 $this->extension = $extension; 26 31 $this->method = $method; -
inc/libs/twig/Test/Node.php
r991 r1101 15 15 * @package twig 16 16 * @author Fabien Potencier <fabien@symfony.com> 17 * @deprecated since 1.12 (to be removed in 2.0) 17 18 */ 18 class Twig_Test_Node implements Twig_TestInterface19 class Twig_Test_Node extends Twig_Test 19 20 { 20 21 protected $class; 21 22 22 public function __construct($class )23 public function __construct($class, array $options = array()) 23 24 { 25 parent::__construct($options); 26 24 27 $this->class = $class; 25 28 } -
inc/libs/twig/TestInterface.php
r991 r1101 15 15 * @package twig 16 16 * @author Fabien Potencier <fabien@symfony.com> 17 * @deprecated since 1.12 (to be removed in 2.0) 17 18 */ 18 19 interface Twig_TestInterface -
inc/libs/twig/TokenParser/For.php
r991 r1101 34 34 { 35 35 $lineno = $token->getLine(); 36 $stream = $this->parser->getStream(); 36 37 $targets = $this->parser->getExpressionParser()->parseAssignmentExpression(); 37 $ this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, 'in');38 $stream->expect(Twig_Token::OPERATOR_TYPE, 'in'); 38 39 $seq = $this->parser->getExpressionParser()->parseExpression(); 39 40 40 41 $ifexpr = null; 41 if ($ this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'if')) {42 $ this->parser->getStream()->next();42 if ($stream->test(Twig_Token::NAME_TYPE, 'if')) { 43 $stream->next(); 43 44 $ifexpr = $this->parser->getExpressionParser()->parseExpression(); 44 45 } 45 46 46 $ this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);47 $stream->expect(Twig_Token::BLOCK_END_TYPE); 47 48 $body = $this->parser->subparse(array($this, 'decideForFork')); 48 if ($ this->parser->getStream()->next()->getValue() == 'else') {49 $ this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);49 if ($stream->next()->getValue() == 'else') { 50 $stream->expect(Twig_Token::BLOCK_END_TYPE); 50 51 $else = $this->parser->subparse(array($this, 'decideForEnd'), true); 51 52 } else { 52 53 $else = null; 53 54 } 54 $ this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);55 $stream->expect(Twig_Token::BLOCK_END_TYPE); 55 56 56 57 if (count($targets) > 1) { … … 63 64 $valueTarget = $targets->getNode(0); 64 65 $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); 66 } 67 68 if ($ifexpr) { 69 $this->checkLoopUsageCondition($stream, $ifexpr); 70 $this->checkLoopUsageBody($stream, $body); 65 71 } 66 72 … … 78 84 } 79 85 86 // the loop variable cannot be used in the condition 87 protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node) 88 { 89 if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) { 90 throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition', $node->getLine(), $stream->getFilename()); 91 } 92 93 foreach ($node as $n) { 94 if (!$n) { 95 continue; 96 } 97 98 $this->checkLoopUsageCondition($stream, $n); 99 } 100 } 101 102 // check usage of non-defined loop-items 103 // it does not catch all problems (for instance when a for is included into another or when the variable is used in an include) 104 protected function checkLoopUsageBody(Twig_TokenStream $stream, Twig_NodeInterface $node) 105 { 106 if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) { 107 $attribute = $node->getNode('attribute'); 108 if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) { 109 throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition', $attribute->getAttribute('value')), $node->getLine(), $stream->getFilename()); 110 } 111 } 112 113 // should check for parent.loop.XXX usage 114 if ($node instanceof Twig_Node_For) { 115 return; 116 } 117 118 foreach ($node as $n) { 119 if (!$n) { 120 continue; 121 } 122 123 $this->checkLoopUsageBody($stream, $n); 124 } 125 } 126 80 127 /** 81 128 * Gets the tag name associated with this token parser. -
inc/libs/twig/TokenParser/Macro.php
r991 r1101 34 34 $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); 35 35 36 $arguments = $this->parser->getExpressionParser()->parseArguments( );36 $arguments = $this->parser->getExpressionParser()->parseArguments(true, true); 37 37 38 38 $stream->expect(Twig_Token::BLOCK_END_TYPE); -
inc/libs/twig/TokenParserBroker.php
r991 r1101 14 14 * Default implementation of a token parser broker. 15 15 * 16 * @package twig 17 * @author Arnaud Le Blanc <arnaud.lb@gmail.com> 16 * @package twig 17 * @author Arnaud Le Blanc <arnaud.lb@gmail.com> 18 * @deprecated since 1.12 (to be removed in 2.0) 18 19 */ 19 20 class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface … … 56 57 57 58 /** 59 * Removes a TokenParser. 60 * 61 * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance 62 */ 63 public function removeTokenParser(Twig_TokenParserInterface $parser) 64 { 65 $name = $parser->getTag(); 66 if (isset($this->parsers[$name]) && $parser === $this->parsers[$name]) { 67 unset($this->parsers[$name]); 68 } 69 } 70 71 /** 58 72 * Adds a TokenParserBroker. 59 73 * … … 63 77 { 64 78 $this->brokers[] = $broker; 79 } 80 81 /** 82 * Removes a TokenParserBroker. 83 * 84 * @param Twig_TokenParserBroker $broker A Twig_TokenParserBroker instance 85 */ 86 public function removeTokenParserBroker(Twig_TokenParserBroker $broker) 87 { 88 if (false !== $pos = array_search($broker, $this->brokers)) { 89 unset($this->brokers[$pos]); 90 } 65 91 } 66 92 -
inc/libs/twig/TokenParserBrokerInterface.php
r991 r1101 16 16 * Token parser brokers allows to implement custom logic in the process of resolving a token parser for a given tag name. 17 17 * 18 * @package twig 19 * @author Arnaud Le Blanc <arnaud.lb@gmail.com> 18 * @package twig 19 * @author Arnaud Le Blanc <arnaud.lb@gmail.com> 20 * @deprecated since 1.12 (to be removed in 2.0) 20 21 */ 21 22 interface Twig_TokenParserBrokerInterface -
inc/libs/twig/TokenStream.php
r991 r1101 59 59 { 60 60 if (!isset($this->tokens[++$this->current])) { 61 throw new Twig_Error_Syntax('Unexpected end of template', $this->token [$this->current - 1]->getLine(), $this->filename);61 throw new Twig_Error_Syntax('Unexpected end of template', $this->tokens[$this->current - 1]->getLine(), $this->filename); 62 62 } 63 63 … … 98 98 { 99 99 if (!isset($this->tokens[$this->current + $number])) { 100 throw new Twig_Error_Syntax('Unexpected end of template', $this->token [$this->current + $number - 1]->getLine(), $this->filename);100 throw new Twig_Error_Syntax('Unexpected end of template', $this->tokens[$this->current + $number - 1]->getLine(), $this->filename); 101 101 } 102 102
Note: See TracChangeset
for help on using the changeset viewer.