Timber - Version 1.1.9

Version Description

  • Timber now retrieves native term meta info #824
  • Added site icon support in Theme #1210
  • Fixes to menu getting by slug #1237 (thanks @motia)
  • Fix to off-site image URLs! #1234 (thanks @njbarrett)
  • Fix inconsistency with Post::get_terms #1222 (thanks @haroldangenent)
Download this release

Release Info

Developer jarednova
Plugin Icon 128x128 Timber
Version 1.1.9
Comparing to
See all releases

Code changes from version 1.1.8 to 1.1.9

Files changed (143) hide show
  1. lib/Helper.php +2 -2
  2. lib/ImageHelper.php +9 -9
  3. lib/Loader.php +2 -1
  4. lib/Menu.php +9 -7
  5. lib/Post.php +2 -2
  6. lib/PostCollection.php +0 -5
  7. lib/PostQuery.php +9 -7
  8. lib/Site.php +21 -0
  9. lib/Term.php +6 -3
  10. lib/Timber.php +1 -1
  11. readme.txt +9 -1
  12. timber-starter-theme/functions.php +7 -2
  13. timber-starter-theme/index.php +0 -4
  14. timber-starter-theme/static/no-timber.html +10 -0
  15. timber.php +1 -1
  16. vendor/autoload.php +1 -1
  17. vendor/composer/autoload_real.php +3 -3
  18. vendor/composer/installed.json +7 -7
  19. vendor/twig/twig/.travis.yml +1 -1
  20. vendor/twig/twig/CHANGELOG +43 -1
  21. vendor/twig/twig/composer.json +1 -1
  22. vendor/twig/twig/doc/advanced.rst +113 -26
  23. vendor/twig/twig/doc/api.rst +27 -5
  24. vendor/twig/twig/doc/deprecated.rst +51 -3
  25. vendor/twig/twig/doc/filters/date.rst +6 -0
  26. vendor/twig/twig/doc/filters/escape.rst +3 -0
  27. vendor/twig/twig/doc/filters/number_format.rst +3 -0
  28. vendor/twig/twig/doc/functions/date.rst +3 -0
  29. vendor/twig/twig/doc/internals.rst +5 -1
  30. vendor/twig/twig/doc/recipes.rst +53 -3
  31. vendor/twig/twig/doc/tags/embed.rst +4 -4
  32. vendor/twig/twig/doc/tests/empty.rst +2 -2
  33. vendor/twig/twig/ext/twig/php_twig.h +1 -1
  34. vendor/twig/twig/ext/twig/twig.c +22 -22
  35. vendor/twig/twig/lib/Twig/Compiler.php +18 -9
  36. vendor/twig/twig/lib/Twig/Environment.php +177 -46
  37. vendor/twig/twig/lib/Twig/Error.php +49 -18
  38. vendor/twig/twig/lib/Twig/ExpressionParser.php +114 -31
  39. vendor/twig/twig/lib/Twig/Extension.php +10 -0
  40. vendor/twig/twig/lib/Twig/Extension/Core.php +18 -81
  41. vendor/twig/twig/lib/Twig/Extension/Escaper.php +10 -4
  42. vendor/twig/twig/lib/Twig/Extension/Profiler.php +1 -1
  43. vendor/twig/twig/lib/Twig/ExtensionInterface.php +2 -0
  44. vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php +7 -7
  45. vendor/twig/twig/lib/Twig/Filter/Method.php +1 -1
  46. vendor/twig/twig/lib/Twig/Function/Method.php +1 -1
  47. vendor/twig/twig/lib/Twig/Lexer.php +13 -5
  48. vendor/twig/twig/lib/Twig/LexerInterface.php +3 -3
  49. vendor/twig/twig/lib/Twig/Loader/Array.php +16 -1
  50. vendor/twig/twig/lib/Twig/Loader/Chain.php +33 -2
  51. vendor/twig/twig/lib/Twig/Loader/Filesystem.php +55 -10
  52. vendor/twig/twig/lib/Twig/Loader/String.php +11 -1
  53. vendor/twig/twig/lib/Twig/LoaderInterface.php +2 -0
  54. vendor/twig/twig/lib/Twig/Node.php +56 -0
  55. vendor/twig/twig/lib/Twig/Node/CheckSecurity.php +3 -3
  56. vendor/twig/twig/lib/Twig/Node/Embed.php +7 -5
  57. vendor/twig/twig/lib/Twig/Node/Expression/Array.php +1 -1
  58. vendor/twig/twig/lib/Twig/Node/Expression/Call.php +54 -18
  59. vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php +4 -4
  60. vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php +8 -3
  61. vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php +3 -3
  62. vendor/twig/twig/lib/Twig/Node/Expression/Test.php +6 -1
  63. vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php +2 -2
  64. vendor/twig/twig/lib/Twig/Node/For.php +9 -4
  65. vendor/twig/twig/lib/Twig/Node/If.php +7 -2
  66. vendor/twig/twig/lib/Twig/Node/Import.php +2 -2
  67. vendor/twig/twig/lib/Twig/Node/Include.php +9 -4
  68. vendor/twig/twig/lib/Twig/Node/Macro.php +3 -3
  69. vendor/twig/twig/lib/Twig/Node/Module.php +79 -23
  70. vendor/twig/twig/lib/Twig/Node/Sandbox.php +1 -1
  71. vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php +1 -1
  72. vendor/twig/twig/lib/Twig/Node/Set.php +1 -1
  73. vendor/twig/twig/lib/Twig/NodeInterface.php +3 -0
  74. vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php +3 -3
  75. vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php +4 -4
  76. vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php +1 -1
  77. vendor/twig/twig/lib/Twig/Parser.php +34 -13
  78. vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php +3 -3
  79. vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php +27 -0
  80. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php +38 -0
  81. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php +38 -0
  82. vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php +4 -2
  83. vendor/twig/twig/lib/Twig/Source.php +49 -0
  84. vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php +31 -0
  85. vendor/twig/twig/lib/Twig/Template.php +60 -51
  86. vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php +11 -5
  87. vendor/twig/twig/lib/Twig/Test/Method.php +1 -1
  88. vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php +2 -2
  89. vendor/twig/twig/lib/Twig/TokenParser/Block.php +2 -2
  90. vendor/twig/twig/lib/Twig/TokenParser/Embed.php +12 -3
  91. vendor/twig/twig/lib/Twig/TokenParser/Extends.php +5 -3
  92. vendor/twig/twig/lib/Twig/TokenParser/For.php +5 -5
  93. vendor/twig/twig/lib/Twig/TokenParser/From.php +1 -1
  94. vendor/twig/twig/lib/Twig/TokenParser/If.php +1 -1
  95. vendor/twig/twig/lib/Twig/TokenParser/Macro.php +1 -1
  96. vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php +4 -3
  97. vendor/twig/twig/lib/Twig/TokenParser/Set.php +2 -2
  98. vendor/twig/twig/lib/Twig/TokenParser/Use.php +1 -1
  99. vendor/twig/twig/lib/Twig/TokenStream.php +56 -10
  100. vendor/twig/twig/test/Twig/Tests/Cache/FilesystemTest.php +1 -1
  101. vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php +165 -48
  102. vendor/twig/twig/test/Twig/Tests/ErrorTest.php +8 -8
  103. vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php +17 -17
  104. vendor/twig/twig/test/Twig/Tests/Extension/CoreTest.php +1 -1
  105. vendor/twig/twig/test/Twig/Tests/Extension/SandboxTest.php +65 -0
  106. vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/block.test +1 -1
  107. vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/name.test +18 -0
  108. vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/child_contents_outside_blocks.test +15 -0
  109. vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable.test +1 -1
  110. vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable_again.test +1 -1
  111. vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_undefined_variable.test +1 -1
  112. vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_tag_with_undefined_variable.test +1 -1
  113. vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/magic_call.test +11 -11
  114. vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format.test +1 -1
  115. vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format_interval.test +1 -1
  116. vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format_default.test +1 -1
  117. vendor/twig/twig/test/Twig/Tests/Fixtures/filters/static_calls.test +10 -0
  118. vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call.test +8 -0
  119. vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call53.test +12 -0
  120. vendor/twig/twig/test/Twig/Tests/Fixtures/functions/static_calls.test +10 -0
  121. vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs_argument.test +0 -1
  122. vendor/twig/twig/test/Twig/Tests/Fixtures/regression/combined_debug_info.test +1 -1
  123. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/complex_dynamic_parent.test +35 -0
  124. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/dynamic_parent.test +35 -0
  125. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/error_line.test +1 -1
  126. vendor/twig/twig/test/Twig/Tests/IntegrationTest.php +27 -2
  127. vendor/twig/twig/test/Twig/Tests/{Fixtures/autoescape/filename.test → LegacyFixtures/autoescape/filename.legacy.test} +0 -0
  128. vendor/twig/twig/test/Twig/Tests/LexerTest.php +33 -22
  129. vendor/twig/twig/test/Twig/Tests/Loader/ArrayTest.php +16 -2
  130. vendor/twig/twig/test/Twig/Tests/Loader/ChainTest.php +46 -5
  131. vendor/twig/twig/test/Twig/Tests/Loader/FilesystemTest.php +64 -13
  132. vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/phar/phar-sample.phar +0 -0
  133. vendor/twig/twig/test/Twig/Tests/Node/ForTest.php +1 -1
  134. vendor/twig/twig/test/Twig/Tests/Node/IfTest.php +1 -1
  135. vendor/twig/twig/test/Twig/Tests/Node/IncludeTest.php +1 -1
  136. vendor/twig/twig/test/Twig/Tests/Node/ModuleTest.php +47 -7
  137. vendor/twig/twig/test/Twig/Tests/Node/SandboxTest.php +1 -1
  138. vendor/twig/twig/test/Twig/Tests/Node/SandboxedPrintTest.php +1 -1
  139. vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php +4 -4
  140. vendor/twig/twig/test/Twig/Tests/ParserTest.php +4 -3
  141. vendor/twig/twig/test/Twig/Tests/TemplateTest.php +23 -27
  142. vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php +12 -0
  143. vendor/twig/twig/test/Twig/Tests/escapingTest.php +1 -1
lib/Helper.php CHANGED
@@ -15,11 +15,11 @@ class Helper {
15
  * @api
16
  * @example
17
  * ```php
18
- * $favorites = Timber::transient('user-'.$uid.'-favorites', function() use ($uid) {
 
19
  * //some expensive query here that's doing something you want to store to a transient
20
  * return $favorites;
21
  * }, 600);
22
- * Timber::context['favorites'] = $favorites;
23
  * Timber::render('single.twig', $context);
24
  * ```
25
  *
15
  * @api
16
  * @example
17
  * ```php
18
+ * $context = Timber::get_context();
19
+ * $context['favorites'] = Timber\Helper::transient('user-' .$uid. '-favorites', function() use ($uid) {
20
  * //some expensive query here that's doing something you want to store to a transient
21
  * return $favorites;
22
  * }, 600);
 
23
  * Timber::render('single.twig', $context);
24
  * ```
25
  *
lib/ImageHelper.php CHANGED
@@ -185,7 +185,7 @@ class ImageHelper {
185
  */
186
  protected static function add_constants() {
187
  if ( !defined('WP_CONTENT_SUBDIR') ) {
188
- $wp_content_path = str_replace(site_url(), '', WP_CONTENT_URL);
189
  define('WP_CONTENT_SUBDIR', $wp_content_path);
190
  }
191
  }
@@ -197,14 +197,14 @@ class ImageHelper {
197
  */
198
  static function add_filters() {
199
  add_filter('upload_dir', function( $arr ) {
200
- $arr['relative'] = str_replace(site_url(), '', $arr['baseurl']);
201
  return $arr;
202
  } );
203
  }
204
 
205
  //-- end of public methods --//
206
 
207
-
208
  /**
209
  * Checks if attachment is an image before deleting generated files
210
  *
@@ -219,8 +219,8 @@ class ImageHelper {
219
  }
220
  }
221
  }
222
-
223
-
224
  /**
225
  * Deletes the auto-generated files for resize and letterboxing created by Timber
226
  * @param string $local_file ex: /var/www/wp-content/uploads/2015/my-pic.jpg
@@ -312,7 +312,7 @@ class ImageHelper {
312
  public static function sideload_image( $file ) {
313
  $loc = self::get_sideloaded_file_loc($file);
314
  if ( file_exists($loc) ) {
315
- return URLHelper::preslashit(URLHelper::get_rel_path($loc));
316
  }
317
  // Download file to temp location
318
  if ( !function_exists('download_url') ) {
@@ -355,7 +355,7 @@ class ImageHelper {
355
  $upload_dir = wp_upload_dir();
356
  $tmp = $url;
357
  if ( 0 === strpos($tmp, ABSPATH) ) {
358
- // we've been given a dir, not an url
359
  $result['absolute'] = true;
360
  if ( 0 === strpos($tmp, $upload_dir['basedir']) ) {
361
  $result['base'] = self::BASE_UPLOADS; // upload based
@@ -484,10 +484,10 @@ class ImageHelper {
484
  $au['subdir'],
485
  $au['basename']
486
  );
487
-
488
  $new_url = apply_filters('timber/image/new_url', $new_url);
489
  $destination_path = apply_filters('timber/image/new_path', $destination_path);
490
-
491
  // if already exists...
492
  if ( file_exists($destination_path) ) {
493
  if ( $force || filemtime($source_path) > filemtime($destination_path) ) {
185
  */
186
  protected static function add_constants() {
187
  if ( !defined('WP_CONTENT_SUBDIR') ) {
188
+ $wp_content_path = str_replace(get_home_url(), '', WP_CONTENT_URL);
189
  define('WP_CONTENT_SUBDIR', $wp_content_path);
190
  }
191
  }
197
  */
198
  static function add_filters() {
199
  add_filter('upload_dir', function( $arr ) {
200
+ $arr['relative'] = str_replace(get_home_url(), '', $arr['baseurl']);
201
  return $arr;
202
  } );
203
  }
204
 
205
  //-- end of public methods --//
206
 
207
+
208
  /**
209
  * Checks if attachment is an image before deleting generated files
210
  *
219
  }
220
  }
221
  }
222
+
223
+
224
  /**
225
  * Deletes the auto-generated files for resize and letterboxing created by Timber
226
  * @param string $local_file ex: /var/www/wp-content/uploads/2015/my-pic.jpg
312
  public static function sideload_image( $file ) {
313
  $loc = self::get_sideloaded_file_loc($file);
314
  if ( file_exists($loc) ) {
315
+ return URLHelper::file_system_to_url($loc);
316
  }
317
  // Download file to temp location
318
  if ( !function_exists('download_url') ) {
355
  $upload_dir = wp_upload_dir();
356
  $tmp = $url;
357
  if ( 0 === strpos($tmp, ABSPATH) ) {
358
+ // we've been given a dir, not an url
359
  $result['absolute'] = true;
360
  if ( 0 === strpos($tmp, $upload_dir['basedir']) ) {
361
  $result['base'] = self::BASE_UPLOADS; // upload based
484
  $au['subdir'],
485
  $au['basename']
486
  );
487
+
488
  $new_url = apply_filters('timber/image/new_url', $new_url);
489
  $destination_path = apply_filters('timber/image/new_path', $destination_path);
490
+
491
  // if already exists...
492
  if ( file_exists($destination_path) ) {
493
  if ( $force || filemtime($source_path) > filemtime($destination_path) ) {
lib/Loader.php CHANGED
@@ -124,7 +124,8 @@ class Loader {
124
  public function get_loader() {
125
  $paths = array_merge($this->locations, array(ini_get('open_basedir') ? ABSPATH : '/'));
126
  $paths = apply_filters('timber/loader/paths', $paths);
127
- return new \Twig_Loader_Filesystem($paths);
 
128
  }
129
 
130
 
124
  public function get_loader() {
125
  $paths = array_merge($this->locations, array(ini_get('open_basedir') ? ABSPATH : '/'));
126
  $paths = apply_filters('timber/loader/paths', $paths);
127
+ $fs = new \Twig_Loader_Filesystem($paths, '/');
128
+ return $fs;
129
  }
130
 
131
 
lib/Menu.php CHANGED
@@ -80,6 +80,7 @@ class Menu extends Core {
80
  * @param integer|string $slug
81
  */
82
  public function __construct( $slug = 0 ) {
 
83
  $locations = get_nav_menu_locations();
84
  if ( $slug != 0 && is_numeric($slug) ) {
85
  $menu_id = $slug;
@@ -87,7 +88,8 @@ class Menu extends Core {
87
  $menu_id = $this->get_menu_id_from_locations($slug, $locations);
88
  } else if ( $slug === false ) {
89
  $menu_id = false;
90
- } else {
 
91
  $menu_id = $this->get_menu_id_from_terms($slug);
92
  }
93
  if ( $menu_id ) {
@@ -161,13 +163,13 @@ class Menu extends Core {
161
  protected function get_menu_id_from_terms( $slug = 0 ) {
162
  if ( !is_numeric($slug) && is_string($slug) ) {
163
  //we have a string so lets search for that
164
- $menu_id = get_term_by('slug', $slug, 'nav_menu');
165
- if ( $menu_id ) {
166
- return $menu_id;
167
  }
168
- $menu_id = get_term_by('name', $slug, 'nav_menu');
169
- if ( $menu_id ) {
170
- return $menu_id;
171
  }
172
  }
173
  $menus = get_terms('nav_menu', array('hide_empty' => true));
80
  * @param integer|string $slug
81
  */
82
  public function __construct( $slug = 0 ) {
83
+ $menu_id = false;
84
  $locations = get_nav_menu_locations();
85
  if ( $slug != 0 && is_numeric($slug) ) {
86
  $menu_id = $slug;
88
  $menu_id = $this->get_menu_id_from_locations($slug, $locations);
89
  } else if ( $slug === false ) {
90
  $menu_id = false;
91
+ }
92
+ if ( !$menu_id ) {
93
  $menu_id = $this->get_menu_id_from_terms($slug);
94
  }
95
  if ( $menu_id ) {
163
  protected function get_menu_id_from_terms( $slug = 0 ) {
164
  if ( !is_numeric($slug) && is_string($slug) ) {
165
  //we have a string so lets search for that
166
+ $menu = get_term_by('slug', $slug, 'nav_menu');
167
+ if ( $menu ) {
168
+ return $menu->term_id;
169
  }
170
+ $menu = get_term_by('name', $slug, 'nav_menu');
171
+ if ( $menu ) {
172
+ return $menu->term_id;
173
  }
174
  }
175
  $menus = get_terms('nav_menu', array('hide_empty' => true));
lib/Post.php CHANGED
@@ -1459,8 +1459,8 @@ class Post extends Core implements CoreInterface {
1459
  * @param bool $merge Should the resulting array be one big one (true)? Or should it be an array of sub-arrays for each taxonomy (false)?
1460
  * @return array
1461
  */
1462
- public function get_terms( $tax = '', $merge = true ) {
1463
- return $this->terms($tax, $merge);
1464
  }
1465
 
1466
  /**
1459
  * @param bool $merge Should the resulting array be one big one (true)? Or should it be an array of sub-arrays for each taxonomy (false)?
1460
  * @return array
1461
  */
1462
+ public function get_terms( $tax = '', $merge = true, $TermClass = '' ) {
1463
+ return $this->terms($tax, $merge, $TermClass);
1464
  }
1465
 
1466
  /**
lib/PostCollection.php CHANGED
@@ -5,11 +5,6 @@ namespace Timber;
5
  use Timber\Helper;
6
  use Timber\Post;
7
 
8
- // Exit if accessed directly
9
- if ( !defined('ABSPATH') ) {
10
- exit;
11
- }
12
-
13
  /**
14
  * PostCollections are internal objects used to hold a collection of posts
15
  */
5
  use Timber\Helper;
6
  use Timber\Post;
7
 
 
 
 
 
 
8
  /**
9
  * PostCollections are internal objects used to hold a collection of posts
10
  */
lib/PostQuery.php CHANGED
@@ -6,25 +6,23 @@ use Timber\Helper;
6
  use Timber\Post;
7
  use Timber\PostGetter;
8
 
9
- // Exit if accessed directly
10
- if ( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
  /**
15
  * A PostQuery allows a user to query for a Collection of WordPress Posts.
16
  * PostCollections are used directly in Twig templates to iterate through and retrieve
17
  * meta information about the collection of posts
18
  * @api
 
19
  */
20
  class PostQuery extends PostCollection {
21
-
22
- //maintain reference to $query object to generate pagination
23
 
24
  protected $userQuery;
25
  protected $queryIterator;
26
  protected $pagination = null;
27
 
 
 
 
 
28
  public function __construct( $query = false, $post_class = '\Timber\Post' ) {
29
  $this->userQuery = $query;
30
  $this->queryIterator = PostGetter::query_posts($query, $post_class);
@@ -34,6 +32,10 @@ class PostQuery extends PostCollection {
34
  parent::__construct($posts, $post_class);
35
  }
36
 
 
 
 
 
37
  protected function get_query() {
38
  return $this->userQuery;
39
  }
6
  use Timber\Post;
7
  use Timber\PostGetter;
8
 
 
 
 
 
 
9
  /**
10
  * A PostQuery allows a user to query for a Collection of WordPress Posts.
11
  * PostCollections are used directly in Twig templates to iterate through and retrieve
12
  * meta information about the collection of posts
13
  * @api
14
+ * @package Timber
15
  */
16
  class PostQuery extends PostCollection {
 
 
17
 
18
  protected $userQuery;
19
  protected $queryIterator;
20
  protected $pagination = null;
21
 
22
+ /**
23
+ * @param mixed $query
24
+ * @param string $post_class
25
+ */
26
  public function __construct( $query = false, $post_class = '\Timber\Post' ) {
27
  $this->userQuery = $query;
28
  $this->queryIterator = PostGetter::query_posts($query, $post_class);
32
  parent::__construct($posts, $post_class);
33
  }
34
 
35
+ /**
36
+ * @return mixed the query the user orignally passed
37
+ * to the pagination object
38
+ */
39
  protected function get_query() {
40
  return $this->userQuery;
41
  }
lib/Site.php CHANGED
@@ -205,6 +205,27 @@ class Site extends Core implements CoreInterface {
205
  return $this->$field;
206
  }
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  /**
209
  * Returns the link to the site's home.
210
  * @example
205
  return $this->$field;
206
  }
207
 
208
+ public function icon() {
209
+ if ( is_multisite() ) {
210
+ return $this->icon_multisite($this->ID);
211
+ }
212
+ $iid = get_option('site_icon');
213
+ if ( $iid ) {
214
+ return new Image($iid);
215
+ }
216
+ }
217
+
218
+ protected function icon_multisite( $site_id ) {
219
+ $image = null;
220
+ $blog_ids = self::switch_to_blog($site_id);
221
+ $iid = get_blog_option($blog_ids['new'], 'site_icon');
222
+ if ( $iid ) {
223
+ $image = new Image($iid);
224
+ }
225
+ switch_to_blog($blog_ids['old']);
226
+ return $image;
227
+ }
228
+
229
  /**
230
  * Returns the link to the site's home.
231
  * @example
lib/Term.php CHANGED
@@ -217,10 +217,13 @@ class Term extends Core implements CoreInterface {
217
  */
218
  public function get_meta_field( $field_name ) {
219
  if ( !isset($this->$field_name) ) {
220
- $field_value = '';
221
- $field_value = apply_filters('timber_term_get_meta_field', $field_value, $this->ID, $field_name, $this);
222
- $field_value = apply_filters('timber/term/meta/field', $field_value, $this->ID, $field_name, $this);
 
 
223
  $this->$field_name = $field_value;
 
224
  }
225
  return $this->$field_name;
226
  }
217
  */
218
  public function get_meta_field( $field_name ) {
219
  if ( !isset($this->$field_name) ) {
220
+ $field_value = get_term_meta($this->ID, $field_name, true);
221
+ if ( !$field_value ) {
222
+ $field_value = apply_filters('timber_term_get_meta_field', '', $this->ID, $field_name, $this);
223
+ $field_value = apply_filters('timber/term/meta/field', $field_value, $this->ID, $field_name, $this);
224
+ }
225
  $this->$field_name = $field_value;
226
+
227
  }
228
  return $this->$field_name;
229
  }
lib/Timber.php CHANGED
@@ -35,7 +35,7 @@ use Timber\Loader;
35
  */
36
  class Timber {
37
 
38
- public static $version = '1.1.8';
39
  public static $locations;
40
  public static $dirname = 'views';
41
  public static $twig_cache = false;
35
  */
36
  class Timber {
37
 
38
+ public static $version = '1.1.9';
39
  public static $locations;
40
  public static $dirname = 'views';
41
  public static $twig_cache = false;
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: jarednova, connorjburton, lggorman
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.7
5
- Stable tag: 1.1.8
6
  Tested up to: 4.6
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
@@ -41,6 +41,14 @@ Timber is great for any WordPress developer who cares about writing good, mainta
41
 
42
  == Changelog ==
43
 
 
 
 
 
 
 
 
 
44
  = 1.1.8 =
45
  * Fixed image generation when images are updated/deleted by WordPress (thanks @dudewithamood)
46
 
2
  Contributors: jarednova, connorjburton, lggorman
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.7
5
+ Stable tag: 1.1.9
6
  Tested up to: 4.6
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
41
 
42
  == Changelog ==
43
 
44
+ = 1.1.9 =
45
+ * Timber now retrieves native term meta info #824
46
+ * Added site icon support in Theme #1210
47
+ * Fixes to menu getting by slug #1237 (thanks @motia)
48
+ * Fix to off-site image URLs! #1234 (thanks @njbarrett)
49
+ * Fix inconsistency with Post::get_terms #1222 (thanks @haroldangenent)
50
+
51
+
52
  = 1.1.8 =
53
  * Fixed image generation when images are updated/deleted by WordPress (thanks @dudewithamood)
54
 
timber-starter-theme/functions.php CHANGED
@@ -2,8 +2,13 @@
2
 
3
  if ( ! class_exists( 'Timber' ) ) {
4
  add_action( 'admin_notices', function() {
5
- echo '<div class="error"><p>Timber not activated. Make sure you activate the plugin in <a href="' . esc_url( admin_url( 'plugins.php#timber' ) ) . '">' . esc_url( admin_url( 'plugins.php' ) ) . '</a></p></div>';
6
- } );
 
 
 
 
 
7
  return;
8
  }
9
 
2
 
3
  if ( ! class_exists( 'Timber' ) ) {
4
  add_action( 'admin_notices', function() {
5
+ echo '<div class="error"><p>Timber not activated. Make sure you activate the plugin in <a href="' . esc_url( admin_url( 'plugins.php#timber' ) ) . '">' . esc_url( admin_url( 'plugins.php') ) . '</a></p></div>';
6
+ });
7
+
8
+ add_filter('template_include', function($template) {
9
+ return get_stylesheet_directory() . '/static/no-timber.html';
10
+ });
11
+
12
  return;
13
  }
14
 
timber-starter-theme/index.php CHANGED
@@ -13,10 +13,6 @@
13
  * @since Timber 0.1
14
  */
15
 
16
- if ( ! class_exists( 'Timber' ) ) {
17
- echo 'Timber not activated. Make sure you activate the plugin in <a href="/wp-admin/plugins.php#timber">/wp-admin/plugins.php</a>';
18
- return;
19
- }
20
  $context = Timber::get_context();
21
  $context['posts'] = Timber::get_posts();
22
  $context['foo'] = 'bar';
13
  * @since Timber 0.1
14
  */
15
 
 
 
 
 
16
  $context = Timber::get_context();
17
  $context['posts'] = Timber::get_posts();
18
  $context['foo'] = 'bar';
timber-starter-theme/static/no-timber.html ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Timber not active</title>
5
+ </head>
6
+
7
+ <body>
8
+ <p>Timber not activated</p>
9
+ </body>
10
+ </html>
timber.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Timber
4
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates.
5
  Plugin URI: http://timber.upstatement.com
6
  Author: Jared Novack + Upstatement
7
- Version: 1.1.8
8
  Author URI: http://upstatement.com/
9
  */
10
  // we look for Composer files first in the plugins dir.
4
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates.
5
  Plugin URI: http://timber.upstatement.com
6
  Author: Jared Novack + Upstatement
7
+ Version: 1.1.9
8
  Author URI: http://upstatement.com/
9
  */
10
  // we look for Composer files first in the plugins dir.
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInita8a20583fdb84a7c5284a224ce4e2214::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit05219471bb425701949f68630de707ca::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInita8a20583fdb84a7c5284a224ce4e2214
6
  {
7
  private static $loader;
8
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInita8a20583fdb84a7c5284a224ce4e2214
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInita8a20583fdb84a7c5284a224ce4e2214', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInita8a20583fdb84a7c5284a224ce4e2214', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit05219471bb425701949f68630de707ca
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit05219471bb425701949f68630de707ca', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit05219471bb425701949f68630de707ca', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
vendor/composer/installed.json CHANGED
@@ -110,17 +110,17 @@
110
  },
111
  {
112
  "name": "twig/twig",
113
- "version": "v1.24.2",
114
- "version_normalized": "1.24.2.0",
115
  "source": {
116
  "type": "git",
117
  "url": "https://github.com/twigphp/Twig.git",
118
- "reference": "33093f6e310e6976baeac7b14f3a6ec02f2d79b7"
119
  },
120
  "dist": {
121
  "type": "zip",
122
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/33093f6e310e6976baeac7b14f3a6ec02f2d79b7",
123
- "reference": "33093f6e310e6976baeac7b14f3a6ec02f2d79b7",
124
  "shasum": ""
125
  },
126
  "require": {
@@ -130,11 +130,11 @@
130
  "symfony/debug": "~2.7",
131
  "symfony/phpunit-bridge": "~2.7"
132
  },
133
- "time": "2016-09-01 17:50:53",
134
  "type": "library",
135
  "extra": {
136
  "branch-alias": {
137
- "dev-master": "1.24-dev"
138
  }
139
  },
140
  "installation-source": "dist",
110
  },
111
  {
112
  "name": "twig/twig",
113
+ "version": "v1.27.0",
114
+ "version_normalized": "1.27.0.0",
115
  "source": {
116
  "type": "git",
117
  "url": "https://github.com/twigphp/Twig.git",
118
+ "reference": "3c6c0033fd3b5679c6e1cb60f4f9766c2b424d97"
119
  },
120
  "dist": {
121
  "type": "zip",
122
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/3c6c0033fd3b5679c6e1cb60f4f9766c2b424d97",
123
+ "reference": "3c6c0033fd3b5679c6e1cb60f4f9766c2b424d97",
124
  "shasum": ""
125
  },
126
  "require": {
130
  "symfony/debug": "~2.7",
131
  "symfony/phpunit-bridge": "~2.7"
132
  },
133
+ "time": "2016-10-25 19:17:17",
134
  "type": "library",
135
  "extra": {
136
  "branch-alias": {
137
+ "dev-master": "1.27-dev"
138
  }
139
  },
140
  "installation-source": "dist",
vendor/twig/twig/.travis.yml CHANGED
@@ -5,7 +5,7 @@ sudo: false
5
  cache:
6
  directories:
7
  - vendor
8
- - $HOME/.composer/cache
9
 
10
  php:
11
  - 5.2
5
  cache:
6
  directories:
7
  - vendor
8
+ - $HOME/.composer/cache/files
9
 
10
  php:
11
  - 5.2
vendor/twig/twig/CHANGELOG CHANGED
@@ -1,7 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  * 1.24.2 (2016-09-01)
2
 
3
  * fixed static callables
4
- * fixed a potential PHP warning when load the cache
5
  * fixed a case where the autoescaping does not work as expected
6
 
7
  * 1.24.1 (2016-05-30)
1
+ * 1.27.0 (2016-10-25)
2
+
3
+ * deprecated Twig_Parser::getEnvironment()
4
+ * deprecated Twig_Parser::addHandler() and Twig_Parser::addNodeVisitor()
5
+ * deprecated Twig_Compiler::addIndentation()
6
+ * fixed regression when registering two extensions having the same class name
7
+ * deprecated Twig_LoaderInterface::getSource() (implement Twig_SourceContextLoaderInterface instead)
8
+ * fixed the filesystem loader with relative paths
9
+ * deprecated Twig_Node::getLine() in favor of Twig_Node::getTemplateLine()
10
+ * deprecated Twig_Template::getSource() in favor of Twig_Template::getSourceContext()
11
+ * deprecated Twig_Node::getFilename() in favor of Twig_Node::getTemplateName()
12
+ * deprecated the "filename" escaping strategy (use "name" instead)
13
+ * added Twig_Source to hold information about the original template
14
+ * deprecated Twig_Error::getTemplateFile() and Twig_Error::setTemplateFile() in favor of Twig_Error::getTemplateName() and Twig_Error::setTemplateName()
15
+ * deprecated Parser::getFilename()
16
+ * fixed template paths when a template name contains a protocol like vfs://
17
+ * improved debugging with Twig_Sandbox_SecurityError exceptions for disallowed methods and properties
18
+
19
+ * 1.26.1 (2016-10-05)
20
+
21
+ * removed template source code from generated template classes when debug is disabled
22
+ * fixed default implementation of Twig_Template::getDebugInfo() for better BC
23
+ * fixed regression on static calls for functions/filters/tests
24
+
25
+ * 1.26.0 (2016-10-02)
26
+
27
+ * added template cache invalidation based on more environment options
28
+ * added a missing deprecation notice
29
+ * fixed template paths when a template is stored in a PHAR file
30
+ * allowed filters/functions/tests implementation to use a different class than the extension they belong to
31
+ * deprecated Twig_ExtensionInterface::getName()
32
+
33
+ * 1.25.0 (2016-09-21)
34
+
35
+ * changed the way we store template source in template classes
36
+ * removed usage of realpath in cache keys
37
+ * fixed Twig cache sharing when used with different versions of PHP
38
+ * removed embed parent workaround for simple use cases
39
+ * deprecated the ability to store non Node instances in Node::$nodes
40
+ * deprecated Twig_Environment::getLexer(), Twig_Environment::getParser(), Twig_Environment::getCompiler()
41
+ * deprecated Twig_Compiler::getFilename()
42
+
43
  * 1.24.2 (2016-09-01)
44
 
45
  * fixed static callables
46
+ * fixed a potential PHP warning when loading the cache
47
  * fixed a case where the autoescaping does not work as expected
48
 
49
  * 1.24.1 (2016-05-30)
vendor/twig/twig/composer.json CHANGED
@@ -40,7 +40,7 @@
40
  },
41
  "extra": {
42
  "branch-alias": {
43
- "dev-master": "1.24-dev"
44
  }
45
  }
46
  }
40
  },
41
  "extra": {
42
  "branch-alias": {
43
+ "dev-master": "1.27-dev"
44
  }
45
  }
46
  }
vendor/twig/twig/doc/advanced.rst CHANGED
@@ -136,7 +136,13 @@ Creating a filter is as simple as associating a name with a PHP callable::
136
  // or a simple PHP function
137
  $filter = new Twig_SimpleFilter('rot13', 'str_rot13');
138
 
 
 
 
 
139
  // or a class method
 
 
140
  $filter = new Twig_SimpleFilter('rot13', array('SomeClass', 'rot13Filter'));
141
 
142
  The first argument passed to the ``Twig_SimpleFilter`` constructor is the name
@@ -525,10 +531,6 @@ reusable class like adding support for internationalization. An extension can
525
  define tags, filters, tests, operators, global variables, functions, and node
526
  visitors.
527
 
528
- Creating an extension also makes for a better separation of code that is
529
- executed at compilation time and code needed at runtime. As such, it makes
530
- your code faster.
531
-
532
  Most of the time, it is useful to create a single extension for your project,
533
  to host all the specific tags and filters you want to add to Twig.
534
 
@@ -613,32 +615,27 @@ An extension is a class that implements the following interface::
613
  * Returns the name of the extension.
614
  *
615
  * @return string The extension name
 
 
616
  */
617
  function getName();
618
  }
619
 
620
- To keep your extension class clean and lean, it can inherit from the built-in
621
- ``Twig_Extension`` class instead of implementing the whole interface. That
622
- way, you just need to implement the ``getName()`` method as the
623
- ``Twig_Extension`` provides empty implementations for all other methods.
624
-
625
- The ``getName()`` method must return a unique identifier for your extension.
626
-
627
- Now, with this information in mind, let's create the most basic extension
628
- possible::
629
 
630
  class Project_Twig_Extension extends Twig_Extension
631
  {
632
- public function getName()
633
- {
634
- return 'project';
635
- }
636
  }
637
 
 
 
 
638
  .. note::
639
 
640
- Of course, this extension does nothing for now. We will customize it in
641
- the next sections.
642
 
643
  Twig does not care where you save your extension on the filesystem, as all
644
  extensions must be registered explicitly to be available in your templates.
@@ -651,7 +648,7 @@ main ``Environment`` object::
651
 
652
  .. tip::
653
 
654
- The bundled extensions are great examples of how extensions work.
655
 
656
  Globals
657
  ~~~~~~~
@@ -770,6 +767,101 @@ The ``getTests()`` method lets you add new test functions::
770
  // ...
771
  }
772
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
773
  Overloading
774
  -----------
775
 
@@ -790,11 +882,6 @@ possible** (order matters)::
790
  {
791
  // do something different from the built-in date filter
792
  }
793
-
794
- public function getName()
795
- {
796
- return 'project';
797
- }
798
  }
799
 
800
  $twig = new Twig_Environment($loader);
@@ -802,7 +889,7 @@ possible** (order matters)::
802
 
803
  Here, we have overloaded the built-in ``date`` filter with a custom one.
804
 
805
- If you do the same on the Twig_Environment itself, beware that it takes
806
  precedence over any other registered extensions::
807
 
808
  $twig = new Twig_Environment($loader);
136
  // or a simple PHP function
137
  $filter = new Twig_SimpleFilter('rot13', 'str_rot13');
138
 
139
+ // or a class static method
140
+ $filter = new Twig_SimpleFilter('rot13', array('SomeClass', 'rot13Filter'));
141
+ $filter = new Twig_SimpleFilter('rot13', 'SomeClass::rot13Filter');
142
+
143
  // or a class method
144
+ $filter = new Twig_SimpleFilter('rot13', array($this, 'rot13Filter'));
145
+ // the one below needs a runtime implementation (see below for more information)
146
  $filter = new Twig_SimpleFilter('rot13', array('SomeClass', 'rot13Filter'));
147
 
148
  The first argument passed to the ``Twig_SimpleFilter`` constructor is the name
531
  define tags, filters, tests, operators, global variables, functions, and node
532
  visitors.
533
 
 
 
 
 
534
  Most of the time, it is useful to create a single extension for your project,
535
  to host all the specific tags and filters you want to add to Twig.
536
 
615
  * Returns the name of the extension.
616
  *
617
  * @return string The extension name
618
+ *
619
+ * @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
620
  */
621
  function getName();
622
  }
623
 
624
+ To keep your extension class clean and lean, inherit from the built-in
625
+ ``Twig_Extension`` class instead of implementing the interface as it provides
626
+ empty implementations for all methods:
 
 
 
 
 
 
627
 
628
  class Project_Twig_Extension extends Twig_Extension
629
  {
 
 
 
 
630
  }
631
 
632
+ Of course, this extension does nothing for now. We will customize it in the
633
+ next sections.
634
+
635
  .. note::
636
 
637
+ Prior to Twig 1.26, you must implement the ``getName()`` method which must
638
+ return a unique identifier for the extension.
639
 
640
  Twig does not care where you save your extension on the filesystem, as all
641
  extensions must be registered explicitly to be available in your templates.
648
 
649
  .. tip::
650
 
651
+ The Twig core extensions are great examples of how extensions work.
652
 
653
  Globals
654
  ~~~~~~~
767
  // ...
768
  }
769
 
770
+ Definition vs Runtime
771
+ ~~~~~~~~~~~~~~~~~~~~~
772
+
773
+ Twig filters, functions, and tests runtime implementations can be defined as
774
+ any valid PHP callable:
775
+
776
+ * **functions/static methods**: Simple to implement and fast (used by all Twig
777
+ core extensions); but it is hard for the runtime to depend on external
778
+ objects;
779
+
780
+ * **closures**: Simple to implement;
781
+
782
+ * **object methods**: More flexible and required if your runtime code depends
783
+ on external objects.
784
+
785
+ The simplest way to use methods is to define them on the extension itself::
786
+
787
+ class Project_Twig_Extension extends Twig_Extension
788
+ {
789
+ private $rot13Provider;
790
+
791
+ public function __construct($rot13Provider)
792
+ {
793
+ $this->rot13Provider = $rot13Provider;
794
+ }
795
+
796
+ public function getFunctions()
797
+ {
798
+ return array(
799
+ new Twig_SimpleFunction('rot13', array($this, 'rot13')),
800
+ );
801
+ }
802
+
803
+ public function rot13($value)
804
+ {
805
+ return $rot13Provider->rot13($value);
806
+ }
807
+ }
808
+
809
+ This is very convenient but not recommended as it makes template compilation
810
+ depend on runtime dependencies even if they are not needed (think for instance
811
+ as a dependency that connects to a database engine).
812
+
813
+ As of Twig 1.26, you can easily decouple the extension definitions from their
814
+ runtime implementations by registering a ``Twig_RuntimeLoaderInterface``
815
+ instance on the environment that knows how to instantiate such runtime classes
816
+ (runtime classes must be autoload-able)::
817
+
818
+ class RuntimeLoader implements Twig_RuntimeLoaderInterface
819
+ {
820
+ public function load($class)
821
+ {
822
+ // implement the logic to create an instance of $class
823
+ // and inject its dependencies
824
+ // most of the time, it means using your dependency injection container
825
+ if ('Project_Twig_RuntimeExtension' === $class) {
826
+ return new $class(new Rot13Provider());
827
+ } else {
828
+ // ...
829
+ }
830
+ }
831
+ }
832
+
833
+ $twig->addRuntimeLoader(new RuntimeLoader());
834
+
835
+ It is now possible to move the runtime logic to a new
836
+ ``Project_Twig_RuntimeExtension`` class and use it directly in the extension::
837
+
838
+ class Project_Twig_RuntimeExtension extends Twig_Extension
839
+ {
840
+ private $rot13Provider;
841
+
842
+ public function __construct($rot13Provider)
843
+ {
844
+ $this->rot13Provider = $rot13Provider;
845
+ }
846
+
847
+ public function rot13($value)
848
+ {
849
+ return $rot13Provider->rot13($value);
850
+ }
851
+ }
852
+
853
+ class Project_Twig_Extension extends Twig_Extension
854
+ {
855
+ public function getFunctions()
856
+ {
857
+ return array(
858
+ new Twig_SimpleFunction('rot13', array('Project_Twig_RuntimeExtension', 'rot13')),
859
+ // or
860
+ new Twig_SimpleFunction('rot13', 'Project_Twig_RuntimeExtension::rot13'),
861
+ );
862
+ }
863
+ }
864
+
865
  Overloading
866
  -----------
867
 
882
  {
883
  // do something different from the built-in date filter
884
  }
 
 
 
 
 
885
  }
886
 
887
  $twig = new Twig_Environment($loader);
889
 
890
  Here, we have overloaded the built-in ``date`` filter with a custom one.
891
 
892
+ If you do the same on the ``Twig_Environment`` itself, beware that it takes
893
  precedence over any other registered extensions::
894
 
895
  $twig = new Twig_Environment($loader);
vendor/twig/twig/doc/api.rst CHANGED
@@ -115,14 +115,14 @@ The following options are available:
115
  ``false`` to disable).
116
 
117
  As of Twig 1.9, you can set the escaping strategy to use (``css``, ``url``,
118
- ``html_attr``, or a PHP callback that takes the template "filename" and must
119
  return the escaping strategy to use -- the callback cannot be a function name
120
  to avoid collision with built-in escaping strategies).
121
 
122
- As of Twig 1.17, the ``filename`` escaping strategy determines the escaping
123
- strategy to use for a template based on the template filename extension (this
124
- strategy does not incur any overhead at runtime as auto-escaping is done at
125
- compilation time.)
126
 
127
  * ``optimizations`` *integer*
128
 
@@ -156,6 +156,9 @@ Here is a list of the built-in loaders Twig provides:
156
  .. versionadded:: 1.10
157
  The ``prependPath()`` and support for namespaces were added in Twig 1.10.
158
 
 
 
 
159
  ``Twig_Loader_Filesystem`` loads templates from the file system. This loader
160
  can find templates in folders on the file system and is the preferred way to
161
  load them::
@@ -190,6 +193,18 @@ Namespaced templates can be accessed via the special
190
 
191
  $twig->render('@admin/index.html', array());
192
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  ``Twig_Loader_Array``
194
  .....................
195
 
@@ -256,6 +271,8 @@ All loaders implement the ``Twig_LoaderInterface``::
256
  * @param string $name string The name of the template to load
257
  *
258
  * @return string The template source code
 
 
259
  */
260
  function getSource($name);
261
 
@@ -280,6 +297,11 @@ All loaders implement the ``Twig_LoaderInterface``::
280
  The ``isFresh()`` method must return ``true`` if the current cached template
281
  is still fresh, given the last modification time, or ``false`` otherwise.
282
 
 
 
 
 
 
283
  .. tip::
284
 
285
  As of Twig 1.11.0, you can also implement ``Twig_ExistsLoaderInterface``
115
  ``false`` to disable).
116
 
117
  As of Twig 1.9, you can set the escaping strategy to use (``css``, ``url``,
118
+ ``html_attr``, or a PHP callback that takes the template name and must
119
  return the escaping strategy to use -- the callback cannot be a function name
120
  to avoid collision with built-in escaping strategies).
121
 
122
+ As of Twig 1.17, the ``filename`` escaping strategy (renamed to ``name`` as
123
+ of Twig 1.27) determines the escaping strategy to use for a template based on
124
+ the template filename extension (this strategy does not incur any overhead at
125
+ runtime as auto-escaping is done at compilation time.)
126
 
127
  * ``optimizations`` *integer*
128
 
156
  .. versionadded:: 1.10
157
  The ``prependPath()`` and support for namespaces were added in Twig 1.10.
158
 
159
+ .. versionadded:: 1.27
160
+ Relative paths support was added in Twig 1.27.
161
+
162
  ``Twig_Loader_Filesystem`` loads templates from the file system. This loader
163
  can find templates in folders on the file system and is the preferred way to
164
  load them::
193
 
194
  $twig->render('@admin/index.html', array());
195
 
196
+ ``Twig_Loader_Filesystem`` support absolute and relative paths. Using relative
197
+ paths is preferred as it makes the cache keys independent of the project root
198
+ directory (for instance, it allows warming the cache from a build server where
199
+ the directory might be different from the one used on production servers)::
200
+
201
+ $loader = new Twig_Loader_Filesystem('templates', getcwd().'/..');
202
+
203
+ .. note::
204
+
205
+ When not passing the root path as a second argument, Twig uses ``getcwd()``
206
+ for relative paths.
207
+
208
  ``Twig_Loader_Array``
209
  .....................
210
 
271
  * @param string $name string The name of the template to load
272
  *
273
  * @return string The template source code
274
+ *
275
+ * @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface
276
  */
277
  function getSource($name);
278
 
297
  The ``isFresh()`` method must return ``true`` if the current cached template
298
  is still fresh, given the last modification time, or ``false`` otherwise.
299
 
300
+ .. note::
301
+
302
+ As of Twig 1.27, you should also implement
303
+ ``Twig_SourceContextLoaderInterface`` to avoid deprecation notices.
304
+
305
  .. tip::
306
 
307
  As of Twig 1.11.0, you can also implement ``Twig_ExistsLoaderInterface``
vendor/twig/twig/doc/deprecated.rst CHANGED
@@ -20,6 +20,11 @@ Token Parsers
20
  * ``Twig_TokenParserBrokerInterface``
21
  * ``Twig_TokenParserBroker``
22
 
 
 
 
 
 
23
  Extensions
24
  ----------
25
 
@@ -37,6 +42,9 @@ Extensions
37
  deprecated. Implement ``Twig_Extension_GlobalsInterface`` to avoid
38
  deprecation notices.
39
 
 
 
 
40
  PEAR
41
  ----
42
 
@@ -109,6 +117,17 @@ Nodes
109
  * As of Twig 1.x, ``Node::toXml()`` is deprecated and will be removed in Twig
110
  2.0.
111
 
 
 
 
 
 
 
 
 
 
 
 
112
  Interfaces
113
  ----------
114
 
@@ -120,16 +139,30 @@ Interfaces
120
  * ``Twig_NodeInterface`` (use ``Twig_Node`` instead)
121
  * ``Twig_ParserInterface`` (use ``Twig_Parser`` instead)
122
  * ``Twig_ExistsLoaderInterface`` (merged with ``Twig_LoaderInterface``)
 
123
  * ``Twig_TemplateInterface`` (use ``Twig_Template`` instead, and use
124
  those constants Twig_Template::ANY_CALL, Twig_Template::ARRAY_CALL,
125
  Twig_Template::METHOD_CALL)
126
 
 
 
 
 
 
 
 
 
 
127
  Loaders
128
  -------
129
 
130
  * As of Twig 1.x, ``Twig_Loader_String`` is deprecated and will be removed in
131
  2.0. You can render a string via ``Twig_Environment::createTemplate()``.
132
 
 
 
 
 
133
  Node Visitors
134
  -------------
135
 
@@ -153,10 +186,25 @@ Globals
153
  Miscellaneous
154
  -------------
155
 
156
- * As of Twig 1.x, ``Twig_Environment::clearTemplateCache()``, ``Twig_Environment::writeCacheFile()``,
157
- ``Twig_Environment::clearCacheFiles()``, ``Twig_Environment::getCacheFilename()``, and
158
- ``Twig_Environment::getTemplateClassPrefix()`` are deprecated and will be removed in 2.0.
 
 
 
 
159
 
160
  * As of Twig 1.x, ``Twig_Template::getEnvironment()`` and
161
  ``Twig_TemplateInterface::getEnvironment()`` are deprecated and will be
162
  removed in 2.0.
 
 
 
 
 
 
 
 
 
 
 
20
  * ``Twig_TokenParserBrokerInterface``
21
  * ``Twig_TokenParserBroker``
22
 
23
+ * As of Twig 1.27, ``Twig_Parser::getFilename()`` is deprecated. From a token
24
+ parser, use ``$this->parser->getStream()->getSourceContext()->getPath()`` instead.
25
+
26
+ * As of Twig 1.27, ``Twig_Parser::getEnvironment()`` is deprecated.
27
+
28
  Extensions
29
  ----------
30
 
42
  deprecated. Implement ``Twig_Extension_GlobalsInterface`` to avoid
43
  deprecation notices.
44
 
45
+ * As of Twig 1.26, the ``Twig_ExtensionInterface::getName()`` method is
46
+ deprecated and it is not used internally anymore.
47
+
48
  PEAR
49
  ----
50
 
117
  * As of Twig 1.x, ``Node::toXml()`` is deprecated and will be removed in Twig
118
  2.0.
119
 
120
+ * As of Twig 1.26, ``Node::$nodes`` should only contains ``Twig_Node``
121
+ instances, storing a ``null`` value is deprecated and won't be possible in
122
+ Twig 2.x.
123
+
124
+ * As of Twig 1.27, the ``filename`` attribute on ``Twig_Node_Module`` is
125
+ deprecated. Use ``getName()`` instead.
126
+
127
+ * As of Twig 1.27, the ``Twig_Node::getFilename()/Twig_Node::getLine()``
128
+ methods are deprecated, use
129
+ ``Twig_Node::getTemplateName()/Twig_Node::getTemplateLine()`` instead.
130
+
131
  Interfaces
132
  ----------
133
 
139
  * ``Twig_NodeInterface`` (use ``Twig_Node`` instead)
140
  * ``Twig_ParserInterface`` (use ``Twig_Parser`` instead)
141
  * ``Twig_ExistsLoaderInterface`` (merged with ``Twig_LoaderInterface``)
142
+ * ``Twig_SourceContextLoaderInterface`` (merged with ``Twig_LoaderInterface``)
143
  * ``Twig_TemplateInterface`` (use ``Twig_Template`` instead, and use
144
  those constants Twig_Template::ANY_CALL, Twig_Template::ARRAY_CALL,
145
  Twig_Template::METHOD_CALL)
146
 
147
+ Compiler
148
+ --------
149
+
150
+ * As of Twig 1.26, the ``Twig_Compiler::getFilename()`` has been deprecated.
151
+ You should not use it anyway as its values is not reliable.
152
+
153
+ * As of Twig 1.27, the ``Twig_Compiler::addIndentation()`` has been deprecated.
154
+ Use ``Twig_Compiler::write('')`` instead.
155
+
156
  Loaders
157
  -------
158
 
159
  * As of Twig 1.x, ``Twig_Loader_String`` is deprecated and will be removed in
160
  2.0. You can render a string via ``Twig_Environment::createTemplate()``.
161
 
162
+ * As of Twig 1.27, ``Twig_LoaderInterface::getSource()`` is deprecated.
163
+ Implement ``Twig_SourceContextLoaderInterface`` instead and use
164
+ ``getSourceContext()``.
165
+
166
  Node Visitors
167
  -------------
168
 
186
  Miscellaneous
187
  -------------
188
 
189
+ * As of Twig 1.x, ``Twig_Environment::clearTemplateCache()``,
190
+ ``Twig_Environment::writeCacheFile()``,
191
+ ``Twig_Environment::clearCacheFiles()``,
192
+ ``Twig_Environment::getCacheFilename()``,
193
+ ``Twig_Environment::getTemplateClassPrefix()``,
194
+ ``Twig_Environment::getLexer()``, ``Twig_Environment::getParser()``, and
195
+ ``Twig_Environment::getCompiler()`` are deprecated and will be removed in 2.0.
196
 
197
  * As of Twig 1.x, ``Twig_Template::getEnvironment()`` and
198
  ``Twig_TemplateInterface::getEnvironment()`` are deprecated and will be
199
  removed in 2.0.
200
+
201
+ * As of Twig 1.27, ``Twig_Error::getTemplateFile()`` and
202
+ ``Twig_Error::setTemplateFile()`` are deprecated. Use
203
+ ``Twig_Error::getTemplateName()`` and ``Twig_Error::setTemplateName()``
204
+ instead.
205
+
206
+ * As of Twig 1.27, ``Twig_Template::getSource()`` is deprecated. Use
207
+ ``Twig_Template::getSourceContext()`` instead.
208
+
209
+ * As of Twig 1.27, ``Twig_Parser::addHandler()`` and
210
+ ``Twig_Parser::addNodeVisitor()`` are deprecated and will be removed in 2.0.
vendor/twig/twig/doc/filters/date.rst CHANGED
@@ -54,6 +54,9 @@ dates and the second one is the default format for date intervals:
54
  .. code-block:: php
55
 
56
  $twig = new Twig_Environment($loader);
 
 
 
57
  $twig->getExtension('core')->setDateFormat('d/m/Y', '%d days');
58
 
59
  Timezone
@@ -79,6 +82,9 @@ The default timezone can also be set globally by calling ``setTimezone()``:
79
  .. code-block:: php
80
 
81
  $twig = new Twig_Environment($loader);
 
 
 
82
  $twig->getExtension('core')->setTimezone('Europe/Paris');
83
 
84
  Arguments
54
  .. code-block:: php
55
 
56
  $twig = new Twig_Environment($loader);
57
+ $twig->getExtension('Twig_Extension_Core')->setDateFormat('d/m/Y', '%d days');
58
+
59
+ // before Twig 1.26
60
  $twig->getExtension('core')->setDateFormat('d/m/Y', '%d days');
61
 
62
  Timezone
82
  .. code-block:: php
83
 
84
  $twig = new Twig_Environment($loader);
85
+ $twig->getExtension('Twig_Extension_Core')->setTimezone('Europe/Paris');
86
+
87
+ // before Twig 1.26
88
  $twig->getExtension('core')->setTimezone('Europe/Paris');
89
 
90
  Arguments
vendor/twig/twig/doc/filters/escape.rst CHANGED
@@ -97,6 +97,9 @@ used in the ``escape`` call) and the second one must be a valid PHP callable:
97
  .. code-block:: php
98
 
99
  $twig = new Twig_Environment($loader);
 
 
 
100
  $twig->getExtension('core')->setEscaper('csv', 'csv_escaper');
101
 
102
  When called by Twig, the callable receives the Twig environment instance, the
97
  .. code-block:: php
98
 
99
  $twig = new Twig_Environment($loader);
100
+ $twig->getExtension('Twig_Extension_Core')->setEscaper('csv', 'csv_escaper');
101
+
102
+ // before Twig 1.26
103
  $twig->getExtension('core')->setEscaper('csv', 'csv_escaper');
104
 
105
  When called by Twig, the callable receives the Twig environment instance, the
vendor/twig/twig/doc/filters/number_format.rst CHANGED
@@ -30,6 +30,9 @@ These defaults can be easily changed through the core extension:
30
  .. code-block:: php
31
 
32
  $twig = new Twig_Environment($loader);
 
 
 
33
  $twig->getExtension('core')->setNumberFormat(3, '.', ',');
34
 
35
  The defaults set for ``number_format`` can be over-ridden upon each call using the
30
  .. code-block:: php
31
 
32
  $twig = new Twig_Environment($loader);
33
+ $twig->getExtension('Twig_Extension_Core')->setNumberFormat(3, '.', ',');
34
+
35
+ // before Twig 1.26
36
  $twig->getExtension('core')->setNumberFormat(3, '.', ',');
37
 
38
  The defaults set for ``number_format`` can be over-ridden upon each call using the
vendor/twig/twig/doc/functions/date.rst CHANGED
@@ -41,6 +41,9 @@ If no argument is passed, the function returns the current date:
41
  .. code-block:: php
42
 
43
  $twig = new Twig_Environment($loader);
 
 
 
44
  $twig->getExtension('core')->setTimezone('Europe/Paris');
45
 
46
  Arguments
41
  .. code-block:: php
42
 
43
  $twig = new Twig_Environment($loader);
44
+ $twig->getExtension('Twig_Extension_Core')->setTimezone('Europe/Paris');
45
+
46
+ // before Twig 1.26
47
  $twig->getExtension('core')->setTimezone('Europe/Paris');
48
 
49
  Arguments
vendor/twig/twig/doc/internals.rst CHANGED
@@ -44,7 +44,11 @@ an instance of ``Twig_Token``, and the stream is an instance of
44
  You can manually convert a source code into a token stream by calling the
45
  ``tokenize()`` method of an environment::
46
 
47
- $stream = $twig->tokenize($source, $identifier);
 
 
 
 
48
 
49
  As the stream has a ``__toString()`` method, you can have a textual
50
  representation of it by echoing the object::
44
  You can manually convert a source code into a token stream by calling the
45
  ``tokenize()`` method of an environment::
46
 
47
+ $stream = $twig->tokenize(new Twig_Source($source, $identifier));
48
+
49
+ .. versionadded:: 1.27
50
+ ``Twig_Source`` was introduced in version 1.27, pass the source and the
51
+ identifier directly on previous versions.
52
 
53
  As the stream has a ``__toString()`` method, you can have a textual
54
  representation of it by echoing the object::
vendor/twig/twig/doc/recipes.rst CHANGED
@@ -306,7 +306,7 @@ saving it. If the template code is stored in a `$template` variable, here is
306
  how you can do it::
307
 
308
  try {
309
- $twig->parse($twig->tokenize($template));
310
 
311
  // the $template is valid
312
  } catch (Twig_Error_Syntax $e) {
@@ -318,7 +318,7 @@ If you iterate over a set of files, you can pass the filename to the
318
 
319
  foreach ($files as $file) {
320
  try {
321
- $twig->parse($twig->tokenize($template, $file));
322
 
323
  // the $template is valid
324
  } catch (Twig_Error_Syntax $e) {
@@ -326,6 +326,10 @@ If you iterate over a set of files, you can pass the filename to the
326
  }
327
  }
328
 
 
 
 
 
329
  .. note::
330
 
331
  This method won't catch any sandbox policy violations because the policy
@@ -413,7 +417,7 @@ We have created a simple ``templates`` table that hosts two templates:
413
 
414
  Now, let's define a loader able to use this database::
415
 
416
- class DatabaseTwigLoader implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
417
  {
418
  protected $dbh;
419
 
@@ -431,6 +435,16 @@ Now, let's define a loader able to use this database::
431
  return $source;
432
  }
433
 
 
 
 
 
 
 
 
 
 
 
434
  // Twig_ExistsLoaderInterface as of Twig 1.11
435
  public function exists($name)
436
  {
@@ -515,4 +529,40 @@ From PHP, it's also possible to load a template stored in a string via
515
 
516
  Never use the ``Twig_Loader_String`` loader, which has severe limitations.
517
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  .. _callback: http://www.php.net/manual/en/function.is-callable.php
306
  how you can do it::
307
 
308
  try {
309
+ $twig->parse($twig->tokenize(new Twig_Source($template)));
310
 
311
  // the $template is valid
312
  } catch (Twig_Error_Syntax $e) {
318
 
319
  foreach ($files as $file) {
320
  try {
321
+ $twig->parse($twig->tokenize(new Twig_Source($template, $file->getFilename(), $file)));
322
 
323
  // the $template is valid
324
  } catch (Twig_Error_Syntax $e) {
326
  }
327
  }
328
 
329
+ .. versionadded:: 1.27
330
+ ``Twig_Source`` was introduced in version 1.27, pass the source and the
331
+ identifier directly on previous versions.
332
+
333
  .. note::
334
 
335
  This method won't catch any sandbox policy violations because the policy
417
 
418
  Now, let's define a loader able to use this database::
419
 
420
+ class DatabaseTwigLoader implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
421
  {
422
  protected $dbh;
423
 
435
  return $source;
436
  }
437
 
438
+ // Twig_SourceContextLoaderInterface as of Twig 1.27
439
+ public function getSourceContext($name)
440
+ {
441
+ if (false === $source = $this->getValue('source', $name)) {
442
+ throw new Twig_Error_Loader(sprintf('Template "%s" does not exist.', $name));
443
+ }
444
+
445
+ return new Twig_Source($source, $name);
446
+ }
447
+
448
  // Twig_ExistsLoaderInterface as of Twig 1.11
449
  public function exists($name)
450
  {
529
 
530
  Never use the ``Twig_Loader_String`` loader, which has severe limitations.
531
 
532
+ Using Twig and AngularJS in the same Templates
533
+ ----------------------------------------------
534
+
535
+ Mixing different template syntaxes in the same file is not a recommended
536
+ practice as both AngularJS and Twig use the same delimiters in their syntax:
537
+ ``{{`` and ``}}``.
538
+
539
+ Still, if you want to use AngularJS and Twig in the same template, there are
540
+ two ways to make it work depending on the amount of AngularJS you need to
541
+ include in your templates:
542
+
543
+ * Escaping the AngularJS delimiters by wrapping AngularJS sections with the
544
+ ``{% verbatim %}`` tag or by escaping each delimiter via ``{{ '{{' }}`` and
545
+ ``{{ '}}' }}``;
546
+
547
+ * Changing the delimiters of one of the template engines (depending on which
548
+ engine you introduced last):
549
+
550
+ * For AngularJS, change the interpolation tags using the
551
+ ``interpolateProvider`` service, for instance at the module initialization
552
+ time:
553
+
554
+ ```js
555
+ angular.module('myApp', []).config(function($interpolateProvider) {
556
+ $interpolateProvider.startSymbol('{[').endSymbol(']}');
557
+ });
558
+ ```
559
+
560
+ * For Twig, change the delimiters via the ``tag_variable`` Lexer option:
561
+
562
+ ```php
563
+ $env->setLexer(new Twig_Lexer($env, array(
564
+ 'tag_variable' => array('{[', ']}'),
565
+ )));
566
+ ```
567
+
568
  .. _callback: http://www.php.net/manual/en/function.is-callable.php
vendor/twig/twig/doc/tags/embed.rst CHANGED
@@ -170,9 +170,9 @@ The ``embed`` tag takes the exact same arguments as the ``include`` tag:
170
  .. warning::
171
 
172
  As embedded templates do not have "names", auto-escaping strategies based
173
- on the template "filename" won't work as expected if you change the
174
- context (for instance, if you embed a CSS/JavaScript template into an HTML
175
- one). In that case, explicitly set the default auto-escaping strategy with
176
- the ``autoescape`` tag.
177
 
178
  .. seealso:: :doc:`include<../tags/include>`
170
  .. warning::
171
 
172
  As embedded templates do not have "names", auto-escaping strategies based
173
+ on the template name won't work as expected if you change the context (for
174
+ instance, if you embed a CSS/JavaScript template into an HTML one). In that
175
+ case, explicitly set the default auto-escaping strategy with the
176
+ ``autoescape`` tag.
177
 
178
  .. seealso:: :doc:`include<../tags/include>`
vendor/twig/twig/doc/tests/empty.rst CHANGED
@@ -1,11 +1,11 @@
1
  ``empty``
2
  =========
3
 
4
- ``empty`` checks if a variable is empty:
 
5
 
6
  .. code-block:: jinja
7
 
8
- {# evaluates to true if the foo variable is null, false, an empty array, or the empty string #}
9
  {% if foo is empty %}
10
  ...
11
  {% endif %}
1
  ``empty``
2
  =========
3
 
4
+ ``empty`` checks if a variable is an empty string, an empty array, an empty
5
+ hash, exactly ``false``, or exactly ``null``:
6
 
7
  .. code-block:: jinja
8
 
 
9
  {% if foo is empty %}
10
  ...
11
  {% endif %}
vendor/twig/twig/ext/twig/php_twig.h CHANGED
@@ -15,7 +15,7 @@
15
  #ifndef PHP_TWIG_H
16
  #define PHP_TWIG_H
17
 
18
- #define PHP_TWIG_VERSION "1.24.2"
19
 
20
  #include "php.h"
21
 
15
  #ifndef PHP_TWIG_H
16
  #define PHP_TWIG_H
17
 
18
+ #define PHP_TWIG_VERSION "1.27.0"
19
 
20
  #include "php.h"
21
 
vendor/twig/twig/ext/twig/twig.c CHANGED
@@ -144,7 +144,7 @@ static zval *TWIG_GET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
144
 
145
  if (!retval) {
146
  if (!EG(exception)) {
147
- zend_error(E_ERROR, "Undefined offset for object of type %s used as array", ce->name);
148
  }
149
  return NULL;
150
  }
@@ -167,7 +167,7 @@ static int TWIG_ISSET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
167
 
168
  if (!retval) {
169
  if (!EG(exception)) {
170
- zend_error(E_ERROR, "Undefined offset for object of type %s used as array", ce->name);
171
  }
172
  return 0;
173
  }
@@ -811,15 +811,15 @@ PHP_FUNCTION(twig_template_get_attributes)
811
  }
812
  */
813
  if (TWIG_INSTANCE_OF(object, zend_ce_arrayaccess TSRMLS_CC)) {
814
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" in object with ArrayAccess of class \"%s\" does not exist", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
815
  } else if (Z_TYPE_P(object) == IS_OBJECT) {
816
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to access a key \"%s\" on an object of class \"%s\" that does not implement ArrayAccess interface", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
817
  } else if (Z_TYPE_P(object) == IS_ARRAY) {
818
  if (0 == zend_hash_num_elements(Z_ARRVAL_P(object))) {
819
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" does not exist as the array is empty", item);
820
  } else {
821
  char *array_keys = TWIG_IMPLODE_ARRAY_KEYS(", ", object TSRMLS_CC);
822
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" for array with keys \"%s\" does not exist", item, array_keys);
823
  efree(array_keys);
824
  }
825
  } else {
@@ -829,15 +829,15 @@ PHP_FUNCTION(twig_template_get_attributes)
829
  convert_to_string(object);
830
  TWIG_RUNTIME_ERROR(template TSRMLS_CC,
831
  (strcmp("array", type) == 0)
832
- ? "Impossible to access a key (\"%s\") on a %s variable"
833
- : "Impossible to access an attribute (\"%s\") on a %s variable",
834
  item, type_name);
835
  } else {
836
  convert_to_string(object);
837
  TWIG_RUNTIME_ERROR(template TSRMLS_CC,
838
  (strcmp("array", type) == 0)
839
- ? "Impossible to access a key (\"%s\") on a %s variable (\"%s\")"
840
- : "Impossible to access an attribute (\"%s\") on a %s variable (\"%s\")",
841
  item, type_name, Z_STRVAL_P(object));
842
  }
843
  zval_ptr_dtor(&object);
@@ -883,11 +883,11 @@ PHP_FUNCTION(twig_template_get_attributes)
883
  if (Z_TYPE_P(object) == IS_NULL) {
884
  convert_to_string_ex(&object);
885
 
886
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable", item, type_name);
887
  } else {
888
  convert_to_string_ex(&object);
889
 
890
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable (\"%s\")", item, type_name, Z_STRVAL_P(object));
891
  }
892
 
893
  zval_ptr_dtor(&object);
@@ -916,8 +916,8 @@ PHP_FUNCTION(twig_template_get_attributes)
916
  return true;
917
  }
918
 
919
- if ($this->env->hasExtension('sandbox')) {
920
- $this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item);
921
  }
922
 
923
  return $object->$item;
@@ -935,8 +935,8 @@ PHP_FUNCTION(twig_template_get_attributes)
935
  efree(item);
936
  RETURN_TRUE;
937
  }
938
- if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "sandbox" TSRMLS_CC)) {
939
- TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "sandbox" TSRMLS_CC), "checkPropertyAllowed", object, zitem TSRMLS_CC);
940
  }
941
  if (EG(exception)) {
942
  efree(item);
@@ -1020,7 +1020,7 @@ PHP_FUNCTION(twig_template_get_attributes)
1020
  return null;
1021
  }
1022
 
1023
- throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName());
1024
  }
1025
 
1026
  if ($isDefinedTest) {
@@ -1040,7 +1040,7 @@ PHP_FUNCTION(twig_template_get_attributes)
1040
  efree(item);
1041
  return;
1042
  }
1043
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Neither the property \"%s\" nor one of the methods \"%s()\", \"get%s()\"/\"is%s()\" or \"__call()\" exist and have public access in class \"%s\"", item, item, item, item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
1044
  efree(item);
1045
  return;
1046
  }
@@ -1052,14 +1052,14 @@ PHP_FUNCTION(twig_template_get_attributes)
1052
  RETURN_TRUE;
1053
  }
1054
  /*
1055
- if ($this->env->hasExtension('sandbox')) {
1056
- $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method);
1057
  }
1058
  */
1059
  MAKE_STD_ZVAL(zmethod);
1060
  ZVAL_STRING(zmethod, method, 1);
1061
- if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "sandbox" TSRMLS_CC)) {
1062
- TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "sandbox" TSRMLS_CC), "checkMethodAllowed", object, zmethod TSRMLS_CC);
1063
  }
1064
  zval_ptr_dtor(&zmethod);
1065
  if (EG(exception)) {
144
 
145
  if (!retval) {
146
  if (!EG(exception)) {
147
+ zend_error(E_ERROR, "Undefined offset for object of type %s used as array.", ce->name);
148
  }
149
  return NULL;
150
  }
167
 
168
  if (!retval) {
169
  if (!EG(exception)) {
170
+ zend_error(E_ERROR, "Undefined offset for object of type %s used as array.", ce->name);
171
  }
172
  return 0;
173
  }
811
  }
812
  */
813
  if (TWIG_INSTANCE_OF(object, zend_ce_arrayaccess TSRMLS_CC)) {
814
+ TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" in object with ArrayAccess of class \"%s\" does not exist.", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
815
  } else if (Z_TYPE_P(object) == IS_OBJECT) {
816
+ TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to access a key \"%s\" on an object of class \"%s\" that does not implement ArrayAccess interface.", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
817
  } else if (Z_TYPE_P(object) == IS_ARRAY) {
818
  if (0 == zend_hash_num_elements(Z_ARRVAL_P(object))) {
819
+ TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" does not exist as the array is empty.", item);
820
  } else {
821
  char *array_keys = TWIG_IMPLODE_ARRAY_KEYS(", ", object TSRMLS_CC);
822
+ TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" for array with keys \"%s\" does not exist.", item, array_keys);
823
  efree(array_keys);
824
  }
825
  } else {
829
  convert_to_string(object);
830
  TWIG_RUNTIME_ERROR(template TSRMLS_CC,
831
  (strcmp("array", type) == 0)
832
+ ? "Impossible to access a key (\"%s\") on a %s variable."
833
+ : "Impossible to access an attribute (\"%s\") on a %s variable.",
834
  item, type_name);
835
  } else {
836
  convert_to_string(object);
837
  TWIG_RUNTIME_ERROR(template TSRMLS_CC,
838
  (strcmp("array", type) == 0)
839
+ ? "Impossible to access a key (\"%s\") on a %s variable (\"%s\")."
840
+ : "Impossible to access an attribute (\"%s\") on a %s variable (\"%s\").",
841
  item, type_name, Z_STRVAL_P(object));
842
  }
843
  zval_ptr_dtor(&object);
883
  if (Z_TYPE_P(object) == IS_NULL) {
884
  convert_to_string_ex(&object);
885
 
886
+ TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable.", item, type_name);
887
  } else {
888
  convert_to_string_ex(&object);
889
 
890
+ TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable (\"%s\").", item, type_name, Z_STRVAL_P(object));
891
  }
892
 
893
  zval_ptr_dtor(&object);
916
  return true;
917
  }
918
 
919
+ if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
920
+ $this->env->getExtension('Twig_Extension_Sandbox')->checkPropertyAllowed($object, $item);
921
  }
922
 
923
  return $object->$item;
935
  efree(item);
936
  RETURN_TRUE;
937
  }
938
+ if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "Twig_Extension_Sandbox" TSRMLS_CC)) {
939
+ TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "Twig_Extension_Sandbox" TSRMLS_CC), "checkPropertyAllowed", object, zitem TSRMLS_CC);
940
  }
941
  if (EG(exception)) {
942
  efree(item);
1020
  return null;
1021
  }
1022
 
1023
+ throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist.', $item, get_class($object)), -1, $this->getTemplateName());
1024
  }
1025
 
1026
  if ($isDefinedTest) {
1040
  efree(item);
1041
  return;
1042
  }
1043
+ TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Neither the property \"%s\" nor one of the methods \"%s()\", \"get%s()\"/\"is%s()\" or \"__call()\" exist and have public access in class \"%s\".", item, item, item, item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
1044
  efree(item);
1045
  return;
1046
  }
1052
  RETURN_TRUE;
1053
  }
1054
  /*
1055
+ if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
1056
+ $this->env->getExtension('Twig_Extension_Sandbox')->checkMethodAllowed($object, $method);
1057
  }
1058
  */
1059
  MAKE_STD_ZVAL(zmethod);
1060
  ZVAL_STRING(zmethod, method, 1);
1061
+ if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "Twig_Extension_Sandbox" TSRMLS_CC)) {
1062
+ TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "Twig_Extension_Sandbox" TSRMLS_CC), "checkMethodAllowed", object, zmethod TSRMLS_CC);
1063
  }
1064
  zval_ptr_dtor(&zmethod);
1065
  if (EG(exception)) {
vendor/twig/twig/lib/Twig/Compiler.php CHANGED
@@ -36,8 +36,13 @@ class Twig_Compiler implements Twig_CompilerInterface
36
  $this->env = $env;
37
  }
38
 
 
 
 
39
  public function getFilename()
40
  {
 
 
41
  return $this->filename;
42
  }
43
 
@@ -80,7 +85,8 @@ class Twig_Compiler implements Twig_CompilerInterface
80
  $this->indentation = $indentation;
81
 
82
  if ($node instanceof Twig_Node_Module) {
83
- $this->filename = $node->getAttribute('filename');
 
84
  }
85
 
86
  $node->compile($this);
@@ -91,7 +97,7 @@ class Twig_Compiler implements Twig_CompilerInterface
91
  public function subcompile(Twig_NodeInterface $node, $raw = true)
92
  {
93
  if (false === $raw) {
94
- $this->addIndentation();
95
  }
96
 
97
  $node->compile($this);
@@ -122,8 +128,7 @@ class Twig_Compiler implements Twig_CompilerInterface
122
  {
123
  $strings = func_get_args();
124
  foreach ($strings as $string) {
125
- $this->addIndentation();
126
- $this->source .= $string;
127
  }
128
 
129
  return $this;
@@ -133,9 +138,13 @@ class Twig_Compiler implements Twig_CompilerInterface
133
  * Appends an indentation to the current PHP code after compilation.
134
  *
135
  * @return Twig_Compiler The current compiler instance
 
 
136
  */
137
  public function addIndentation()
138
  {
 
 
139
  $this->source .= str_repeat(' ', $this->indentation * 4);
140
 
141
  return $this;
@@ -207,8 +216,8 @@ class Twig_Compiler implements Twig_CompilerInterface
207
  */
208
  public function addDebugInfo(Twig_NodeInterface $node)
209
  {
210
- if ($node->getLine() != $this->lastLine) {
211
- $this->write(sprintf("// line %d\n", $node->getLine()));
212
 
213
  // when mbstring.func_overload is set to 2
214
  // mb_substr_count() replaces substr_count()
@@ -220,9 +229,9 @@ class Twig_Compiler implements Twig_CompilerInterface
220
  $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
221
  }
222
  $this->sourceOffset = strlen($this->source);
223
- $this->debugInfo[$this->sourceLine] = $node->getLine();
224
 
225
- $this->lastLine = $node->getLine();
226
  }
227
 
228
  return $this;
@@ -262,7 +271,7 @@ class Twig_Compiler implements Twig_CompilerInterface
262
  {
263
  // can't outdent by more steps than the current indentation level
264
  if ($this->indentation < $step) {
265
- throw new LogicException('Unable to call outdent() as the indentation would become negative');
266
  }
267
 
268
  $this->indentation -= $step;
36
  $this->env = $env;
37
  }
38
 
39
+ /**
40
+ * @deprecated since 1.25 (to be removed in 2.0)
41
+ */
42
  public function getFilename()
43
  {
44
+ @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
45
+
46
  return $this->filename;
47
  }
48
 
85
  $this->indentation = $indentation;
86
 
87
  if ($node instanceof Twig_Node_Module) {
88
+ // to be removed in 2.0
89
+ $this->filename = $node->getTemplateName();
90
  }
91
 
92
  $node->compile($this);
97
  public function subcompile(Twig_NodeInterface $node, $raw = true)
98
  {
99
  if (false === $raw) {
100
+ $this->source .= str_repeat(' ', $this->indentation * 4);
101
  }
102
 
103
  $node->compile($this);
128
  {
129
  $strings = func_get_args();
130
  foreach ($strings as $string) {
131
+ $this->source .= str_repeat(' ', $this->indentation * 4).$string;
 
132
  }
133
 
134
  return $this;
138
  * Appends an indentation to the current PHP code after compilation.
139
  *
140
  * @return Twig_Compiler The current compiler instance
141
+ *
142
+ * @deprecated since 1.27 (to be removed in 2.0).
143
  */
144
  public function addIndentation()
145
  {
146
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use write(\'\') instead.', E_USER_DEPRECATED);
147
+
148
  $this->source .= str_repeat(' ', $this->indentation * 4);
149
 
150
  return $this;
216
  */
217
  public function addDebugInfo(Twig_NodeInterface $node)
218
  {
219
+ if ($node->getTemplateLine() != $this->lastLine) {
220
+ $this->write(sprintf("// line %d\n", $node->getTemplateLine()));
221
 
222
  // when mbstring.func_overload is set to 2
223
  // mb_substr_count() replaces substr_count()
229
  $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
230
  }
231
  $this->sourceOffset = strlen($this->source);
232
+ $this->debugInfo[$this->sourceLine] = $node->getTemplateLine();
233
 
234
+ $this->lastLine = $node->getTemplateLine();
235
  }
236
 
237
  return $this;
271
  {
272
  // can't outdent by more steps than the current indentation level
273
  if ($this->indentation < $step) {
274
+ throw new LogicException('Unable to call outdent() as the indentation would become negative.');
275
  }
276
 
277
  $this->indentation -= $step;
vendor/twig/twig/lib/Twig/Environment.php CHANGED
@@ -16,7 +16,7 @@
16
  */
17
  class Twig_Environment
18
  {
19
- const VERSION = '1.24.2';
20
 
21
  protected $charset;
22
  protected $loader;
@@ -49,6 +49,10 @@ class Twig_Environment
49
  private $bcWriteCacheFile = false;
50
  private $bcGetCacheFilename = false;
51
  private $lastModifiedExtension = 0;
 
 
 
 
52
 
53
  /**
54
  * Constructor.
@@ -78,8 +82,8 @@ class Twig_Environment
78
  * * false: disable auto-escaping
79
  * * true: equivalent to html
80
  * * html, js: set the autoescaping to one of the supported strategies
81
- * * filename: set the autoescaping strategy based on the template filename extension
82
- * * PHP callback: a PHP callback that returns an escaping strategy based on the template "filename"
83
  *
84
  * * optimizations: A flag that indicates which optimizations to apply
85
  * (default to -1 which means that all optimizations are enabled;
@@ -155,6 +159,7 @@ class Twig_Environment
155
  public function setBaseTemplateClass($class)
156
  {
157
  $this->baseTemplateClass = $class;
 
158
  }
159
 
160
  /**
@@ -163,6 +168,7 @@ class Twig_Environment
163
  public function enableDebug()
164
  {
165
  $this->debug = true;
 
166
  }
167
 
168
  /**
@@ -171,6 +177,7 @@ class Twig_Environment
171
  public function disableDebug()
172
  {
173
  $this->debug = false;
 
174
  }
175
 
176
  /**
@@ -215,6 +222,7 @@ class Twig_Environment
215
  public function enableStrictVariables()
216
  {
217
  $this->strictVariables = true;
 
218
  }
219
 
220
  /**
@@ -223,6 +231,7 @@ class Twig_Environment
223
  public function disableStrictVariables()
224
  {
225
  $this->strictVariables = false;
 
226
  }
227
 
228
  /**
@@ -300,7 +309,10 @@ class Twig_Environment
300
  *
301
  * * The cache key for the given template;
302
  * * The currently enabled extensions;
303
- * * Whether the Twig C extension is available or not.
 
 
 
304
  *
305
  * @param string $name The name for which to calculate the template class name
306
  * @param int|null $index The index if it is an embedded template
@@ -309,9 +321,7 @@ class Twig_Environment
309
  */
310
  public function getTemplateClass($name, $index = null)
311
  {
312
- $key = $this->getLoader()->getCacheKey($name);
313
- $key .= json_encode(array_keys($this->extensions));
314
- $key .= function_exists('twig_template_get_attributes');
315
 
316
  return $this->templateClassPrefix.hash('sha256', $key).(null === $index ? '' : '_'.$index);
317
  }
@@ -393,7 +403,15 @@ class Twig_Environment
393
  }
394
 
395
  if (!class_exists($cls, false)) {
396
- $content = $this->compileSource($this->getLoader()->getSource($name), $name);
 
 
 
 
 
 
 
 
397
  if ($this->bcWriteCacheFile) {
398
  $this->writeCacheFile($key, $content);
399
  } else {
@@ -546,9 +564,13 @@ class Twig_Environment
546
  * Gets the Lexer instance.
547
  *
548
  * @return Twig_LexerInterface A Twig_LexerInterface instance
 
 
549
  */
550
  public function getLexer()
551
  {
 
 
552
  if (null === $this->lexer) {
553
  $this->lexer = new Twig_Lexer($this);
554
  }
@@ -569,8 +591,8 @@ class Twig_Environment
569
  /**
570
  * Tokenizes a source code.
571
  *
572
- * @param string $source The template source code
573
- * @param string $name The template name
574
  *
575
  * @return Twig_TokenStream A Twig_TokenStream instance
576
  *
@@ -578,16 +600,29 @@ class Twig_Environment
578
  */
579
  public function tokenize($source, $name = null)
580
  {
581
- return $this->getLexer()->tokenize($source, $name);
 
 
 
 
 
 
 
 
 
582
  }
583
 
584
  /**
585
  * Gets the Parser instance.
586
  *
587
  * @return Twig_ParserInterface A Twig_ParserInterface instance
 
 
588
  */
589
  public function getParser()
590
  {
 
 
591
  if (null === $this->parser) {
592
  $this->parser = new Twig_Parser($this);
593
  }
@@ -616,16 +651,24 @@ class Twig_Environment
616
  */
617
  public function parse(Twig_TokenStream $stream)
618
  {
619
- return $this->getParser()->parse($stream);
 
 
 
 
620
  }
621
 
622
  /**
623
  * Gets the Compiler instance.
624
  *
625
  * @return Twig_CompilerInterface A Twig_CompilerInterface instance
 
 
626
  */
627
  public function getCompiler()
628
  {
 
 
629
  if (null === $this->compiler) {
630
  $this->compiler = new Twig_Compiler($this);
631
  }
@@ -652,14 +695,18 @@ class Twig_Environment
652
  */
653
  public function compile(Twig_NodeInterface $node)
654
  {
655
- return $this->getCompiler()->compile($node)->getSource();
 
 
 
 
656
  }
657
 
658
  /**
659
  * Compiles a template source code.
660
  *
661
- * @param string $source The template source code
662
- * @param string $name The template name
663
  *
664
  * @return string The compiled PHP source code
665
  *
@@ -667,19 +714,18 @@ class Twig_Environment
667
  */
668
  public function compileSource($source, $name = null)
669
  {
670
- try {
671
- $compiled = $this->compile($this->parse($this->tokenize($source, $name)), $source);
672
-
673
- if (isset($source[0])) {
674
- $compiled .= '/* '.str_replace(array('*/', "\r\n", "\r", "\n"), array('*//* ', "\n", "\n", "*/\n/* "), $source)."*/\n";
675
- }
676
 
677
- return $compiled;
 
678
  } catch (Twig_Error $e) {
679
- $e->setTemplateFile($name);
680
  throw $e;
681
  } catch (Exception $e) {
682
- throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e);
683
  }
684
  }
685
 
@@ -690,6 +736,10 @@ class Twig_Environment
690
  */
691
  public function setLoader(Twig_LoaderInterface $loader)
692
  {
 
 
 
 
693
  $this->loader = $loader;
694
  }
695
 
@@ -752,29 +802,80 @@ class Twig_Environment
752
  /**
753
  * Returns true if the given extension is registered.
754
  *
755
- * @param string $name The extension name
756
  *
757
  * @return bool Whether the extension is registered or not
758
  */
759
- public function hasExtension($name)
760
  {
761
- return isset($this->extensions[$name]);
 
 
 
 
 
 
 
 
 
762
  }
763
 
764
  /**
765
- * Gets an extension by name.
 
 
 
 
 
 
 
 
766
  *
767
- * @param string $name The extension name
768
  *
769
  * @return Twig_ExtensionInterface A Twig_ExtensionInterface instance
770
  */
771
- public function getExtension($name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
772
  {
773
- if (!isset($this->extensions[$name])) {
774
- throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $name));
775
  }
776
 
777
- return $this->extensions[$name];
 
 
 
 
 
 
778
  }
779
 
780
  /**
@@ -784,19 +885,22 @@ class Twig_Environment
784
  */
785
  public function addExtension(Twig_ExtensionInterface $extension)
786
  {
787
- $name = $extension->getName();
788
-
789
  if ($this->extensionInitialized) {
790
- throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $name));
791
  }
792
 
793
- if (isset($this->extensions[$name])) {
794
- @trigger_error(sprintf('The possibility to register the same extension twice ("%s") is deprecated since version 1.23 and will be removed in Twig 2.0. Use proper PHP inheritance instead.', $name), E_USER_DEPRECATED);
 
 
 
 
795
  }
796
 
797
  $this->lastModifiedExtension = 0;
798
-
799
- $this->extensions[$name] = $extension;
 
800
  }
801
 
802
  /**
@@ -816,7 +920,17 @@ class Twig_Environment
816
  throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
817
  }
818
 
819
- unset($this->extensions[$name]);
 
 
 
 
 
 
 
 
 
 
820
  }
821
 
822
  /**
@@ -834,7 +948,7 @@ class Twig_Environment
834
  /**
835
  * Returns all registered extensions.
836
  *
837
- * @return array An array of extensions
838
  */
839
  public function getExtensions()
840
  {
@@ -931,7 +1045,7 @@ class Twig_Environment
931
  public function addFilter($name, $filter = null)
932
  {
933
  if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) {
934
- throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter');
935
  }
936
 
937
  if ($name instanceof Twig_SimpleFilter) {
@@ -1026,7 +1140,7 @@ class Twig_Environment
1026
  public function addTest($name, $test = null)
1027
  {
1028
  if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) {
1029
- throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest');
1030
  }
1031
 
1032
  if ($name instanceof Twig_SimpleTest) {
@@ -1090,7 +1204,7 @@ class Twig_Environment
1090
  public function addFunction($name, $function = null)
1091
  {
1092
  if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) {
1093
- throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction');
1094
  }
1095
 
1096
  if ($name instanceof Twig_SimpleFunction) {
@@ -1388,7 +1502,7 @@ class Twig_Environment
1388
 
1389
  $this->parsers->addTokenParserBroker($parser);
1390
  } else {
1391
- throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances');
1392
  }
1393
  }
1394
 
@@ -1415,4 +1529,21 @@ class Twig_Environment
1415
  {
1416
  $this->cache->write($file, $content);
1417
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1418
  }
16
  */
17
  class Twig_Environment
18
  {
19
+ const VERSION = '1.27.0';
20
 
21
  protected $charset;
22
  protected $loader;
49
  private $bcWriteCacheFile = false;
50
  private $bcGetCacheFilename = false;
51
  private $lastModifiedExtension = 0;
52
+ private $extensionsByClass = array();
53
+ private $runtimeLoaders = array();
54
+ private $runtimes = array();
55
+ private $optionsHash;
56
 
57
  /**
58
  * Constructor.
82
  * * false: disable auto-escaping
83
  * * true: equivalent to html
84
  * * html, js: set the autoescaping to one of the supported strategies
85
+ * * name: set the autoescaping strategy based on the template name extension
86
+ * * PHP callback: a PHP callback that returns an escaping strategy based on the template "name"
87
  *
88
  * * optimizations: A flag that indicates which optimizations to apply
89
  * (default to -1 which means that all optimizations are enabled;
159
  public function setBaseTemplateClass($class)
160
  {
161
  $this->baseTemplateClass = $class;
162
+ $this->updateOptionsHash();
163
  }
164
 
165
  /**
168
  public function enableDebug()
169
  {
170
  $this->debug = true;
171
+ $this->updateOptionsHash();
172
  }
173
 
174
  /**
177
  public function disableDebug()
178
  {
179
  $this->debug = false;
180
+ $this->updateOptionsHash();
181
  }
182
 
183
  /**
222
  public function enableStrictVariables()
223
  {
224
  $this->strictVariables = true;
225
+ $this->updateOptionsHash();
226
  }
227
 
228
  /**
231
  public function disableStrictVariables()
232
  {
233
  $this->strictVariables = false;
234
+ $this->updateOptionsHash();
235
  }
236
 
237
  /**
309
  *
310
  * * The cache key for the given template;
311
  * * The currently enabled extensions;
312
+ * * Whether the Twig C extension is available or not;
313
+ * * PHP version;
314
+ * * Twig version;
315
+ * * Options with what environment was created.
316
  *
317
  * @param string $name The name for which to calculate the template class name
318
  * @param int|null $index The index if it is an embedded template
321
  */
322
  public function getTemplateClass($name, $index = null)
323
  {
324
+ $key = $this->getLoader()->getCacheKey($name).$this->optionsHash;
 
 
325
 
326
  return $this->templateClassPrefix.hash('sha256', $key).(null === $index ? '' : '_'.$index);
327
  }
403
  }
404
 
405
  if (!class_exists($cls, false)) {
406
+ $loader = $this->getLoader();
407
+ if (!$loader instanceof Twig_SourceContextLoaderInterface) {
408
+ $source = new Twig_Source($loader->getSource($name), $name);
409
+ } else {
410
+ $source = $loader->getSourceContext($name);
411
+ }
412
+
413
+ $content = $this->compileSource($source);
414
+
415
  if ($this->bcWriteCacheFile) {
416
  $this->writeCacheFile($key, $content);
417
  } else {
564
  * Gets the Lexer instance.
565
  *
566
  * @return Twig_LexerInterface A Twig_LexerInterface instance
567
+ *
568
+ * @deprecated since 1.25 (to be removed in 2.0)
569
  */
570
  public function getLexer()
571
  {
572
+ @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
573
+
574
  if (null === $this->lexer) {
575
  $this->lexer = new Twig_Lexer($this);
576
  }
591
  /**
592
  * Tokenizes a source code.
593
  *
594
+ * @param string|Twig_Source $source The template source code
595
+ * @param string $name The template name (deprecated)
596
  *
597
  * @return Twig_TokenStream A Twig_TokenStream instance
598
  *
600
  */
601
  public function tokenize($source, $name = null)
602
  {
603
+ if (!$source instanceof Twig_Source) {
604
+ @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
605
+ $source = new Twig_Source($source, $name);
606
+ }
607
+
608
+ if (null === $this->lexer) {
609
+ $this->lexer = new Twig_Lexer($this);
610
+ }
611
+
612
+ return $this->lexer->tokenize($source);
613
  }
614
 
615
  /**
616
  * Gets the Parser instance.
617
  *
618
  * @return Twig_ParserInterface A Twig_ParserInterface instance
619
+ *
620
+ * @deprecated since 1.25 (to be removed in 2.0)
621
  */
622
  public function getParser()
623
  {
624
+ @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
625
+
626
  if (null === $this->parser) {
627
  $this->parser = new Twig_Parser($this);
628
  }
651
  */
652
  public function parse(Twig_TokenStream $stream)
653
  {
654
+ if (null === $this->parser) {
655
+ $this->parser = new Twig_Parser($this);
656
+ }
657
+
658
+ return $this->parser->parse($stream);
659
  }
660
 
661
  /**
662
  * Gets the Compiler instance.
663
  *
664
  * @return Twig_CompilerInterface A Twig_CompilerInterface instance
665
+ *
666
+ * @deprecated since 1.25 (to be removed in 2.0)
667
  */
668
  public function getCompiler()
669
  {
670
+ @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
671
+
672
  if (null === $this->compiler) {
673
  $this->compiler = new Twig_Compiler($this);
674
  }
695
  */
696
  public function compile(Twig_NodeInterface $node)
697
  {
698
+ if (null === $this->compiler) {
699
+ $this->compiler = new Twig_Compiler($this);
700
+ }
701
+
702
+ return $this->compiler->compile($node)->getSource();
703
  }
704
 
705
  /**
706
  * Compiles a template source code.
707
  *
708
+ * @param string|Twig_Source $source The template source code
709
+ * @param string $name The template name (deprecated)
710
  *
711
  * @return string The compiled PHP source code
712
  *
714
  */
715
  public function compileSource($source, $name = null)
716
  {
717
+ if (!$source instanceof Twig_Source) {
718
+ @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
719
+ $source = new Twig_Source($source, $name);
720
+ }
 
 
721
 
722
+ try {
723
+ return $this->compile($this->parse($this->tokenize($source)));
724
  } catch (Twig_Error $e) {
725
+ $e->setTemplateName($source->getName());
726
  throw $e;
727
  } catch (Exception $e) {
728
+ throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source->getName(), $e);
729
  }
730
  }
731
 
736
  */
737
  public function setLoader(Twig_LoaderInterface $loader)
738
  {
739
+ if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader), 'Mock_Twig_LoaderInterface')) {
740
+ @trigger_error(sprintf('Twig loader "%s" should implement Twig_SourceContextLoaderInterface since version 1.27.', get_class($loader)), E_USER_DEPRECATED);
741
+ }
742
+
743
  $this->loader = $loader;
744
  }
745
 
802
  /**
803
  * Returns true if the given extension is registered.
804
  *
805
+ * @param string $class The extension class name
806
  *
807
  * @return bool Whether the extension is registered or not
808
  */
809
+ public function hasExtension($class)
810
  {
811
+ $class = ltrim($class, '\\');
812
+ if (isset($this->extensions[$class])) {
813
+ if ($class !== get_class($this->extensions[$class])) {
814
+ @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
815
+ }
816
+
817
+ return true;
818
+ }
819
+
820
+ return isset($this->extensionsByClass[ltrim($class, '\\')]);
821
  }
822
 
823
  /**
824
+ * Adds a runtime loader.
825
+ */
826
+ public function addRuntimeLoader(Twig_RuntimeLoaderInterface $loader)
827
+ {
828
+ $this->runtimeLoaders[] = $loader;
829
+ }
830
+
831
+ /**
832
+ * Gets an extension by class name.
833
  *
834
+ * @param string $class The extension class name
835
  *
836
  * @return Twig_ExtensionInterface A Twig_ExtensionInterface instance
837
  */
838
+ public function getExtension($class)
839
+ {
840
+ $class = ltrim($class, '\\');
841
+
842
+ if (isset($this->extensions[$class])) {
843
+ if ($class !== get_class($this->extensions[$class])) {
844
+ @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
845
+ }
846
+
847
+ return $this->extensions[$class];
848
+ }
849
+
850
+ if (!isset($this->extensionsByClass[$class])) {
851
+ throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $class));
852
+ }
853
+
854
+ return $this->extensionsByClass[$class];
855
+ }
856
+
857
+ /**
858
+ * Returns the runtime implementation of a Twig element (filter/function/test).
859
+ *
860
+ * @param string $class A runtime class name
861
+ *
862
+ * @return object The runtime implementation
863
+ *
864
+ * @throws Twig_Error_Runtime When the template cannot be found
865
+ */
866
+ public function getRuntime($class)
867
  {
868
+ if (isset($this->runtimes[$class])) {
869
+ return $this->runtimes[$class];
870
  }
871
 
872
+ foreach ($this->runtimeLoaders as $loader) {
873
+ if (null !== $runtime = $loader->load($class)) {
874
+ return $this->runtimes[$class] = $runtime;
875
+ }
876
+ }
877
+
878
+ throw new Twig_Error_Runtime(sprintf('Unable to load the "%s" runtime.', $class));
879
  }
880
 
881
  /**
885
  */
886
  public function addExtension(Twig_ExtensionInterface $extension)
887
  {
 
 
888
  if ($this->extensionInitialized) {
889
+ throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName()));
890
  }
891
 
892
+ $class = get_class($extension);
893
+ if ($class !== $extension->getName()) {
894
+ if (isset($this->extensions[$extension->getName()])) {
895
+ unset($this->extensions[$extension->getName()], $this->extensionsByClass[$class]);
896
+ @trigger_error(sprintf('The possibility to register the same extension twice ("%s") is deprecated since version 1.23 and will be removed in Twig 2.0. Use proper PHP inheritance instead.', $extension->getName()), E_USER_DEPRECATED);
897
+ }
898
  }
899
 
900
  $this->lastModifiedExtension = 0;
901
+ $this->extensionsByClass[$class] = $extension;
902
+ $this->extensions[$extension->getName()] = $extension;
903
+ $this->updateOptionsHash();
904
  }
905
 
906
  /**
920
  throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
921
  }
922
 
923
+ $class = ltrim($name, '\\');
924
+ if (isset($this->extensions[$class])) {
925
+ if ($class !== get_class($this->extensions[$class])) {
926
+ @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
927
+ }
928
+
929
+ unset($this->extensions[$class]);
930
+ }
931
+
932
+ unset($this->extensions[$class]);
933
+ $this->updateOptionsHash();
934
  }
935
 
936
  /**
948
  /**
949
  * Returns all registered extensions.
950
  *
951
+ * @return Twig_ExtensionInterface[] An array of extensions (keys are for internal usage only and should not be relied on)
952
  */
953
  public function getExtensions()
954
  {
1045
  public function addFilter($name, $filter = null)
1046
  {
1047
  if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) {
1048
+ throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter.');
1049
  }
1050
 
1051
  if ($name instanceof Twig_SimpleFilter) {
1140
  public function addTest($name, $test = null)
1141
  {
1142
  if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) {
1143
+ throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest.');
1144
  }
1145
 
1146
  if ($name instanceof Twig_SimpleTest) {
1204
  public function addFunction($name, $function = null)
1205
  {
1206
  if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) {
1207
+ throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction.');
1208
  }
1209
 
1210
  if ($name instanceof Twig_SimpleFunction) {
1502
 
1503
  $this->parsers->addTokenParserBroker($parser);
1504
  } else {
1505
+ throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances.');
1506
  }
1507
  }
1508
 
1529
  {
1530
  $this->cache->write($file, $content);
1531
  }
1532
+
1533
+ private function updateOptionsHash()
1534
+ {
1535
+ $hashParts = array_merge(
1536
+ array_keys($this->extensions),
1537
+ array(
1538
+ (int) function_exists('twig_template_get_attributes'),
1539
+ PHP_MAJOR_VERSION,
1540
+ PHP_MINOR_VERSION,
1541
+ self::VERSION,
1542
+ (int) $this->debug,
1543
+ $this->baseTemplateClass,
1544
+ (int) $this->strictVariables,
1545
+ )
1546
+ );
1547
+ $this->optionsHash = implode(':', $hashParts);
1548
+ }
1549
  }
vendor/twig/twig/lib/Twig/Error.php CHANGED
@@ -25,8 +25,8 @@
25
  * and line number) yourself by passing them to the constructor. If some or all
26
  * these information are not available from where you throw the exception, then
27
  * this class will guess them automatically (when the line number is set to -1
28
- * and/or the filename is set to null). As this is a costly operation, this
29
- * can be disabled by passing false for both the filename and the line number
30
  * when creating a new instance of this class.
31
  *
32
  * @author Fabien Potencier <fabien@symfony.com>
@@ -34,6 +34,7 @@
34
  class Twig_Error extends Exception
35
  {
36
  protected $lineno;
 
37
  protected $filename;
38
  protected $rawMessage;
39
  protected $previous;
@@ -41,21 +42,21 @@ class Twig_Error extends Exception
41
  /**
42
  * Constructor.
43
  *
44
- * Set both the line number and the filename to false to
45
  * disable automatic guessing of the original template name
46
  * and line number.
47
  *
48
  * Set the line number to -1 to enable its automatic guessing.
49
- * Set the filename to null to enable its automatic guessing.
50
  *
51
  * By default, automatic guessing is enabled.
52
  *
53
  * @param string $message The error message
54
  * @param int $lineno The template line where the error occurred
55
- * @param string $filename The template file name where the error occurred
56
  * @param Exception $previous The previous exception
57
  */
58
- public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null)
59
  {
60
  if (PHP_VERSION_ID < 50300) {
61
  $this->previous = $previous;
@@ -65,9 +66,9 @@ class Twig_Error extends Exception
65
  }
66
 
67
  $this->lineno = $lineno;
68
- $this->filename = $filename;
69
 
70
- if (-1 === $this->lineno || null === $this->filename) {
71
  $this->guessTemplateInfo();
72
  }
73
 
@@ -87,23 +88,53 @@ class Twig_Error extends Exception
87
  }
88
 
89
  /**
90
- * Gets the filename where the error occurred.
91
  *
92
- * @return string The filename
 
 
93
  */
94
  public function getTemplateFile()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  {
96
  return $this->filename;
97
  }
98
 
99
  /**
100
- * Sets the filename where the error occurred.
101
  *
102
- * @param string $filename The filename
103
  */
104
- public function setTemplateFile($filename)
105
  {
106
- $this->filename = $filename;
107
 
108
  $this->updateRepr();
109
  }
@@ -182,11 +213,11 @@ class Twig_Error extends Exception
182
 
183
  if ($this->filename) {
184
  if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) {
185
- $filename = sprintf('"%s"', $this->filename);
186
  } else {
187
- $filename = json_encode($this->filename);
188
  }
189
- $this->message .= sprintf(' in %s', $filename);
190
  }
191
 
192
  if ($this->lineno && $this->lineno >= 0) {
@@ -227,7 +258,7 @@ class Twig_Error extends Exception
227
  }
228
  }
229
 
230
- // update template filename
231
  if (null !== $template && null === $this->filename) {
232
  $this->filename = $template->getTemplateName();
233
  }
25
  * and line number) yourself by passing them to the constructor. If some or all
26
  * these information are not available from where you throw the exception, then
27
  * this class will guess them automatically (when the line number is set to -1
28
+ * and/or the name is set to null). As this is a costly operation, this
29
+ * can be disabled by passing false for both the name and the line number
30
  * when creating a new instance of this class.
31
  *
32
  * @author Fabien Potencier <fabien@symfony.com>
34
  class Twig_Error extends Exception
35
  {
36
  protected $lineno;
37
+ // to be renamed to name in 2.0
38
  protected $filename;
39
  protected $rawMessage;
40
  protected $previous;
42
  /**
43
  * Constructor.
44
  *
45
+ * Set both the line number and the name to false to
46
  * disable automatic guessing of the original template name
47
  * and line number.
48
  *
49
  * Set the line number to -1 to enable its automatic guessing.
50
+ * Set the name to null to enable its automatic guessing.
51
  *
52
  * By default, automatic guessing is enabled.
53
  *
54
  * @param string $message The error message
55
  * @param int $lineno The template line where the error occurred
56
+ * @param string $name The template logical name where the error occurred
57
  * @param Exception $previous The previous exception
58
  */
59
+ public function __construct($message, $lineno = -1, $name = null, Exception $previous = null)
60
  {
61
  if (PHP_VERSION_ID < 50300) {
62
  $this->previous = $previous;
66
  }
67
 
68
  $this->lineno = $lineno;
69
+ $this->filename = $name;
70
 
71
+ if (-1 === $lineno || null === $name) {
72
  $this->guessTemplateInfo();
73
  }
74
 
88
  }
89
 
90
  /**
91
+ * Gets the logical name where the error occurred.
92
  *
93
+ * @return string The name
94
+ *
95
+ * @deprecated since 1.27 (to be removed in 2.0). Use getTemplateName() instead.
96
  */
97
  public function getTemplateFile()
98
+ {
99
+ @trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateName() instead.', __METHOD__), E_USER_DEPRECATED);
100
+
101
+ return $this->filename;
102
+ }
103
+
104
+ /**
105
+ * Sets the logical name where the error occurred.
106
+ *
107
+ * @param string $name The name
108
+ *
109
+ * @deprecated since 1.27 (to be removed in 2.0). Use setTemplateName() instead.
110
+ */
111
+ public function setTemplateFile($name)
112
+ {
113
+ @trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use setTemplateName() instead.', __METHOD__), E_USER_DEPRECATED);
114
+
115
+ $this->filename = $name;
116
+
117
+ $this->updateRepr();
118
+ }
119
+
120
+ /**
121
+ * Gets the logical name where the error occurred.
122
+ *
123
+ * @return string The name
124
+ */
125
+ public function getTemplateName()
126
  {
127
  return $this->filename;
128
  }
129
 
130
  /**
131
+ * Sets the logical name where the error occurred.
132
  *
133
+ * @param string $name The name
134
  */
135
+ public function setTemplateName($name)
136
  {
137
+ $this->filename = $name;
138
 
139
  $this->updateRepr();
140
  }
213
 
214
  if ($this->filename) {
215
  if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) {
216
+ $name = sprintf('"%s"', $this->filename);
217
  } else {
218
+ $name = json_encode($this->filename);
219
  }
220
+ $this->message .= sprintf(' in %s', $name);
221
  }
222
 
223
  if ($this->lineno && $this->lineno >= 0) {
258
  }
259
  }
260
 
261
+ // update template name
262
  if (null !== $template && null === $this->filename) {
263
  $this->filename = $template->getTemplateName();
264
  }
vendor/twig/twig/lib/Twig/ExpressionParser.php CHANGED
@@ -19,6 +19,8 @@
19
  * @see http://en.wikipedia.org/wiki/Operator-precedence_parser
20
  *
21
  * @author Fabien Potencier <fabien@symfony.com>
 
 
22
  */
23
  class Twig_ExpressionParser
24
  {
@@ -29,11 +31,23 @@ class Twig_ExpressionParser
29
  protected $unaryOperators;
30
  protected $binaryOperators;
31
 
32
- public function __construct(Twig_Parser $parser, array $unaryOperators, array $binaryOperators)
 
 
33
  {
34
  $this->parser = $parser;
35
- $this->unaryOperators = $unaryOperators;
36
- $this->binaryOperators = $binaryOperators;
 
 
 
 
 
 
 
 
 
 
37
  }
38
 
39
  public function parseExpression($precedence = 0)
@@ -44,7 +58,11 @@ class Twig_ExpressionParser
44
  $op = $this->binaryOperators[$token->getValue()];
45
  $this->parser->getStream()->next();
46
 
47
- if (isset($op['callable'])) {
 
 
 
 
48
  $expr = call_user_func($op['callable'], $this->parser, $expr);
49
  } else {
50
  $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
@@ -171,7 +189,7 @@ class Twig_ExpressionParser
171
  $negClass = 'Twig_Node_Expression_Unary_Neg';
172
  $posClass = 'Twig_Node_Expression_Unary_Pos';
173
  if (!(in_array($ref->getName(), array($negClass, $posClass)) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) {
174
- throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getFilename());
175
  }
176
 
177
  $this->parser->getStream()->next();
@@ -187,7 +205,7 @@ class Twig_ExpressionParser
187
  } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
188
  $node = $this->parseHashExpression();
189
  } else {
190
- throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getFilename());
191
  }
192
  }
193
 
@@ -216,7 +234,7 @@ class Twig_ExpressionParser
216
 
217
  $expr = array_shift($nodes);
218
  foreach ($nodes as $node) {
219
- $expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getLine());
220
  }
221
 
222
  return $expr;
@@ -278,7 +296,7 @@ class Twig_ExpressionParser
278
  } else {
279
  $current = $stream->getCurrent();
280
 
281
- throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $this->parser->getFilename());
282
  }
283
 
284
  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
@@ -317,11 +335,11 @@ class Twig_ExpressionParser
317
  case 'parent':
318
  $this->parseArguments();
319
  if (!count($this->parser->getBlockStack())) {
320
- throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden.', $line, $this->parser->getFilename());
321
  }
322
 
323
  if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
324
- throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getFilename());
325
  }
326
 
327
  return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
@@ -330,7 +348,7 @@ class Twig_ExpressionParser
330
  case 'attribute':
331
  $args = $this->parseArguments();
332
  if (count($args) < 2) {
333
- throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getFilename());
334
  }
335
 
336
  return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line);
@@ -379,18 +397,18 @@ class Twig_ExpressionParser
379
  }
380
  }
381
  } else {
382
- throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename());
383
  }
384
 
385
  if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
386
  if (!$arg instanceof Twig_Node_Expression_Constant) {
387
- throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename());
388
  }
389
 
390
  $name = $arg->getAttribute('value');
391
 
392
  if ($this->parser->isReservedMacroName($name)) {
393
- throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $this->parser->getFilename());
394
  }
395
 
396
  $node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno);
@@ -500,7 +518,7 @@ class Twig_ExpressionParser
500
  $name = null;
501
  if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
502
  if (!$value instanceof Twig_Node_Expression_Name) {
503
- throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given.', get_class($value)), $token->getLine(), $this->parser->getFilename());
504
  }
505
  $name = $value->getAttribute('name');
506
 
@@ -508,7 +526,7 @@ class Twig_ExpressionParser
508
  $value = $this->parsePrimaryExpression();
509
 
510
  if (!$this->checkConstantExpression($value)) {
511
- 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());
512
  }
513
  } else {
514
  $value = $this->parseExpression();
@@ -536,16 +554,17 @@ class Twig_ExpressionParser
536
 
537
  public function parseAssignmentExpression()
538
  {
 
539
  $targets = array();
540
  while (true) {
541
- $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
542
  $value = $token->getValue();
543
  if (in_array(strtolower($value), array('true', 'false', 'none', 'null'))) {
544
- throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $value), $token->getLine(), $this->parser->getFilename());
545
  }
546
  $targets[] = new Twig_Node_Expression_AssignName($value, $token->getLine());
547
 
548
- if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
549
  break;
550
  }
551
  }
@@ -566,13 +585,79 @@ class Twig_ExpressionParser
566
  return new Twig_Node($targets);
567
  }
568
 
569
- protected function getFunctionNodeClass($name, $line)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
570
  {
571
- $env = $this->parser->getEnvironment();
 
 
 
 
 
 
 
 
 
 
 
 
572
 
573
- if (false === $function = $env->getFunction($name)) {
574
- $e = new Twig_Error_Syntax(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getFilename());
575
- $e->addSuggestions($name, array_keys($env->getFunctions()));
 
 
 
 
 
 
 
 
 
576
 
577
  throw $e;
578
  }
@@ -585,7 +670,7 @@ class Twig_ExpressionParser
585
  if ($function->getAlternative()) {
586
  $message .= sprintf('. Use "%s" instead', $function->getAlternative());
587
  }
588
- $message .= sprintf(' in %s at line %d.', $this->parser->getFilename(), $line);
589
 
590
  @trigger_error($message, E_USER_DEPRECATED);
591
  }
@@ -599,11 +684,9 @@ class Twig_ExpressionParser
599
 
600
  protected function getFilterNodeClass($name, $line)
601
  {
602
- $env = $this->parser->getEnvironment();
603
-
604
- if (false === $filter = $env->getFilter($name)) {
605
- $e = new Twig_Error_Syntax(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getFilename());
606
- $e->addSuggestions($name, array_keys($env->getFilters()));
607
 
608
  throw $e;
609
  }
@@ -616,7 +699,7 @@ class Twig_ExpressionParser
616
  if ($filter->getAlternative()) {
617
  $message .= sprintf('. Use "%s" instead', $filter->getAlternative());
618
  }
619
- $message .= sprintf(' in %s at line %d.', $this->parser->getFilename(), $line);
620
 
621
  @trigger_error($message, E_USER_DEPRECATED);
622
  }
19
  * @see http://en.wikipedia.org/wiki/Operator-precedence_parser
20
  *
21
  * @author Fabien Potencier <fabien@symfony.com>
22
+ *
23
+ * @internal
24
  */
25
  class Twig_ExpressionParser
26
  {
31
  protected $unaryOperators;
32
  protected $binaryOperators;
33
 
34
+ private $env;
35
+
36
+ public function __construct(Twig_Parser $parser, Twig_Environment $env = null)
37
  {
38
  $this->parser = $parser;
39
+
40
+ if ($env instanceof Twig_Environment) {
41
+ $this->env = $env;
42
+ $this->unaryOperators = $env->getUnaryOperators();
43
+ $this->binaryOperators = $env->getBinaryOperators();
44
+ } else {
45
+ @trigger_error('Passing the operators as constructor arguments to '.__METHOD__.' is deprecated since version 1.27. Pass the environment instead.', E_USER_DEPRECATED);
46
+
47
+ $this->env = $parser->getEnvironment();
48
+ $this->unaryOperators = func_get_arg(1);
49
+ $this->binaryOperators = func_get_arg(2);
50
+ }
51
  }
52
 
53
  public function parseExpression($precedence = 0)
58
  $op = $this->binaryOperators[$token->getValue()];
59
  $this->parser->getStream()->next();
60
 
61
+ if ('is not' === $token->getValue()) {
62
+ $expr = $this->parseNotTestExpression($expr);
63
+ } elseif ('is' === $token->getValue()) {
64
+ $expr = $this->parseTestExpression($expr);
65
+ } elseif (isset($op['callable'])) {
66
  $expr = call_user_func($op['callable'], $this->parser, $expr);
67
  } else {
68
  $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
189
  $negClass = 'Twig_Node_Expression_Unary_Neg';
190
  $posClass = 'Twig_Node_Expression_Unary_Pos';
191
  if (!(in_array($ref->getName(), array($negClass, $posClass)) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) {
192
+ throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext()->getName());
193
  }
194
 
195
  $this->parser->getStream()->next();
205
  } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
206
  $node = $this->parseHashExpression();
207
  } else {
208
+ throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext()->getName());
209
  }
210
  }
211
 
234
 
235
  $expr = array_shift($nodes);
236
  foreach ($nodes as $node) {
237
+ $expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getTemplateLine());
238
  }
239
 
240
  return $expr;
296
  } else {
297
  $current = $stream->getCurrent();
298
 
299
+ throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext()->getName());
300
  }
301
 
302
  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
335
  case 'parent':
336
  $this->parseArguments();
337
  if (!count($this->parser->getBlockStack())) {
338
+ throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext()->getName());
339
  }
340
 
341
  if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
342
+ throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext()->getName());
343
  }
344
 
345
  return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
348
  case 'attribute':
349
  $args = $this->parseArguments();
350
  if (count($args) < 2) {
351
+ throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext()->getName());
352
  }
353
 
354
  return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line);
397
  }
398
  }
399
  } else {
400
+ throw new Twig_Error_Syntax('Expected name or number.', $lineno, $stream->getSourceContext()->getName());
401
  }
402
 
403
  if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
404
  if (!$arg instanceof Twig_Node_Expression_Constant) {
405
+ throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $stream->getSourceContext()->getName());
406
  }
407
 
408
  $name = $arg->getAttribute('value');
409
 
410
  if ($this->parser->isReservedMacroName($name)) {
411
+ throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext()->getName());
412
  }
413
 
414
  $node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno);
518
  $name = null;
519
  if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
520
  if (!$value instanceof Twig_Node_Expression_Name) {
521
+ throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given.', get_class($value)), $token->getLine(), $stream->getSourceContext()->getName());
522
  }
523
  $name = $value->getAttribute('name');
524
 
526
  $value = $this->parsePrimaryExpression();
527
 
528
  if (!$this->checkConstantExpression($value)) {
529
+ 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(), $stream->getSourceContext()->getName());
530
  }
531
  } else {
532
  $value = $this->parseExpression();
554
 
555
  public function parseAssignmentExpression()
556
  {
557
+ $stream = $this->parser->getStream();
558
  $targets = array();
559
  while (true) {
560
+ $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
561
  $value = $token->getValue();
562
  if (in_array(strtolower($value), array('true', 'false', 'none', 'null'))) {
563
+ throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext()->getName());
564
  }
565
  $targets[] = new Twig_Node_Expression_AssignName($value, $token->getLine());
566
 
567
+ if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
568
  break;
569
  }
570
  }
585
  return new Twig_Node($targets);
586
  }
587
 
588
+ private function parseNotTestExpression(Twig_NodeInterface $node)
589
+ {
590
+ return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
591
+ }
592
+
593
+ private function parseTestExpression(Twig_NodeInterface $node)
594
+ {
595
+ $stream = $this->parser->getStream();
596
+ list($name, $test) = $this->getTest($node->getTemplateLine());
597
+
598
+ $class = $this->getTestNodeClass($test);
599
+ $arguments = null;
600
+ if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
601
+ $arguments = $this->parser->getExpressionParser()->parseArguments(true);
602
+ }
603
+
604
+ return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
605
+ }
606
+
607
+ private function getTest($line)
608
+ {
609
+ $stream = $this->parser->getStream();
610
+ $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
611
+
612
+ if ($test = $this->env->getTest($name)) {
613
+ return array($name, $test);
614
+ }
615
+
616
+ if ($stream->test(Twig_Token::NAME_TYPE)) {
617
+ // try 2-words tests
618
+ $name = $name.' '.$this->parser->getCurrentToken()->getValue();
619
+
620
+ if ($test = $this->env->getTest($name)) {
621
+ $stream->next();
622
+
623
+ return array($name, $test);
624
+ }
625
+ }
626
+
627
+ $e = new Twig_Error_Syntax(sprintf('Unknown "%s" test.', $name), $line, $stream->getSourceContext()->getName());
628
+ $e->addSuggestions($name, array_keys($this->env->getTests()));
629
+
630
+ throw $e;
631
+ }
632
+
633
+ private function getTestNodeClass($test)
634
  {
635
+ if ($test instanceof Twig_SimpleTest && $test->isDeprecated()) {
636
+ $stream = $this->parser->getStream();
637
+ $message = sprintf('Twig Test "%s" is deprecated', $test->getName());
638
+ if (!is_bool($test->getDeprecatedVersion())) {
639
+ $message .= sprintf(' since version %s', $test->getDeprecatedVersion());
640
+ }
641
+ if ($test->getAlternative()) {
642
+ $message .= sprintf('. Use "%s" instead', $test->getAlternative());
643
+ }
644
+ $message .= sprintf(' in %s at line %d.', $stream->getSourceContext()->getName(), $stream->getCurrent()->getLine());
645
+
646
+ @trigger_error($message, E_USER_DEPRECATED);
647
+ }
648
 
649
+ if ($test instanceof Twig_SimpleTest) {
650
+ return $test->getNodeClass();
651
+ }
652
+
653
+ return $test instanceof Twig_Test_Node ? $test->getClass() : 'Twig_Node_Expression_Test';
654
+ }
655
+
656
+ protected function getFunctionNodeClass($name, $line)
657
+ {
658
+ if (false === $function = $this->env->getFunction($name)) {
659
+ $e = new Twig_Error_Syntax(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext()->getName());
660
+ $e->addSuggestions($name, array_keys($this->env->getFunctions()));
661
 
662
  throw $e;
663
  }
670
  if ($function->getAlternative()) {
671
  $message .= sprintf('. Use "%s" instead', $function->getAlternative());
672
  }
673
+ $message .= sprintf(' in %s at line %d.', $this->parser->getStream()->getSourceContext()->getName(), $line);
674
 
675
  @trigger_error($message, E_USER_DEPRECATED);
676
  }
684
 
685
  protected function getFilterNodeClass($name, $line)
686
  {
687
+ if (false === $filter = $this->env->getFilter($name)) {
688
+ $e = new Twig_Error_Syntax(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext()->getName());
689
+ $e->addSuggestions($name, array_keys($this->env->getFilters()));
 
 
690
 
691
  throw $e;
692
  }
699
  if ($filter->getAlternative()) {
700
  $message .= sprintf('. Use "%s" instead', $filter->getAlternative());
701
  }
702
+ $message .= sprintf(' in %s at line %d.', $this->parser->getStream()->getSourceContext()->getName(), $line);
703
 
704
  @trigger_error($message, E_USER_DEPRECATED);
705
  }
vendor/twig/twig/lib/Twig/Extension.php CHANGED
@@ -76,4 +76,14 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
76
  {
77
  return array();
78
  }
 
 
 
 
 
 
 
 
 
 
79
  }
76
  {
77
  return array();
78
  }
79
+
80
+ /**
81
+ * {@inheritdoc}
82
+ *
83
+ * @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
84
+ */
85
+ public function getName()
86
+ {
87
+ return get_class($this);
88
+ }
89
  }
vendor/twig/twig/lib/Twig/Extension/Core.php CHANGED
@@ -258,82 +258,14 @@ class Twig_Extension_Core extends Twig_Extension
258
  '/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
259
  '//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
260
  '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
261
- 'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
262
- 'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
263
  '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
264
  '??' => array('precedence' => 300, 'class' => 'Twig_Node_Expression_NullCoalesce', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
265
  ),
266
  );
267
  }
268
 
269
- public function parseNotTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
270
- {
271
- return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine());
272
- }
273
-
274
- public function parseTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
275
- {
276
- $stream = $parser->getStream();
277
- list($name, $test) = $this->getTest($parser, $node->getLine());
278
-
279
- if ($test instanceof Twig_SimpleTest && $test->isDeprecated()) {
280
- $message = sprintf('Twig Test "%s" is deprecated', $name);
281
- if (!is_bool($test->getDeprecatedVersion())) {
282
- $message .= sprintf(' since version %s', $test->getDeprecatedVersion());
283
- }
284
- if ($test->getAlternative()) {
285
- $message .= sprintf('. Use "%s" instead', $test->getAlternative());
286
- }
287
- $message .= sprintf(' in %s at line %d.', $stream->getFilename(), $stream->getCurrent()->getLine());
288
-
289
- @trigger_error($message, E_USER_DEPRECATED);
290
- }
291
-
292
- $class = $this->getTestNodeClass($parser, $test);
293
- $arguments = null;
294
- if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
295
- $arguments = $parser->getExpressionParser()->parseArguments(true);
296
- }
297
-
298
- return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine());
299
- }
300
-
301
- protected function getTest(Twig_Parser $parser, $line)
302
- {
303
- $stream = $parser->getStream();
304
- $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
305
- $env = $parser->getEnvironment();
306
-
307
- if ($test = $env->getTest($name)) {
308
- return array($name, $test);
309
- }
310
-
311
- if ($stream->test(Twig_Token::NAME_TYPE)) {
312
- // try 2-words tests
313
- $name = $name.' '.$parser->getCurrentToken()->getValue();
314
-
315
- if ($test = $env->getTest($name)) {
316
- $parser->getStream()->next();
317
-
318
- return array($name, $test);
319
- }
320
- }
321
-
322
- $e = new Twig_Error_Syntax(sprintf('Unknown "%s" test.', $name), $line, $parser->getFilename());
323
- $e->addSuggestions($name, array_keys($env->getTests()));
324
-
325
- throw $e;
326
- }
327
-
328
- protected function getTestNodeClass(Twig_Parser $parser, $test)
329
- {
330
- if ($test instanceof Twig_SimpleTest) {
331
- return $test->getNodeClass();
332
- }
333
-
334
- return $test instanceof Twig_Test_Node ? $test->getClass() : 'Twig_Node_Expression_Test';
335
- }
336
-
337
  public function getName()
338
  {
339
  return 'core';
@@ -433,7 +365,7 @@ function twig_random(Twig_Environment $env, $values = null)
433
  function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null)
434
  {
435
  if (null === $format) {
436
- $formats = $env->getExtension('core')->getDateFormat();
437
  $format = $date instanceof DateInterval ? $formats[1] : $formats[0];
438
  }
439
 
@@ -488,7 +420,7 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
488
  // determine the timezone
489
  if (false !== $timezone) {
490
  if (null === $timezone) {
491
- $timezone = $env->getExtension('core')->getTimezone();
492
  } elseif (!$timezone instanceof DateTimeZone) {
493
  $timezone = new DateTimeZone($timezone);
494
  }
@@ -509,14 +441,14 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
509
  }
510
 
511
  if (null === $date || 'now' === $date) {
512
- return new DateTime($date, false !== $timezone ? $timezone : $env->getExtension('core')->getTimezone());
513
  }
514
 
515
  $asString = (string) $date;
516
  if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
517
  $date = new DateTime('@'.$date);
518
  } else {
519
- $date = new DateTime($date, $env->getExtension('core')->getTimezone());
520
  }
521
 
522
  if (false !== $timezone) {
@@ -544,7 +476,7 @@ function twig_replace_filter($str, $from, $to = null)
544
 
545
  return strtr($str, $from, $to);
546
  } elseif (!is_array($from)) {
547
- throw new Twig_Error_Runtime(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".',is_object($from) ? get_class($from) : gettype($from)));
548
  }
549
 
550
  return strtr($str, $from);
@@ -589,7 +521,7 @@ function twig_round($value, $precision = 0, $method = 'common')
589
  */
590
  function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
591
  {
592
- $defaults = $env->getExtension('core')->getNumberFormat();
593
  if (null === $decimal) {
594
  $decimal = $defaults[0];
595
  }
@@ -978,7 +910,7 @@ function twig_in_filter($value, $compare)
978
  * Escapes a string.
979
  *
980
  * @param Twig_Environment $env A Twig_Environment instance
981
- * @param string $string The value to be escaped
982
  * @param string $strategy The escaping strategy
983
  * @param string $charset The charset
984
  * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
@@ -1115,7 +1047,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1115
  static $escapers;
1116
 
1117
  if (null === $escapers) {
1118
- $escapers = $env->getExtension('core')->getEscapers();
1119
  }
1120
 
1121
  if (isset($escapers[$strategy])) {
@@ -1451,8 +1383,8 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
1451
  $variables = array_merge($context, $variables);
1452
  }
1453
 
1454
- if ($isSandboxed = $sandboxed && $env->hasExtension('sandbox')) {
1455
- $sandbox = $env->getExtension('sandbox');
1456
  if (!$alreadySandboxed = $sandbox->isSandboxed()) {
1457
  $sandbox->enableSandbox();
1458
  }
@@ -1489,8 +1421,13 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
1489
  */
1490
  function twig_source(Twig_Environment $env, $name, $ignoreMissing = false)
1491
  {
 
1492
  try {
1493
- return $env->getLoader()->getSource($name);
 
 
 
 
1494
  } catch (Twig_Error_Loader $e) {
1495
  if (!$ignoreMissing) {
1496
  throw $e;
258
  '/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
259
  '//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
260
  '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
261
+ 'is' => array('precedence' => 100, 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
262
+ 'is not' => array('precedence' => 100, 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
263
  '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
264
  '??' => array('precedence' => 300, 'class' => 'Twig_Node_Expression_NullCoalesce', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
265
  ),
266
  );
267
  }
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  public function getName()
270
  {
271
  return 'core';
365
  function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null)
366
  {
367
  if (null === $format) {
368
+ $formats = $env->getExtension('Twig_Extension_Core')->getDateFormat();
369
  $format = $date instanceof DateInterval ? $formats[1] : $formats[0];
370
  }
371
 
420
  // determine the timezone
421
  if (false !== $timezone) {
422
  if (null === $timezone) {
423
+ $timezone = $env->getExtension('Twig_Extension_Core')->getTimezone();
424
  } elseif (!$timezone instanceof DateTimeZone) {
425
  $timezone = new DateTimeZone($timezone);
426
  }
441
  }
442
 
443
  if (null === $date || 'now' === $date) {
444
+ return new DateTime($date, false !== $timezone ? $timezone : $env->getExtension('Twig_Extension_Core')->getTimezone());
445
  }
446
 
447
  $asString = (string) $date;
448
  if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
449
  $date = new DateTime('@'.$date);
450
  } else {
451
+ $date = new DateTime($date, $env->getExtension('Twig_Extension_Core')->getTimezone());
452
  }
453
 
454
  if (false !== $timezone) {
476
 
477
  return strtr($str, $from, $to);
478
  } elseif (!is_array($from)) {
479
+ throw new Twig_Error_Runtime(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', is_object($from) ? get_class($from) : gettype($from)));
480
  }
481
 
482
  return strtr($str, $from);
521
  */
522
  function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
523
  {
524
+ $defaults = $env->getExtension('Twig_Extension_Core')->getNumberFormat();
525
  if (null === $decimal) {
526
  $decimal = $defaults[0];
527
  }
910
  * Escapes a string.
911
  *
912
  * @param Twig_Environment $env A Twig_Environment instance
913
+ * @param mixed $string The value to be escaped
914
  * @param string $strategy The escaping strategy
915
  * @param string $charset The charset
916
  * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
1047
  static $escapers;
1048
 
1049
  if (null === $escapers) {
1050
+ $escapers = $env->getExtension('Twig_Extension_Core')->getEscapers();
1051
  }
1052
 
1053
  if (isset($escapers[$strategy])) {
1383
  $variables = array_merge($context, $variables);
1384
  }
1385
 
1386
+ if ($isSandboxed = $sandboxed && $env->hasExtension('Twig_Extension_Sandbox')) {
1387
+ $sandbox = $env->getExtension('Twig_Extension_Sandbox');
1388
  if (!$alreadySandboxed = $sandbox->isSandboxed()) {
1389
  $sandbox->enableSandbox();
1390
  }
1421
  */
1422
  function twig_source(Twig_Environment $env, $name, $ignoreMissing = false)
1423
  {
1424
+ $loader = $env->getLoader();
1425
  try {
1426
+ if (!$loader instanceof Twig_SourceContextLoaderInterface) {
1427
+ return $loader->getSource($name);
1428
+ } else {
1429
+ return $loader->getSourceContext($name)->getCode();
1430
+ }
1431
  } catch (Twig_Error_Loader $e) {
1432
  if (!$ignoreMissing) {
1433
  throw $e;
vendor/twig/twig/lib/Twig/Extension/Escaper.php CHANGED
@@ -45,7 +45,7 @@ class Twig_Extension_Escaper extends Twig_Extension
45
  * Sets the default strategy to use when not defined by the user.
46
  *
47
  * The strategy can be a valid PHP callback that takes the template
48
- * "filename" as an argument and returns the strategy to use.
49
  *
50
  * @param string|false|callable $defaultStrategy An escaping strategy
51
  */
@@ -59,6 +59,12 @@ class Twig_Extension_Escaper extends Twig_Extension
59
  }
60
 
61
  if ('filename' === $defaultStrategy) {
 
 
 
 
 
 
62
  $defaultStrategy = array('Twig_FileExtensionEscapingStrategy', 'guess');
63
  }
64
 
@@ -68,16 +74,16 @@ class Twig_Extension_Escaper extends Twig_Extension
68
  /**
69
  * Gets the default strategy to use when not defined by the user.
70
  *
71
- * @param string $filename The template "filename"
72
  *
73
  * @return string|false The default strategy to use for the template
74
  */
75
- public function getDefaultStrategy($filename)
76
  {
77
  // disable string callables to avoid calling a function named html or js,
78
  // or any other upcoming escaping strategy
79
  if (!is_string($this->defaultStrategy) && false !== $this->defaultStrategy) {
80
- return call_user_func($this->defaultStrategy, $filename);
81
  }
82
 
83
  return $this->defaultStrategy;
45
  * Sets the default strategy to use when not defined by the user.
46
  *
47
  * The strategy can be a valid PHP callback that takes the template
48
+ * name as an argument and returns the strategy to use.
49
  *
50
  * @param string|false|callable $defaultStrategy An escaping strategy
51
  */
59
  }
60
 
61
  if ('filename' === $defaultStrategy) {
62
+ @trigger_error('Using "filename" as the default strategy is deprecated since version 1.27. Use "name" instead.', E_USER_DEPRECATED);
63
+
64
+ $defaultStrategy = 'name';
65
+ }
66
+
67
+ if ('name' === $defaultStrategy) {
68
  $defaultStrategy = array('Twig_FileExtensionEscapingStrategy', 'guess');
69
  }
70
 
74
  /**
75
  * Gets the default strategy to use when not defined by the user.
76
  *
77
+ * @param string $name The template name
78
  *
79
  * @return string|false The default strategy to use for the template
80
  */
81
+ public function getDefaultStrategy($name)
82
  {
83
  // disable string callables to avoid calling a function named html or js,
84
  // or any other upcoming escaping strategy
85
  if (!is_string($this->defaultStrategy) && false !== $this->defaultStrategy) {
86
+ return call_user_func($this->defaultStrategy, $name);
87
  }
88
 
89
  return $this->defaultStrategy;
vendor/twig/twig/lib/Twig/Extension/Profiler.php CHANGED
@@ -36,7 +36,7 @@ class Twig_Extension_Profiler extends Twig_Extension
36
 
37
  public function getNodeVisitors()
38
  {
39
- return array(new Twig_Profiler_NodeVisitor_Profiler($this->getName()));
40
  }
41
 
42
  public function getName()
36
 
37
  public function getNodeVisitors()
38
  {
39
+ return array(new Twig_Profiler_NodeVisitor_Profiler(get_class($this)));
40
  }
41
 
42
  public function getName()
vendor/twig/twig/lib/Twig/ExtensionInterface.php CHANGED
@@ -82,6 +82,8 @@ interface Twig_ExtensionInterface
82
  * Returns the name of the extension.
83
  *
84
  * @return string The extension name
 
 
85
  */
86
  public function getName();
87
  }
82
  * Returns the name of the extension.
83
  *
84
  * @return string The extension name
85
+ *
86
+ * @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
87
  */
88
  public function getName();
89
  }
vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php CHANGED
@@ -13,7 +13,7 @@
13
  * Default autoescaping strategy based on file names.
14
  *
15
  * This strategy sets the HTML as the default autoescaping strategy,
16
- * but changes it based on the filename.
17
  *
18
  * Note that there is no runtime performance impact as the
19
  * default autoescaping strategy is set at compilation time.
@@ -25,21 +25,21 @@ class Twig_FileExtensionEscapingStrategy
25
  /**
26
  * Guesses the best autoescaping strategy based on the file name.
27
  *
28
- * @param string $filename The template file name
29
  *
30
  * @return string|false The escaping strategy name to use or false to disable
31
  */
32
- public static function guess($filename)
33
  {
34
- if (in_array(substr($filename, -1), array('/', '\\'))) {
35
  return 'html'; // return html for directories
36
  }
37
 
38
- if ('.twig' === substr($filename, -5)) {
39
- $filename = substr($filename, 0, -5);
40
  }
41
 
42
- $extension = pathinfo($filename, PATHINFO_EXTENSION);
43
 
44
  switch ($extension) {
45
  case 'js':
13
  * Default autoescaping strategy based on file names.
14
  *
15
  * This strategy sets the HTML as the default autoescaping strategy,
16
+ * but changes it based on the template name.
17
  *
18
  * Note that there is no runtime performance impact as the
19
  * default autoescaping strategy is set at compilation time.
25
  /**
26
  * Guesses the best autoescaping strategy based on the file name.
27
  *
28
+ * @param string $name The template name
29
  *
30
  * @return string|false The escaping strategy name to use or false to disable
31
  */
32
+ public static function guess($name)
33
  {
34
+ if (in_array(substr($name, -1), array('/', '\\'))) {
35
  return 'html'; // return html for directories
36
  }
37
 
38
+ if ('.twig' === substr($name, -5)) {
39
+ $name = substr($name, 0, -5);
40
  }
41
 
42
+ $extension = pathinfo($name, PATHINFO_EXTENSION);
43
 
44
  switch ($extension) {
45
  case 'js':
vendor/twig/twig/lib/Twig/Filter/Method.php CHANGED
@@ -37,6 +37,6 @@ class Twig_Filter_Method extends Twig_Filter
37
 
38
  public function compile()
39
  {
40
- return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
41
  }
42
  }
37
 
38
  public function compile()
39
  {
40
+ return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method);
41
  }
42
  }
vendor/twig/twig/lib/Twig/Function/Method.php CHANGED
@@ -38,6 +38,6 @@ class Twig_Function_Method extends Twig_Function
38
 
39
  public function compile()
40
  {
41
- return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
42
  }
43
  }
38
 
39
  public function compile()
40
  {
41
+ return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method);
42
  }
43
  }
vendor/twig/twig/lib/Twig/Lexer.php CHANGED
@@ -26,6 +26,7 @@ class Twig_Lexer implements Twig_LexerInterface
26
  protected $states;
27
  protected $brackets;
28
  protected $env;
 
29
  protected $filename;
30
  protected $options;
31
  protected $regexes;
@@ -75,8 +76,15 @@ class Twig_Lexer implements Twig_LexerInterface
75
  /**
76
  * {@inheritdoc}
77
  */
78
- public function tokenize($code, $filename = null)
79
  {
 
 
 
 
 
 
 
80
  if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
81
  $mbEncoding = mb_internal_encoding();
82
  mb_internal_encoding('ASCII');
@@ -84,8 +92,8 @@ class Twig_Lexer implements Twig_LexerInterface
84
  $mbEncoding = null;
85
  }
86
 
87
- $this->code = str_replace(array("\r\n", "\r"), "\n", $code);
88
- $this->filename = $filename;
89
  $this->cursor = 0;
90
  $this->lineno = 1;
91
  $this->end = strlen($this->code);
@@ -136,7 +144,7 @@ class Twig_Lexer implements Twig_LexerInterface
136
  mb_internal_encoding($mbEncoding);
137
  }
138
 
139
- return new Twig_TokenStream($this->tokens, $this->filename);
140
  }
141
 
142
  protected function lexData()
@@ -403,7 +411,7 @@ class Twig_Lexer implements Twig_LexerInterface
403
  protected function popState()
404
  {
405
  if (0 === count($this->states)) {
406
- throw new Exception('Cannot pop state without a previous state');
407
  }
408
 
409
  $this->state = array_pop($this->states);
26
  protected $states;
27
  protected $brackets;
28
  protected $env;
29
+ // to be renamed to $name in 2.0 (where it is private)
30
  protected $filename;
31
  protected $options;
32
  protected $regexes;
76
  /**
77
  * {@inheritdoc}
78
  */
79
+ public function tokenize($code, $name = null)
80
  {
81
+ if (!$code instanceof Twig_Source) {
82
+ @trigger_error(sprintf('Passing a string as the $code argument of %s() is deprecated since version 1.27 and will be removed in 2.0. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
83
+ $source = new Twig_Source($code, $name);
84
+ } else {
85
+ $source = $code;
86
+ }
87
+
88
  if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
89
  $mbEncoding = mb_internal_encoding();
90
  mb_internal_encoding('ASCII');
92
  $mbEncoding = null;
93
  }
94
 
95
+ $this->code = str_replace(array("\r\n", "\r"), "\n", $source->getCode());
96
+ $this->filename = $source->getName();
97
  $this->cursor = 0;
98
  $this->lineno = 1;
99
  $this->end = strlen($this->code);
144
  mb_internal_encoding($mbEncoding);
145
  }
146
 
147
+ return new Twig_TokenStream($this->tokens, $source);
148
  }
149
 
150
  protected function lexData()
411
  protected function popState()
412
  {
413
  if (0 === count($this->states)) {
414
+ throw new Exception('Cannot pop state without a previous state.');
415
  }
416
 
417
  $this->state = array_pop($this->states);
vendor/twig/twig/lib/Twig/LexerInterface.php CHANGED
@@ -21,12 +21,12 @@ interface Twig_LexerInterface
21
  /**
22
  * Tokenizes a source code.
23
  *
24
- * @param string $code The source code
25
- * @param string $filename A unique identifier for the source code
26
  *
27
  * @return Twig_TokenStream A token stream instance
28
  *
29
  * @throws Twig_Error_Syntax When the code is syntactically wrong
30
  */
31
- public function tokenize($code, $filename = null);
32
  }
21
  /**
22
  * Tokenizes a source code.
23
  *
24
+ * @param string|Twig_Source $code The source code
25
+ * @param string $name A unique identifier for the source code
26
  *
27
  * @return Twig_TokenStream A token stream instance
28
  *
29
  * @throws Twig_Error_Syntax When the code is syntactically wrong
30
  */
31
+ public function tokenize($code, $name = null);
32
  }
vendor/twig/twig/lib/Twig/Loader/Array.php CHANGED
@@ -21,7 +21,7 @@
21
  *
22
  * @author Fabien Potencier <fabien@symfony.com>
23
  */
24
- class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
25
  {
26
  protected $templates = array();
27
 
@@ -51,6 +51,8 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
51
  */
52
  public function getSource($name)
53
  {
 
 
54
  $name = (string) $name;
55
  if (!isset($this->templates[$name])) {
56
  throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
@@ -59,6 +61,19 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
59
  return $this->templates[$name];
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  /**
63
  * {@inheritdoc}
64
  */
21
  *
22
  * @author Fabien Potencier <fabien@symfony.com>
23
  */
24
+ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
25
  {
26
  protected $templates = array();
27
 
51
  */
52
  public function getSource($name)
53
  {
54
+ @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
55
+
56
  $name = (string) $name;
57
  if (!isset($this->templates[$name])) {
58
  throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
61
  return $this->templates[$name];
62
  }
63
 
64
+ /**
65
+ * {@inheritdoc}
66
+ */
67
+ public function getSourceContext($name)
68
+ {
69
+ $name = (string) $name;
70
+ if (!isset($this->templates[$name])) {
71
+ throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
72
+ }
73
+
74
+ return new Twig_Source($this->templates[$name], $name);
75
+ }
76
+
77
  /**
78
  * {@inheritdoc}
79
  */
vendor/twig/twig/lib/Twig/Loader/Chain.php CHANGED
@@ -14,7 +14,7 @@
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
18
  {
19
  private $hasSourceCache = array();
20
  protected $loaders = array();
@@ -47,6 +47,8 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
47
  */
48
  public function getSource($name)
49
  {
 
 
50
  $exceptions = array();
51
  foreach ($this->loaders as $loader) {
52
  if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
@@ -63,6 +65,31 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
63
  throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
64
  }
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  /**
67
  * {@inheritdoc}
68
  */
@@ -84,7 +111,11 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
84
  }
85
 
86
  try {
87
- $loader->getSource($name);
 
 
 
 
88
 
89
  return $this->hasSourceCache[$name] = true;
90
  } catch (Twig_Error_Loader $e) {
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
+ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
18
  {
19
  private $hasSourceCache = array();
20
  protected $loaders = array();
47
  */
48
  public function getSource($name)
49
  {
50
+ @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
51
+
52
  $exceptions = array();
53
  foreach ($this->loaders as $loader) {
54
  if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
65
  throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
66
  }
67
 
68
+ /**
69
+ * {@inheritdoc}
70
+ */
71
+ public function getSourceContext($name)
72
+ {
73
+ $exceptions = array();
74
+ foreach ($this->loaders as $loader) {
75
+ if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
76
+ continue;
77
+ }
78
+
79
+ try {
80
+ if ($loader instanceof Twig_SourceContextLoaderInterface) {
81
+ return $loader->getSourceContext($name);
82
+ }
83
+
84
+ return new Twig_Source($loader->getSource($name), $name);
85
+ } catch (Twig_Error_Loader $e) {
86
+ $exceptions[] = $e->getMessage();
87
+ }
88
+ }
89
+
90
+ throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
91
+ }
92
+
93
  /**
94
  * {@inheritdoc}
95
  */
111
  }
112
 
113
  try {
114
+ if ($loader instanceof Twig_SourceContextLoaderInterface) {
115
+ $loader->getSourceContext($name);
116
+ } else {
117
+ $loader->getSource($name);
118
+ }
119
 
120
  return $this->hasSourceCache[$name] = true;
121
  } catch (Twig_Error_Loader $e) {
vendor/twig/twig/lib/Twig/Loader/Filesystem.php CHANGED
@@ -14,7 +14,7 @@
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
- class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
18
  {
19
  /** Identifier of the main namespace. */
20
  const MAIN_NAMESPACE = '__main__';
@@ -23,13 +23,21 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
23
  protected $cache = array();
24
  protected $errorCache = array();
25
 
 
 
26
  /**
27
  * Constructor.
28
  *
29
- * @param string|array $paths A path or an array of paths where to look for templates
 
30
  */
31
- public function __construct($paths = array())
32
  {
 
 
 
 
 
33
  if ($paths) {
34
  $this->setPaths($paths);
35
  }
@@ -81,7 +89,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
81
  * Adds a path where templates are stored.
82
  *
83
  * @param string $path A path where to look for templates
84
- * @param string $namespace A path name
85
  *
86
  * @throws Twig_Error_Loader
87
  */
@@ -90,8 +98,9 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
90
  // invalidate the cache
91
  $this->cache = $this->errorCache = array();
92
 
93
- if (!is_dir($path)) {
94
- throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
 
95
  }
96
 
97
  $this->paths[$namespace][] = rtrim($path, '/\\');
@@ -101,7 +110,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
101
  * Prepends a path where templates are stored.
102
  *
103
  * @param string $path A path where to look for templates
104
- * @param string $namespace A path name
105
  *
106
  * @throws Twig_Error_Loader
107
  */
@@ -110,8 +119,9 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
110
  // invalidate the cache
111
  $this->cache = $this->errorCache = array();
112
 
113
- if (!is_dir($path)) {
114
- throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
 
115
  }
116
 
117
  $path = rtrim($path, '/\\');
@@ -128,15 +138,33 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
128
  */
129
  public function getSource($name)
130
  {
 
 
131
  return file_get_contents($this->findTemplate($name));
132
  }
133
 
 
 
 
 
 
 
 
 
 
 
134
  /**
135
  * {@inheritdoc}
136
  */
137
  public function getCacheKey($name)
138
  {
139
- return $this->findTemplate($name);
 
 
 
 
 
 
140
  }
141
 
142
  /**
@@ -153,6 +181,8 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
153
  try {
154
  return false !== $this->findTemplate($name, false);
155
  } catch (Twig_Error_Loader $exception) {
 
 
156
  return false;
157
  }
158
  }
@@ -197,6 +227,10 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
197
  }
198
 
199
  foreach ($this->paths[$namespace] as $path) {
 
 
 
 
200
  if (is_file($path.'/'.$shortname)) {
201
  if (false !== $realpath = realpath($path.'/'.$shortname)) {
202
  return $this->cache[$name] = $realpath;
@@ -257,4 +291,15 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
257
  }
258
  }
259
  }
 
 
 
 
 
 
 
 
 
 
 
260
  }
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  */
17
+ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
18
  {
19
  /** Identifier of the main namespace. */
20
  const MAIN_NAMESPACE = '__main__';
23
  protected $cache = array();
24
  protected $errorCache = array();
25
 
26
+ private $rootPath;
27
+
28
  /**
29
  * Constructor.
30
  *
31
+ * @param string|array $paths A path or an array of paths where to look for templates
32
+ * @param string|null $rootPath The root path common to all relative paths (null for getcwd())
33
  */
34
+ public function __construct($paths = array(), $rootPath = null)
35
  {
36
+ $this->rootPath = (null === $rootPath ? getcwd() : $rootPath).DIRECTORY_SEPARATOR;
37
+ if (false !== $realPath = realpath($rootPath)) {
38
+ $this->rootPath = $realPath.DIRECTORY_SEPARATOR;
39
+ }
40
+
41
  if ($paths) {
42
  $this->setPaths($paths);
43
  }
89
  * Adds a path where templates are stored.
90
  *
91
  * @param string $path A path where to look for templates
92
+ * @param string $namespace A path namespace
93
  *
94
  * @throws Twig_Error_Loader
95
  */
98
  // invalidate the cache
99
  $this->cache = $this->errorCache = array();
100
 
101
+ $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
102
+ if (!is_dir($checkPath)) {
103
+ throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
104
  }
105
 
106
  $this->paths[$namespace][] = rtrim($path, '/\\');
110
  * Prepends a path where templates are stored.
111
  *
112
  * @param string $path A path where to look for templates
113
+ * @param string $namespace A path namespace
114
  *
115
  * @throws Twig_Error_Loader
116
  */
119
  // invalidate the cache
120
  $this->cache = $this->errorCache = array();
121
 
122
+ $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
123
+ if (!is_dir($checkPath)) {
124
+ throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
125
  }
126
 
127
  $path = rtrim($path, '/\\');
138
  */
139
  public function getSource($name)
140
  {
141
+ @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
142
+
143
  return file_get_contents($this->findTemplate($name));
144
  }
145
 
146
+ /**
147
+ * {@inheritdoc}
148
+ */
149
+ public function getSourceContext($name)
150
+ {
151
+ $path = $this->findTemplate($name);
152
+
153
+ return new Twig_Source(file_get_contents($path), $name, $path);
154
+ }
155
+
156
  /**
157
  * {@inheritdoc}
158
  */
159
  public function getCacheKey($name)
160
  {
161
+ $path = $this->findTemplate($name);
162
+ $len = strlen($this->rootPath);
163
+ if (0 === strncmp($this->rootPath, $path, $len)) {
164
+ return substr($path, $len);
165
+ }
166
+
167
+ return $path;
168
  }
169
 
170
  /**
181
  try {
182
  return false !== $this->findTemplate($name, false);
183
  } catch (Twig_Error_Loader $exception) {
184
+ @trigger_error(sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', get_class($this)), E_USER_DEPRECATED);
185
+
186
  return false;
187
  }
188
  }
227
  }
228
 
229
  foreach ($this->paths[$namespace] as $path) {
230
+ if (!$this->isAbsolutePath($path)) {
231
+ $path = $this->rootPath.'/'.$path;
232
+ }
233
+
234
  if (is_file($path.'/'.$shortname)) {
235
  if (false !== $realpath = realpath($path.'/'.$shortname)) {
236
  return $this->cache[$name] = $realpath;
291
  }
292
  }
293
  }
294
+
295
+ private function isAbsolutePath($file)
296
+ {
297
+ return strspn($file, '/\\', 0, 1)
298
+ || (strlen($file) > 3 && ctype_alpha($file[0])
299
+ && substr($file, 1, 1) === ':'
300
+ && strspn($file, '/\\', 2, 1)
301
+ )
302
+ || null !== parse_url($file, PHP_URL_SCHEME)
303
+ ;
304
+ }
305
  }
vendor/twig/twig/lib/Twig/Loader/String.php CHANGED
@@ -27,16 +27,26 @@
27
  *
28
  * @author Fabien Potencier <fabien@symfony.com>
29
  */
30
- class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
31
  {
32
  /**
33
  * {@inheritdoc}
34
  */
35
  public function getSource($name)
36
  {
 
 
37
  return $name;
38
  }
39
 
 
 
 
 
 
 
 
 
40
  /**
41
  * {@inheritdoc}
42
  */
27
  *
28
  * @author Fabien Potencier <fabien@symfony.com>
29
  */
30
+ class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
31
  {
32
  /**
33
  * {@inheritdoc}
34
  */
35
  public function getSource($name)
36
  {
37
+ @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
38
+
39
  return $name;
40
  }
41
 
42
+ /**
43
+ * {@inheritdoc}
44
+ */
45
+ public function getSourceContext($name)
46
+ {
47
+ return new Twig_Source($name, $name);
48
+ }
49
+
50
  /**
51
  * {@inheritdoc}
52
  */
vendor/twig/twig/lib/Twig/LoaderInterface.php CHANGED
@@ -24,6 +24,8 @@ interface Twig_LoaderInterface
24
  * @return string The template source code
25
  *
26
  * @throws Twig_Error_Loader When $name is not found
 
 
27
  */
28
  public function getSource($name);
29
 
24
  * @return string The template source code
25
  *
26
  * @throws Twig_Error_Loader When $name is not found
27
+ *
28
+ * @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface
29
  */
30
  public function getSource($name);
31
 
vendor/twig/twig/lib/Twig/Node.php CHANGED
@@ -22,6 +22,8 @@ class Twig_Node implements Twig_NodeInterface
22
  protected $lineno;
23
  protected $tag;
24
 
 
 
25
  /**
26
  * Constructor.
27
  *
@@ -35,6 +37,11 @@ class Twig_Node implements Twig_NodeInterface
35
  */
36
  public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null)
37
  {
 
 
 
 
 
38
  $this->nodes = $nodes;
39
  $this->attributes = $attributes;
40
  $this->lineno = $lineno;
@@ -111,8 +118,18 @@ class Twig_Node implements Twig_NodeInterface
111
  }
112
  }
113
 
 
 
 
 
 
 
 
 
114
  public function getLine()
115
  {
 
 
116
  return $this->lineno;
117
  }
118
 
@@ -206,6 +223,10 @@ class Twig_Node implements Twig_NodeInterface
206
  */
207
  public function setNode($name, $node = null)
208
  {
 
 
 
 
209
  $this->nodes[$name] = $node;
210
  }
211
 
@@ -228,4 +249,39 @@ class Twig_Node implements Twig_NodeInterface
228
  {
229
  return new ArrayIterator($this->nodes);
230
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  }
22
  protected $lineno;
23
  protected $tag;
24
 
25
+ private $name;
26
+
27
  /**
28
  * Constructor.
29
  *
37
  */
38
  public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null)
39
  {
40
+ foreach ($nodes as $name => $node) {
41
+ if (!$node instanceof Twig_NodeInterface) {
42
+ @trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', is_object($node) ? get_class($node) : null === $node ? 'null' : gettype($node), $name, get_class($this)), E_USER_DEPRECATED);
43
+ }
44
+ }
45
  $this->nodes = $nodes;
46
  $this->attributes = $attributes;
47
  $this->lineno = $lineno;
118
  }
119
  }
120
 
121
+ public function getTemplateLine()
122
+ {
123
+ return $this->lineno;
124
+ }
125
+
126
+ /**
127
+ * @deprecated since 1.27 (to be removed in 2.0)
128
+ */
129
  public function getLine()
130
  {
131
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateName() instead.', E_USER_DEPRECATED);
132
+
133
  return $this->lineno;
134
  }
135
 
223
  */
224
  public function setNode($name, $node = null)
225
  {
226
+ if (!$node instanceof Twig_NodeInterface) {
227
+ @trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', is_object($node) ? get_class($node) : null === $node ? 'null' : gettype($node), $name, get_class($this)), E_USER_DEPRECATED);
228
+ }
229
+
230
  $this->nodes[$name] = $node;
231
  }
232
 
249
  {
250
  return new ArrayIterator($this->nodes);
251
  }
252
+
253
+ public function setTemplateName($name)
254
+ {
255
+ $this->name = $name;
256
+ foreach ($this->nodes as $node) {
257
+ if (null !== $node) {
258
+ $node->setTemplateName($name);
259
+ }
260
+ }
261
+ }
262
+
263
+ public function getTemplateName()
264
+ {
265
+ return $this->name;
266
+ }
267
+
268
+ /**
269
+ * @deprecated since 1.27 (to be removed in 2.0)
270
+ */
271
+ public function setFilename($name)
272
+ {
273
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use setTemplateName() instead.', E_USER_DEPRECATED);
274
+
275
+ $this->setTemplateName($name);
276
+ }
277
+
278
+ /**
279
+ * @deprecated since 1.27 (to be removed in 2.0)
280
+ */
281
+ public function getFilename()
282
+ {
283
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateName() instead.', E_USER_DEPRECATED);
284
+
285
+ return $this->name;
286
+ }
287
  }
vendor/twig/twig/lib/Twig/Node/CheckSecurity.php CHANGED
@@ -33,7 +33,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
33
  foreach (array('tags', 'filters', 'functions') as $type) {
34
  foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
35
  if ($node instanceof Twig_Node) {
36
- ${$type}[$name] = $node->getLine();
37
  } else {
38
  ${$type}[$node] = null;
39
  }
@@ -46,7 +46,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
46
  ->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
47
  ->write("try {\n")
48
  ->indent()
49
- ->write("\$this->env->getExtension('sandbox')->checkSecurity(\n")
50
  ->indent()
51
  ->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n")
52
  ->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n")
@@ -56,7 +56,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
56
  ->outdent()
57
  ->write("} catch (Twig_Sandbox_SecurityError \$e) {\n")
58
  ->indent()
59
- ->write("\$e->setTemplateFile(\$this->getTemplateName());\n\n")
60
  ->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
61
  ->indent()
62
  ->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
33
  foreach (array('tags', 'filters', 'functions') as $type) {
34
  foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
35
  if ($node instanceof Twig_Node) {
36
+ ${$type}[$name] = $node->getTemplateLine();
37
  } else {
38
  ${$type}[$node] = null;
39
  }
46
  ->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
47
  ->write("try {\n")
48
  ->indent()
49
+ ->write("\$this->env->getExtension('Twig_Extension_Sandbox')->checkSecurity(\n")
50
  ->indent()
51
  ->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n")
52
  ->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n")
56
  ->outdent()
57
  ->write("} catch (Twig_Sandbox_SecurityError \$e) {\n")
58
  ->indent()
59
+ ->write("\$e->setTemplateName(\$this->getTemplateName());\n\n")
60
  ->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
61
  ->indent()
62
  ->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
vendor/twig/twig/lib/Twig/Node/Embed.php CHANGED
@@ -17,11 +17,13 @@
17
  class Twig_Node_Embed extends Twig_Node_Include
18
  {
19
  // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
20
- public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
21
  {
22
  parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
23
 
24
- $this->setAttribute('filename', $filename);
 
 
25
  $this->setAttribute('index', $index);
26
  }
27
 
@@ -29,11 +31,11 @@ class Twig_Node_Embed extends Twig_Node_Include
29
  {
30
  $compiler
31
  ->write('$this->loadTemplate(')
32
- ->string($this->getAttribute('filename'))
33
  ->raw(', ')
34
- ->repr($compiler->getFilename())
35
  ->raw(', ')
36
- ->repr($this->getLine())
37
  ->raw(', ')
38
  ->string($this->getAttribute('index'))
39
  ->raw(')')
17
  class Twig_Node_Embed extends Twig_Node_Include
18
  {
19
  // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
20
+ public function __construct($name, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
21
  {
22
  parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
23
 
24
+ $this->setAttribute('name', $name);
25
+ // to be removed in 2.0, used name instead
26
+ $this->setAttribute('filename', $name);
27
  $this->setAttribute('index', $index);
28
  }
29
 
31
  {
32
  $compiler
33
  ->write('$this->loadTemplate(')
34
+ ->string($this->getAttribute('name'))
35
  ->raw(', ')
36
+ ->repr($this->getTemplateName())
37
  ->raw(', ')
38
+ ->repr($this->getTemplateLine())
39
  ->raw(', ')
40
  ->string($this->getAttribute('index'))
41
  ->raw(')')
vendor/twig/twig/lib/Twig/Node/Expression/Array.php CHANGED
@@ -54,7 +54,7 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
54
  public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null)
55
  {
56
  if (null === $key) {
57
- $key = new Twig_Node_Expression_Constant(++$this->index, $value->getLine());
58
  }
59
 
60
  array_push($this->nodes, $key, $value);
54
  public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null)
55
  {
56
  if (null === $key) {
57
+ $key = new Twig_Node_Expression_Constant(++$this->index, $value->getTemplateLine());
58
  }
59
 
60
  array_push($this->nodes, $key, $value);
vendor/twig/twig/lib/Twig/Node/Expression/Call.php CHANGED
@@ -10,18 +10,29 @@
10
  */
11
  abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
12
  {
 
 
13
  protected function compileCallable(Twig_Compiler $compiler)
14
  {
15
  $closingParenthesis = false;
16
  if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
17
- if (is_string($callable)) {
18
  $compiler->raw($callable);
19
- } elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) {
20
- $compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', $callable[0]->getName(), $callable[1]));
21
  } else {
22
- $type = ucfirst($this->getAttribute('type'));
23
- $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name')));
24
- $closingParenthesis = true;
 
 
 
 
 
 
 
 
 
 
 
25
  }
26
  } else {
27
  $compiler->raw($this->getAttribute('thing')->compile());
@@ -71,7 +82,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
71
  $first = false;
72
  }
73
 
74
- if ($this->hasNode('arguments') && null !== $this->getNode('arguments')) {
75
  $callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
76
 
77
  $arguments = $this->getArguments($callable, $this->getNode('arguments'));
@@ -121,7 +132,6 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
121
  throw new LogicException($message);
122
  }
123
 
124
- // manage named arguments
125
  $callableParameters = $this->getCallableParameters($callable, $isVariadic);
126
  $arguments = array();
127
  $names = array();
@@ -195,7 +205,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
195
  throw new Twig_Error_Syntax(sprintf(
196
  'Unknown argument%s "%s" for %s "%s(%s)".',
197
  count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)
198
- ), $unknownParameter ? $unknownParameter->getLine() : -1);
199
  }
200
 
201
  return $arguments;
@@ -208,15 +218,9 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
208
 
209
  private function getCallableParameters($callable, $isVariadic)
210
  {
211
- if (is_array($callable)) {
212
- $r = new ReflectionMethod($callable[0], $callable[1]);
213
- } elseif (is_object($callable) && !$callable instanceof Closure) {
214
- $r = new ReflectionObject($callable);
215
- $r = $r->getMethod('__invoke');
216
- } elseif (is_string($callable) && false !== strpos($callable, '::')) {
217
- $r = new ReflectionMethod($callable);
218
- } else {
219
- $r = new ReflectionFunction($callable);
220
  }
221
 
222
  $parameters = $r->getParameters();
@@ -250,4 +254,36 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
250
 
251
  return $parameters;
252
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  }
10
  */
11
  abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
12
  {
13
+ private $reflector;
14
+
15
  protected function compileCallable(Twig_Compiler $compiler)
16
  {
17
  $closingParenthesis = false;
18
  if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
19
+ if (is_string($callable) && false === strpos($callable, '::')) {
20
  $compiler->raw($callable);
 
 
21
  } else {
22
+ list($r, $callable) = $this->reflectCallable($callable);
23
+ if ($r instanceof ReflectionMethod && is_string($callable[0])) {
24
+ if ($r->isStatic()) {
25
+ $compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
26
+ } else {
27
+ $compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
28
+ }
29
+ } elseif ($r instanceof ReflectionMethod && $callable[0] instanceof Twig_ExtensionInterface) {
30
+ $compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', get_class($callable[0]), $callable[1]));
31
+ } else {
32
+ $type = ucfirst($this->getAttribute('type'));
33
+ $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name')));
34
+ $closingParenthesis = true;
35
+ }
36
  }
37
  } else {
38
  $compiler->raw($this->getAttribute('thing')->compile());
82
  $first = false;
83
  }
84
 
85
+ if ($this->hasNode('arguments')) {
86
  $callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
87
 
88
  $arguments = $this->getArguments($callable, $this->getNode('arguments'));
132
  throw new LogicException($message);
133
  }
134
 
 
135
  $callableParameters = $this->getCallableParameters($callable, $isVariadic);
136
  $arguments = array();
137
  $names = array();
205
  throw new Twig_Error_Syntax(sprintf(
206
  'Unknown argument%s "%s" for %s "%s(%s)".',
207
  count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)
208
+ ), $unknownParameter ? $unknownParameter->getTemplateLine() : -1);
209
  }
210
 
211
  return $arguments;
218
 
219
  private function getCallableParameters($callable, $isVariadic)
220
  {
221
+ list($r, $_) = $this->reflectCallable($callable);
222
+ if (null === $r) {
223
+ return array();
 
 
 
 
 
 
224
  }
225
 
226
  $parameters = $r->getParameters();
254
 
255
  return $parameters;
256
  }
257
+
258
+ private function reflectCallable($callable)
259
+ {
260
+ if (null !== $this->reflector) {
261
+ return $this->reflector;
262
+ }
263
+
264
+ if (is_array($callable)) {
265
+ if (!method_exists($callable[0], $callable[1])) {
266
+ // __call()
267
+ return array(null, array());
268
+ }
269
+ $r = new ReflectionMethod($callable[0], $callable[1]);
270
+ } elseif (is_object($callable) && !$callable instanceof Closure) {
271
+ $r = new ReflectionObject($callable);
272
+ $r = $r->getMethod('__invoke');
273
+ $callable = array($callable, '__invoke');
274
+ } elseif (is_string($callable) && false !== $pos = strpos($callable, '::')) {
275
+ $class = substr($callable, 0, $pos);
276
+ $method = substr($callable, $pos + 2);
277
+ if (!method_exists($class, $method)) {
278
+ // __staticCall()
279
+ return array(null, array());
280
+ }
281
+ $r = new ReflectionMethod($callable);
282
+ $callable = array($class, $method);
283
+ } else {
284
+ $r = new ReflectionFunction($callable);
285
+ }
286
+
287
+ return $this->reflector = array($r, $callable);
288
+ }
289
  }
vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php CHANGED
@@ -22,13 +22,13 @@ class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter
22
  {
23
  public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
24
  {
25
- $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getLine()), $arguments, $node->getLine());
26
 
27
  if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) {
28
- $test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getLine());
29
- $false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getLine());
30
 
31
- $node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getLine());
32
  } else {
33
  $node = $default;
34
  }
22
  {
23
  public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
24
  {
25
+ $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine());
26
 
27
  if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) {
28
+ $test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getTemplateLine());
29
+ $false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getTemplateLine());
30
 
31
+ $node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getTemplateLine());
32
  } else {
33
  $node = $default;
34
  }
vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php CHANGED
@@ -13,7 +13,12 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
13
  {
14
  public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression $arguments = null, $type, $lineno)
15
  {
16
- parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno);
 
 
 
 
 
17
  }
18
 
19
  public function compile(Twig_Compiler $compiler)
@@ -36,10 +41,10 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
36
  $needFourth = $this->getAttribute('ignore_strict_check');
37
  $needThird = $needFourth || $this->getAttribute('is_defined_test');
38
  $needSecond = $needThird || Twig_Template::ANY_CALL !== $this->getAttribute('type');
39
- $needFirst = $needSecond || null !== $this->getNode('arguments');
40
 
41
  if ($needFirst) {
42
- if (null !== $this->getNode('arguments')) {
43
  $compiler->raw(', ')->subcompile($this->getNode('arguments'));
44
  } else {
45
  $compiler->raw(', array()');
13
  {
14
  public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression $arguments = null, $type, $lineno)
15
  {
16
+ $nodes = array('node' => $node, 'attribute' => $attribute);
17
+ if (null !== $arguments) {
18
+ $nodes['arguments'] = $arguments;
19
+ }
20
+
21
+ parent::__construct($nodes, array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno);
22
  }
23
 
24
  public function compile(Twig_Compiler $compiler)
41
  $needFourth = $this->getAttribute('ignore_strict_check');
42
  $needThird = $needFourth || $this->getAttribute('is_defined_test');
43
  $needSecond = $needThird || Twig_Template::ANY_CALL !== $this->getAttribute('type');
44
+ $needFirst = $needSecond || $this->hasNode('arguments');
45
 
46
  if ($needFirst) {
47
+ if ($this->hasNode('arguments')) {
48
  $compiler->raw(', ')->subcompile($this->getNode('arguments'));
49
  } else {
50
  $compiler->raw(', array()');
vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php CHANGED
@@ -13,9 +13,9 @@ class Twig_Node_Expression_NullCoalesce extends Twig_Node_Expression_Conditional
13
  public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
14
  {
15
  $test = new Twig_Node_Expression_Binary_And(
16
- new Twig_Node_Expression_Test_Defined(clone $left, 'defined', new Twig_Node(), $left->getLine()),
17
- new Twig_Node_Expression_Unary_Not(new Twig_Node_Expression_Test_Null($left, 'null', new Twig_Node(), $left->getLine()), $left->getLine()),
18
- $left->getLine()
19
  );
20
 
21
  parent::__construct($test, $left, $right, $lineno);
13
  public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
14
  {
15
  $test = new Twig_Node_Expression_Binary_And(
16
+ new Twig_Node_Expression_Test_Defined(clone $left, 'defined', new Twig_Node(), $left->getTemplateLine()),
17
+ new Twig_Node_Expression_Unary_Not(new Twig_Node_Expression_Test_Null($left, 'null', new Twig_Node(), $left->getTemplateLine()), $left->getTemplateLine()),
18
+ $left->getTemplateLine()
19
  );
20
 
21
  parent::__construct($test, $left, $right, $lineno);
vendor/twig/twig/lib/Twig/Node/Expression/Test.php CHANGED
@@ -12,7 +12,12 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression_Call
12
  {
13
  public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
14
  {
15
- parent::__construct(array('node' => $node, 'arguments' => $arguments), array('name' => $name), $lineno);
 
 
 
 
 
16
  }
17
 
18
  public function compile(Twig_Compiler $compiler)
12
  {
13
  public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
14
  {
15
+ $nodes = array('node' => $node);
16
+ if (null !== $arguments) {
17
+ $nodes['arguments'] = $arguments;
18
+ }
19
+
20
+ parent::__construct($nodes, array('name' => $name), $lineno);
21
  }
22
 
23
  public function compile(Twig_Compiler $compiler)
vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php CHANGED
@@ -32,9 +32,9 @@ class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test
32
 
33
  $this->changeIgnoreStrictCheck($node);
34
  } elseif ($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array) {
35
- $node = new Twig_Node_Expression_Constant(true, $node->getLine());
36
  } else {
37
- throw new Twig_Error_Syntax('The "defined" test only works with simple variables.', $this->getLine());
38
  }
39
 
40
  parent::__construct($node, $name, $arguments, $lineno);
32
 
33
  $this->changeIgnoreStrictCheck($node);
34
  } elseif ($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array) {
35
+ $node = new Twig_Node_Expression_Constant(true, $node->getTemplateLine());
36
  } else {
37
+ throw new Twig_Error_Syntax('The "defined" test only works with simple variables.', $this->getTemplateLine());
38
  }
39
 
40
  parent::__construct($node, $name, $arguments, $lineno);
vendor/twig/twig/lib/Twig/Node/For.php CHANGED
@@ -27,7 +27,12 @@ class Twig_Node_For extends Twig_Node
27
  $body = new Twig_Node_If(new Twig_Node(array($ifexpr, $body)), null, $lineno, $tag);
28
  }
29
 
30
- parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else), array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag);
 
 
 
 
 
31
  }
32
 
33
  public function compile(Twig_Compiler $compiler)
@@ -40,7 +45,7 @@ class Twig_Node_For extends Twig_Node
40
  ->raw(");\n")
41
  ;
42
 
43
- if (null !== $this->getNode('else')) {
44
  $compiler->write("\$context['_iterated'] = false;\n");
45
  }
46
 
@@ -69,7 +74,7 @@ class Twig_Node_For extends Twig_Node
69
  }
70
  }
71
 
72
- $this->loop->setAttribute('else', null !== $this->getNode('else'));
73
  $this->loop->setAttribute('with_loop', $this->getAttribute('with_loop'));
74
  $this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr'));
75
 
@@ -85,7 +90,7 @@ class Twig_Node_For extends Twig_Node
85
  ->write("}\n")
86
  ;
87
 
88
- if (null !== $this->getNode('else')) {
89
  $compiler
90
  ->write("if (!\$context['_iterated']) {\n")
91
  ->indent()
27
  $body = new Twig_Node_If(new Twig_Node(array($ifexpr, $body)), null, $lineno, $tag);
28
  }
29
 
30
+ $nodes = array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body);
31
+ if (null !== $else) {
32
+ $nodes['else'] = $else;
33
+ }
34
+
35
+ parent::__construct($nodes, array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag);
36
  }
37
 
38
  public function compile(Twig_Compiler $compiler)
45
  ->raw(");\n")
46
  ;
47
 
48
+ if ($this->hasNode('else')) {
49
  $compiler->write("\$context['_iterated'] = false;\n");
50
  }
51
 
74
  }
75
  }
76
 
77
+ $this->loop->setAttribute('else', $this->hasNode('else'));
78
  $this->loop->setAttribute('with_loop', $this->getAttribute('with_loop'));
79
  $this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr'));
80
 
90
  ->write("}\n")
91
  ;
92
 
93
+ if ($this->hasNode('else')) {
94
  $compiler
95
  ->write("if (!\$context['_iterated']) {\n")
96
  ->indent()
vendor/twig/twig/lib/Twig/Node/If.php CHANGED
@@ -19,7 +19,12 @@ class Twig_Node_If extends Twig_Node
19
  {
20
  public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null)
21
  {
22
- parent::__construct(array('tests' => $tests, 'else' => $else), array(), $lineno, $tag);
 
 
 
 
 
23
  }
24
 
25
  public function compile(Twig_Compiler $compiler)
@@ -45,7 +50,7 @@ class Twig_Node_If extends Twig_Node
45
  ;
46
  }
47
 
48
- if ($this->hasNode('else') && null !== $this->getNode('else')) {
49
  $compiler
50
  ->outdent()
51
  ->write("} else {\n")
19
  {
20
  public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null)
21
  {
22
+ $nodes = array('tests' => $tests);
23
+ if (null !== $else) {
24
+ $nodes['else'] = $else;
25
+ }
26
+
27
+ parent::__construct($nodes, array(), $lineno, $tag);
28
  }
29
 
30
  public function compile(Twig_Compiler $compiler)
50
  ;
51
  }
52
 
53
+ if ($this->hasNode('else')) {
54
  $compiler
55
  ->outdent()
56
  ->write("} else {\n")
vendor/twig/twig/lib/Twig/Node/Import.php CHANGED
@@ -37,9 +37,9 @@ class Twig_Node_Import extends Twig_Node
37
  ->raw('$this->loadTemplate(')
38
  ->subcompile($this->getNode('expr'))
39
  ->raw(', ')
40
- ->repr($compiler->getFilename())
41
  ->raw(', ')
42
- ->repr($this->getLine())
43
  ->raw(')')
44
  ;
45
  }
37
  ->raw('$this->loadTemplate(')
38
  ->subcompile($this->getNode('expr'))
39
  ->raw(', ')
40
+ ->repr($this->getTemplateName())
41
  ->raw(', ')
42
+ ->repr($this->getTemplateLine())
43
  ->raw(')')
44
  ;
45
  }
vendor/twig/twig/lib/Twig/Node/Include.php CHANGED
@@ -19,7 +19,12 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
19
  {
20
  public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
21
  {
22
- parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag);
 
 
 
 
 
23
  }
24
 
25
  public function compile(Twig_Compiler $compiler)
@@ -59,16 +64,16 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
59
  ->write('$this->loadTemplate(')
60
  ->subcompile($this->getNode('expr'))
61
  ->raw(', ')
62
- ->repr($compiler->getFilename())
63
  ->raw(', ')
64
- ->repr($this->getLine())
65
  ->raw(')')
66
  ;
67
  }
68
 
69
  protected function addTemplateArguments(Twig_Compiler $compiler)
70
  {
71
- if (null === $this->getNode('variables')) {
72
  $compiler->raw(false === $this->getAttribute('only') ? '$context' : 'array()');
73
  } elseif (false === $this->getAttribute('only')) {
74
  $compiler
19
  {
20
  public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
21
  {
22
+ $nodes = array('expr' => $expr);
23
+ if (null !== $variables) {
24
+ $nodes['variables'] = $variables;
25
+ }
26
+
27
+ parent::__construct($nodes, array('only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag);
28
  }
29
 
30
  public function compile(Twig_Compiler $compiler)
64
  ->write('$this->loadTemplate(')
65
  ->subcompile($this->getNode('expr'))
66
  ->raw(', ')
67
+ ->repr($this->getTemplateName())
68
  ->raw(', ')
69
+ ->repr($this->getTemplateLine())
70
  ->raw(')')
71
  ;
72
  }
73
 
74
  protected function addTemplateArguments(Twig_Compiler $compiler)
75
  {
76
+ if (!$this->hasNode('variables')) {
77
  $compiler->raw(false === $this->getAttribute('only') ? '$context' : 'array()');
78
  } elseif (false === $this->getAttribute('only')) {
79
  $compiler
vendor/twig/twig/lib/Twig/Node/Macro.php CHANGED
@@ -22,7 +22,7 @@ class Twig_Node_Macro extends Twig_Node
22
  {
23
  foreach ($arguments as $argumentName => $argument) {
24
  if (self::VARARGS_NAME === $argumentName) {
25
- throw new Twig_Error_Syntax(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getLine());
26
  }
27
  }
28
 
@@ -70,7 +70,7 @@ class Twig_Node_Macro extends Twig_Node
70
 
71
  foreach ($this->getNode('arguments') as $name => $default) {
72
  $compiler
73
- ->addIndentation()
74
  ->string($name)
75
  ->raw(' => $__'.$name.'__')
76
  ->raw(",\n")
@@ -78,7 +78,7 @@ class Twig_Node_Macro extends Twig_Node
78
  }
79
 
80
  $compiler
81
- ->addIndentation()
82
  ->string(self::VARARGS_NAME)
83
  ->raw(' => ')
84
  ;
22
  {
23
  foreach ($arguments as $argumentName => $argument) {
24
  if (self::VARARGS_NAME === $argumentName) {
25
+ throw new Twig_Error_Syntax(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getTemplateLine());
26
  }
27
  }
28
 
70
 
71
  foreach ($this->getNode('arguments') as $name => $default) {
72
  $compiler
73
+ ->write('')
74
  ->string($name)
75
  ->raw(' => $__'.$name.'__')
76
  ->raw(",\n")
78
  }
79
 
80
  $compiler
81
+ ->write('')
82
  ->string(self::VARARGS_NAME)
83
  ->raw(' => ')
84
  ;
vendor/twig/twig/lib/Twig/Node/Module.php CHANGED
@@ -21,11 +21,18 @@
21
  */
22
  class Twig_Node_Module extends Twig_Node
23
  {
24
- public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $filename)
 
 
25
  {
26
- // embedded templates are set as attributes so that they are only visited once by the visitors
27
- parent::__construct(array(
28
- 'parent' => $parent,
 
 
 
 
 
29
  'body' => $body,
30
  'blocks' => $blocks,
31
  'macros' => $macros,
@@ -35,11 +42,23 @@ class Twig_Node_Module extends Twig_Node
35
  'constructor_start' => new Twig_Node(),
36
  'constructor_end' => new Twig_Node(),
37
  'class_end' => new Twig_Node(),
38
- ), array(
39
- 'filename' => $filename,
 
 
 
 
 
 
 
 
 
40
  'index' => null,
41
  'embedded_templates' => $embeddedTemplates,
42
  ), 1);
 
 
 
43
  }
44
 
45
  public function setIndex($index)
@@ -67,7 +86,7 @@ class Twig_Node_Module extends Twig_Node
67
  if (
68
  count($this->getNode('blocks'))
69
  || count($this->getNode('traits'))
70
- || null === $this->getNode('parent')
71
  || $this->getNode('parent') instanceof Twig_Node_Expression_Constant
72
  || count($this->getNode('constructor_start'))
73
  || count($this->getNode('constructor_end'))
@@ -89,14 +108,19 @@ class Twig_Node_Module extends Twig_Node
89
 
90
  $this->compileDebugInfo($compiler);
91
 
 
 
 
 
92
  $this->compileClassFooter($compiler);
93
  }
94
 
95
  protected function compileGetParent(Twig_Compiler $compiler)
96
  {
97
- if (null === $parent = $this->getNode('parent')) {
98
  return;
99
  }
 
100
 
101
  $compiler
102
  ->write("protected function doGetParent(array \$context)\n", "{\n")
@@ -112,9 +136,9 @@ class Twig_Node_Module extends Twig_Node
112
  ->raw('$this->loadTemplate(')
113
  ->subcompile($parent)
114
  ->raw(', ')
115
- ->repr($compiler->getFilename())
116
  ->raw(', ')
117
- ->repr($this->getNode('parent')->getLine())
118
  ->raw(')')
119
  ;
120
  }
@@ -130,9 +154,9 @@ class Twig_Node_Module extends Twig_Node
130
  {
131
  $compiler
132
  ->write("\n\n")
133
- // if the filename contains */, add a blank to avoid a PHP parse error
134
- ->write('/* '.str_replace('*/', '* /', $this->getAttribute('filename'))." */\n")
135
- ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'), $this->getAttribute('index')))
136
  ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
137
  ->write("{\n")
138
  ->indent()
@@ -149,17 +173,17 @@ class Twig_Node_Module extends Twig_Node
149
  ;
150
 
151
  // parent
152
- if (null === $parent = $this->getNode('parent')) {
153
  $compiler->write("\$this->parent = false;\n\n");
154
- } elseif ($parent instanceof Twig_Node_Expression_Constant) {
155
  $compiler
156
  ->addDebugInfo($parent)
157
  ->write('$this->parent = $this->loadTemplate(')
158
  ->subcompile($parent)
159
  ->raw(', ')
160
- ->repr($compiler->getFilename())
161
  ->raw(', ')
162
- ->repr($this->getNode('parent')->getLine())
163
  ->raw(");\n")
164
  ;
165
  }
@@ -277,7 +301,8 @@ class Twig_Node_Module extends Twig_Node
277
  ->subcompile($this->getNode('body'))
278
  ;
279
 
280
- if (null !== $parent = $this->getNode('parent')) {
 
281
  $compiler->addDebugInfo($parent);
282
  if ($parent instanceof Twig_Node_Expression_Constant) {
283
  $compiler->write('$this->parent');
@@ -314,7 +339,7 @@ class Twig_Node_Module extends Twig_Node
314
  ->write("public function getTemplateName()\n", "{\n")
315
  ->indent()
316
  ->write('return ')
317
- ->repr($this->getAttribute('filename'))
318
  ->raw(";\n")
319
  ->outdent()
320
  ->write("}\n\n")
@@ -330,7 +355,7 @@ class Twig_Node_Module extends Twig_Node
330
  //
331
  // Put another way, a template can be used as a trait if it
332
  // only contains blocks and use statements.
333
- $traitable = null === $this->getNode('parent') && 0 === count($this->getNode('macros'));
334
  if ($traitable) {
335
  if ($this->getNode('body') instanceof Twig_Node_Body) {
336
  $nodes = $this->getNode('body')->getNode(0);
@@ -380,6 +405,37 @@ class Twig_Node_Module extends Twig_Node
380
  ->indent()
381
  ->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true))))
382
  ->outdent()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
  ->write("}\n")
384
  ;
385
  }
@@ -391,13 +447,13 @@ class Twig_Node_Module extends Twig_Node
391
  ->write(sprintf('%s = $this->loadTemplate(', $var))
392
  ->subcompile($node)
393
  ->raw(', ')
394
- ->repr($compiler->getFilename())
395
  ->raw(', ')
396
- ->repr($node->getLine())
397
  ->raw(");\n")
398
  ;
399
  } else {
400
- throw new LogicException('Trait templates can only be constant nodes');
401
  }
402
  }
403
  }
21
  */
22
  class Twig_Node_Module extends Twig_Node
23
  {
24
+ private $source;
25
+
26
+ public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $name, $source = '')
27
  {
28
+ if (!$name instanceof Twig_Source) {
29
+ @trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
30
+ $this->source = new Twig_Source($source, $name);
31
+ } else {
32
+ $this->source = $name;
33
+ }
34
+
35
+ $nodes = array(
36
  'body' => $body,
37
  'blocks' => $blocks,
38
  'macros' => $macros,
42
  'constructor_start' => new Twig_Node(),
43
  'constructor_end' => new Twig_Node(),
44
  'class_end' => new Twig_Node(),
45
+ );
46
+ if (null !== $parent) {
47
+ $nodes['parent'] = $parent;
48
+ }
49
+
50
+ // embedded templates are set as attributes so that they are only visited once by the visitors
51
+ parent::__construct($nodes, array(
52
+ // source to be remove in 2.0
53
+ 'source' => $this->source->getCode(),
54
+ // filename to be remove in 2.0 (use getTemplateName() instead)
55
+ 'filename' => $this->source->getName(),
56
  'index' => null,
57
  'embedded_templates' => $embeddedTemplates,
58
  ), 1);
59
+
60
+ // populate the template name of all node children
61
+ $this->setTemplateName($this->source->getName());
62
  }
63
 
64
  public function setIndex($index)
86
  if (
87
  count($this->getNode('blocks'))
88
  || count($this->getNode('traits'))
89
+ || !$this->hasNode('parent')
90
  || $this->getNode('parent') instanceof Twig_Node_Expression_Constant
91
  || count($this->getNode('constructor_start'))
92
  || count($this->getNode('constructor_end'))
108
 
109
  $this->compileDebugInfo($compiler);
110
 
111
+ $this->compileGetSource($compiler);
112
+
113
+ $this->compileGetSourceContext($compiler);
114
+
115
  $this->compileClassFooter($compiler);
116
  }
117
 
118
  protected function compileGetParent(Twig_Compiler $compiler)
119
  {
120
+ if (!$this->hasNode('parent')) {
121
  return;
122
  }
123
+ $parent = $this->getNode('parent');
124
 
125
  $compiler
126
  ->write("protected function doGetParent(array \$context)\n", "{\n")
136
  ->raw('$this->loadTemplate(')
137
  ->subcompile($parent)
138
  ->raw(', ')
139
+ ->repr($this->source->getName())
140
  ->raw(', ')
141
+ ->repr($parent->getTemplateLine())
142
  ->raw(')')
143
  ;
144
  }
154
  {
155
  $compiler
156
  ->write("\n\n")
157
+ // if the template name contains */, add a blank to avoid a PHP parse error
158
+ ->write('/* '.str_replace('*/', '* /', $this->source->getName())." */\n")
159
+ ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->source->getName(), $this->getAttribute('index')))
160
  ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
161
  ->write("{\n")
162
  ->indent()
173
  ;
174
 
175
  // parent
176
+ if (!$this->hasNode('parent')) {
177
  $compiler->write("\$this->parent = false;\n\n");
178
+ } elseif (($parent = $this->getNode('parent')) && $parent instanceof Twig_Node_Expression_Constant) {
179
  $compiler
180
  ->addDebugInfo($parent)
181
  ->write('$this->parent = $this->loadTemplate(')
182
  ->subcompile($parent)
183
  ->raw(', ')
184
+ ->repr($this->source->getName())
185
  ->raw(', ')
186
+ ->repr($parent->getTemplateLine())
187
  ->raw(");\n")
188
  ;
189
  }
301
  ->subcompile($this->getNode('body'))
302
  ;
303
 
304
+ if ($this->hasNode('parent')) {
305
+ $parent = $this->getNode('parent');
306
  $compiler->addDebugInfo($parent);
307
  if ($parent instanceof Twig_Node_Expression_Constant) {
308
  $compiler->write('$this->parent');
339
  ->write("public function getTemplateName()\n", "{\n")
340
  ->indent()
341
  ->write('return ')
342
+ ->repr($this->source->getName())
343
  ->raw(";\n")
344
  ->outdent()
345
  ->write("}\n\n")
355
  //
356
  // Put another way, a template can be used as a trait if it
357
  // only contains blocks and use statements.
358
+ $traitable = !$this->hasNode('parent') && 0 === count($this->getNode('macros'));
359
  if ($traitable) {
360
  if ($this->getNode('body') instanceof Twig_Node_Body) {
361
  $nodes = $this->getNode('body')->getNode(0);
405
  ->indent()
406
  ->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true))))
407
  ->outdent()
408
+ ->write("}\n\n")
409
+ ;
410
+ }
411
+
412
+ protected function compileGetSource(Twig_Compiler $compiler)
413
+ {
414
+ $compiler
415
+ ->write("/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */\n")
416
+ ->write("public function getSource()\n", "{\n")
417
+ ->indent()
418
+ ->write("@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);\n\n")
419
+ ->write('return $this->getSourceContext()->getCode();')
420
+ ->raw("\n")
421
+ ->outdent()
422
+ ->write("}\n\n")
423
+ ;
424
+ }
425
+
426
+ protected function compileGetSourceContext(Twig_Compiler $compiler)
427
+ {
428
+ $compiler
429
+ ->write("public function getSourceContext()\n", "{\n")
430
+ ->indent()
431
+ ->write('return new Twig_Source(')
432
+ ->string($compiler->getEnvironment()->isDebug() ? $this->source->getCode() : '')
433
+ ->raw(', ')
434
+ ->string($this->source->getName())
435
+ ->raw(', ')
436
+ ->string($this->source->getPath())
437
+ ->raw(");\n")
438
+ ->outdent()
439
  ->write("}\n")
440
  ;
441
  }
447
  ->write(sprintf('%s = $this->loadTemplate(', $var))
448
  ->subcompile($node)
449
  ->raw(', ')
450
+ ->repr($node->getTemplateName())
451
  ->raw(', ')
452
+ ->repr($node->getTemplateLine())
453
  ->raw(");\n")
454
  ;
455
  } else {
456
+ throw new LogicException('Trait templates can only be constant nodes.');
457
  }
458
  }
459
  }
vendor/twig/twig/lib/Twig/Node/Sandbox.php CHANGED
@@ -25,7 +25,7 @@ class Twig_Node_Sandbox extends Twig_Node
25
  {
26
  $compiler
27
  ->addDebugInfo($this)
28
- ->write("\$sandbox = \$this->env->getExtension('sandbox');\n")
29
  ->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n")
30
  ->indent()
31
  ->write("\$sandbox->enableSandbox();\n")
25
  {
26
  $compiler
27
  ->addDebugInfo($this)
28
+ ->write("\$sandbox = \$this->env->getExtension('Twig_Extension_Sandbox');\n")
29
  ->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n")
30
  ->indent()
31
  ->write("\$sandbox->enableSandbox();\n")
vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php CHANGED
@@ -25,7 +25,7 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
25
  {
26
  $compiler
27
  ->addDebugInfo($this)
28
- ->write('echo $this->env->getExtension(\'sandbox\')->ensureToStringAllowed(')
29
  ->subcompile($this->getNode('expr'))
30
  ->raw(");\n")
31
  ;
25
  {
26
  $compiler
27
  ->addDebugInfo($this)
28
+ ->write('echo $this->env->getExtension(\'Twig_Extension_Sandbox\')->ensureToStringAllowed(')
29
  ->subcompile($this->getNode('expr'))
30
  ->raw(");\n")
31
  ;
vendor/twig/twig/lib/Twig/Node/Set.php CHANGED
@@ -30,7 +30,7 @@ class Twig_Node_Set extends Twig_Node
30
 
31
  $values = $this->getNode('values');
32
  if ($values instanceof Twig_Node_Text) {
33
- $this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getLine()));
34
  $this->setAttribute('capture', false);
35
  }
36
  }
30
 
31
  $values = $this->getNode('values');
32
  if ($values instanceof Twig_Node_Text) {
33
+ $this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getTemplateLine()));
34
  $this->setAttribute('capture', false);
35
  }
36
  }
vendor/twig/twig/lib/Twig/NodeInterface.php CHANGED
@@ -25,6 +25,9 @@ interface Twig_NodeInterface extends Countable, IteratorAggregate
25
  */
26
  public function compile(Twig_Compiler $compiler);
27
 
 
 
 
28
  public function getLine();
29
 
30
  public function getNodeTag();
25
  */
26
  public function compile(Twig_Compiler $compiler);
27
 
28
+ /**
29
+ * @deprecated since 1.27 (to be removed in 2.0)
30
+ */
31
  public function getLine();
32
 
33
  public function getNodeTag();
vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php CHANGED
@@ -34,7 +34,7 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
34
  protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
35
  {
36
  if ($node instanceof Twig_Node_Module) {
37
- if ($env->hasExtension('escaper') && $defaultStrategy = $env->getExtension('escaper')->getDefaultStrategy($node->getAttribute('filename'))) {
38
  $this->defaultStrategy = $defaultStrategy;
39
  }
40
  $this->safeVars = array();
@@ -90,7 +90,7 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
90
 
91
  return new $class(
92
  $this->getEscaperFilter($type, $expression),
93
- $node->getLine()
94
  );
95
  }
96
 
@@ -142,7 +142,7 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
142
 
143
  protected function getEscaperFilter($type, Twig_NodeInterface $node)
144
  {
145
- $line = $node->getLine();
146
  $name = new Twig_Node_Expression_Constant('escape', $line);
147
  $args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line), new Twig_Node_Expression_Constant(null, $line), new Twig_Node_Expression_Constant(true, $line)));
148
 
34
  protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
35
  {
36
  if ($node instanceof Twig_Node_Module) {
37
+ if ($env->hasExtension('Twig_Extension_Escaper') && $defaultStrategy = $env->getExtension('Twig_Extension_Escaper')->getDefaultStrategy($node->getTemplateName())) {
38
  $this->defaultStrategy = $defaultStrategy;
39
  }
40
  $this->safeVars = array();
90
 
91
  return new $class(
92
  $this->getEscaperFilter($type, $expression),
93
+ $node->getTemplateLine()
94
  );
95
  }
96
 
142
 
143
  protected function getEscaperFilter($type, Twig_NodeInterface $node)
144
  {
145
+ $line = $node->getTemplateLine();
146
  $name = new Twig_Node_Expression_Constant('escape', $line);
147
  $args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line), new Twig_Node_Expression_Constant(null, $line), new Twig_Node_Expression_Constant(true, $line)));
148
 
vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php CHANGED
@@ -56,7 +56,7 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
56
  $this->enterOptimizeFor($node, $env);
57
  }
58
 
59
- if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) {
60
  if ($this->inABody) {
61
  if (!$node instanceof Twig_Node_Expression) {
62
  if (get_class($node) !== 'Twig_Node') {
@@ -90,14 +90,14 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
90
 
91
  $node = $this->optimizePrintNode($node, $env);
92
 
93
- if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) {
94
  if ($node instanceof Twig_Node_Body) {
95
  $this->inABody = false;
96
  } elseif ($this->inABody) {
97
  if (!$expression && get_class($node) !== 'Twig_Node' && $prependedNodes = array_shift($this->prependedNodes)) {
98
  $nodes = array();
99
  foreach (array_unique($prependedNodes) as $name) {
100
- $nodes[] = new Twig_Node_SetTemp($name, $node->getLine());
101
  }
102
 
103
  $nodes[] = $node;
@@ -114,7 +114,7 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
114
  if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) {
115
  $this->prependedNodes[0][] = $node->getAttribute('name');
116
 
117
- return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getLine());
118
  }
119
 
120
  return $node;
56
  $this->enterOptimizeFor($node, $env);
57
  }
58
 
59
+ if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('Twig_Extension_Sandbox')) {
60
  if ($this->inABody) {
61
  if (!$node instanceof Twig_Node_Expression) {
62
  if (get_class($node) !== 'Twig_Node') {
90
 
91
  $node = $this->optimizePrintNode($node, $env);
92
 
93
+ if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('Twig_Extension_Sandbox')) {
94
  if ($node instanceof Twig_Node_Body) {
95
  $this->inABody = false;
96
  } elseif ($this->inABody) {
97
  if (!$expression && get_class($node) !== 'Twig_Node' && $prependedNodes = array_shift($this->prependedNodes)) {
98
  $nodes = array();
99
  foreach (array_unique($prependedNodes) as $name) {
100
+ $nodes[] = new Twig_Node_SetTemp($name, $node->getTemplateLine());
101
  }
102
 
103
  $nodes[] = $node;
114
  if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) {
115
  $this->prependedNodes[0][] = $node->getAttribute('name');
116
 
117
+ return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getTemplateLine());
118
  }
119
 
120
  return $node;
vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php CHANGED
@@ -51,7 +51,7 @@ class Twig_NodeVisitor_Sandbox extends Twig_BaseNodeVisitor
51
 
52
  // wrap print to check __toString() calls
53
  if ($node instanceof Twig_Node_Print) {
54
- return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getLine(), $node->getNodeTag());
55
  }
56
  }
57
 
51
 
52
  // wrap print to check __toString() calls
53
  if ($node instanceof Twig_Node_Print) {
54
+ return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getTemplateLine(), $node->getNodeTag());
55
  }
56
  }
57
 
vendor/twig/twig/lib/Twig/Parser.php CHANGED
@@ -42,8 +42,13 @@ class Twig_Parser implements Twig_ParserInterface
42
  $this->env = $env;
43
  }
44
 
 
 
 
45
  public function getEnvironment()
46
  {
 
 
47
  return $this->env;
48
  }
49
 
@@ -52,9 +57,14 @@ class Twig_Parser implements Twig_ParserInterface
52
  return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
53
  }
54
 
 
 
 
55
  public function getFilename()
56
  {
57
- return $this->stream->getFilename();
 
 
58
  }
59
 
60
  /**
@@ -64,6 +74,7 @@ class Twig_Parser implements Twig_ParserInterface
64
  {
65
  // push all variables into the stack to keep the current state of the parser
66
  // using get_object_vars() instead of foreach would lead to https://bugs.php.net/71336
 
67
  $vars = array();
68
  foreach ($this as $k => $v) {
69
  $vars[$k] = $v;
@@ -84,7 +95,7 @@ class Twig_Parser implements Twig_ParserInterface
84
  }
85
 
86
  if (null === $this->expressionParser) {
87
- $this->expressionParser = new Twig_ExpressionParser($this, $this->env->getUnaryOperators(), $this->env->getBinaryOperators());
88
  }
89
 
90
  $this->stream = $stream;
@@ -103,8 +114,8 @@ class Twig_Parser implements Twig_ParserInterface
103
  $body = new Twig_Node();
104
  }
105
  } catch (Twig_Error_Syntax $e) {
106
- if (!$e->getTemplateFile()) {
107
- $e->setTemplateFile($this->getFilename());
108
  }
109
 
110
  if (!$e->getTemplateLine()) {
@@ -114,7 +125,7 @@ class Twig_Parser implements Twig_ParserInterface
114
  throw $e;
115
  }
116
 
117
- $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $this->getFilename());
118
 
119
  $traverser = new Twig_NodeTraverser($this->env, $this->visitors);
120
 
@@ -151,7 +162,7 @@ class Twig_Parser implements Twig_ParserInterface
151
  $token = $this->getCurrentToken();
152
 
153
  if ($token->getType() !== Twig_Token::NAME_TYPE) {
154
- throw new Twig_Error_Syntax('A block must start with a tag name.', $token->getLine(), $this->getFilename());
155
  }
156
 
157
  if (null !== $test && call_user_func($test, $token)) {
@@ -169,13 +180,13 @@ class Twig_Parser implements Twig_ParserInterface
169
  $subparser = $this->handlers->getTokenParser($token->getValue());
170
  if (null === $subparser) {
171
  if (null !== $test) {
172
- $e = new Twig_Error_Syntax(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->getFilename());
173
 
174
  if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) {
175
  $e->appendMessage(sprintf(' (expecting closing tag for the "%s" tag defined near line %s).', $test[0]->getTag(), $lineno));
176
  }
177
  } else {
178
- $e = new Twig_Error_Syntax(sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->getFilename());
179
  $e->addSuggestions($token->getValue(), array_keys($this->env->getTags()));
180
  }
181
 
@@ -191,7 +202,7 @@ class Twig_Parser implements Twig_ParserInterface
191
  break;
192
 
193
  default:
194
- throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', 0, $this->getFilename());
195
  }
196
  }
197
 
@@ -202,13 +213,23 @@ class Twig_Parser implements Twig_ParserInterface
202
  return new Twig_Node($rv, array(), $lineno);
203
  }
204
 
 
 
 
205
  public function addHandler($name, $class)
206
  {
 
 
207
  $this->handlers[$name] = $class;
208
  }
209
 
 
 
 
210
  public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
211
  {
 
 
212
  $this->visitors[] = $visitor;
213
  }
214
 
@@ -244,7 +265,7 @@ class Twig_Parser implements Twig_ParserInterface
244
 
245
  public function setBlock($name, Twig_Node_Block $value)
246
  {
247
- $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getLine());
248
  }
249
 
250
  public function hasMacro($name)
@@ -255,7 +276,7 @@ class Twig_Parser implements Twig_ParserInterface
255
  public function setMacro($name, Twig_Node_Macro $node)
256
  {
257
  if ($this->isReservedMacroName($name)) {
258
- throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->getLine(), $this->getFilename());
259
  }
260
 
261
  $this->macros[$name] = $node;
@@ -373,10 +394,10 @@ class Twig_Parser implements Twig_ParserInterface
373
  (!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface)
374
  ) {
375
  if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) {
376
- throw new Twig_Error_Syntax('A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed.', $node->getLine(), $this->getFilename());
377
  }
378
 
379
- throw new Twig_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->getFilename());
380
  }
381
 
382
  // bypass "set" nodes as they "capture" the output
42
  $this->env = $env;
43
  }
44
 
45
+ /**
46
+ * @deprecated since 1.27 (to be removed in 2.0)
47
+ */
48
  public function getEnvironment()
49
  {
50
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED);
51
+
52
  return $this->env;
53
  }
54
 
57
  return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
58
  }
59
 
60
+ /**
61
+ * @deprecated since 1.27 (to be removed in 2.0). Use $parser->getStream()->getSourceContext()->getPath() instead.
62
+ */
63
  public function getFilename()
64
  {
65
+ @trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use $parser->getStream()->getSourceContext()->getPath() instead.', __METHOD__), E_USER_DEPRECATED);
66
+
67
+ return $this->stream->getSourceContext()->getName();
68
  }
69
 
70
  /**
74
  {
75
  // push all variables into the stack to keep the current state of the parser
76
  // using get_object_vars() instead of foreach would lead to https://bugs.php.net/71336
77
+ // This hack can be removed when min version if PHP 7.0
78
  $vars = array();
79
  foreach ($this as $k => $v) {
80
  $vars[$k] = $v;
95
  }
96
 
97
  if (null === $this->expressionParser) {
98
+ $this->expressionParser = new Twig_ExpressionParser($this, $this->env);
99
  }
100
 
101
  $this->stream = $stream;
114
  $body = new Twig_Node();
115
  }
116
  } catch (Twig_Error_Syntax $e) {
117
+ if (!$e->getTemplateName()) {
118
+ $e->setTemplateName($this->stream->getSourceContext()->getName());
119
  }
120
 
121
  if (!$e->getTemplateLine()) {
125
  throw $e;
126
  }
127
 
128
+ $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $stream->getSourceContext());
129
 
130
  $traverser = new Twig_NodeTraverser($this->env, $this->visitors);
131
 
162
  $token = $this->getCurrentToken();
163
 
164
  if ($token->getType() !== Twig_Token::NAME_TYPE) {
165
+ throw new Twig_Error_Syntax('A block must start with a tag name.', $token->getLine(), $this->stream->getSourceContext()->getName());
166
  }
167
 
168
  if (null !== $test && call_user_func($test, $token)) {
180
  $subparser = $this->handlers->getTokenParser($token->getValue());
181
  if (null === $subparser) {
182
  if (null !== $test) {
183
+ $e = new Twig_Error_Syntax(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->stream->getSourceContext()->getName());
184
 
185
  if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) {
186
  $e->appendMessage(sprintf(' (expecting closing tag for the "%s" tag defined near line %s).', $test[0]->getTag(), $lineno));
187
  }
188
  } else {
189
+ $e = new Twig_Error_Syntax(sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->stream->getSourceContext()->getName());
190
  $e->addSuggestions($token->getValue(), array_keys($this->env->getTags()));
191
  }
192
 
202
  break;
203
 
204
  default:
205
+ throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', 0, $this->stream->getSourceContext()->getName());
206
  }
207
  }
208
 
213
  return new Twig_Node($rv, array(), $lineno);
214
  }
215
 
216
+ /**
217
+ * @deprecated since 1.27 (to be removed in 2.0)
218
+ */
219
  public function addHandler($name, $class)
220
  {
221
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED);
222
+
223
  $this->handlers[$name] = $class;
224
  }
225
 
226
+ /**
227
+ * @deprecated since 1.27 (to be removed in 2.0)
228
+ */
229
  public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
230
  {
231
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED);
232
+
233
  $this->visitors[] = $visitor;
234
  }
235
 
265
 
266
  public function setBlock($name, Twig_Node_Block $value)
267
  {
268
+ $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getTemplateLine());
269
  }
270
 
271
  public function hasMacro($name)
276
  public function setMacro($name, Twig_Node_Macro $node)
277
  {
278
  if ($this->isReservedMacroName($name)) {
279
+ throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->getTemplateLine(), $this->stream->getSourceContext()->getName());
280
  }
281
 
282
  $this->macros[$name] = $node;
394
  (!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface)
395
  ) {
396
  if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) {
397
+ throw new Twig_Error_Syntax('A template that extends another one cannot start with a byte order mark (BOM); it must be removed.', $node->getTemplateLine(), $this->stream->getSourceContext()->getName());
398
  }
399
 
400
+ throw new Twig_Error_Syntax('A template that extends another one cannot include contents outside Twig blocks. Did you forget to put the contents inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext()->getName());
401
  }
402
 
403
  // bypass "set" nodes as they "capture" the output
vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php CHANGED
@@ -36,19 +36,19 @@ class Twig_Profiler_NodeVisitor_Profiler extends Twig_BaseNodeVisitor
36
  {
37
  if ($node instanceof Twig_Node_Module) {
38
  $varName = $this->getVarName();
39
- $node->setNode('display_start', new Twig_Node(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::TEMPLATE, $node->getAttribute('filename'), $varName), $node->getNode('display_start'))));
40
  $node->setNode('display_end', new Twig_Node(array(new Twig_Profiler_Node_LeaveProfile($varName), $node->getNode('display_end'))));
41
  } elseif ($node instanceof Twig_Node_Block) {
42
  $varName = $this->getVarName();
43
  $node->setNode('body', new Twig_Node_Body(array(
44
- new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::BLOCK, $node->getAttribute('name'), $varName),
45
  $node->getNode('body'),
46
  new Twig_Profiler_Node_LeaveProfile($varName),
47
  )));
48
  } elseif ($node instanceof Twig_Node_Macro) {
49
  $varName = $this->getVarName();
50
  $node->setNode('body', new Twig_Node_Body(array(
51
- new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::MACRO, $node->getAttribute('name'), $varName),
52
  $node->getNode('body'),
53
  new Twig_Profiler_Node_LeaveProfile($varName),
54
  )));
36
  {
37
  if ($node instanceof Twig_Node_Module) {
38
  $varName = $this->getVarName();
39
+ $node->setNode('display_start', new Twig_Node(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::TEMPLATE, $node->getTemplateName(), $varName), $node->getNode('display_start'))));
40
  $node->setNode('display_end', new Twig_Node(array(new Twig_Profiler_Node_LeaveProfile($varName), $node->getNode('display_end'))));
41
  } elseif ($node instanceof Twig_Node_Block) {
42
  $varName = $this->getVarName();
43
  $node->setNode('body', new Twig_Node_Body(array(
44
+ new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::BLOCK, $node->getTemplateName(), $varName),
45
  $node->getNode('body'),
46
  new Twig_Profiler_Node_LeaveProfile($varName),
47
  )));
48
  } elseif ($node instanceof Twig_Node_Macro) {
49
  $varName = $this->getVarName();
50
  $node->setNode('body', new Twig_Node_Body(array(
51
+ new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::MACRO, $node->getTemplateName(), $varName),
52
  $node->getNode('body'),
53
  new Twig_Profiler_Node_LeaveProfile($varName),
54
  )));
vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) Fabien Potencier
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Creates runtime implementations for Twig elements (filters/functions/tests).
14
+ *
15
+ * @author Fabien Potencier <fabien@symfony.com>
16
+ */
17
+ interface Twig_RuntimeLoaderInterface
18
+ {
19
+ /**
20
+ * Creates the runtime implementation of a Twig element (filter/function/test).
21
+ *
22
+ * @param string $class A runtime class
23
+ *
24
+ * @return object|null The runtime instance or null if the loader does not know how to create the runtime for this class
25
+ */
26
+ public function load($class);
27
+ }
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) 2009 Fabien Potencier
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Exception thrown when a not allowed class method is used in a template.
14
+ *
15
+ * @author Kit Burton-Senior <mail@kitbs.com>
16
+ */
17
+ class Twig_Sandbox_SecurityNotAllowedMethodError extends Twig_Sandbox_SecurityError
18
+ {
19
+ private $className;
20
+ private $methodName;
21
+
22
+ public function __construct($message, $className, $methodName, $lineno = -1, $filename = null, Exception $previous = null)
23
+ {
24
+ parent::__construct($message, $lineno, $filename, $previous);
25
+ $this->className = $className;
26
+ $this->methodName = $methodName;
27
+ }
28
+
29
+ public function getClassName()
30
+ {
31
+ return $this->className;
32
+ }
33
+
34
+ public function getMethodName()
35
+ {
36
+ return $this->methodName;
37
+ }
38
+ }
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) 2009 Fabien Potencier
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Exception thrown when a not allowed class property is used in a template.
14
+ *
15
+ * @author Kit Burton-Senior <mail@kitbs.com>
16
+ */
17
+ class Twig_Sandbox_SecurityNotAllowedPropertyError extends Twig_Sandbox_SecurityError
18
+ {
19
+ private $className;
20
+ private $propertyName;
21
+
22
+ public function __construct($message, $className, $propertyName, $lineno = -1, $filename = null, Exception $previous = null)
23
+ {
24
+ parent::__construct($message, $lineno, $filename, $previous);
25
+ $this->className = $className;
26
+ $this->propertyName = $propertyName;
27
+ }
28
+
29
+ public function getClassName()
30
+ {
31
+ return $this->className;
32
+ }
33
+
34
+ public function getPropertyName()
35
+ {
36
+ return $this->propertyName;
37
+ }
38
+ }
vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php CHANGED
@@ -97,7 +97,8 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac
97
  }
98
 
99
  if (!$allowed) {
100
- throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, get_class($obj)));
 
101
  }
102
  }
103
 
@@ -113,7 +114,8 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac
113
  }
114
 
115
  if (!$allowed) {
116
- throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, get_class($obj)));
 
117
  }
118
  }
119
  }
97
  }
98
 
99
  if (!$allowed) {
100
+ $class = get_class($obj);
101
+ throw new Twig_Sandbox_SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method);
102
  }
103
  }
104
 
114
  }
115
 
116
  if (!$allowed) {
117
+ $class = get_class($obj);
118
+ throw new Twig_Sandbox_SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property);
119
  }
120
  }
121
  }
vendor/twig/twig/lib/Twig/Source.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) 2016 Fabien Potencier
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Holds information about a non-compiled Twig template.
14
+ *
15
+ * @author Fabien Potencier <fabien@symfony.com>
16
+ */
17
+ class Twig_Source
18
+ {
19
+ private $code;
20
+ private $name;
21
+ private $path;
22
+
23
+ /**
24
+ * @param string $code The template source code
25
+ * @param string $name The template logical name
26
+ * @param string $path The filesystem path of the template if any
27
+ */
28
+ public function __construct($code, $name, $path = '')
29
+ {
30
+ $this->code = $code;
31
+ $this->name = $name;
32
+ $this->path = $path;
33
+ }
34
+
35
+ public function getCode()
36
+ {
37
+ return $this->code;
38
+ }
39
+
40
+ public function getName()
41
+ {
42
+ return $this->name;
43
+ }
44
+
45
+ public function getPath()
46
+ {
47
+ return $this->path;
48
+ }
49
+ }
vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) 2016 Fabien Potencier
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Adds a getSourceContext() method for loaders.
14
+ *
15
+ * @author Fabien Potencier <fabien@symfony.com>
16
+ *
17
+ * @deprecated since 1.27 (to be removed in 3.0)
18
+ */
19
+ interface Twig_SourceContextLoaderInterface
20
+ {
21
+ /**
22
+ * Returns the source context for a given template logical name.
23
+ *
24
+ * @param string $name The template logical name
25
+ *
26
+ * @return Twig_Source
27
+ *
28
+ * @throws Twig_Error_Loader When $name is not found
29
+ */
30
+ public function getSourceContext($name);
31
+ }
vendor/twig/twig/lib/Twig/Template.php CHANGED
@@ -42,6 +42,42 @@ abstract class Twig_Template implements Twig_TemplateInterface
42
  */
43
  abstract public function getTemplateName();
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  /**
46
  * @deprecated since 1.20 (to be removed in 2.0)
47
  */
@@ -85,7 +121,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
85
  $this->parents[$parent] = $this->loadTemplate($parent);
86
  }
87
  } catch (Twig_Error_Loader $e) {
88
- $e->setTemplateFile(null);
89
  $e->guess();
90
 
91
  throw $e;
@@ -125,7 +161,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
125
  } elseif (false !== $parent = $this->getParent($context)) {
126
  $parent->displayBlock($name, $context, $blocks, false);
127
  } else {
128
- throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName());
129
  }
130
  }
131
 
@@ -166,8 +202,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
166
  try {
167
  $template->$block($context, $blocks);
168
  } catch (Twig_Error $e) {
169
- if (!$e->getTemplateFile()) {
170
- $e->setTemplateFile($template->getTemplateName());
171
  }
172
 
173
  // this is mostly useful for Twig_Error_Loader exceptions
@@ -285,8 +321,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
285
 
286
  return $this->env->loadTemplate($template, $index);
287
  } catch (Twig_Error $e) {
288
- if (!$e->getTemplateFile()) {
289
- $e->setTemplateFile($templateName ? $templateName : $this->getTemplateName());
290
  }
291
 
292
  if ($e->getTemplateLine()) {
@@ -320,33 +356,6 @@ abstract class Twig_Template implements Twig_TemplateInterface
320
  return $this->blocks;
321
  }
322
 
323
- /**
324
- * Returns the template source code.
325
- *
326
- * @return string|null The template source code or null if it is not available
327
- */
328
- public function getSource()
329
- {
330
- $reflector = new ReflectionClass($this);
331
- $file = $reflector->getFileName();
332
-
333
- if (!file_exists($file)) {
334
- return;
335
- }
336
-
337
- $source = file($file, FILE_IGNORE_NEW_LINES);
338
- array_splice($source, 0, $reflector->getEndLine());
339
-
340
- $i = 0;
341
- while (isset($source[$i]) && '/* */' === substr_replace($source[$i], '', 3, -2)) {
342
- $source[$i] = str_replace('*//* ', '*/', substr($source[$i], 3, -2));
343
- ++$i;
344
- }
345
- array_splice($source, $i);
346
-
347
- return implode("\n", $source);
348
- }
349
-
350
  /**
351
  * {@inheritdoc}
352
  */
@@ -386,8 +395,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
386
  try {
387
  $this->doDisplay($context, $blocks);
388
  } catch (Twig_Error $e) {
389
- if (!$e->getTemplateFile()) {
390
- $e->setTemplateFile($this->getTemplateName());
391
  }
392
 
393
  // this is mostly useful for Twig_Error_Loader exceptions
@@ -439,7 +448,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
439
  return;
440
  }
441
 
442
- throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item), -1, $this->getTemplateName());
443
  }
444
 
445
  return $context[$item];
@@ -485,25 +494,25 @@ abstract class Twig_Template implements Twig_TemplateInterface
485
  }
486
 
487
  if ($object instanceof ArrayAccess) {
488
- $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist', $arrayItem, get_class($object));
489
  } elseif (is_object($object)) {
490
- $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface', $item, get_class($object));
491
  } elseif (is_array($object)) {
492
  if (empty($object)) {
493
- $message = sprintf('Key "%s" does not exist as the array is empty', $arrayItem);
494
  } else {
495
- $message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object)));
496
  }
497
  } elseif (self::ARRAY_CALL === $type) {
498
  if (null === $object) {
499
- $message = sprintf('Impossible to access a key ("%s") on a null variable', $item);
500
  } else {
501
- $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
502
  }
503
  } elseif (null === $object) {
504
- $message = sprintf('Impossible to access an attribute ("%s") on a null variable', $item);
505
  } else {
506
- $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
507
  }
508
 
509
  throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
@@ -520,9 +529,9 @@ abstract class Twig_Template implements Twig_TemplateInterface
520
  }
521
 
522
  if (null === $object) {
523
- $message = sprintf('Impossible to invoke a method ("%s") on a null variable', $item);
524
  } else {
525
- $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
526
  }
527
 
528
  throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
@@ -535,8 +544,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
535
  return true;
536
  }
537
 
538
- if ($this->env->hasExtension('sandbox')) {
539
- $this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item);
540
  }
541
 
542
  return $object->$item;
@@ -587,15 +596,15 @@ abstract class Twig_Template implements Twig_TemplateInterface
587
  return;
588
  }
589
 
590
- throw new Twig_Error_Runtime(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s"', $item, get_class($object)), -1, $this->getTemplateName());
591
  }
592
 
593
  if ($isDefinedTest) {
594
  return true;
595
  }
596
 
597
- if ($this->env->hasExtension('sandbox')) {
598
- $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method);
599
  }
600
 
601
  // Some objects throw exceptions when they have __call, and the method we try
42
  */
43
  abstract public function getTemplateName();
44
 
45
+ /**
46
+ * Returns debug information about the template.
47
+ *
48
+ * @return array Debug information
49
+ *
50
+ * @internal
51
+ */
52
+ public function getDebugInfo()
53
+ {
54
+ return array();
55
+ }
56
+
57
+ /**
58
+ * Returns the template source code.
59
+ *
60
+ * @return string The template source code
61
+ *
62
+ * @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead
63
+ */
64
+ public function getSource()
65
+ {
66
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);
67
+
68
+ return '';
69
+ }
70
+
71
+ /**
72
+ * Returns information about the original template source code.
73
+ *
74
+ * @return Twig_Source
75
+ */
76
+ public function getSourceContext()
77
+ {
78
+ return new Twig_Source('', $this->getTemplateName());
79
+ }
80
+
81
  /**
82
  * @deprecated since 1.20 (to be removed in 2.0)
83
  */
121
  $this->parents[$parent] = $this->loadTemplate($parent);
122
  }
123
  } catch (Twig_Error_Loader $e) {
124
+ $e->setTemplateName(null);
125
  $e->guess();
126
 
127
  throw $e;
161
  } elseif (false !== $parent = $this->getParent($context)) {
162
  $parent->displayBlock($name, $context, $blocks, false);
163
  } else {
164
+ throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getTemplateName());
165
  }
166
  }
167
 
202
  try {
203
  $template->$block($context, $blocks);
204
  } catch (Twig_Error $e) {
205
+ if (!$e->getTemplateName()) {
206
+ $e->setTemplateName($template->getTemplateName());
207
  }
208
 
209
  // this is mostly useful for Twig_Error_Loader exceptions
321
 
322
  return $this->env->loadTemplate($template, $index);
323
  } catch (Twig_Error $e) {
324
+ if (!$e->getTemplateName()) {
325
+ $e->setTemplateName($templateName ? $templateName : $this->getTemplateName());
326
  }
327
 
328
  if ($e->getTemplateLine()) {
356
  return $this->blocks;
357
  }
358
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
  /**
360
  * {@inheritdoc}
361
  */
395
  try {
396
  $this->doDisplay($context, $blocks);
397
  } catch (Twig_Error $e) {
398
+ if (!$e->getTemplateName()) {
399
+ $e->setTemplateName($this->getTemplateName());
400
  }
401
 
402
  // this is mostly useful for Twig_Error_Loader exceptions
448
  return;
449
  }
450
 
451
+ throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist.', $item), -1, $this->getTemplateName());
452
  }
453
 
454
  return $context[$item];
494
  }
495
 
496
  if ($object instanceof ArrayAccess) {
497
+ $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist.', $arrayItem, get_class($object));
498
  } elseif (is_object($object)) {
499
+ $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface.', $item, get_class($object));
500
  } elseif (is_array($object)) {
501
  if (empty($object)) {
502
+ $message = sprintf('Key "%s" does not exist as the array is empty.', $arrayItem);
503
  } else {
504
+ $message = sprintf('Key "%s" for array with keys "%s" does not exist.', $arrayItem, implode(', ', array_keys($object)));
505
  }
506
  } elseif (self::ARRAY_CALL === $type) {
507
  if (null === $object) {
508
+ $message = sprintf('Impossible to access a key ("%s") on a null variable.', $item);
509
  } else {
510
+ $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s").', $item, gettype($object), $object);
511
  }
512
  } elseif (null === $object) {
513
+ $message = sprintf('Impossible to access an attribute ("%s") on a null variable.', $item);
514
  } else {
515
+ $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s").', $item, gettype($object), $object);
516
  }
517
 
518
  throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
529
  }
530
 
531
  if (null === $object) {
532
+ $message = sprintf('Impossible to invoke a method ("%s") on a null variable.', $item);
533
  } else {
534
+ $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s").', $item, gettype($object), $object);
535
  }
536
 
537
  throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
544
  return true;
545
  }
546
 
547
+ if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
548
+ $this->env->getExtension('Twig_Extension_Sandbox')->checkPropertyAllowed($object, $item);
549
  }
550
 
551
  return $object->$item;
596
  return;
597
  }
598
 
599
+ throw new Twig_Error_Runtime(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s".', $item, get_class($object)), -1, $this->getTemplateName());
600
  }
601
 
602
  if ($isDefinedTest) {
603
  return true;
604
  }
605
 
606
+ if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
607
+ $this->env->getExtension('Twig_Extension_Sandbox')->checkMethodAllowed($object, $method);
608
  }
609
 
610
  // Some objects throw exceptions when they have __call, and the method we try
vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php CHANGED
@@ -167,13 +167,14 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
167
  if (false !== $exception) {
168
  $message = $e->getMessage();
169
  $this->assertSame(trim($exception), trim(sprintf('%s: %s', get_class($e), $message)));
170
- $this->assertSame('.', substr($message, strlen($message) - 1), $message, 'Exception message must end with a dot.');
 
171
 
172
  return;
173
  }
174
 
175
  if ($e instanceof Twig_Error_Syntax) {
176
- $e->setTemplateFile($file);
177
 
178
  throw $e;
179
  }
@@ -191,7 +192,7 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
191
  }
192
 
193
  if ($e instanceof Twig_Error_Syntax) {
194
- $e->setTemplateFile($file);
195
  } else {
196
  $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
197
  }
@@ -211,8 +212,13 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
211
 
212
  foreach (array_keys($templates) as $name) {
213
  echo "Template: $name\n";
214
- $source = $loader->getSource($name);
215
- echo $twig->compile($twig->parse($twig->tokenize($source, $name)));
 
 
 
 
 
216
  }
217
  }
218
  $this->assertEquals($expected, $output, $message.' (in '.$file.')');
167
  if (false !== $exception) {
168
  $message = $e->getMessage();
169
  $this->assertSame(trim($exception), trim(sprintf('%s: %s', get_class($e), $message)));
170
+ $last = substr($message, strlen($message) - 1);
171
+ $this->assertTrue('.' === $last || '?' === $last, $message, 'Exception message must end with a dot or a question mark.');
172
 
173
  return;
174
  }
175
 
176
  if ($e instanceof Twig_Error_Syntax) {
177
+ $e->setTemplateName($file);
178
 
179
  throw $e;
180
  }
192
  }
193
 
194
  if ($e instanceof Twig_Error_Syntax) {
195
+ $e->setTemplateName($file);
196
  } else {
197
  $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
198
  }
212
 
213
  foreach (array_keys($templates) as $name) {
214
  echo "Template: $name\n";
215
+ $loader = $twig->getLoader();
216
+ if (!$loader instanceof Twig_SourceContextLoaderInterface) {
217
+ $source = new Twig_Source($loader->getSource($name), $name);
218
+ } else {
219
+ $source = $loader->getSourceContext($name);
220
+ }
221
+ echo $twig->compile($twig->parse($twig->tokenize($source)));
222
  }
223
  }
224
  $this->assertEquals($expected, $output, $message.' (in '.$file.')');
vendor/twig/twig/lib/Twig/Test/Method.php CHANGED
@@ -35,6 +35,6 @@ class Twig_Test_Method extends Twig_Test
35
 
36
  public function compile()
37
  {
38
- return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
39
  }
40
  }
35
 
36
  public function compile()
37
  {
38
+ return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method);
39
  }
40
  }
vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php CHANGED
@@ -39,7 +39,7 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser
39
  } else {
40
  $expr = $this->parser->getExpressionParser()->parseExpression();
41
  if (!$expr instanceof Twig_Node_Expression_Constant) {
42
- throw new Twig_Error_Syntax('An escaping strategy must be a string or a bool.', $stream->getCurrent()->getLine(), $stream->getFilename());
43
  }
44
  $value = $expr->getAttribute('value');
45
 
@@ -53,7 +53,7 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser
53
  @trigger_error('Using the autoescape tag with "true" or "false" before the strategy name is deprecated since version 1.21.', E_USER_DEPRECATED);
54
 
55
  if (false === $value) {
56
- throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getFilename());
57
  }
58
 
59
  $value = $stream->next()->getValue();
39
  } else {
40
  $expr = $this->parser->getExpressionParser()->parseExpression();
41
  if (!$expr instanceof Twig_Node_Expression_Constant) {
42
+ throw new Twig_Error_Syntax('An escaping strategy must be a string or a bool.', $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
43
  }
44
  $value = $expr->getAttribute('value');
45
 
53
  @trigger_error('Using the autoescape tag with "true" or "false" before the strategy name is deprecated since version 1.21.', E_USER_DEPRECATED);
54
 
55
  if (false === $value) {
56
+ throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
57
  }
58
 
59
  $value = $stream->next()->getValue();
vendor/twig/twig/lib/Twig/TokenParser/Block.php CHANGED
@@ -28,7 +28,7 @@ class Twig_TokenParser_Block extends Twig_TokenParser
28
  $stream = $this->parser->getStream();
29
  $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
30
  if ($this->parser->hasBlock($name)) {
31
- throw new Twig_Error_Syntax(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getLine()), $stream->getCurrent()->getLine(), $stream->getFilename());
32
  }
33
  $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno));
34
  $this->parser->pushLocalScope();
@@ -40,7 +40,7 @@ class Twig_TokenParser_Block extends Twig_TokenParser
40
  $value = $token->getValue();
41
 
42
  if ($value != $name) {
43
- throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename());
44
  }
45
  }
46
  } else {
28
  $stream = $this->parser->getStream();
29
  $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
30
  if ($this->parser->hasBlock($name)) {
31
+ throw new Twig_Error_Syntax(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
32
  }
33
  $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno));
34
  $this->parser->pushLocalScope();
40
  $value = $token->getValue();
41
 
42
  if ($value != $name) {
43
+ throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
44
  }
45
  }
46
  } else {
vendor/twig/twig/lib/Twig/TokenParser/Embed.php CHANGED
@@ -22,24 +22,33 @@ class Twig_TokenParser_Embed extends Twig_TokenParser_Include
22
 
23
  list($variables, $only, $ignoreMissing) = $this->parseArguments();
24
 
 
 
 
 
 
 
 
25
  // inject a fake parent to make the parent() function work
26
  $stream->injectTokens(array(
27
  new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()),
28
  new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()),
29
- new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine()),
30
  new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()),
31
  ));
32
 
33
  $module = $this->parser->parse($stream, array($this, 'decideBlockEnd'), true);
34
 
35
  // override the parent with the correct one
36
- $module->setNode('parent', $parent);
 
 
37
 
38
  $this->parser->embedTemplate($module);
39
 
40
  $stream->expect(Twig_Token::BLOCK_END_TYPE);
41
 
42
- return new Twig_Node_Embed($module->getAttribute('filename'), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
43
  }
44
 
45
  public function decideBlockEnd(Twig_Token $token)
22
 
23
  list($variables, $only, $ignoreMissing) = $this->parseArguments();
24
 
25
+ $parentToken = $fakeParentToken = new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine());
26
+ if ($parent instanceof Twig_Node_Expression_Constant) {
27
+ $parentToken = new Twig_Token(Twig_Token::STRING_TYPE, $parent->getAttribute('value'), $token->getLine());
28
+ } elseif ($parent instanceof Twig_Node_Expression_Name) {
29
+ $parentToken = new Twig_Token(Twig_Token::NAME_TYPE, $parent->getAttribute('name'), $token->getLine());
30
+ }
31
+
32
  // inject a fake parent to make the parent() function work
33
  $stream->injectTokens(array(
34
  new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()),
35
  new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()),
36
+ $parentToken,
37
  new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()),
38
  ));
39
 
40
  $module = $this->parser->parse($stream, array($this, 'decideBlockEnd'), true);
41
 
42
  // override the parent with the correct one
43
+ if ($fakeParentToken === $parentToken) {
44
+ $module->setNode('parent', $parent);
45
+ }
46
 
47
  $this->parser->embedTemplate($module);
48
 
49
  $stream->expect(Twig_Token::BLOCK_END_TYPE);
50
 
51
+ return new Twig_Node_Embed($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
52
  }
53
 
54
  public function decideBlockEnd(Twig_Token $token)
vendor/twig/twig/lib/Twig/TokenParser/Extends.php CHANGED
@@ -21,16 +21,18 @@ class Twig_TokenParser_Extends extends Twig_TokenParser
21
  {
22
  public function parse(Twig_Token $token)
23
  {
 
 
24
  if (!$this->parser->isMainScope()) {
25
- throw new Twig_Error_Syntax('Cannot extend from a block.', $token->getLine(), $this->parser->getFilename());
26
  }
27
 
28
  if (null !== $this->parser->getParent()) {
29
- throw new Twig_Error_Syntax('Multiple extends tags are forbidden.', $token->getLine(), $this->parser->getFilename());
30
  }
31
  $this->parser->setParent($this->parser->getExpressionParser()->parseExpression());
32
 
33
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
34
  }
35
 
36
  public function getTag()
21
  {
22
  public function parse(Twig_Token $token)
23
  {
24
+ $stream = $this->parser->getStream();
25
+
26
  if (!$this->parser->isMainScope()) {
27
+ throw new Twig_Error_Syntax('Cannot extend from a block.', $token->getLine(), $stream->getSourceContext()->getName());
28
  }
29
 
30
  if (null !== $this->parser->getParent()) {
31
+ throw new Twig_Error_Syntax('Multiple extends tags are forbidden.', $token->getLine(), $stream->getSourceContext()->getName());
32
  }
33
  $this->parser->setParent($this->parser->getExpressionParser()->parseExpression());
34
 
35
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
36
  }
37
 
38
  public function getTag()
vendor/twig/twig/lib/Twig/TokenParser/For.php CHANGED
@@ -48,13 +48,13 @@ class Twig_TokenParser_For extends Twig_TokenParser
48
 
49
  if (count($targets) > 1) {
50
  $keyTarget = $targets->getNode(0);
51
- $keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->getLine());
52
  $valueTarget = $targets->getNode(1);
53
- $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine());
54
  } else {
55
  $keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno);
56
  $valueTarget = $targets->getNode(0);
57
- $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine());
58
  }
59
 
60
  if ($ifexpr) {
@@ -79,7 +79,7 @@ class Twig_TokenParser_For extends Twig_TokenParser
79
  protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node)
80
  {
81
  if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
82
- throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition.', $node->getLine(), $stream->getFilename());
83
  }
84
 
85
  foreach ($node as $n) {
@@ -98,7 +98,7 @@ class Twig_TokenParser_For extends Twig_TokenParser
98
  if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
99
  $attribute = $node->getNode('attribute');
100
  if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) {
101
- 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());
102
  }
103
  }
104
 
48
 
49
  if (count($targets) > 1) {
50
  $keyTarget = $targets->getNode(0);
51
+ $keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->getTemplateLine());
52
  $valueTarget = $targets->getNode(1);
53
+ $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
54
  } else {
55
  $keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno);
56
  $valueTarget = $targets->getNode(0);
57
+ $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
58
  }
59
 
60
  if ($ifexpr) {
79
  protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node)
80
  {
81
  if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
82
+ throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition.', $node->getTemplateLine(), $stream->getSourceContext()->getName());
83
  }
84
 
85
  foreach ($node as $n) {
98
  if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
99
  $attribute = $node->getNode('attribute');
100
  if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) {
101
+ throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition.', $attribute->getAttribute('value')), $node->getTemplateLine(), $stream->getSourceContext()->getName());
102
  }
103
  }
104
 
vendor/twig/twig/lib/Twig/TokenParser/From.php CHANGED
@@ -46,7 +46,7 @@ class Twig_TokenParser_From extends Twig_TokenParser
46
 
47
  foreach ($targets as $name => $alias) {
48
  if ($this->parser->isReservedMacroName($name)) {
49
- throw new Twig_Error_Syntax(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getFilename());
50
  }
51
 
52
  $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var'));
46
 
47
  foreach ($targets as $name => $alias) {
48
  if ($this->parser->isReservedMacroName($name)) {
49
+ throw new Twig_Error_Syntax(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext()->getName());
50
  }
51
 
52
  $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var'));
vendor/twig/twig/lib/Twig/TokenParser/If.php CHANGED
@@ -56,7 +56,7 @@ class Twig_TokenParser_If extends Twig_TokenParser
56
  break;
57
 
58
  default:
59
- throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->getFilename());
60
  }
61
  }
62
 
56
  break;
57
 
58
  default:
59
+ throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
60
  }
61
  }
62
 
vendor/twig/twig/lib/Twig/TokenParser/Macro.php CHANGED
@@ -35,7 +35,7 @@ class Twig_TokenParser_Macro extends Twig_TokenParser
35
  $value = $token->getValue();
36
 
37
  if ($value != $name) {
38
- throw new Twig_Error_Syntax(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename());
39
  }
40
  }
41
  $this->parser->popLocalScope();
35
  $value = $token->getValue();
36
 
37
  if ($value != $name) {
38
+ throw new Twig_Error_Syntax(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
39
  }
40
  }
41
  $this->parser->popLocalScope();
vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php CHANGED
@@ -24,9 +24,10 @@ class Twig_TokenParser_Sandbox extends Twig_TokenParser
24
  {
25
  public function parse(Twig_Token $token)
26
  {
27
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
 
28
  $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
29
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
30
 
31
  // in a sandbox tag, only include tags are allowed
32
  if (!$body instanceof Twig_Node_Include) {
@@ -36,7 +37,7 @@ class Twig_TokenParser_Sandbox extends Twig_TokenParser
36
  }
37
 
38
  if (!$node instanceof Twig_Node_Include) {
39
- throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section.', $node->getLine(), $this->parser->getFilename());
40
  }
41
  }
42
  }
24
  {
25
  public function parse(Twig_Token $token)
26
  {
27
+ $stream = $this->parser->getStream();
28
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
29
  $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
30
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
31
 
32
  // in a sandbox tag, only include tags are allowed
33
  if (!$body instanceof Twig_Node_Include) {
37
  }
38
 
39
  if (!$node instanceof Twig_Node_Include) {
40
+ throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section.', $node->getTemplateLine(), $stream->getSourceContext()->getName());
41
  }
42
  }
43
  }
vendor/twig/twig/lib/Twig/TokenParser/Set.php CHANGED
@@ -41,13 +41,13 @@ class Twig_TokenParser_Set extends Twig_TokenParser
41
  $stream->expect(Twig_Token::BLOCK_END_TYPE);
42
 
43
  if (count($names) !== count($values)) {
44
- throw new Twig_Error_Syntax('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getFilename());
45
  }
46
  } else {
47
  $capture = true;
48
 
49
  if (count($names) > 1) {
50
- throw new Twig_Error_Syntax('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getFilename());
51
  }
52
 
53
  $stream->expect(Twig_Token::BLOCK_END_TYPE);
41
  $stream->expect(Twig_Token::BLOCK_END_TYPE);
42
 
43
  if (count($names) !== count($values)) {
44
+ throw new Twig_Error_Syntax('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
45
  }
46
  } else {
47
  $capture = true;
48
 
49
  if (count($names) > 1) {
50
+ throw new Twig_Error_Syntax('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
51
  }
52
 
53
  $stream->expect(Twig_Token::BLOCK_END_TYPE);
vendor/twig/twig/lib/Twig/TokenParser/Use.php CHANGED
@@ -31,7 +31,7 @@ class Twig_TokenParser_Use extends Twig_TokenParser
31
  $stream = $this->parser->getStream();
32
 
33
  if (!$template instanceof Twig_Node_Expression_Constant) {
34
- throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getFilename());
35
  }
36
 
37
  $targets = array();
31
  $stream = $this->parser->getStream();
32
 
33
  if (!$template instanceof Twig_Node_Expression_Constant) {
34
+ throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
35
  }
36
 
37
  $targets = array();
vendor/twig/twig/lib/Twig/TokenStream.php CHANGED
@@ -21,16 +21,30 @@ class Twig_TokenStream
21
  protected $current = 0;
22
  protected $filename;
23
 
 
 
24
  /**
25
  * Constructor.
26
  *
27
- * @param array $tokens An array of tokens
28
- * @param string $filename The name of the filename which tokens are associated with
 
29
  */
30
- public function __construct(array $tokens, $filename = null)
31
  {
 
 
 
 
 
 
 
 
 
32
  $this->tokens = $tokens;
33
- $this->filename = $filename;
 
 
34
  }
35
 
36
  /**
@@ -56,7 +70,7 @@ class Twig_TokenStream
56
  public function next()
57
  {
58
  if (!isset($this->tokens[++$this->current])) {
59
- throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->filename);
60
  }
61
 
62
  return $this->tokens[$this->current - 1];
@@ -89,7 +103,7 @@ class Twig_TokenStream
89
  Twig_Token::typeToEnglish($token->getType()), $token->getValue(),
90
  Twig_Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
91
  $line,
92
- $this->filename
93
  );
94
  }
95
  $this->next();
@@ -107,7 +121,7 @@ class Twig_TokenStream
107
  public function look($number = 1)
108
  {
109
  if (!isset($this->tokens[$this->current + $number])) {
110
- throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->filename);
111
  }
112
 
113
  return $this->tokens[$this->current + $number];
@@ -144,12 +158,44 @@ class Twig_TokenStream
144
  }
145
 
146
  /**
147
- * Gets the filename associated with this stream.
148
  *
149
- * @return string
 
 
150
  */
151
  public function getFilename()
152
  {
153
- return $this->filename;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  }
155
  }
21
  protected $current = 0;
22
  protected $filename;
23
 
24
+ private $source;
25
+
26
  /**
27
  * Constructor.
28
  *
29
+ * @param array $tokens An array of tokens
30
+ * @param string|null $name The name of the template which tokens are associated with
31
+ * @param string|null $source The source code associated with the tokens
32
  */
33
+ public function __construct(array $tokens, $name = null, $source = null)
34
  {
35
+ if (!$name instanceof Twig_Source) {
36
+ if (null !== $name || null !== $source) {
37
+ @trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
38
+ }
39
+ $this->source = new Twig_Source($source, $name);
40
+ } else {
41
+ $this->source = $name;
42
+ }
43
+
44
  $this->tokens = $tokens;
45
+
46
+ // deprecated, not used anymore, to be removed in 2.0
47
+ $this->filename = $this->source->getName();
48
  }
49
 
50
  /**
70
  public function next()
71
  {
72
  if (!isset($this->tokens[++$this->current])) {
73
+ throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->source->getName());
74
  }
75
 
76
  return $this->tokens[$this->current - 1];
103
  Twig_Token::typeToEnglish($token->getType()), $token->getValue(),
104
  Twig_Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
105
  $line,
106
+ $this->source->getName()
107
  );
108
  }
109
  $this->next();
121
  public function look($number = 1)
122
  {
123
  if (!isset($this->tokens[$this->current + $number])) {
124
+ throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->source->getName());
125
  }
126
 
127
  return $this->tokens[$this->current + $number];
158
  }
159
 
160
  /**
161
+ * Gets the name associated with this stream (null if not defined).
162
  *
163
+ * @return string|null
164
+ *
165
+ * @deprecated since 1.27 (to be removed in 2.0)
166
  */
167
  public function getFilename()
168
  {
169
+ @trigger_error(sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED);
170
+
171
+ return $this->source->getName();
172
+ }
173
+
174
+ /**
175
+ * Gets the source code associated with this stream.
176
+ *
177
+ * @return string
178
+ *
179
+ * @internal Don't use this as it might be empty depending on the environment configuration
180
+ *
181
+ * @deprecated since 1.27 (to be removed in 2.0)
182
+ */
183
+ public function getSource()
184
+ {
185
+ @trigger_error(sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED);
186
+
187
+ return $this->source->getCode();
188
+ }
189
+
190
+ /**
191
+ * Gets the source associated with this stream.
192
+ *
193
+ * @return Twig_Source
194
+ *
195
+ * @internal
196
+ */
197
+ public function getSourceContext()
198
+ {
199
+ return $this->source;
200
  }
201
  }
vendor/twig/twig/test/Twig/Tests/Cache/FilesystemTest.php CHANGED
@@ -115,7 +115,7 @@ class Twig_Tests_Cache_FilesystemTest extends PHPUnit_Framework_TestCase
115
  // Create root directory.
116
  @mkdir($this->directory, 0777, true);
117
  // Create read-only subdirectory.
118
- @mkdir($this->directory.'/cache' , 0555);
119
  $this->assertTrue(is_dir($this->directory.'/cache'));
120
 
121
  $this->cache->write($key, $content);
115
  // Create root directory.
116
  @mkdir($this->directory, 0777, true);
117
  // Create read-only subdirectory.
118
+ @mkdir($this->directory.'/cache', 0555);
119
  $this->assertTrue(is_dir($this->directory.'/cache'));
120
 
121
  $this->cache->write($key, $content);
vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php CHANGED
@@ -15,6 +15,27 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
15
  {
16
  private $deprecations = array();
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  /**
19
  * @expectedException LogicException
20
  * @expectedExceptionMessage You must set a loader first.
@@ -43,16 +64,21 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
43
  $this->assertEquals('foo\x3Cbr\x2F\x20\x3E foo\x3Cbr\x2F\x20\x3E', $twig->render('js', array('bar' => 'foo<br/ >')));
44
  }
45
 
46
- public function escapingStrategyCallback($filename)
47
  {
48
- return $filename;
49
  }
50
 
51
  public function testGlobals()
52
  {
 
 
 
 
 
53
  // globals can be added after calling getGlobals
54
 
55
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
56
  $twig->addGlobal('foo', 'foo');
57
  $twig->getGlobals();
58
  $twig->addGlobal('foo', 'bar');
@@ -60,7 +86,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
60
  $this->assertEquals('bar', $globals['foo']);
61
 
62
  // globals can be modified after a template has been loaded
63
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
64
  $twig->addGlobal('foo', 'foo');
65
  $twig->getGlobals();
66
  $twig->loadTemplate('index');
@@ -69,7 +95,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
69
  $this->assertEquals('bar', $globals['foo']);
70
 
71
  // globals can be modified after extensions init
72
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
73
  $twig->addGlobal('foo', 'foo');
74
  $twig->getGlobals();
75
  $twig->getFunctions();
@@ -78,7 +104,8 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
78
  $this->assertEquals('bar', $globals['foo']);
79
 
80
  // globals can be modified after extensions and a template has been loaded
81
- $twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{foo}}')));
 
82
  $twig->addGlobal('foo', 'foo');
83
  $twig->getGlobals();
84
  $twig->getFunctions();
@@ -87,7 +114,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
87
  $globals = $twig->getGlobals();
88
  $this->assertEquals('bar', $globals['foo']);
89
 
90
- $twig = new Twig_Environment($loader);
91
  $twig->getGlobals();
92
  $twig->addGlobal('foo', 'bar');
93
  $template = $twig->loadTemplate('index');
@@ -95,7 +122,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
95
 
96
  /* to be uncomment in Twig 2.0
97
  // globals cannot be added after a template has been loaded
98
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
99
  $twig->addGlobal('foo', 'foo');
100
  $twig->getGlobals();
101
  $twig->loadTemplate('index');
@@ -107,7 +134,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
107
  }
108
 
109
  // globals cannot be added after extensions init
110
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
111
  $twig->addGlobal('foo', 'foo');
112
  $twig->getGlobals();
113
  $twig->getFunctions();
@@ -119,7 +146,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
119
  }
120
 
121
  // globals cannot be added after extensions and a template has been loaded
122
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
123
  $twig->addGlobal('foo', 'foo');
124
  $twig->getGlobals();
125
  $twig->getFunctions();
@@ -132,7 +159,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
132
  }
133
 
134
  // test adding globals after a template has been loaded without call to getGlobals
135
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
136
  $twig->loadTemplate('index');
137
  try {
138
  $twig->addGlobal('bar', 'bar');
@@ -143,18 +170,6 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
143
  */
144
  }
145
 
146
- public function testCompileSourceInlinesSource()
147
- {
148
- $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
149
-
150
- $source = "<? */*foo*/ ?>\r\nbar\n";
151
- $expected = "/* <? *//* *foo*//* ?>*/\n/* bar*/\n/* */\n";
152
- $compiled = $twig->compileSource($source, 'index');
153
-
154
- $this->assertContains($expected, $compiled);
155
- $this->assertNotContains('/**', $compiled);
156
- }
157
-
158
  public function testExtensionsAreNotInitializedWhenRenderingACompiledTemplate()
159
  {
160
  $cache = new Twig_Cache_Filesystem($dir = sys_get_temp_dir().'/twig');
@@ -164,7 +179,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
164
  $twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{ foo }}')), $options);
165
 
166
  $key = $cache->generateKey('index', $twig->getTemplateClass('index'));
167
- $cache->write($key, $twig->compileSource('{{ foo }}', 'index'));
168
 
169
  // check that extensions won't be initialized when rendering a template that is already in the cache
170
  $twig = $this
@@ -262,6 +277,38 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
262
  $twig->loadTemplate($templateName);
263
  }
264
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  public function testAddExtension()
266
  {
267
  $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
@@ -275,7 +322,13 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
275
  $this->assertArrayHasKey('foo_binary', $twig->getBinaryOperators());
276
  $this->assertArrayHasKey('foo_global', $twig->getGlobals());
277
  $visitors = $twig->getNodeVisitors();
278
- $this->assertEquals('Twig_Tests_EnvironmentTest_NodeVisitor', get_class($visitors[2]));
 
 
 
 
 
 
279
  }
280
 
281
  /**
@@ -292,7 +345,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
292
  $this->assertArrayHasKey('foo_global', $twig->getGlobals());
293
 
294
  $this->assertCount(1, $this->deprecations);
295
- $this->assertContains('Defining the getGlobals() method in the "environment_test" extension ', $this->deprecations[0]);
296
 
297
  restore_error_handler();
298
  }
@@ -303,7 +356,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
303
  public function testRemoveExtension()
304
  {
305
  $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
306
- $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension());
307
  $twig->removeExtension('environment_test');
308
 
309
  $this->assertFalse(array_key_exists('test', $twig->getTags()));
@@ -318,17 +371,22 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
318
 
319
  public function testAddMockExtension()
320
  {
321
- $extension = $this->getMockBuilder('Twig_ExtensionInterface')->getMock();
322
- $extension->expects($this->once())
323
- ->method('getName')
324
- ->will($this->returnValue('mock'));
 
 
 
 
 
325
 
326
  $loader = new Twig_Loader_Array(array('page' => 'hey'));
327
 
328
  $twig = new Twig_Environment($loader);
329
  $twig->addExtension($extension);
330
 
331
- $this->assertInstanceOf('Twig_ExtensionInterface', $twig->getExtension('mock'));
332
  $this->assertTrue($twig->isTemplateFresh('page', time()));
333
  }
334
 
@@ -354,7 +412,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
354
  $twig->initRuntime();
355
 
356
  $this->assertCount(1, $this->deprecations);
357
- $this->assertContains('Defining the initRuntime() method in the "with_deprecation" extension is deprecated since version 1.23.', $this->deprecations[0]);
358
 
359
  restore_error_handler();
360
  }
@@ -377,8 +435,8 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
377
  $this->deprecations = array();
378
  set_error_handler(array($this, 'handleError'));
379
 
380
- $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension());
381
- $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension());
382
 
383
  $this->assertCount(1, $this->deprecations);
384
  $this->assertContains('The possibility to register the same extension twice', $this->deprecations[0]);
@@ -386,13 +444,41 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
386
  restore_error_handler();
387
  }
388
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  protected function getMockLoader($templateName, $templateContent)
390
  {
391
- $loader = $this->getMockBuilder('Twig_LoaderInterface')->getMock();
 
 
392
  $loader->expects($this->any())
393
- ->method('getSource')
394
  ->with($templateName)
395
- ->will($this->returnValue($templateContent));
396
  $loader->expects($this->any())
397
  ->method('getCacheKey')
398
  ->with($templateName)
@@ -410,11 +496,6 @@ class Twig_Tests_EnvironmentTest_Extension_WithGlobals extends Twig_Extension
410
  'foo_global' => 'foo_global',
411
  );
412
  }
413
-
414
- public function getName()
415
- {
416
- return 'environment_test';
417
- }
418
  }
419
 
420
  class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension implements Twig_Extension_GlobalsInterface
@@ -468,13 +549,31 @@ class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension implements Twi
468
  'foo_global' => 'foo_global',
469
  );
470
  }
 
471
 
 
 
472
  public function getName()
473
  {
474
  return 'environment_test';
475
  }
476
  }
477
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
478
  class Twig_Tests_EnvironmentTest_TokenParser extends Twig_TokenParser
479
  {
480
  public function parse(Twig_Token $token)
@@ -510,21 +609,39 @@ class Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime extends Twi
510
  public function initRuntime(Twig_Environment $env)
511
  {
512
  }
 
513
 
514
- public function getName()
 
 
515
  {
516
- return 'with_deprecation';
517
  }
518
  }
519
 
520
- class Twig_Tests_EnvironmentTest_ExtensionWithoutDeprecationInitRuntime extends Twig_Extension implements Twig_Extension_InitRuntimeInterface
521
  {
522
- public function initRuntime(Twig_Environment $env)
523
  {
 
 
 
 
524
  }
525
 
526
  public function getName()
527
  {
528
- return 'without_deprecation';
 
 
 
 
 
 
 
 
529
  }
530
  }
 
 
 
 
15
  {
16
  private $deprecations = array();
17
 
18
+ /**
19
+ * @group legacy
20
+ */
21
+ public function testLegacyTokenizeSignature()
22
+ {
23
+ $env = new Twig_Environment();
24
+ $stream = $env->tokenize('{{ foo }}', 'foo');
25
+ $this->assertEquals('{{ foo }}', $stream->getSource());
26
+ $this->assertEquals('foo', $stream->getFilename());
27
+ }
28
+
29
+ /**
30
+ * @group legacy
31
+ */
32
+ public function testLegacyCompileSourceSignature()
33
+ {
34
+ $loader = new Twig_Loader_Array(array('foo' => '{{ foo }}'));
35
+ $env = new Twig_Environment($loader);
36
+ $this->assertContains('getTemplateName', $env->compileSource('{{ foo }}', 'foo'));
37
+ }
38
+
39
  /**
40
  * @expectedException LogicException
41
  * @expectedExceptionMessage You must set a loader first.
64
  $this->assertEquals('foo\x3Cbr\x2F\x20\x3E foo\x3Cbr\x2F\x20\x3E', $twig->render('js', array('bar' => 'foo<br/ >')));
65
  }
66
 
67
+ public function escapingStrategyCallback($name)
68
  {
69
+ return $name;
70
  }
71
 
72
  public function testGlobals()
73
  {
74
+ // to be removed in 2.0
75
+ $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
76
+ //$loader = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock();
77
+ $loader->expects($this->any())->method('getSourceContext')->will($this->returnValue(new Twig_Source('', '')));
78
+
79
  // globals can be added after calling getGlobals
80
 
81
+ $twig = new Twig_Environment($loader);
82
  $twig->addGlobal('foo', 'foo');
83
  $twig->getGlobals();
84
  $twig->addGlobal('foo', 'bar');
86
  $this->assertEquals('bar', $globals['foo']);
87
 
88
  // globals can be modified after a template has been loaded
89
+ $twig = new Twig_Environment($loader);
90
  $twig->addGlobal('foo', 'foo');
91
  $twig->getGlobals();
92
  $twig->loadTemplate('index');
95
  $this->assertEquals('bar', $globals['foo']);
96
 
97
  // globals can be modified after extensions init
98
+ $twig = new Twig_Environment($loader);
99
  $twig->addGlobal('foo', 'foo');
100
  $twig->getGlobals();
101
  $twig->getFunctions();
104
  $this->assertEquals('bar', $globals['foo']);
105
 
106
  // globals can be modified after extensions and a template has been loaded
107
+ $arrayLoader = new Twig_Loader_Array(array('index' => '{{foo}}'));
108
+ $twig = new Twig_Environment($arrayLoader);
109
  $twig->addGlobal('foo', 'foo');
110
  $twig->getGlobals();
111
  $twig->getFunctions();
114
  $globals = $twig->getGlobals();
115
  $this->assertEquals('bar', $globals['foo']);
116
 
117
+ $twig = new Twig_Environment($arrayLoader);
118
  $twig->getGlobals();
119
  $twig->addGlobal('foo', 'bar');
120
  $template = $twig->loadTemplate('index');
122
 
123
  /* to be uncomment in Twig 2.0
124
  // globals cannot be added after a template has been loaded
125
+ $twig = new Twig_Environment($loader);
126
  $twig->addGlobal('foo', 'foo');
127
  $twig->getGlobals();
128
  $twig->loadTemplate('index');
134
  }
135
 
136
  // globals cannot be added after extensions init
137
+ $twig = new Twig_Environment($loader);
138
  $twig->addGlobal('foo', 'foo');
139
  $twig->getGlobals();
140
  $twig->getFunctions();
146
  }
147
 
148
  // globals cannot be added after extensions and a template has been loaded
149
+ $twig = new Twig_Environment($loader);
150
  $twig->addGlobal('foo', 'foo');
151
  $twig->getGlobals();
152
  $twig->getFunctions();
159
  }
160
 
161
  // test adding globals after a template has been loaded without call to getGlobals
162
+ $twig = new Twig_Environment($loader);
163
  $twig->loadTemplate('index');
164
  try {
165
  $twig->addGlobal('bar', 'bar');
170
  */
171
  }
172
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  public function testExtensionsAreNotInitializedWhenRenderingACompiledTemplate()
174
  {
175
  $cache = new Twig_Cache_Filesystem($dir = sys_get_temp_dir().'/twig');
179
  $twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{ foo }}')), $options);
180
 
181
  $key = $cache->generateKey('index', $twig->getTemplateClass('index'));
182
+ $cache->write($key, $twig->compileSource(new Twig_Source('{{ foo }}', 'index')));
183
 
184
  // check that extensions won't be initialized when rendering a template that is already in the cache
185
  $twig = $this
277
  $twig->loadTemplate($templateName);
278
  }
279
 
280
+ /**
281
+ * @group legacy
282
+ */
283
+ public function testHasGetExtensionWithDynamicName()
284
+ {
285
+ $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
286
+
287
+ $ext1 = new Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName('ext1');
288
+ $ext2 = new Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName('ext2');
289
+ $twig->addExtension($ext1);
290
+ $twig->addExtension($ext2);
291
+
292
+ $this->assertTrue($twig->hasExtension('ext1'));
293
+ $this->assertTrue($twig->hasExtension('ext2'));
294
+
295
+ $this->assertTrue($twig->hasExtension('Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName'));
296
+
297
+ $this->assertSame($ext1, $twig->getExtension('ext1'));
298
+ $this->assertSame($ext2, $twig->getExtension('ext2'));
299
+ }
300
+
301
+ public function testHasGetExtensionByClassName()
302
+ {
303
+ $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
304
+ $twig->addExtension($ext = new Twig_Tests_EnvironmentTest_Extension());
305
+ $this->assertTrue($twig->hasExtension('Twig_Tests_EnvironmentTest_Extension'));
306
+ $this->assertTrue($twig->hasExtension('\Twig_Tests_EnvironmentTest_Extension'));
307
+
308
+ $this->assertSame($ext, $twig->getExtension('Twig_Tests_EnvironmentTest_Extension'));
309
+ $this->assertSame($ext, $twig->getExtension('\Twig_Tests_EnvironmentTest_Extension'));
310
+ }
311
+
312
  public function testAddExtension()
313
  {
314
  $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
322
  $this->assertArrayHasKey('foo_binary', $twig->getBinaryOperators());
323
  $this->assertArrayHasKey('foo_global', $twig->getGlobals());
324
  $visitors = $twig->getNodeVisitors();
325
+ $found = false;
326
+ foreach ($visitors as $visitor) {
327
+ if ($visitor instanceof Twig_Tests_EnvironmentTest_NodeVisitor) {
328
+ $found = true;
329
+ }
330
+ }
331
+ $this->assertTrue($found);
332
  }
333
 
334
  /**
345
  $this->assertArrayHasKey('foo_global', $twig->getGlobals());
346
 
347
  $this->assertCount(1, $this->deprecations);
348
+ $this->assertContains('Defining the getGlobals() method in the "Twig_Tests_EnvironmentTest_Extension_WithGlobals" extension ', $this->deprecations[0]);
349
 
350
  restore_error_handler();
351
  }
356
  public function testRemoveExtension()
357
  {
358
  $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
359
+ $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName());
360
  $twig->removeExtension('environment_test');
361
 
362
  $this->assertFalse(array_key_exists('test', $twig->getTags()));
371
 
372
  public function testAddMockExtension()
373
  {
374
+ // should be replaced by the following in 2.0 (this current code is just to avoid a dep notice)
375
+ // $extension = $this->getMockBuilder('Twig_Extension')->getMock();
376
+ $extension = eval(<<<EOF
377
+ class Twig_Tests_EnvironmentTest_ExtensionInEval extends Twig_Extension
378
+ {
379
+ }
380
+ EOF
381
+ );
382
+ $extension = new Twig_Tests_EnvironmentTest_ExtensionInEval();
383
 
384
  $loader = new Twig_Loader_Array(array('page' => 'hey'));
385
 
386
  $twig = new Twig_Environment($loader);
387
  $twig->addExtension($extension);
388
 
389
+ $this->assertInstanceOf('Twig_ExtensionInterface', $twig->getExtension(get_class($extension)));
390
  $this->assertTrue($twig->isTemplateFresh('page', time()));
391
  }
392
 
412
  $twig->initRuntime();
413
 
414
  $this->assertCount(1, $this->deprecations);
415
+ $this->assertContains('Defining the initRuntime() method in the "Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime" extension is deprecated since version 1.23.', $this->deprecations[0]);
416
 
417
  restore_error_handler();
418
  }
435
  $this->deprecations = array();
436
  set_error_handler(array($this, 'handleError'));
437
 
438
+ $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName());
439
+ $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName());
440
 
441
  $this->assertCount(1, $this->deprecations);
442
  $this->assertContains('The possibility to register the same extension twice', $this->deprecations[0]);
444
  restore_error_handler();
445
  }
446
 
447
+ public function testAddRuntimeLoader()
448
+ {
449
+ $runtimeLoader = $this->getMockBuilder('Twig_RuntimeLoaderInterface')->getMock();
450
+ $runtimeLoader->expects($this->any())->method('load')->will($this->returnValue(new Twig_Tests_EnvironmentTest_Runtime()));
451
+
452
+ $loader = new Twig_Loader_Array(array(
453
+ 'func_array' => '{{ from_runtime_array("foo") }}',
454
+ 'func_array_default' => '{{ from_runtime_array() }}',
455
+ 'func_array_named_args' => '{{ from_runtime_array(name="foo") }}',
456
+ 'func_string' => '{{ from_runtime_string("foo") }}',
457
+ 'func_string_default' => '{{ from_runtime_string() }}',
458
+ 'func_string_named_args' => '{{ from_runtime_string(name="foo") }}',
459
+ ));
460
+
461
+ $twig = new Twig_Environment($loader);
462
+ $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithoutRuntime());
463
+ $twig->addRuntimeLoader($runtimeLoader);
464
+
465
+ $this->assertEquals('foo', $twig->render('func_array'));
466
+ $this->assertEquals('bar', $twig->render('func_array_default'));
467
+ $this->assertEquals('foo', $twig->render('func_array_named_args'));
468
+ $this->assertEquals('foo', $twig->render('func_string'));
469
+ $this->assertEquals('bar', $twig->render('func_string_default'));
470
+ $this->assertEquals('foo', $twig->render('func_string_named_args'));
471
+ }
472
+
473
  protected function getMockLoader($templateName, $templateContent)
474
  {
475
+ // to be removed in 2.0
476
+ $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
477
+ //$loader = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock();
478
  $loader->expects($this->any())
479
+ ->method('getSourceContext')
480
  ->with($templateName)
481
+ ->will($this->returnValue(new Twig_Source($templateContent, $templateName)));
482
  $loader->expects($this->any())
483
  ->method('getCacheKey')
484
  ->with($templateName)
496
  'foo_global' => 'foo_global',
497
  );
498
  }
 
 
 
 
 
499
  }
500
 
501
  class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension implements Twig_Extension_GlobalsInterface
549
  'foo_global' => 'foo_global',
550
  );
551
  }
552
+ }
553
 
554
+ class Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName extends Twig_Extension
555
+ {
556
  public function getName()
557
  {
558
  return 'environment_test';
559
  }
560
  }
561
 
562
+ class Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName extends Twig_Extension
563
+ {
564
+ private $name;
565
+
566
+ public function __construct($name)
567
+ {
568
+ $this->name = $name;
569
+ }
570
+
571
+ public function getName()
572
+ {
573
+ return $this->name;
574
+ }
575
+ }
576
+
577
  class Twig_Tests_EnvironmentTest_TokenParser extends Twig_TokenParser
578
  {
579
  public function parse(Twig_Token $token)
609
  public function initRuntime(Twig_Environment $env)
610
  {
611
  }
612
+ }
613
 
614
+ class Twig_Tests_EnvironmentTest_ExtensionWithoutDeprecationInitRuntime extends Twig_Extension implements Twig_Extension_InitRuntimeInterface
615
+ {
616
+ public function initRuntime(Twig_Environment $env)
617
  {
 
618
  }
619
  }
620
 
621
+ class Twig_Tests_EnvironmentTest_ExtensionWithoutRuntime extends Twig_Extension
622
  {
623
+ public function getFunctions()
624
  {
625
+ return array(
626
+ new Twig_SimpleFunction('from_runtime_array', array('Twig_Tests_EnvironmentTest_Runtime', 'fromRuntime')),
627
+ new Twig_SimpleFunction('from_runtime_string', 'Twig_Tests_EnvironmentTest_Runtime::fromRuntime'),
628
+ );
629
  }
630
 
631
  public function getName()
632
  {
633
+ return 'from_runtime';
634
+ }
635
+ }
636
+
637
+ class Twig_Tests_EnvironmentTest_Runtime
638
+ {
639
+ public function fromRuntime($name = 'bar')
640
+ {
641
+ return $name;
642
  }
643
  }
644
+
645
+ interface Twig_EnvironmentTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface
646
+ {
647
+ }
vendor/twig/twig/test/Twig/Tests/ErrorTest.php CHANGED
@@ -14,7 +14,7 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
14
  public function testErrorWithObjectFilename()
15
  {
16
  $error = new Twig_Error('foo');
17
- $error->setTemplateFile(new SplFileInfo(__FILE__));
18
 
19
  $this->assertContains('test'.DIRECTORY_SEPARATOR.'Twig'.DIRECTORY_SEPARATOR.'Tests'.DIRECTORY_SEPARATOR.'ErrorTest.php', $error->getMessage());
20
  }
@@ -22,7 +22,7 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
22
  public function testErrorWithArrayFilename()
23
  {
24
  $error = new Twig_Error('foo');
25
- $error->setTemplateFile(array('foo' => 'bar'));
26
 
27
  $this->assertEquals('foo in {"foo":"bar"}', $error->getMessage());
28
  }
@@ -38,9 +38,9 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
38
 
39
  $this->fail();
40
  } catch (Twig_Error_Runtime $e) {
41
- $this->assertEquals('Variable "foo" does not exist in "index.html" at line 3', $e->getMessage());
42
  $this->assertEquals(3, $e->getTemplateLine());
43
- $this->assertEquals('index.html', $e->getTemplateFile());
44
  }
45
 
46
  try {
@@ -50,7 +50,7 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
50
  } catch (Twig_Error_Runtime $e) {
51
  $this->assertEquals('An exception has been thrown during the rendering of a template ("Runtime error...") in "index.html" at line 3.', $e->getMessage());
52
  $this->assertEquals(3, $e->getTemplateLine());
53
- $this->assertEquals('index.html', $e->getTemplateFile());
54
  }
55
  }
56
 
@@ -69,9 +69,9 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
69
 
70
  $this->fail();
71
  } catch (Twig_Error_Runtime $e) {
72
- $this->assertEquals(sprintf('Variable "foo" does not exist in "%s" at line %d', $name, $line), $e->getMessage());
73
  $this->assertEquals($line, $e->getTemplateLine());
74
- $this->assertEquals($name, $e->getTemplateFile());
75
  }
76
 
77
  try {
@@ -81,7 +81,7 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
81
  } catch (Twig_Error_Runtime $e) {
82
  $this->assertEquals(sprintf('An exception has been thrown during the rendering of a template ("Runtime error...") in "%s" at line %d.', $name, $line), $e->getMessage());
83
  $this->assertEquals($line, $e->getTemplateLine());
84
- $this->assertEquals($name, $e->getTemplateFile());
85
  }
86
  }
87
 
14
  public function testErrorWithObjectFilename()
15
  {
16
  $error = new Twig_Error('foo');
17
+ $error->setTemplateName(new SplFileInfo(__FILE__));
18
 
19
  $this->assertContains('test'.DIRECTORY_SEPARATOR.'Twig'.DIRECTORY_SEPARATOR.'Tests'.DIRECTORY_SEPARATOR.'ErrorTest.php', $error->getMessage());
20
  }
22
  public function testErrorWithArrayFilename()
23
  {
24
  $error = new Twig_Error('foo');
25
+ $error->setTemplateName(array('foo' => 'bar'));
26
 
27
  $this->assertEquals('foo in {"foo":"bar"}', $error->getMessage());
28
  }
38
 
39
  $this->fail();
40
  } catch (Twig_Error_Runtime $e) {
41
+ $this->assertEquals('Variable "foo" does not exist in "index.html" at line 3.', $e->getMessage());
42
  $this->assertEquals(3, $e->getTemplateLine());
43
+ $this->assertEquals('index.html', $e->getTemplateName());
44
  }
45
 
46
  try {
50
  } catch (Twig_Error_Runtime $e) {
51
  $this->assertEquals('An exception has been thrown during the rendering of a template ("Runtime error...") in "index.html" at line 3.', $e->getMessage());
52
  $this->assertEquals(3, $e->getTemplateLine());
53
+ $this->assertEquals('index.html', $e->getTemplateName());
54
  }
55
  }
56
 
69
 
70
  $this->fail();
71
  } catch (Twig_Error_Runtime $e) {
72
+ $this->assertEquals(sprintf('Variable "foo" does not exist in "%s" at line %d.', $name, $line), $e->getMessage());
73
  $this->assertEquals($line, $e->getTemplateLine());
74
+ $this->assertEquals($name, $e->getTemplateName());
75
  }
76
 
77
  try {
81
  } catch (Twig_Error_Runtime $e) {
82
  $this->assertEquals(sprintf('An exception has been thrown during the rendering of a template ("Runtime error...") in "%s" at line %d.', $name, $line), $e->getMessage());
83
  $this->assertEquals($line, $e->getTemplateLine());
84
+ $this->assertEquals($name, $e->getTemplateName());
85
  }
86
  }
87
 
vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php CHANGED
@@ -20,7 +20,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
20
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
21
  $parser = new Twig_Parser($env);
22
 
23
- $parser->parse($env->tokenize($template, 'index'));
24
  }
25
 
26
  public function getFailingTestsForAssignment()
@@ -47,7 +47,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
47
  public function testArrayExpression($template, $expected)
48
  {
49
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
50
- $stream = $env->tokenize($template, 'index');
51
  $parser = new Twig_Parser($env);
52
 
53
  $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
@@ -62,7 +62,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
62
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
63
  $parser = new Twig_Parser($env);
64
 
65
- $parser->parse($env->tokenize($template, 'index'));
66
  }
67
 
68
  public function getFailingTestsForArray()
@@ -155,7 +155,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
155
  public function testStringExpressionDoesNotConcatenateTwoConsecutiveStrings()
156
  {
157
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
158
- $stream = $env->tokenize('{{ "a" "b" }}', 'index');
159
  $parser = new Twig_Parser($env);
160
 
161
  $parser->parse($stream);
@@ -167,7 +167,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
167
  public function testStringExpression($template, $expected)
168
  {
169
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
170
- $stream = $env->tokenize($template, 'index');
171
  $parser = new Twig_Parser($env);
172
 
173
  $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
@@ -228,7 +228,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
228
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
229
  $parser = new Twig_Parser($env);
230
 
231
- $parser->parse($env->tokenize('{{ foo.bar(name="Foo") }}', 'index'));
232
  }
233
 
234
  /**
@@ -239,7 +239,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
239
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
240
  $parser = new Twig_Parser($env);
241
 
242
- $parser->parse($env->tokenize('{% from _self import foo %}{% macro foo() %}{% endmacro %}{{ foo(name="Foo") }}', 'index'));
243
  }
244
 
245
  /**
@@ -251,7 +251,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
251
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
252
  $parser = new Twig_Parser($env);
253
 
254
- $parser->parse($env->tokenize('{% macro foo("a") %}{% endmacro %}', 'index'));
255
  }
256
 
257
  /**
@@ -264,7 +264,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
264
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
265
  $parser = new Twig_Parser($env);
266
 
267
- $parser->parse($env->tokenize($template, 'index'));
268
  }
269
 
270
  public function getMacroDefinitionDoesNotSupportNonConstantDefaultValues()
@@ -283,7 +283,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
283
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
284
  $parser = new Twig_Parser($env);
285
 
286
- $parser->parse($env->tokenize($template, 'index'));
287
  }
288
 
289
  public function getMacroDefinitionSupportsConstantDefaultValues()
@@ -308,7 +308,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
308
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
309
  $parser = new Twig_Parser($env);
310
 
311
- $parser->parse($env->tokenize('{{ cycl() }}', 'index'));
312
  }
313
 
314
  /**
@@ -320,7 +320,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
320
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
321
  $parser = new Twig_Parser($env);
322
 
323
- $parser->parse($env->tokenize('{{ foobar() }}', 'index'));
324
  }
325
 
326
  /**
@@ -332,7 +332,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
332
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
333
  $parser = new Twig_Parser($env);
334
 
335
- $parser->parse($env->tokenize('{{ 1|lowe }}', 'index'));
336
  }
337
 
338
  /**
@@ -344,7 +344,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
344
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
345
  $parser = new Twig_Parser($env);
346
 
347
- $parser->parse($env->tokenize('{{ 1|foobar }}', 'index'));
348
  }
349
 
350
  /**
@@ -355,8 +355,8 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
355
  {
356
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
357
  $parser = new Twig_Parser($env);
358
-
359
- $parser->parse($env->tokenize('{{ 1 is nul }}', 'index'));
360
  }
361
 
362
  /**
@@ -368,6 +368,6 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
368
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
369
  $parser = new Twig_Parser($env);
370
 
371
- $parser->parse($env->tokenize('{{ 1 is foobar }}', 'index'));
372
  }
373
  }
20
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
21
  $parser = new Twig_Parser($env);
22
 
23
+ $parser->parse($env->tokenize(new Twig_Source($template, 'index')));
24
  }
25
 
26
  public function getFailingTestsForAssignment()
47
  public function testArrayExpression($template, $expected)
48
  {
49
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
50
+ $stream = $env->tokenize(new Twig_Source($template, ''));
51
  $parser = new Twig_Parser($env);
52
 
53
  $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
62
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
63
  $parser = new Twig_Parser($env);
64
 
65
+ $parser->parse($env->tokenize(new Twig_Source($template, 'index')));
66
  }
67
 
68
  public function getFailingTestsForArray()
155
  public function testStringExpressionDoesNotConcatenateTwoConsecutiveStrings()
156
  {
157
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
158
+ $stream = $env->tokenize(new Twig_Source('{{ "a" "b" }}', 'index'));
159
  $parser = new Twig_Parser($env);
160
 
161
  $parser->parse($stream);
167
  public function testStringExpression($template, $expected)
168
  {
169
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
170
+ $stream = $env->tokenize(new Twig_Source($template, ''));
171
  $parser = new Twig_Parser($env);
172
 
173
  $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
228
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
229
  $parser = new Twig_Parser($env);
230
 
231
+ $parser->parse($env->tokenize(new Twig_Source('{{ foo.bar(name="Foo") }}', 'index')));
232
  }
233
 
234
  /**
239
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
240
  $parser = new Twig_Parser($env);
241
 
242
+ $parser->parse($env->tokenize(new Twig_Source('{% from _self import foo %}{% macro foo() %}{% endmacro %}{{ foo(name="Foo") }}', 'index')));
243
  }
244
 
245
  /**
251
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
252
  $parser = new Twig_Parser($env);
253
 
254
+ $parser->parse($env->tokenize(new Twig_Source('{% macro foo("a") %}{% endmacro %}', 'index')));
255
  }
256
 
257
  /**
264
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
265
  $parser = new Twig_Parser($env);
266
 
267
+ $parser->parse($env->tokenize(new Twig_Source($template, 'index')));
268
  }
269
 
270
  public function getMacroDefinitionDoesNotSupportNonConstantDefaultValues()
283
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
284
  $parser = new Twig_Parser($env);
285
 
286
+ $parser->parse($env->tokenize(new Twig_Source($template, 'index')));
287
  }
288
 
289
  public function getMacroDefinitionSupportsConstantDefaultValues()
308
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
309
  $parser = new Twig_Parser($env);
310
 
311
+ $parser->parse($env->tokenize(new Twig_Source('{{ cycl() }}', 'index')));
312
  }
313
 
314
  /**
320
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
321
  $parser = new Twig_Parser($env);
322
 
323
+ $parser->parse($env->tokenize(new Twig_Source('{{ foobar() }}', 'index')));
324
  }
325
 
326
  /**
332
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
333
  $parser = new Twig_Parser($env);
334
 
335
+ $parser->parse($env->tokenize(new Twig_Source('{{ 1|lowe }}', 'index')));
336
  }
337
 
338
  /**
344
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
345
  $parser = new Twig_Parser($env);
346
 
347
+ $parser->parse($env->tokenize(new Twig_Source('{{ 1|foobar }}', 'index')));
348
  }
349
 
350
  /**
355
  {
356
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
357
  $parser = new Twig_Parser($env);
358
+ $stream = $env->tokenize(new Twig_Source('{{ 1 is nul }}', 'index'));
359
+ $parser->parse($stream);
360
  }
361
 
362
  /**
368
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
369
  $parser = new Twig_Parser($env);
370
 
371
+ $parser->parse($env->tokenize(new Twig_Source('{{ 1 is foobar }}', 'index')));
372
  }
373
  }
vendor/twig/twig/test/Twig/Tests/Extension/CoreTest.php CHANGED
@@ -118,7 +118,7 @@ class Twig_Tests_Extension_CoreTest extends PHPUnit_Framework_TestCase
118
  public function testCustomEscaper()
119
  {
120
  $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
121
- $twig->getExtension('core')->setEscaper('foo', 'foo_escaper_for_test');
122
 
123
  $this->assertEquals('fooUTF-8', twig_escape_filter($twig, 'foo', 'foo'));
124
  $this->assertEquals('UTF-8', twig_escape_filter($twig, null, 'foo'));
118
  public function testCustomEscaper()
119
  {
120
  $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
121
+ $twig->getExtension('Twig_Extension_Core')->setEscaper('foo', 'foo_escaper_for_test');
122
 
123
  $this->assertEquals('fooUTF-8', twig_escape_filter($twig, 'foo', 'foo'));
124
  $this->assertEquals('UTF-8', twig_escape_filter($twig, null, 'foo'));
vendor/twig/twig/test/Twig/Tests/Extension/SandboxTest.php CHANGED
@@ -51,83 +51,146 @@ class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase
51
  {
52
  $twig = $this->getEnvironment(false, array(), self::$templates);
53
  $this->assertEquals('FOO', $twig->loadTemplate('1_basic')->render(self::$params), 'Sandbox does nothing if it is disabled globally');
 
54
 
 
 
55
  $twig = $this->getEnvironment(true, array(), self::$templates);
56
  try {
57
  $twig->loadTemplate('1_basic1')->render(self::$params);
58
  $this->fail('Sandbox throws a SecurityError exception if an unallowed method is called');
59
  } catch (Twig_Sandbox_SecurityError $e) {
 
 
 
60
  }
 
61
 
 
 
62
  $twig = $this->getEnvironment(true, array(), self::$templates);
63
  try {
64
  $twig->loadTemplate('1_basic2')->render(self::$params);
65
  $this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called');
66
  } catch (Twig_Sandbox_SecurityError $e) {
 
 
67
  }
 
68
 
 
 
69
  $twig = $this->getEnvironment(true, array(), self::$templates);
70
  try {
71
  $twig->loadTemplate('1_basic3')->render(self::$params);
72
  $this->fail('Sandbox throws a SecurityError exception if an unallowed tag is used in the template');
73
  } catch (Twig_Sandbox_SecurityError $e) {
 
 
74
  }
 
75
 
 
 
76
  $twig = $this->getEnvironment(true, array(), self::$templates);
77
  try {
78
  $twig->loadTemplate('1_basic4')->render(self::$params);
79
  $this->fail('Sandbox throws a SecurityError exception if an unallowed property is called in the template');
80
  } catch (Twig_Sandbox_SecurityError $e) {
 
 
 
81
  }
 
82
 
 
 
83
  $twig = $this->getEnvironment(true, array(), self::$templates);
84
  try {
85
  $twig->loadTemplate('1_basic5')->render(self::$params);
86
  $this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template');
87
  } catch (Twig_Sandbox_SecurityError $e) {
 
 
 
88
  }
 
89
 
 
 
90
  $twig = $this->getEnvironment(true, array(), self::$templates);
91
  try {
92
  $twig->loadTemplate('1_basic6')->render(self::$params);
93
  $this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template');
94
  } catch (Twig_Sandbox_SecurityError $e) {
 
 
 
95
  }
 
96
 
 
 
97
  $twig = $this->getEnvironment(true, array(), self::$templates);
98
  try {
99
  $twig->loadTemplate('1_basic7')->render(self::$params);
100
  $this->fail('Sandbox throws a SecurityError exception if an unallowed function is called in the template');
101
  } catch (Twig_Sandbox_SecurityError $e) {
 
 
102
  }
 
103
 
 
 
104
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => 'foo'));
105
  FooObject::reset();
106
  $this->assertEquals('foo', $twig->loadTemplate('1_basic1')->render(self::$params), 'Sandbox allow some methods');
107
  $this->assertEquals(1, FooObject::$called['foo'], 'Sandbox only calls method once');
 
108
 
 
 
109
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => '__toString'));
110
  FooObject::reset();
111
  $this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allow some methods');
112
  $this->assertEquals(1, FooObject::$called['__toString'], 'Sandbox only calls method once');
 
113
 
 
 
114
  $twig = $this->getEnvironment(false, array(), self::$templates);
115
  FooObject::reset();
116
  $this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allows __toString when sandbox disabled');
117
  $this->assertEquals(1, FooObject::$called['__toString'], 'Sandbox only calls method once');
 
118
 
 
 
119
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array('upper'));
120
  $this->assertEquals('FABIEN', $twig->loadTemplate('1_basic2')->render(self::$params), 'Sandbox allow some filters');
 
121
 
 
 
122
  $twig = $this->getEnvironment(true, array(), self::$templates, array('if'));
123
  $this->assertEquals('foo', $twig->loadTemplate('1_basic3')->render(self::$params), 'Sandbox allow some tags');
 
124
 
 
 
125
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array('FooObject' => 'bar'));
126
  $this->assertEquals('bar', $twig->loadTemplate('1_basic4')->render(self::$params), 'Sandbox allow some properties');
 
127
 
 
 
128
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array(), array('cycle'));
129
  $this->assertEquals('bar', $twig->loadTemplate('1_basic7')->render(self::$params), 'Sandbox allow some functions');
 
130
 
 
 
131
  foreach (array('getfoobar', 'getFoobar', 'getFooBar') as $name) {
132
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => $name));
133
  FooObject::reset();
@@ -158,6 +221,8 @@ class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase
158
  $twig->loadTemplate('3_basic')->render(self::$params);
159
  $this->fail('Sandbox throws a SecurityError exception when the included file is sandboxed');
160
  } catch (Twig_Sandbox_SecurityError $e) {
 
 
161
  }
162
  }
163
 
51
  {
52
  $twig = $this->getEnvironment(false, array(), self::$templates);
53
  $this->assertEquals('FOO', $twig->loadTemplate('1_basic')->render(self::$params), 'Sandbox does nothing if it is disabled globally');
54
+ }
55
 
56
+ public function testSandboxUnallowedMethodAccessor()
57
+ {
58
  $twig = $this->getEnvironment(true, array(), self::$templates);
59
  try {
60
  $twig->loadTemplate('1_basic1')->render(self::$params);
61
  $this->fail('Sandbox throws a SecurityError exception if an unallowed method is called');
62
  } catch (Twig_Sandbox_SecurityError $e) {
63
+ $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedMethodError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedMethodError');
64
+ $this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class');
65
+ $this->assertEquals('foo', $e->getMethodName(), 'Exception should be raised on the "foo" method');
66
  }
67
+ }
68
 
69
+ public function testSandboxUnallowedFilter()
70
+ {
71
  $twig = $this->getEnvironment(true, array(), self::$templates);
72
  try {
73
  $twig->loadTemplate('1_basic2')->render(self::$params);
74
  $this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called');
75
  } catch (Twig_Sandbox_SecurityError $e) {
76
+ $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedFilterError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedFilterError');
77
+ $this->assertEquals('upper', $e->getFilterName(), 'Exception should be raised on the "upper" filter');
78
  }
79
+ }
80
 
81
+ public function testSandboxUnallowedTag()
82
+ {
83
  $twig = $this->getEnvironment(true, array(), self::$templates);
84
  try {
85
  $twig->loadTemplate('1_basic3')->render(self::$params);
86
  $this->fail('Sandbox throws a SecurityError exception if an unallowed tag is used in the template');
87
  } catch (Twig_Sandbox_SecurityError $e) {
88
+ $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedTagError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedTagError');
89
+ $this->assertEquals('if', $e->getTagName(), 'Exception should be raised on the "if" tag');
90
  }
91
+ }
92
 
93
+ public function testSandboxUnallowedProperty()
94
+ {
95
  $twig = $this->getEnvironment(true, array(), self::$templates);
96
  try {
97
  $twig->loadTemplate('1_basic4')->render(self::$params);
98
  $this->fail('Sandbox throws a SecurityError exception if an unallowed property is called in the template');
99
  } catch (Twig_Sandbox_SecurityError $e) {
100
+ $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedPropertyError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedPropertyError');
101
+ $this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class');
102
+ $this->assertEquals('bar', $e->getPropertyName(), 'Exception should be raised on the "bar" property');
103
  }
104
+ }
105
 
106
+ public function testSandboxUnallowedToString()
107
+ {
108
  $twig = $this->getEnvironment(true, array(), self::$templates);
109
  try {
110
  $twig->loadTemplate('1_basic5')->render(self::$params);
111
  $this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template');
112
  } catch (Twig_Sandbox_SecurityError $e) {
113
+ $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedMethodError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedMethodError');
114
+ $this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class');
115
+ $this->assertEquals('__tostring', $e->getMethodName(), 'Exception should be raised on the "__toString" method');
116
  }
117
+ }
118
 
119
+ public function testSandboxUnallowedToStringArray()
120
+ {
121
  $twig = $this->getEnvironment(true, array(), self::$templates);
122
  try {
123
  $twig->loadTemplate('1_basic6')->render(self::$params);
124
  $this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template');
125
  } catch (Twig_Sandbox_SecurityError $e) {
126
+ $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedMethodError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedMethodError');
127
+ $this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class');
128
+ $this->assertEquals('__tostring', $e->getMethodName(), 'Exception should be raised on the "__toString" method');
129
  }
130
+ }
131
 
132
+ public function testSandboxUnallowedFunction()
133
+ {
134
  $twig = $this->getEnvironment(true, array(), self::$templates);
135
  try {
136
  $twig->loadTemplate('1_basic7')->render(self::$params);
137
  $this->fail('Sandbox throws a SecurityError exception if an unallowed function is called in the template');
138
  } catch (Twig_Sandbox_SecurityError $e) {
139
+ $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedFunctionError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedFunctionError');
140
+ $this->assertEquals('cycle', $e->getFunctionName(), 'Exception should be raised on the "cycle" function');
141
  }
142
+ }
143
 
144
+ public function testSandboxAllowMethodFoo()
145
+ {
146
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => 'foo'));
147
  FooObject::reset();
148
  $this->assertEquals('foo', $twig->loadTemplate('1_basic1')->render(self::$params), 'Sandbox allow some methods');
149
  $this->assertEquals(1, FooObject::$called['foo'], 'Sandbox only calls method once');
150
+ }
151
 
152
+ public function testSandboxAllowMethodToString()
153
+ {
154
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => '__toString'));
155
  FooObject::reset();
156
  $this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allow some methods');
157
  $this->assertEquals(1, FooObject::$called['__toString'], 'Sandbox only calls method once');
158
+ }
159
 
160
+ public function testSandboxAllowMethodToStringDisabled()
161
+ {
162
  $twig = $this->getEnvironment(false, array(), self::$templates);
163
  FooObject::reset();
164
  $this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allows __toString when sandbox disabled');
165
  $this->assertEquals(1, FooObject::$called['__toString'], 'Sandbox only calls method once');
166
+ }
167
 
168
+ public function testSandboxAllowFilter()
169
+ {
170
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array('upper'));
171
  $this->assertEquals('FABIEN', $twig->loadTemplate('1_basic2')->render(self::$params), 'Sandbox allow some filters');
172
+ }
173
 
174
+ public function testSandboxAllowTag()
175
+ {
176
  $twig = $this->getEnvironment(true, array(), self::$templates, array('if'));
177
  $this->assertEquals('foo', $twig->loadTemplate('1_basic3')->render(self::$params), 'Sandbox allow some tags');
178
+ }
179
 
180
+ public function testSandboxAllowProperty()
181
+ {
182
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array('FooObject' => 'bar'));
183
  $this->assertEquals('bar', $twig->loadTemplate('1_basic4')->render(self::$params), 'Sandbox allow some properties');
184
+ }
185
 
186
+ public function testSandboxAllowFunction()
187
+ {
188
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array(), array('cycle'));
189
  $this->assertEquals('bar', $twig->loadTemplate('1_basic7')->render(self::$params), 'Sandbox allow some functions');
190
+ }
191
 
192
+ public function testSandboxAllowFunctionsCaseInsensitive()
193
+ {
194
  foreach (array('getfoobar', 'getFoobar', 'getFooBar') as $name) {
195
  $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => $name));
196
  FooObject::reset();
221
  $twig->loadTemplate('3_basic')->render(self::$params);
222
  $this->fail('Sandbox throws a SecurityError exception when the included file is sandboxed');
223
  } catch (Twig_Sandbox_SecurityError $e) {
224
+ $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedTagError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedTagError');
225
+ $this->assertEquals('sandbox', $e->getTagName());
226
  }
227
  }
228
 
vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/block.test CHANGED
@@ -16,6 +16,6 @@ blocks and autoescape
16
  --DATA--
17
  return array('br' => '<br />')
18
  --CONFIG--
19
- return array('autoescape' => 'filename')
20
  --EXPECT--
21
  &lt;br /&gt;
16
  --DATA--
17
  return array('br' => '<br />')
18
  --CONFIG--
19
+ return array('autoescape' => 'name')
20
  --EXPECT--
21
  &lt;br /&gt;
vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/name.test ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ "name" autoescape strategy
3
+ --TEMPLATE--
4
+ {{ br -}}
5
+ {{ include('index.html.twig') -}}
6
+ {{ include('index.txt.twig') -}}
7
+ --TEMPLATE(index.html.twig)--
8
+ {{ br -}}
9
+ --TEMPLATE(index.txt.twig)--
10
+ {{ br -}}
11
+ --DATA--
12
+ return array('br' => '<br />')
13
+ --CONFIG--
14
+ return array('autoescape' => 'name')
15
+ --EXPECT--
16
+ &lt;br /&gt;
17
+ &lt;br /&gt;
18
+ <br />
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/child_contents_outside_blocks.test ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ Exception for child templates defining contents outside blocks defined by parent
3
+ --TEMPLATE--
4
+ {% extends 'base.twig' %}
5
+
6
+ Content outside a block.
7
+
8
+ {% block sidebar %}
9
+ Content inside a block.
10
+ {% endblock %}
11
+ --TEMPLATE(base.twig)--
12
+ {% block sidebar %}
13
+ {% endblock %}
14
+ --EXCEPTION--
15
+ Twig_Error_Syntax: A template that extends another one cannot include contents outside Twig blocks. Did you forget to put the contents inside a {% block %} tag in "index.twig" at line 3?
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable.test CHANGED
@@ -15,4 +15,4 @@ Exception for multiline array with undefined variable
15
  --DATA--
16
  return array('foobar' => 'foobar')
17
  --EXCEPTION--
18
- Twig_Error_Runtime: Variable "foo2" does not exist in "index.twig" at line 11
15
  --DATA--
16
  return array('foobar' => 'foobar')
17
  --EXCEPTION--
18
+ Twig_Error_Runtime: Variable "foo2" does not exist in "index.twig" at line 11.
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable_again.test CHANGED
@@ -15,4 +15,4 @@ Exception for multiline array with undefined variable
15
  --DATA--
16
  return array()
17
  --EXCEPTION--
18
- Twig_Error_Runtime: Variable "foobar" does not exist in "index.twig" at line 7
15
  --DATA--
16
  return array()
17
  --EXCEPTION--
18
+ Twig_Error_Runtime: Variable "foobar" does not exist in "index.twig" at line 7.
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_undefined_variable.test CHANGED
@@ -9,4 +9,4 @@ Foo
9
  --DATA--
10
  return array()
11
  --EXCEPTION--
12
- Twig_Error_Runtime: Variable "with_context" does not exist in "index.twig" at line 3
9
  --DATA--
10
  return array()
11
  --EXCEPTION--
12
+ Twig_Error_Runtime: Variable "with_context" does not exist in "index.twig" at line 3.
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_tag_with_undefined_variable.test CHANGED
@@ -9,4 +9,4 @@ Foo
9
  --DATA--
10
  return array()
11
  --EXCEPTION--
12
- Twig_Error_Runtime: Variable "vars" does not exist in "index.twig" at line 3
9
  --DATA--
10
  return array()
11
  --EXCEPTION--
12
+ Twig_Error_Runtime: Variable "vars" does not exist in "index.twig" at line 3.
vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/magic_call.test CHANGED
@@ -6,21 +6,21 @@ Twig supports __call() for attributes
6
  --DATA--
7
  class TestClassForMagicCallAttributes
8
  {
9
- public function getBar()
10
- {
11
- return 'bar_from_getbar';
12
- }
13
-
14
- public function __call($method, $arguments)
15
- {
16
- if ('foo' === $method)
17
  {
18
- return 'foo_from_call';
19
  }
20
 
21
- return false;
22
- }
 
 
 
 
 
 
23
  }
 
24
  return array('foo' => new TestClassForMagicCallAttributes())
25
  --EXPECT--
26
  foo_from_call
6
  --DATA--
7
  class TestClassForMagicCallAttributes
8
  {
9
+ public function getBar()
 
 
 
 
 
 
 
10
  {
11
+ return 'bar_from_getbar';
12
  }
13
 
14
+ public function __call($method, $arguments)
15
+ {
16
+ if ('foo' === $method) {
17
+ return 'foo_from_call';
18
+ }
19
+
20
+ return false;
21
+ }
22
  }
23
+
24
  return array('foo' => new TestClassForMagicCallAttributes())
25
  --EXPECT--
26
  foo_from_call
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format.test CHANGED
@@ -5,7 +5,7 @@
5
  {{ date1|date('d/m/Y') }}
6
  --DATA--
7
  date_default_timezone_set('UTC');
8
- $twig->getExtension('core')->setDateFormat('Y-m-d', '%d days %h hours');
9
  return array(
10
  'date1' => mktime(13, 45, 0, 10, 4, 2010),
11
  )
5
  {{ date1|date('d/m/Y') }}
6
  --DATA--
7
  date_default_timezone_set('UTC');
8
+ $twig->getExtension('Twig_Extension_Core')->setDateFormat('Y-m-d', '%d days %h hours');
9
  return array(
10
  'date1' => mktime(13, 45, 0, 10, 4, 2010),
11
  )
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format_interval.test CHANGED
@@ -7,7 +7,7 @@ version_compare(phpversion(), '5.3.0', '>=')
7
  {{ date2|date('%d days') }}
8
  --DATA--
9
  date_default_timezone_set('UTC');
10
- $twig->getExtension('core')->setDateFormat('Y-m-d', '%d days %h hours');
11
  return array(
12
  'date2' => new DateInterval('P2D'),
13
  )
7
  {{ date2|date('%d days') }}
8
  --DATA--
9
  date_default_timezone_set('UTC');
10
+ $twig->getExtension('Twig_Extension_Core')->setDateFormat('Y-m-d', '%d days %h hours');
11
  return array(
12
  'date2' => new DateInterval('P2D'),
13
  )
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format_default.test CHANGED
@@ -9,7 +9,7 @@
9
  {{ 1020.25|number_format(2, ',') }}
10
  {{ 1020.25|number_format(2, ',', '.') }}
11
  --DATA--
12
- $twig->getExtension('core')->setNumberFormat(2, '!', '=');
13
  return array();
14
  --EXPECT--
15
  20!00
9
  {{ 1020.25|number_format(2, ',') }}
10
  {{ 1020.25|number_format(2, ',', '.') }}
11
  --DATA--
12
+ $twig->getExtension('Twig_Extension_Core')->setNumberFormat(2, '!', '=');
13
  return array();
14
  --EXPECT--
15
  20!00
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/static_calls.test ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ Filters as static method calls
3
+ --TEMPLATE--
4
+ {{ 'foo'|static_call_string }}
5
+ {{ 'foo'|static_call_array }}
6
+ --DATA--
7
+ return array('foo' => 'foo')
8
+ --EXPECT--
9
+ *foo*
10
+ *foo*
vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call.test ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ __call calls
3
+ --TEMPLATE--
4
+ {{ 'foo'|magic_call }}
5
+ --DATA--
6
+ return array()
7
+ --EXPECT--
8
+ magic_foo
vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call53.test ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ __staticCall calls
3
+ --CONDITION--
4
+ version_compare(phpversion(), '5.3.0', '>=')
5
+ --TEMPLATE--
6
+ {{ 'foo'|magic_call_string }}
7
+ {{ 'foo'|magic_call_array }}
8
+ --DATA--
9
+ return array()
10
+ --EXPECT--
11
+ static_magic_foo
12
+ static_magic_foo
vendor/twig/twig/test/Twig/Tests/Fixtures/functions/static_calls.test ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ Functions as static method calls
3
+ --TEMPLATE--
4
+ {{ static_call_string('foo') }}
5
+ {{ static_call_array('foo') }}
6
+ --DATA--
7
+ return array('foo' => 'foo')
8
+ --EXPECT--
9
+ *foo*
10
+ *foo*
vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs_argument.test CHANGED
@@ -5,4 +5,3 @@ macro with varargs argument
5
  {% endmacro %}
6
  --EXCEPTION--
7
  Twig_Error_Syntax: The argument "varargs" in macro "test" cannot be defined because the variable "varargs" is reserved for arbitrary arguments in "index.twig" at line 2.
8
-
5
  {% endmacro %}
6
  --EXCEPTION--
7
  Twig_Error_Syntax: The argument "varargs" in macro "test" cannot be defined because the variable "varargs" is reserved for arbitrary arguments in "index.twig" at line 2.
 
vendor/twig/twig/test/Twig/Tests/Fixtures/regression/combined_debug_info.test CHANGED
@@ -12,4 +12,4 @@ foo
12
  --DATA--
13
  return array('foo' => 'foo');
14
  --EXCEPTION--
15
- Twig_Error_Runtime: Impossible to access an attribute ("bar") on a string variable ("foo") in "foo" at line 3
12
  --DATA--
13
  return array('foo' => 'foo');
14
  --EXCEPTION--
15
+ Twig_Error_Runtime: Impossible to access an attribute ("bar") on a string variable ("foo") in "foo" at line 3.
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/complex_dynamic_parent.test ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ "embed" tag
3
+ --TEMPLATE--
4
+ FOO
5
+ {% embed foo ~ ".twig" %}
6
+ {% block c1 %}
7
+ {{ parent() }}
8
+ block1extended
9
+ {% endblock %}
10
+ {% endembed %}
11
+
12
+ BAR
13
+ --TEMPLATE(foo.twig)--
14
+ A
15
+ {% block c1 %}
16
+ block1
17
+ {% endblock %}
18
+ B
19
+ {% block c2 %}
20
+ block2
21
+ {% endblock %}
22
+ C
23
+ --DATA--
24
+ return array('foo' => 'foo')
25
+ --EXPECT--
26
+ FOO
27
+
28
+ A
29
+ block1
30
+
31
+ block1extended
32
+ B
33
+ block2
34
+ C
35
+ BAR
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/dynamic_parent.test ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ "embed" tag
3
+ --TEMPLATE--
4
+ FOO
5
+ {% embed foo %}
6
+ {% block c1 %}
7
+ {{ parent() }}
8
+ block1extended
9
+ {% endblock %}
10
+ {% endembed %}
11
+
12
+ BAR
13
+ --TEMPLATE(foo.twig)--
14
+ A
15
+ {% block c1 %}
16
+ block1
17
+ {% endblock %}
18
+ B
19
+ {% block c2 %}
20
+ block2
21
+ {% endblock %}
22
+ C
23
+ --DATA--
24
+ return array('foo' => 'foo.twig')
25
+ --EXPECT--
26
+ FOO
27
+
28
+ A
29
+ block1
30
+
31
+ block1extended
32
+ B
33
+ block2
34
+ C
35
+ BAR
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/error_line.test CHANGED
@@ -13,4 +13,4 @@ BAR
13
  --DATA--
14
  return array()
15
  --EXCEPTION--
16
- Twig_Error_Runtime: Variable "nothing" does not exist in "index.twig" at line 5
13
  --DATA--
14
  return array()
15
  --EXCEPTION--
16
+ Twig_Error_Runtime: Variable "nothing" does not exist in "index.twig" at line 5.
vendor/twig/twig/test/Twig/Tests/IntegrationTest.php CHANGED
@@ -141,6 +141,11 @@ class TwigTestExtension extends Twig_Extension
141
  new Twig_SimpleFilter('nl2br', array($this, 'nl2br'), array('pre_escape' => 'html', 'is_safe' => array('html'))),
142
  new Twig_SimpleFilter('escape_something', array($this, 'escape_something'), array('is_safe' => array('something'))),
143
  new Twig_SimpleFilter('preserves_safety', array($this, 'preserves_safety'), array('preserves_safety' => array('html'))),
 
 
 
 
 
144
  new Twig_SimpleFilter('*_path', array($this, 'dynamic_path')),
145
  new Twig_SimpleFilter('*_foo_*_bar', array($this, 'dynamic_foo')),
146
  );
@@ -152,6 +157,8 @@ class TwigTestExtension extends Twig_Extension
152
  new Twig_SimpleFunction('§', array($this, '§Function')),
153
  new Twig_SimpleFunction('safe_br', array($this, 'br'), array('is_safe' => array('html'))),
154
  new Twig_SimpleFunction('unsafe_br', array($this, 'br')),
 
 
155
  new Twig_SimpleFunction('*_path', array($this, 'dynamic_path')),
156
  new Twig_SimpleFunction('*_foo_*_bar', array($this, 'dynamic_foo')),
157
  );
@@ -212,6 +219,11 @@ class TwigTestExtension extends Twig_Extension
212
  return strtoupper($value);
213
  }
214
 
 
 
 
 
 
215
  public function br()
216
  {
217
  return '<br />';
@@ -222,8 +234,21 @@ class TwigTestExtension extends Twig_Extension
222
  return false !== strpos($value, ' ');
223
  }
224
 
225
- public function getName()
 
 
 
 
 
 
 
 
 
226
  {
227
- return 'integration_test';
 
 
 
 
228
  }
229
  }
141
  new Twig_SimpleFilter('nl2br', array($this, 'nl2br'), array('pre_escape' => 'html', 'is_safe' => array('html'))),
142
  new Twig_SimpleFilter('escape_something', array($this, 'escape_something'), array('is_safe' => array('something'))),
143
  new Twig_SimpleFilter('preserves_safety', array($this, 'preserves_safety'), array('preserves_safety' => array('html'))),
144
+ new Twig_SimpleFilter('static_call_string', 'TwigTestExtension::staticCall'),
145
+ new Twig_SimpleFilter('static_call_array', array('TwigTestExtension', 'staticCall')),
146
+ new Twig_SimpleFilter('magic_call', array($this, 'magicCall')),
147
+ new Twig_SimpleFilter('magic_call_string', 'TwigTestExtension::magicStaticCall'),
148
+ new Twig_SimpleFilter('magic_call_array', array('TwigTestExtension', 'magicStaticCall')),
149
  new Twig_SimpleFilter('*_path', array($this, 'dynamic_path')),
150
  new Twig_SimpleFilter('*_foo_*_bar', array($this, 'dynamic_foo')),
151
  );
157
  new Twig_SimpleFunction('§', array($this, '§Function')),
158
  new Twig_SimpleFunction('safe_br', array($this, 'br'), array('is_safe' => array('html'))),
159
  new Twig_SimpleFunction('unsafe_br', array($this, 'br')),
160
+ new Twig_SimpleFunction('static_call_string', 'TwigTestExtension::staticCall'),
161
+ new Twig_SimpleFunction('static_call_array', array('TwigTestExtension', 'staticCall')),
162
  new Twig_SimpleFunction('*_path', array($this, 'dynamic_path')),
163
  new Twig_SimpleFunction('*_foo_*_bar', array($this, 'dynamic_foo')),
164
  );
219
  return strtoupper($value);
220
  }
221
 
222
+ public static function staticCall($value)
223
+ {
224
+ return "*$value*";
225
+ }
226
+
227
  public function br()
228
  {
229
  return '<br />';
234
  return false !== strpos($value, ' ');
235
  }
236
 
237
+ public function __call($method, $arguments)
238
+ {
239
+ if ('magicCall' !== $method) {
240
+ throw new BadMethodCallException('Unexpected call to __call');
241
+ }
242
+
243
+ return 'magic_'.$arguments[0];
244
+ }
245
+
246
+ public static function __callStatic($method, $arguments)
247
  {
248
+ if ('magicStaticCall' !== $method) {
249
+ throw new BadMethodCallException('Unexpected call to __callStatic');
250
+ }
251
+
252
+ return 'static_magic_'.$arguments[0];
253
  }
254
  }
vendor/twig/twig/test/Twig/Tests/{Fixtures/autoescape/filename.test → LegacyFixtures/autoescape/filename.legacy.test} RENAMED
File without changes
vendor/twig/twig/test/Twig/Tests/LexerTest.php CHANGED
@@ -10,12 +10,23 @@
10
  */
11
  class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
12
  {
 
 
 
 
 
 
 
 
 
 
 
13
  public function testNameLabelForTag()
14
  {
15
  $template = '{% § %}';
16
 
17
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
18
- $stream = $lexer->tokenize($template);
19
 
20
  $stream->expect(Twig_Token::BLOCK_START_TYPE);
21
  $this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
@@ -26,7 +37,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
26
  $template = '{{ §() }}';
27
 
28
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
29
- $stream = $lexer->tokenize($template);
30
 
31
  $stream->expect(Twig_Token::VAR_START_TYPE);
32
  $this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
@@ -43,7 +54,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
43
  protected function countToken($template, $type, $value = null)
44
  {
45
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
46
- $stream = $lexer->tokenize($template);
47
 
48
  $count = 0;
49
  while (!$stream->isEOF()) {
@@ -68,7 +79,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
68
  ."}}\n";
69
 
70
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
71
- $stream = $lexer->tokenize($template);
72
 
73
  // foo\nbar\n
74
  $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
@@ -88,7 +99,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
88
  ."}}\n";
89
 
90
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
91
- $stream = $lexer->tokenize($template);
92
 
93
  // foo\nbar
94
  $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
@@ -103,7 +114,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
103
  $template = '{# '.str_repeat('*', 100000).' #}';
104
 
105
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
106
- $lexer->tokenize($template);
107
 
108
  // should not throw an exception
109
  }
@@ -113,7 +124,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
113
  $template = '{% verbatim %}'.str_repeat('*', 100000).'{% endverbatim %}';
114
 
115
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
116
- $lexer->tokenize($template);
117
 
118
  // should not throw an exception
119
  }
@@ -123,7 +134,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
123
  $template = '{{ '.str_repeat('x', 100000).' }}';
124
 
125
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
126
- $lexer->tokenize($template);
127
 
128
  // should not throw an exception
129
  }
@@ -133,7 +144,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
133
  $template = '{% '.str_repeat('x', 100000).' %}';
134
 
135
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
136
- $lexer->tokenize($template);
137
 
138
  // should not throw an exception
139
  }
@@ -143,7 +154,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
143
  $template = '{{ 922337203685477580700 }}';
144
 
145
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
146
- $stream = $lexer->tokenize($template);
147
  $stream->next();
148
  $node = $stream->next();
149
  $this->assertEquals('922337203685477580700', $node->getValue());
@@ -157,7 +168,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
157
  );
158
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
159
  foreach ($tests as $template => $expected) {
160
- $stream = $lexer->tokenize($template);
161
  $stream->expect(Twig_Token::VAR_START_TYPE);
162
  $stream->expect(Twig_Token::STRING_TYPE, $expected);
163
  }
@@ -168,7 +179,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
168
  $template = 'foo {{ "bar #{ baz + 1 }" }}';
169
 
170
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
171
- $stream = $lexer->tokenize($template);
172
  $stream->expect(Twig_Token::TEXT_TYPE, 'foo ');
173
  $stream->expect(Twig_Token::VAR_START_TYPE);
174
  $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
@@ -185,7 +196,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
185
  $template = '{{ "bar \#{baz+1}" }}';
186
 
187
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
188
- $stream = $lexer->tokenize($template);
189
  $stream->expect(Twig_Token::VAR_START_TYPE);
190
  $stream->expect(Twig_Token::STRING_TYPE, 'bar #{baz+1}');
191
  $stream->expect(Twig_Token::VAR_END_TYPE);
@@ -196,7 +207,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
196
  $template = '{{ "bar # baz" }}';
197
 
198
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
199
- $stream = $lexer->tokenize($template);
200
  $stream->expect(Twig_Token::VAR_START_TYPE);
201
  $stream->expect(Twig_Token::STRING_TYPE, 'bar # baz');
202
  $stream->expect(Twig_Token::VAR_END_TYPE);
@@ -211,7 +222,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
211
  $template = '{{ "bar #{x" }}';
212
 
213
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
214
- $lexer->tokenize($template);
215
  }
216
 
217
  public function testStringWithNestedInterpolations()
@@ -219,7 +230,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
219
  $template = '{{ "bar #{ "foo#{bar}" }" }}';
220
 
221
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
222
- $stream = $lexer->tokenize($template);
223
  $stream->expect(Twig_Token::VAR_START_TYPE);
224
  $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
225
  $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
@@ -236,7 +247,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
236
  $template = '{% foo "bar #{ "foo#{bar}" }" %}';
237
 
238
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
239
- $stream = $lexer->tokenize($template);
240
  $stream->expect(Twig_Token::BLOCK_START_TYPE);
241
  $stream->expect(Twig_Token::NAME_TYPE, 'foo');
242
  $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
@@ -254,7 +265,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
254
  $template = "{{ 1 and\n0}}";
255
 
256
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
257
- $stream = $lexer->tokenize($template);
258
  $stream->expect(Twig_Token::VAR_START_TYPE);
259
  $stream->expect(Twig_Token::NUMBER_TYPE, 1);
260
  $stream->expect(Twig_Token::OPERATOR_TYPE, 'and');
@@ -262,7 +273,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
262
 
263
  /**
264
  * @expectedException Twig_Error_Syntax
265
- * @expectedExceptionMessage Unclosed "variable" at line 3
266
  */
267
  public function testUnterminatedVariable()
268
  {
@@ -276,12 +287,12 @@ bar
276
  ';
277
 
278
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
279
- $lexer->tokenize($template);
280
  }
281
 
282
  /**
283
  * @expectedException Twig_Error_Syntax
284
- * @expectedExceptionMessage Unclosed "block" at line 3
285
  */
286
  public function testUnterminatedBlock()
287
  {
@@ -295,6 +306,6 @@ bar
295
  ';
296
 
297
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
298
- $lexer->tokenize($template);
299
  }
300
  }
10
  */
11
  class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
12
  {
13
+ /**
14
+ * @group legacy
15
+ */
16
+ public function testLegacyConstructorSignature()
17
+ {
18
+ $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
19
+ $stream = $lexer->tokenize('{{ foo }}', 'foo');
20
+ $this->assertEquals('foo', $stream->getFilename());
21
+ $this->assertEquals('{{ foo }}', $stream->getSource());
22
+ }
23
+
24
  public function testNameLabelForTag()
25
  {
26
  $template = '{% § %}';
27
 
28
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
29
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
30
 
31
  $stream->expect(Twig_Token::BLOCK_START_TYPE);
32
  $this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
37
  $template = '{{ §() }}';
38
 
39
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
40
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
41
 
42
  $stream->expect(Twig_Token::VAR_START_TYPE);
43
  $this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
54
  protected function countToken($template, $type, $value = null)
55
  {
56
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
57
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
58
 
59
  $count = 0;
60
  while (!$stream->isEOF()) {
79
  ."}}\n";
80
 
81
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
82
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
83
 
84
  // foo\nbar\n
85
  $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
99
  ."}}\n";
100
 
101
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
102
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
103
 
104
  // foo\nbar
105
  $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
114
  $template = '{# '.str_repeat('*', 100000).' #}';
115
 
116
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
117
+ $lexer->tokenize(new Twig_Source($template, 'index'));
118
 
119
  // should not throw an exception
120
  }
124
  $template = '{% verbatim %}'.str_repeat('*', 100000).'{% endverbatim %}';
125
 
126
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
127
+ $lexer->tokenize(new Twig_Source($template, 'index'));
128
 
129
  // should not throw an exception
130
  }
134
  $template = '{{ '.str_repeat('x', 100000).' }}';
135
 
136
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
137
+ $lexer->tokenize(new Twig_Source($template, 'index'));
138
 
139
  // should not throw an exception
140
  }
144
  $template = '{% '.str_repeat('x', 100000).' %}';
145
 
146
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
147
+ $lexer->tokenize(new Twig_Source($template, 'index'));
148
 
149
  // should not throw an exception
150
  }
154
  $template = '{{ 922337203685477580700 }}';
155
 
156
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
157
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
158
  $stream->next();
159
  $node = $stream->next();
160
  $this->assertEquals('922337203685477580700', $node->getValue());
168
  );
169
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
170
  foreach ($tests as $template => $expected) {
171
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
172
  $stream->expect(Twig_Token::VAR_START_TYPE);
173
  $stream->expect(Twig_Token::STRING_TYPE, $expected);
174
  }
179
  $template = 'foo {{ "bar #{ baz + 1 }" }}';
180
 
181
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
182
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
183
  $stream->expect(Twig_Token::TEXT_TYPE, 'foo ');
184
  $stream->expect(Twig_Token::VAR_START_TYPE);
185
  $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
196
  $template = '{{ "bar \#{baz+1}" }}';
197
 
198
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
199
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
200
  $stream->expect(Twig_Token::VAR_START_TYPE);
201
  $stream->expect(Twig_Token::STRING_TYPE, 'bar #{baz+1}');
202
  $stream->expect(Twig_Token::VAR_END_TYPE);
207
  $template = '{{ "bar # baz" }}';
208
 
209
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
210
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
211
  $stream->expect(Twig_Token::VAR_START_TYPE);
212
  $stream->expect(Twig_Token::STRING_TYPE, 'bar # baz');
213
  $stream->expect(Twig_Token::VAR_END_TYPE);
222
  $template = '{{ "bar #{x" }}';
223
 
224
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
225
+ $lexer->tokenize(new Twig_Source($template, 'index'));
226
  }
227
 
228
  public function testStringWithNestedInterpolations()
230
  $template = '{{ "bar #{ "foo#{bar}" }" }}';
231
 
232
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
233
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
234
  $stream->expect(Twig_Token::VAR_START_TYPE);
235
  $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
236
  $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
247
  $template = '{% foo "bar #{ "foo#{bar}" }" %}';
248
 
249
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
250
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
251
  $stream->expect(Twig_Token::BLOCK_START_TYPE);
252
  $stream->expect(Twig_Token::NAME_TYPE, 'foo');
253
  $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
265
  $template = "{{ 1 and\n0}}";
266
 
267
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
268
+ $stream = $lexer->tokenize(new Twig_Source($template, 'index'));
269
  $stream->expect(Twig_Token::VAR_START_TYPE);
270
  $stream->expect(Twig_Token::NUMBER_TYPE, 1);
271
  $stream->expect(Twig_Token::OPERATOR_TYPE, 'and');
273
 
274
  /**
275
  * @expectedException Twig_Error_Syntax
276
+ * @expectedExceptionMessage Unclosed "variable" in "index" at line 3
277
  */
278
  public function testUnterminatedVariable()
279
  {
287
  ';
288
 
289
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
290
+ $lexer->tokenize(new Twig_Source($template, 'index'));
291
  }
292
 
293
  /**
294
  * @expectedException Twig_Error_Syntax
295
+ * @expectedExceptionMessage Unclosed "block" in "index" at line 3
296
  */
297
  public function testUnterminatedBlock()
298
  {
306
  ';
307
 
308
  $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
309
+ $lexer->tokenize(new Twig_Source($template, 'index'));
310
  }
311
  }
vendor/twig/twig/test/Twig/Tests/Loader/ArrayTest.php CHANGED
@@ -11,6 +11,9 @@
11
 
12
  class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
13
  {
 
 
 
14
  public function testGetSource()
15
  {
16
  $loader = new Twig_Loader_Array(array('foo' => 'bar'));
@@ -19,6 +22,7 @@ class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
19
  }
20
 
21
  /**
 
22
  * @expectedException Twig_Error_Loader
23
  */
24
  public function testGetSourceWhenTemplateDoesNotExist()
@@ -28,6 +32,16 @@ class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
28
  $loader->getSource('foo');
29
  }
30
 
 
 
 
 
 
 
 
 
 
 
31
  public function testGetCacheKey()
32
  {
33
  $loader = new Twig_Loader_Array(array('foo' => 'bar'));
@@ -50,7 +64,7 @@ class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
50
  $loader = new Twig_Loader_Array(array());
51
  $loader->setTemplate('foo', 'bar');
52
 
53
- $this->assertEquals('bar', $loader->getSource('foo'));
54
  }
55
 
56
  public function testIsFresh()
@@ -75,7 +89,7 @@ class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
75
  $loader = new Twig_Loader_Array(array('foo' => 'bar'));
76
 
77
  $loader->getCacheKey($name);
78
- $loader->getSource($name);
79
  $loader->isFresh($name, time());
80
  $loader->setTemplate($name, 'foobar');
81
  }
11
 
12
  class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
13
  {
14
+ /**
15
+ * @group legacy
16
+ */
17
  public function testGetSource()
18
  {
19
  $loader = new Twig_Loader_Array(array('foo' => 'bar'));
22
  }
23
 
24
  /**
25
+ * @group legacy
26
  * @expectedException Twig_Error_Loader
27
  */
28
  public function testGetSourceWhenTemplateDoesNotExist()
32
  $loader->getSource('foo');
33
  }
34
 
35
+ /**
36
+ * @expectedException Twig_Error_Loader
37
+ */
38
+ public function testGetSourceContextWhenTemplateDoesNotExist()
39
+ {
40
+ $loader = new Twig_Loader_Array(array());
41
+
42
+ $loader->getSourceContext('foo');
43
+ }
44
+
45
  public function testGetCacheKey()
46
  {
47
  $loader = new Twig_Loader_Array(array('foo' => 'bar'));
64
  $loader = new Twig_Loader_Array(array());
65
  $loader->setTemplate('foo', 'bar');
66
 
67
+ $this->assertEquals('bar', $loader->getSourceContext('foo')->getCode());
68
  }
69
 
70
  public function testIsFresh()
89
  $loader = new Twig_Loader_Array(array('foo' => 'bar'));
90
 
91
  $loader->getCacheKey($name);
92
+ $loader->getSourceContext($name);
93
  $loader->isFresh($name, time());
94
  $loader->setTemplate($name, 'foobar');
95
  }
vendor/twig/twig/test/Twig/Tests/Loader/ChainTest.php CHANGED
@@ -11,6 +11,9 @@
11
 
12
  class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
13
  {
 
 
 
14
  public function testGetSource()
15
  {
16
  $loader = new Twig_Loader_Chain(array(
@@ -22,9 +25,41 @@ class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
22
  $this->assertEquals('foo', $loader->getSource('bar'));
23
  }
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  /**
26
  * @expectedException Twig_Error_Loader
27
  */
 
 
 
 
 
 
 
 
 
 
 
28
  public function testGetSourceWhenTemplateDoesNotExist()
29
  {
30
  $loader = new Twig_Loader_Chain(array());
@@ -58,17 +93,19 @@ class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
58
  $loader = new Twig_Loader_Chain();
59
  $loader->addLoader(new Twig_Loader_Array(array('foo' => 'bar')));
60
 
61
- $this->assertEquals('bar', $loader->getSource('foo'));
62
  }
63
 
64
  public function testExists()
65
  {
66
- $loader1 = $this->getMockBuilder('Twig_Loader_Array')->setMethods(array('exists', 'getSource'))->disableOriginalConstructor()->getMock();
67
  $loader1->expects($this->once())->method('exists')->will($this->returnValue(false));
68
- $loader1->expects($this->never())->method('getSource');
69
 
70
- $loader2 = $this->getMockBuilder('Twig_LoaderInterface')->getMock();
71
- $loader2->expects($this->once())->method('getSource')->will($this->returnValue('content'));
 
 
72
 
73
  $loader = new Twig_Loader_Chain();
74
  $loader->addLoader($loader1);
@@ -77,3 +114,7 @@ class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
77
  $this->assertTrue($loader->exists('foo'));
78
  }
79
  }
 
 
 
 
11
 
12
  class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
13
  {
14
+ /**
15
+ * @group legacy
16
+ */
17
  public function testGetSource()
18
  {
19
  $loader = new Twig_Loader_Chain(array(
25
  $this->assertEquals('foo', $loader->getSource('bar'));
26
  }
27
 
28
+ public function testGetSourceContext()
29
+ {
30
+ $path = dirname(__FILE__).'/../Fixtures';
31
+ $loader = new Twig_Loader_Chain(array(
32
+ new Twig_Loader_Array(array('foo' => 'bar')),
33
+ new Twig_Loader_Array(array('errors/index.html' => 'baz')),
34
+ new Twig_Loader_Filesystem(array($path)),
35
+ ));
36
+
37
+ $this->assertEquals('foo', $loader->getSourceContext('foo')->getName());
38
+ $this->assertSame('', $loader->getSourceContext('foo')->getPath());
39
+
40
+ $this->assertEquals('errors/index.html', $loader->getSourceContext('errors/index.html')->getName());
41
+ $this->assertSame('', $loader->getSourceContext('errors/index.html')->getPath());
42
+ $this->assertEquals('baz', $loader->getSourceContext('errors/index.html')->getCode());
43
+
44
+ $this->assertEquals('errors/base.html', $loader->getSourceContext('errors/base.html')->getName());
45
+ $this->assertEquals(realpath($path.'/errors/base.html'), realpath($loader->getSourceContext('errors/base.html')->getPath()));
46
+ $this->assertNotEquals('baz', $loader->getSourceContext('errors/base.html')->getCode());
47
+ }
48
+
49
  /**
50
  * @expectedException Twig_Error_Loader
51
  */
52
+ public function testGetSourceContextWhenTemplateDoesNotExist()
53
+ {
54
+ $loader = new Twig_Loader_Chain(array());
55
+
56
+ $loader->getSourceContext('foo');
57
+ }
58
+
59
+ /**
60
+ * @group legacy
61
+ * @expectedException Twig_Error_Loader
62
+ */
63
  public function testGetSourceWhenTemplateDoesNotExist()
64
  {
65
  $loader = new Twig_Loader_Chain(array());
93
  $loader = new Twig_Loader_Chain();
94
  $loader->addLoader(new Twig_Loader_Array(array('foo' => 'bar')));
95
 
96
+ $this->assertEquals('bar', $loader->getSourceContext('foo')->getCode());
97
  }
98
 
99
  public function testExists()
100
  {
101
+ $loader1 = $this->getMockBuilder('Twig_Loader_Array')->setMethods(array('exists', 'getSourceContext'))->disableOriginalConstructor()->getMock();
102
  $loader1->expects($this->once())->method('exists')->will($this->returnValue(false));
103
+ $loader1->expects($this->never())->method('getSourceContext');
104
 
105
+ // can be removed in 2.0
106
+ $loader2 = $this->getMockBuilder('Twig_ChainTestLoaderInterface')->getMock();
107
+ //$loader2 = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock();
108
+ $loader2->expects($this->once())->method('getSourceContext')->will($this->returnValue(new Twig_Source('content', 'index')));
109
 
110
  $loader = new Twig_Loader_Chain();
111
  $loader->addLoader($loader1);
114
  $this->assertTrue($loader->exists('foo'));
115
  }
116
  }
117
+
118
+ interface Twig_ChainTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface
119
+ {
120
+ }
vendor/twig/twig/test/Twig/Tests/Loader/FilesystemTest.php CHANGED
@@ -11,6 +11,14 @@
11
 
12
  class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
13
  {
 
 
 
 
 
 
 
 
14
  /**
15
  * @dataProvider getSecurityTests
16
  */
@@ -51,11 +59,12 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
51
  );
52
  }
53
 
54
- public function testPaths()
 
 
 
55
  {
56
- $basePath = dirname(__FILE__).'/Fixtures';
57
-
58
- $loader = new Twig_Loader_Filesystem(array($basePath.'/normal', $basePath.'/normal_bis'));
59
  $loader->setPaths(array($basePath.'/named', $basePath.'/named_bis'), 'named');
60
  $loader->addPath($basePath.'/named_ter', 'named');
61
  $loader->addPath($basePath.'/normal_ter');
@@ -77,13 +86,42 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
77
  $basePath.'/named_ter',
78
  ), $loader->getPaths('named'));
79
 
80
- $this->assertEquals(
81
- realpath($basePath.'/named_quater/named_absolute.html'),
82
- realpath($loader->getCacheKey('@named/named_absolute.html'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  );
84
- $this->assertEquals("path (final)\n", $loader->getSource('index.html'));
85
- $this->assertEquals("path (final)\n", $loader->getSource('@__main__/index.html'));
86
- $this->assertEquals("named path (final)\n", $loader->getSource('@named/index.html'));
87
  }
88
 
89
  public function testEmptyConstructor()
@@ -109,7 +147,7 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
109
  $loader->addPath($basePath.'/named', 'named');
110
 
111
  try {
112
- $loader->getSource('@named/nowhere.html');
113
  } catch (Exception $e) {
114
  $this->assertInstanceof('Twig_Error_Loader', $e);
115
  $this->assertContains('Unable to find template "@named/nowhere.html"', $e->getMessage());
@@ -124,11 +162,11 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
124
  $loader->addPath($basePath.'/named', 'named');
125
 
126
  // prime the cache for index.html in the named namespace
127
- $namedSource = $loader->getSource('@named/index.html');
128
  $this->assertEquals("named path\n", $namedSource);
129
 
130
  // get index.html from the main namespace
131
- $this->assertEquals("path\n", $loader->getSource('index.html'));
132
  }
133
 
134
  public function testLoadTemplateAndRenderBlockWithCache()
@@ -172,4 +210,17 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
172
  $template = $twig->loadTemplate($templateName);
173
  $this->assertSame('VALID Child', $template->renderBlock('body', array()));
174
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  }
11
 
12
  class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
13
  {
14
+ public function testGetSourceContext()
15
+ {
16
+ $path = dirname(__FILE__).'/../Fixtures';
17
+ $loader = new Twig_Loader_Filesystem(array($path));
18
+ $this->assertEquals('errors/index.html', $loader->getSourceContext('errors/index.html')->getName());
19
+ $this->assertEquals(realpath($path.'/errors/index.html'), realpath($loader->getSourceContext('errors/index.html')->getPath()));
20
+ }
21
+
22
  /**
23
  * @dataProvider getSecurityTests
24
  */
59
  );
60
  }
61
 
62
+ /**
63
+ * @dataProvider getBasePaths
64
+ */
65
+ public function testPaths($basePath, $cacheKey, $rootPath)
66
  {
67
+ $loader = new Twig_Loader_Filesystem(array($basePath.'/normal', $basePath.'/normal_bis'), $rootPath);
 
 
68
  $loader->setPaths(array($basePath.'/named', $basePath.'/named_bis'), 'named');
69
  $loader->addPath($basePath.'/named_ter', 'named');
70
  $loader->addPath($basePath.'/normal_ter');
86
  $basePath.'/named_ter',
87
  ), $loader->getPaths('named'));
88
 
89
+ // do not use realpath here as it would make the test unuseful
90
+ $this->assertEquals($cacheKey, str_replace('\\', '/', $loader->getCacheKey('@named/named_absolute.html')));
91
+ $this->assertEquals("path (final)\n", $loader->getSourceContext('index.html')->getCode());
92
+ $this->assertEquals("path (final)\n", $loader->getSourceContext('@__main__/index.html')->getCode());
93
+ $this->assertEquals("named path (final)\n", $loader->getSourceContext('@named/index.html')->getCode());
94
+ }
95
+
96
+ public function getBasePaths()
97
+ {
98
+ return array(
99
+ array(
100
+ dirname(__FILE__).'/Fixtures',
101
+ 'test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html',
102
+ null,
103
+ ),
104
+ array(
105
+ dirname(__FILE__).'/Fixtures/../Fixtures',
106
+ 'test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html',
107
+ null,
108
+ ),
109
+ array(
110
+ 'test/Twig/Tests/Loader/Fixtures',
111
+ 'test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html',
112
+ getcwd(),
113
+ ),
114
+ array(
115
+ 'Fixtures',
116
+ 'Fixtures/named_quater/named_absolute.html',
117
+ getcwd().'/test/Twig/Tests/Loader',
118
+ ),
119
+ array(
120
+ 'Fixtures',
121
+ 'Fixtures/named_quater/named_absolute.html',
122
+ getcwd().'/test/../test/Twig/Tests/Loader',
123
+ ),
124
  );
 
 
 
125
  }
126
 
127
  public function testEmptyConstructor()
147
  $loader->addPath($basePath.'/named', 'named');
148
 
149
  try {
150
+ $loader->getSourceContext('@named/nowhere.html');
151
  } catch (Exception $e) {
152
  $this->assertInstanceof('Twig_Error_Loader', $e);
153
  $this->assertContains('Unable to find template "@named/nowhere.html"', $e->getMessage());
162
  $loader->addPath($basePath.'/named', 'named');
163
 
164
  // prime the cache for index.html in the named namespace
165
+ $namedSource = $loader->getSourceContext('@named/index.html')->getCode();
166
  $this->assertEquals("named path\n", $namedSource);
167
 
168
  // get index.html from the main namespace
169
+ $this->assertEquals("path\n", $loader->getSourceContext('index.html')->getCode());
170
  }
171
 
172
  public function testLoadTemplateAndRenderBlockWithCache()
210
  $template = $twig->loadTemplate($templateName);
211
  $this->assertSame('VALID Child', $template->renderBlock('body', array()));
212
  }
213
+
214
+ /**
215
+ * @requires PHP 5.3
216
+ */
217
+ public function testLoadTemplateFromPhar()
218
+ {
219
+ $loader = new Twig_Loader_Filesystem(array());
220
+ // phar-sample.phar was created with the following script:
221
+ // $f = new Phar('phar-test.phar');
222
+ // $f->addFromString('hello.twig', 'hello from phar');
223
+ $loader->addPath('phar://'.dirname(__FILE__).'/Fixtures/phar/phar-sample.phar');
224
+ $this->assertSame('hello from phar', $loader->getSourceContext('hello.twig')->getCode());
225
+ }
226
  }
vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/phar/phar-sample.phar ADDED
Binary file
vendor/twig/twig/test/Twig/Tests/Node/ForTest.php CHANGED
@@ -28,7 +28,7 @@ class Twig_Tests_Node_ForTest extends Twig_Test_NodeTestCase
28
  $this->assertTrue($node->getAttribute('ifexpr'));
29
  $this->assertEquals('Twig_Node_If', get_class($node->getNode('body')));
30
  $this->assertEquals($body, $node->getNode('body')->getNode('tests')->getNode(1)->getNode(0));
31
- $this->assertNull($node->getNode('else'));
32
 
33
  $else = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1);
34
  $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1);
28
  $this->assertTrue($node->getAttribute('ifexpr'));
29
  $this->assertEquals('Twig_Node_If', get_class($node->getNode('body')));
30
  $this->assertEquals($body, $node->getNode('body')->getNode('tests')->getNode(1)->getNode(0));
31
+ $this->assertFalse($node->hasNode('else'));
32
 
33
  $else = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1);
34
  $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1);
vendor/twig/twig/test/Twig/Tests/Node/IfTest.php CHANGED
@@ -21,7 +21,7 @@ class Twig_Tests_Node_IfTest extends Twig_Test_NodeTestCase
21
  $node = new Twig_Node_If($t, $else, 1);
22
 
23
  $this->assertEquals($t, $node->getNode('tests'));
24
- $this->assertNull($node->getNode('else'));
25
 
26
  $else = new Twig_Node_Print(new Twig_Node_Expression_Name('bar', 1), 1);
27
  $node = new Twig_Node_If($t, $else, 1);
21
  $node = new Twig_Node_If($t, $else, 1);
22
 
23
  $this->assertEquals($t, $node->getNode('tests'));
24
+ $this->assertFalse($node->hasNode('else'));
25
 
26
  $else = new Twig_Node_Print(new Twig_Node_Expression_Name('bar', 1), 1);
27
  $node = new Twig_Node_If($t, $else, 1);
vendor/twig/twig/test/Twig/Tests/Node/IncludeTest.php CHANGED
@@ -16,7 +16,7 @@ class Twig_Tests_Node_IncludeTest extends Twig_Test_NodeTestCase
16
  $expr = new Twig_Node_Expression_Constant('foo.twig', 1);
17
  $node = new Twig_Node_Include($expr, null, false, false, 1);
18
 
19
- $this->assertNull($node->getNode('variables'));
20
  $this->assertEquals($expr, $node->getNode('expr'));
21
  $this->assertFalse($node->getAttribute('only'));
22
 
16
  $expr = new Twig_Node_Expression_Constant('foo.twig', 1);
17
  $node = new Twig_Node_Include($expr, null, false, false, 1);
18
 
19
+ $this->assertFalse($node->hasNode('variables'));
20
  $this->assertEquals($expr, $node->getNode('expr'));
21
  $this->assertFalse($node->getAttribute('only'));
22
 
vendor/twig/twig/test/Twig/Tests/Node/ModuleTest.php CHANGED
@@ -18,14 +18,14 @@ class Twig_Tests_Node_ModuleTest extends Twig_Test_NodeTestCase
18
  $blocks = new Twig_Node();
19
  $macros = new Twig_Node();
20
  $traits = new Twig_Node();
21
- $filename = 'foo.twig';
22
- $node = new Twig_Node_Module($body, $parent, $blocks, $macros, $traits, new Twig_Node(array()), $filename);
23
 
24
  $this->assertEquals($body, $node->getNode('body'));
25
  $this->assertEquals($blocks, $node->getNode('blocks'));
26
  $this->assertEquals($macros, $node->getNode('macros'));
27
  $this->assertEquals($parent, $node->getNode('parent'));
28
- $this->assertEquals($filename, $node->getAttribute('filename'));
29
  }
30
 
31
  public function getTests()
@@ -39,9 +39,9 @@ class Twig_Tests_Node_ModuleTest extends Twig_Test_NodeTestCase
39
  $blocks = new Twig_Node();
40
  $macros = new Twig_Node();
41
  $traits = new Twig_Node();
42
- $filename = 'foo.twig';
43
 
44
- $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $filename);
45
  $tests[] = array($node, <<<EOF
46
  <?php
47
 
@@ -73,6 +73,19 @@ class __TwigTemplate_%x extends Twig_Template
73
  {
74
  return array ( 19 => 1,);
75
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  }
77
  EOF
78
  , $twig, true);
@@ -82,7 +95,7 @@ EOF
82
  $body = new Twig_Node(array($import));
83
  $extends = new Twig_Node_Expression_Constant('layout.twig', 1);
84
 
85
- $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $filename);
86
  $tests[] = array($node, <<<EOF
87
  <?php
88
 
@@ -126,6 +139,19 @@ class __TwigTemplate_%x extends Twig_Template
126
  {
127
  return array ( 26 => 1, 24 => 2, 11 => 1,);
128
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  }
130
  EOF
131
  , $twig, true);
@@ -139,7 +165,8 @@ EOF
139
  2
140
  );
141
 
142
- $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $filename);
 
143
  $tests[] = array($node, <<<EOF
144
  <?php
145
 
@@ -174,6 +201,19 @@ class __TwigTemplate_%x extends Twig_Template
174
  {
175
  return array ( 17 => 2, 15 => 4, 9 => 2,);
176
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  }
178
  EOF
179
  , $twig, true);
18
  $blocks = new Twig_Node();
19
  $macros = new Twig_Node();
20
  $traits = new Twig_Node();
21
+ $source = new Twig_Source('{{ foo }}', 'foo.twig');
22
+ $node = new Twig_Node_Module($body, $parent, $blocks, $macros, $traits, new Twig_Node(array()), $source);
23
 
24
  $this->assertEquals($body, $node->getNode('body'));
25
  $this->assertEquals($blocks, $node->getNode('blocks'));
26
  $this->assertEquals($macros, $node->getNode('macros'));
27
  $this->assertEquals($parent, $node->getNode('parent'));
28
+ $this->assertEquals($source->getName(), $node->getTemplateName());
29
  }
30
 
31
  public function getTests()
39
  $blocks = new Twig_Node();
40
  $macros = new Twig_Node();
41
  $traits = new Twig_Node();
42
+ $source = new Twig_Source('{{ foo }}', 'foo.twig');
43
 
44
+ $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $source);
45
  $tests[] = array($node, <<<EOF
46
  <?php
47
 
73
  {
74
  return array ( 19 => 1,);
75
  }
76
+
77
+ /** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */
78
+ public function getSource()
79
+ {
80
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);
81
+
82
+ return \$this->getSourceContext()->getCode();
83
+ }
84
+
85
+ public function getSourceContext()
86
+ {
87
+ return new Twig_Source("", "foo.twig", "");
88
+ }
89
  }
90
  EOF
91
  , $twig, true);
95
  $body = new Twig_Node(array($import));
96
  $extends = new Twig_Node_Expression_Constant('layout.twig', 1);
97
 
98
+ $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $source);
99
  $tests[] = array($node, <<<EOF
100
  <?php
101
 
139
  {
140
  return array ( 26 => 1, 24 => 2, 11 => 1,);
141
  }
142
+
143
+ /** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */
144
+ public function getSource()
145
+ {
146
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);
147
+
148
+ return \$this->getSourceContext()->getCode();
149
+ }
150
+
151
+ public function getSourceContext()
152
+ {
153
+ return new Twig_Source("", "foo.twig", "");
154
+ }
155
  }
156
  EOF
157
  , $twig, true);
165
  2
166
  );
167
 
168
+ $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('debug' => true));
169
+ $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $source);
170
  $tests[] = array($node, <<<EOF
171
  <?php
172
 
201
  {
202
  return array ( 17 => 2, 15 => 4, 9 => 2,);
203
  }
204
+
205
+ /** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */
206
+ public function getSource()
207
+ {
208
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);
209
+
210
+ return \$this->getSourceContext()->getCode();
211
+ }
212
+
213
+ public function getSourceContext()
214
+ {
215
+ return new Twig_Source("{{ foo }}", "foo.twig", "");
216
+ }
217
  }
218
  EOF
219
  , $twig, true);
vendor/twig/twig/test/Twig/Tests/Node/SandboxTest.php CHANGED
@@ -28,7 +28,7 @@ class Twig_Tests_Node_SandboxTest extends Twig_Test_NodeTestCase
28
 
29
  $tests[] = array($node, <<<EOF
30
  // line 1
31
- \$sandbox = \$this->env->getExtension('sandbox');
32
  if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {
33
  \$sandbox->enableSandbox();
34
  }
28
 
29
  $tests[] = array($node, <<<EOF
30
  // line 1
31
+ \$sandbox = \$this->env->getExtension('Twig_Extension_Sandbox');
32
  if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {
33
  \$sandbox->enableSandbox();
34
  }
vendor/twig/twig/test/Twig/Tests/Node/SandboxedPrintTest.php CHANGED
@@ -24,7 +24,7 @@ class Twig_Tests_Node_SandboxedPrintTest extends Twig_Test_NodeTestCase
24
 
25
  $tests[] = array(new Twig_Node_SandboxedPrint(new Twig_Node_Expression_Constant('foo', 1), 1), <<<EOF
26
  // line 1
27
- echo \$this->env->getExtension('sandbox')->ensureToStringAllowed("foo");
28
  EOF
29
  );
30
 
24
 
25
  $tests[] = array(new Twig_Node_SandboxedPrint(new Twig_Node_Expression_Constant('foo', 1), 1), <<<EOF
26
  // line 1
27
+ echo \$this->env->getExtension('Twig_Extension_Sandbox')->ensureToStringAllowed("foo");
28
  EOF
29
  );
30
 
vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php CHANGED
@@ -14,7 +14,7 @@ class Twig_Tests_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase
14
  {
15
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
16
 
17
- $stream = $env->parse($env->tokenize('{{ block("foo") }}', 'index'));
18
 
19
  $node = $stream->getNode('body')->getNode(0);
20
 
@@ -26,7 +26,7 @@ class Twig_Tests_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase
26
  {
27
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
28
 
29
- $stream = $env->parse($env->tokenize('{% extends "foo" %}{% block content %}{{ parent() }}{% endblock %}', 'index'));
30
 
31
  $node = $stream->getNode('blocks')->getNode('content')->getNode(0)->getNode('body');
32
 
@@ -41,7 +41,7 @@ class Twig_Tests_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase
41
  }
42
 
43
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
44
- $stream = $env->parse($env->tokenize('{{ block(name|lower) }}', 'index'));
45
 
46
  $node = $stream->getNode('body')->getNode(0)->getNode(1);
47
 
@@ -56,7 +56,7 @@ class Twig_Tests_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase
56
  {
57
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false));
58
 
59
- $stream = $env->parse($env->tokenize($template, 'index'));
60
 
61
  foreach ($expected as $target => $withLoop) {
62
  $this->assertTrue($this->checkForConfiguration($stream, $target, $withLoop), sprintf('variable %s is %soptimized', $target, $withLoop ? 'not ' : ''));
14
  {
15
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
16
 
17
+ $stream = $env->parse($env->tokenize(new Twig_Source('{{ block("foo") }}', 'index')));
18
 
19
  $node = $stream->getNode('body')->getNode(0);
20
 
26
  {
27
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
28
 
29
+ $stream = $env->parse($env->tokenize(new Twig_Source('{% extends "foo" %}{% block content %}{{ parent() }}{% endblock %}', 'index')));
30
 
31
  $node = $stream->getNode('blocks')->getNode('content')->getNode(0)->getNode('body');
32
 
41
  }
42
 
43
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
44
+ $stream = $env->parse($env->tokenize(new Twig_Source('{{ block(name|lower) }}', 'index')));
45
 
46
  $node = $stream->getNode('body')->getNode(0)->getNode(1);
47
 
56
  {
57
  $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false));
58
 
59
+ $stream = $env->parse($env->tokenize(new Twig_Source($template, 'index')));
60
 
61
  foreach ($expected as $target => $withLoop) {
62
  $this->assertTrue($this->checkForConfiguration($stream, $target, $withLoop), sprintf('variable %s is %soptimized', $target, $withLoop ? 'not ' : ''));
vendor/twig/twig/test/Twig/Tests/ParserTest.php CHANGED
@@ -100,7 +100,7 @@ class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase
100
 
101
  /**
102
  * @expectedException Twig_Error_Syntax
103
- * @expectedExceptionMessage A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed at line 1.
104
  */
105
  public function testFilterBodyNodesWithBOM()
106
  {
@@ -141,14 +141,14 @@ class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase
141
  'optimizations' => 0,
142
  ));
143
 
144
- $twig->parse($twig->tokenize(<<<EOF
145
  {% from _self import foo %}
146
 
147
  {% macro foo() %}
148
  {{ foo }}
149
  {% endmacro %}
150
  EOF
151
- ));
152
  }
153
 
154
  protected function getParser()
@@ -156,6 +156,7 @@ EOF
156
  $parser = new TestParser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
157
  $parser->setParent(new Twig_Node());
158
  $parser->stream = $this->getMockBuilder('Twig_TokenStream')->disableOriginalConstructor()->getMock();
 
159
 
160
  return $parser;
161
  }
100
 
101
  /**
102
  * @expectedException Twig_Error_Syntax
103
+ * @expectedExceptionMessage A template that extends another one cannot start with a byte order mark (BOM); it must be removed at line 1
104
  */
105
  public function testFilterBodyNodesWithBOM()
106
  {
141
  'optimizations' => 0,
142
  ));
143
 
144
+ $twig->parse($twig->tokenize(new Twig_Source(<<<EOF
145
  {% from _self import foo %}
146
 
147
  {% macro foo() %}
148
  {{ foo }}
149
  {% endmacro %}
150
  EOF
151
+ , 'index')));
152
  }
153
 
154
  protected function getParser()
156
  $parser = new TestParser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
157
  $parser->setParent(new Twig_Node());
158
  $parser->stream = $this->getMockBuilder('Twig_TokenStream')->disableOriginalConstructor()->getMock();
159
+ $parser->stream->expects($this->any())->method('getSourceContext')->will($this->returnValue(new Twig_Source('', '')));
160
 
161
  return $parser;
162
  }
vendor/twig/twig/test/Twig/Tests/TemplateTest.php CHANGED
@@ -56,22 +56,22 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
56
  public function getAttributeExceptions()
57
  {
58
  $tests = array(
59
- array('{{ string["a"] }}', 'Impossible to access a key ("a") on a string variable ("foo") in "%s" at line 1', false),
60
- array('{{ null["a"] }}', 'Impossible to access a key ("a") on a null variable in "%s" at line 1', false),
61
- array('{{ empty_array["a"] }}', 'Key "a" does not exist as the array is empty in "%s" at line 1', false),
62
- array('{{ array["a"] }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1', false),
63
- array('{{ array_access["a"] }}', 'Key "a" in object with ArrayAccess of class "Twig_TemplateArrayAccessObject" does not exist in "%s" at line 1', false),
64
- array('{{ string.a }}', 'Impossible to access an attribute ("a") on a string variable ("foo") in "%s" at line 1', false),
65
- array('{{ string.a() }}', 'Impossible to invoke a method ("a") on a string variable ("foo") in "%s" at line 1', false),
66
- array('{{ null.a }}', 'Impossible to access an attribute ("a") on a null variable in "%s" at line 1', false),
67
- array('{{ null.a() }}', 'Impossible to invoke a method ("a") on a null variable in "%s" at line 1', false),
68
- array('{{ empty_array.a }}', 'Key "a" does not exist as the array is empty in "%s" at line 1', false),
69
- array('{{ array.a }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1', false),
70
- array('{{ attribute(array, -10) }}', 'Key "-10" for array with keys "foo" does not exist in "%s" at line 1', false),
71
- array('{{ array_access.a }}', 'Neither the property "a" nor one of the methods "a()", "geta()"/"isa()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1', false),
72
- array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', 'Neither the property "missing_method" nor one of the methods "missing_method()", "getmissing_method()"/"ismissing_method()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1', false),
73
  array('{{ magic_exception.test }}', 'An exception has been thrown during the rendering of a template ("Hey! Don\'t try to isset me!") in "%s" at line 1.', false),
74
- array('{{ object["a"] }}', 'Impossible to access a key "a" on an object of class "stdClass" that does not implement ArrayAccess interface in "%s" at line 1', false),
75
  );
76
 
77
  if (function_exists('twig_template_get_attributes')) {
@@ -84,13 +84,6 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
84
  return $tests;
85
  }
86
 
87
- public function testGetSource()
88
- {
89
- $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()), false);
90
-
91
- $this->assertSame("<? */*bar*/ ?>\n", $template->getSource());
92
- }
93
-
94
  /**
95
  * @dataProvider getGetAttributeWithSandbox
96
  */
@@ -394,9 +387,9 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
394
 
395
  // tests when input is not an array or object
396
  $tests = array_merge($tests, array(
397
- array(false, null, 42, 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a integer variable ("42")'),
398
- array(false, null, 'string', 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a string variable ("string")'),
399
- array(false, null, array(), 'a', array(), $anyType, false, 'Key "a" does not exist as the array is empty'),
400
  ));
401
 
402
  // add twig_template_get_attributes tests
@@ -453,6 +446,11 @@ class Twig_TemplateTest extends Twig_Template
453
  return array();
454
  }
455
 
 
 
 
 
 
456
  protected function doGetParent(array $context)
457
  {
458
  }
@@ -470,8 +468,6 @@ class Twig_TemplateTest extends Twig_Template
470
  }
471
  }
472
  }
473
- /* <? *//* *bar*//* ?>*/
474
- /* */
475
 
476
  class Twig_TemplateArrayAccessObject implements ArrayAccess
477
  {
56
  public function getAttributeExceptions()
57
  {
58
  $tests = array(
59
+ array('{{ string["a"] }}', 'Impossible to access a key ("a") on a string variable ("foo") in "%s" at line 1.', false),
60
+ array('{{ null["a"] }}', 'Impossible to access a key ("a") on a null variable in "%s" at line 1.', false),
61
+ array('{{ empty_array["a"] }}', 'Key "a" does not exist as the array is empty in "%s" at line 1.', false),
62
+ array('{{ array["a"] }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1.', false),
63
+ array('{{ array_access["a"] }}', 'Key "a" in object with ArrayAccess of class "Twig_TemplateArrayAccessObject" does not exist in "%s" at line 1.', false),
64
+ array('{{ string.a }}', 'Impossible to access an attribute ("a") on a string variable ("foo") in "%s" at line 1.', false),
65
+ array('{{ string.a() }}', 'Impossible to invoke a method ("a") on a string variable ("foo") in "%s" at line 1.', false),
66
+ array('{{ null.a }}', 'Impossible to access an attribute ("a") on a null variable in "%s" at line 1.', false),
67
+ array('{{ null.a() }}', 'Impossible to invoke a method ("a") on a null variable in "%s" at line 1.', false),
68
+ array('{{ empty_array.a }}', 'Key "a" does not exist as the array is empty in "%s" at line 1.', false),
69
+ array('{{ array.a }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1.', false),
70
+ array('{{ attribute(array, -10) }}', 'Key "-10" for array with keys "foo" does not exist in "%s" at line 1.', false),
71
+ array('{{ array_access.a }}', 'Neither the property "a" nor one of the methods "a()", "geta()"/"isa()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1.', false),
72
+ array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', 'Neither the property "missing_method" nor one of the methods "missing_method()", "getmissing_method()"/"ismissing_method()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1.', false),
73
  array('{{ magic_exception.test }}', 'An exception has been thrown during the rendering of a template ("Hey! Don\'t try to isset me!") in "%s" at line 1.', false),
74
+ array('{{ object["a"] }}', 'Impossible to access a key "a" on an object of class "stdClass" that does not implement ArrayAccess interface in "%s" at line 1.', false),
75
  );
76
 
77
  if (function_exists('twig_template_get_attributes')) {
84
  return $tests;
85
  }
86
 
 
 
 
 
 
 
 
87
  /**
88
  * @dataProvider getGetAttributeWithSandbox
89
  */
387
 
388
  // tests when input is not an array or object
389
  $tests = array_merge($tests, array(
390
+ array(false, null, 42, 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a integer variable ("42").'),
391
+ array(false, null, 'string', 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a string variable ("string").'),
392
+ array(false, null, array(), 'a', array(), $anyType, false, 'Key "a" does not exist as the array is empty.'),
393
  ));
394
 
395
  // add twig_template_get_attributes tests
446
  return array();
447
  }
448
 
449
+ public function getSource()
450
+ {
451
+ return '';
452
+ }
453
+
454
  protected function doGetParent(array $context)
455
  {
456
  }
468
  }
469
  }
470
  }
 
 
471
 
472
  class Twig_TemplateArrayAccessObject implements ArrayAccess
473
  {
vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php CHANGED
@@ -27,6 +27,18 @@ class Twig_Tests_TokenStreamTest extends PHPUnit_Framework_TestCase
27
  );
28
  }
29
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  public function testNext()
31
  {
32
  $stream = new Twig_TokenStream(self::$tokens);
27
  );
28
  }
29
 
30
+ /**
31
+ * @group legacy
32
+ */
33
+ public function testLegacyConstructorSignature()
34
+ {
35
+ $stream = new Twig_TokenStream(array(), 'foo', '{{ foo }}');
36
+ $this->assertEquals('foo', $stream->getFilename());
37
+ $this->assertEquals('{{ foo }}', $stream->getSource());
38
+ $this->assertEquals('foo', $stream->getSourceContext()->getName());
39
+ $this->assertEquals('{{ foo }}', $stream->getSourceContext()->getCode());
40
+ }
41
+
42
  public function testNext()
43
  {
44
  $stream = new Twig_TokenStream(self::$tokens);
vendor/twig/twig/test/Twig/Tests/escapingTest.php CHANGED
@@ -250,7 +250,7 @@ class Twig_Test_EscapingTest extends PHPUnit_Framework_TestCase
250
  .chr($codepoint >> 6 & 0x3f | 0x80)
251
  .chr($codepoint & 0x3f | 0x80);
252
  }
253
- throw new Exception('Codepoint requested outside of Unicode range');
254
  }
255
 
256
  public function testJavascriptEscapingEscapesOwaspRecommendedRanges()
250
  .chr($codepoint >> 6 & 0x3f | 0x80)
251
  .chr($codepoint & 0x3f | 0x80);
252
  }
253
+ throw new Exception('Codepoint requested outside of Unicode range.');
254
  }
255
 
256
  public function testJavascriptEscapingEscapesOwaspRecommendedRanges()