Weather Underground - Version 2.1.3

Version Description

Download this release

Release Info

Developer katzwebdesign
Plugin Icon 128x128 Weather Underground
Version 2.1.3
Comparing to
See all releases

Code changes from version 2.1.1 to 2.1.3

Files changed (151) hide show
  1. inc/class-KWS-wunderground.php +20 -0
  2. inc/class-ajax.php +1 -1
  3. inc/class-display.php +1 -1
  4. inc/class-request.php +34 -22
  5. inc/class-template.php +11 -2
  6. inc/class-widget.php +1 -1
  7. inc/functions.php +1 -1
  8. readme.txt +31 -1
  9. vendor/composer/ClassLoader.php +4 -4
  10. vendor/composer/LICENSE +21 -0
  11. vendor/composer/autoload_real.php +0 -5
  12. vendor/composer/installed.json +7 -7
  13. vendor/twig/twig/CHANGELOG +77 -0
  14. vendor/twig/twig/LICENSE +1 -1
  15. vendor/twig/twig/composer.json +1 -1
  16. vendor/twig/twig/doc/advanced.rst +5 -5
  17. vendor/twig/twig/doc/deprecated.rst +21 -7
  18. vendor/twig/twig/doc/filters/merge.rst +2 -1
  19. vendor/twig/twig/doc/filters/sort.rst +2 -1
  20. vendor/twig/twig/doc/intro.rst +3 -3
  21. vendor/twig/twig/doc/recipes.rst +45 -15
  22. vendor/twig/twig/doc/tags/extends.rst +2 -2
  23. vendor/twig/twig/doc/templates.rst +40 -20
  24. vendor/twig/twig/ext/twig/php_twig.h +1 -1
  25. vendor/twig/twig/ext/twig/twig.c +1 -1
  26. vendor/twig/twig/lib/Twig/Autoloader.php +3 -3
  27. vendor/twig/twig/lib/Twig/Cache/Filesystem.php +96 -0
  28. vendor/twig/twig/lib/Twig/Cache/Null.php +48 -0
  29. vendor/twig/twig/lib/Twig/CacheInterface.php +56 -0
  30. vendor/twig/twig/lib/Twig/Environment.php +201 -84
  31. vendor/twig/twig/lib/Twig/Error.php +22 -0
  32. vendor/twig/twig/lib/Twig/Error/Syntax.php +33 -0
  33. vendor/twig/twig/lib/Twig/ExpressionParser.php +28 -25
  34. vendor/twig/twig/lib/Twig/Extension.php +10 -24
  35. vendor/twig/twig/lib/Twig/Extension/Core.php +104 -80
  36. vendor/twig/twig/lib/Twig/Extension/Debug.php +0 -10
  37. vendor/twig/twig/lib/Twig/Extension/Escaper.php +1 -21
  38. vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php +22 -0
  39. vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php +22 -0
  40. vendor/twig/twig/lib/Twig/Extension/Optimizer.php +0 -6
  41. vendor/twig/twig/lib/Twig/Extension/Profiler.php +0 -6
  42. vendor/twig/twig/lib/Twig/Extension/Sandbox.php +0 -15
  43. vendor/twig/twig/lib/Twig/Extension/Staging.php +2 -21
  44. vendor/twig/twig/lib/Twig/Extension/StringLoader.php +2 -8
  45. vendor/twig/twig/lib/Twig/ExtensionInterface.php +8 -4
  46. vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php +13 -4
  47. vendor/twig/twig/lib/Twig/Lexer.php +9 -9
  48. vendor/twig/twig/lib/Twig/Loader/Chain.php +3 -3
  49. vendor/twig/twig/lib/Twig/Loader/Filesystem.php +1 -1
  50. vendor/twig/twig/lib/Twig/Loader/String.php +3 -1
  51. vendor/twig/twig/lib/Twig/Node.php +2 -2
  52. vendor/twig/twig/lib/Twig/Node/AutoEscape.php +0 -5
  53. vendor/twig/twig/lib/Twig/Node/Block.php +0 -5
  54. vendor/twig/twig/lib/Twig/Node/BlockReference.php +0 -5
  55. vendor/twig/twig/lib/Twig/Node/Do.php +0 -5
  56. vendor/twig/twig/lib/Twig/Node/Expression/Array.php +0 -5
  57. vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php +0 -5
  58. vendor/twig/twig/lib/Twig/Node/Expression/Binary.php +0 -5
  59. vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php +0 -5
  60. vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php +0 -5
  61. vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php +0 -5
  62. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php +0 -5
  63. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php +0 -5
  64. vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php +0 -5
  65. vendor/twig/twig/lib/Twig/Node/Expression/Call.php +51 -45
  66. vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php +4 -5
  67. vendor/twig/twig/lib/Twig/Node/Expression/Name.php +0 -8
  68. vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php +23 -0
  69. vendor/twig/twig/lib/Twig/Node/Expression/Parent.php +0 -5
  70. vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php +5 -3
  71. vendor/twig/twig/lib/Twig/Node/Flush.php +0 -5
  72. vendor/twig/twig/lib/Twig/Node/For.php +1 -7
  73. vendor/twig/twig/lib/Twig/Node/ForLoop.php +0 -5
  74. vendor/twig/twig/lib/Twig/Node/If.php +0 -5
  75. vendor/twig/twig/lib/Twig/Node/Import.php +0 -5
  76. vendor/twig/twig/lib/Twig/Node/Include.php +0 -5
  77. vendor/twig/twig/lib/Twig/Node/Macro.php +6 -6
  78. vendor/twig/twig/lib/Twig/Node/Module.php +0 -5
  79. vendor/twig/twig/lib/Twig/Node/Print.php +0 -5
  80. vendor/twig/twig/lib/Twig/Node/Sandbox.php +0 -5
  81. vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php +0 -10
  82. vendor/twig/twig/lib/Twig/Node/Set.php +0 -5
  83. vendor/twig/twig/lib/Twig/Node/Spaceless.php +0 -5
  84. vendor/twig/twig/lib/Twig/Node/Text.php +0 -5
  85. vendor/twig/twig/lib/Twig/Parser.php +17 -17
  86. vendor/twig/twig/lib/Twig/Profiler/Profile.php +10 -0
  87. vendor/twig/twig/lib/Twig/SimpleFilter.php +5 -0
  88. vendor/twig/twig/lib/Twig/SimpleFunction.php +5 -0
  89. vendor/twig/twig/lib/Twig/SimpleTest.php +5 -0
  90. vendor/twig/twig/lib/Twig/Template.php +52 -1
  91. vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php +56 -8
  92. vendor/twig/twig/lib/Twig/Test/NodeTestCase.php +8 -4
  93. vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php +2 -14
  94. vendor/twig/twig/lib/Twig/TokenParser/Block.php +2 -14
  95. vendor/twig/twig/lib/Twig/TokenParser/Do.php +0 -12
  96. vendor/twig/twig/lib/Twig/TokenParser/Embed.php +0 -12
  97. vendor/twig/twig/lib/Twig/TokenParser/Extends.php +2 -14
  98. vendor/twig/twig/lib/Twig/TokenParser/Filter.php +0 -12
  99. vendor/twig/twig/lib/Twig/TokenParser/Flush.php +0 -12
  100. vendor/twig/twig/lib/Twig/TokenParser/For.php +2 -14
  101. vendor/twig/twig/lib/Twig/TokenParser/From.php +1 -13
  102. vendor/twig/twig/lib/Twig/TokenParser/If.php +1 -13
  103. vendor/twig/twig/lib/Twig/TokenParser/Import.php +0 -12
  104. vendor/twig/twig/lib/Twig/TokenParser/Include.php +0 -12
  105. vendor/twig/twig/lib/Twig/TokenParser/Macro.php +1 -13
  106. vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php +1 -13
  107. vendor/twig/twig/lib/Twig/TokenParser/Set.php +0 -12
  108. vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php +0 -12
  109. vendor/twig/twig/lib/Twig/TokenParser/Use.php +0 -12
  110. vendor/twig/twig/lib/Twig/TokenParserBroker.php +5 -4
  111. vendor/twig/twig/lib/Twig/TokenStream.php +3 -3
  112. vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php +255 -18
  113. vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php +45 -4
  114. vendor/twig/twig/test/Twig/Tests/Extension/CoreTest.php +2 -0
  115. vendor/twig/twig/test/Twig/Tests/Extension/SandboxTest.php +1 -1
  116. vendor/twig/twig/test/Twig/Tests/FileCachingTest.php +13 -29
  117. vendor/twig/twig/test/Twig/Tests/FileExtensionEscapingStrategyTest.php +3 -1
  118. vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/syntax_error_in_reused_template.test +10 -0
  119. vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/unclosed_tag.test +1 -1
  120. vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_template_in_child_template.test +15 -0
  121. vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/two_word_operators_as_variables.test +1 -1
  122. vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_keys.test +10 -0
  123. vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_zero_elements.test +10 -0
  124. vendor/twig/twig/test/Twig/Tests/Fixtures/filters/merge.test +3 -1
  125. vendor/twig/twig/test/Twig/Tests/Fixtures/filters/replace.test +6 -2
  126. vendor/twig/twig/test/Twig/Tests/Fixtures/filters/sort.test +3 -1
  127. vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling.test +16 -0
  128. vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling_ignore_missing.test +13 -0
  129. vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs.test +21 -0
  130. vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs_argument.test +8 -0
  131. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.legacy.test +11 -0
  132. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/block_unique_name.test +1 -1
  133. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/with_extends.test +4 -1
  134. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined.test +1 -1
  135. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined_cond.test +1 -1
  136. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_in_a_block.test +1 -1
  137. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends.test +1 -1
  138. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid1.test +1 -1
  139. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid2.test +1 -1
  140. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance.test +2 -2
  141. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance2.test +2 -2
  142. vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/mixed_usage_with_raw.test +1 -1
  143. vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined.test +21 -0
  144. vendor/twig/twig/test/Twig/Tests/Node/ForTest.php +4 -4
  145. vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php +4 -0
  146. vendor/twig/twig/test/Twig/Tests/Node/ModuleTest.php +6 -6
  147. vendor/twig/twig/test/Twig/Tests/ParserTest.php +17 -1
  148. vendor/twig/twig/test/Twig/Tests/TemplateTest.php +12 -3
  149. vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php +1 -1
  150. vendor/twig/twig/test/Twig/Tests/escapingTest.php +1 -1
  151. wunderground.php +47 -5
inc/class-KWS-wunderground.php CHANGED
@@ -12,6 +12,12 @@ class KWS_Wunderground {
12
 
13
  var $alerts;
14
 
 
 
 
 
 
 
15
  function __construct( Wunderground_Request $request ) {
16
 
17
  $results = $request->get_results();
@@ -19,6 +25,9 @@ class KWS_Wunderground {
19
  if( !empty( $results->error ) ) {
20
  // TODO: Handle properly
21
  Wunderground_Plugin::log_error( 'Error loading results KWS_Wunderground', $results->error );
 
 
 
22
  return NULL;
23
  }
24
 
@@ -30,4 +39,15 @@ class KWS_Wunderground {
30
  Wunderground_Plugin::log_debug( 'Wunderground_Forecast', $this );
31
  }
32
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
12
 
13
  var $alerts;
14
 
15
+ /**
16
+ * @since 2.1.2
17
+ * @var null
18
+ */
19
+ var $error = null;
20
+
21
  function __construct( Wunderground_Request $request ) {
22
 
23
  $results = $request->get_results();
25
  if( !empty( $results->error ) ) {
26
  // TODO: Handle properly
27
  Wunderground_Plugin::log_error( 'Error loading results KWS_Wunderground', $results->error );
28
+
29
+ $this->error = $results->error;
30
+
31
  return NULL;
32
  }
33
 
39
  Wunderground_Plugin::log_debug( 'Wunderground_Forecast', $this );
40
  }
41
 
42
+ /**
43
+ * Return error, if any.
44
+ *
45
+ * @since 2.1.2
46
+ *
47
+ * @return null|string NULL if no error. Error string if error.
48
+ */
49
+ public function get_error() {
50
+ return $this->error;
51
+ }
52
+
53
  }
inc/class-ajax.php CHANGED
@@ -23,7 +23,7 @@ final class Wunderground_Ajax {
23
  'h' => 0, // No hurricanes, please.
24
  'c' => $country,
25
  'type' => 'city',
26
- ), 'http://autocomplete.wunderground.com/aq' );
27
 
28
  $response = Wunderground_Request::request( $url );
29
 
23
  'h' => 0, // No hurricanes, please.
24
  'c' => $country,
25
  'type' => 'city',
26
+ ), 'https://autocomplete.wunderground.com/aq' );
27
 
28
  $response = Wunderground_Request::request( $url );
29
 
inc/class-display.php CHANGED
@@ -45,7 +45,7 @@ class Wunderground_Display {
45
  wp_enqueue_script( 'wunderground-widget', plugins_url( 'assets/js/widget'.$min.'.js', Wunderground_Plugin::$file ), array('jquery-ui-autocomplete'), Wunderground_Plugin::version );
46
 
47
  wp_localize_script( 'wunderground-widget', 'WuWidget', array(
48
- 'apiKey' => '3ffab52910ec1a0e',
49
  '_wpnonce' => wp_create_nonce('wunderground-aq'),
50
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
51
  'is_admin' => is_admin(),
45
  wp_enqueue_script( 'wunderground-widget', plugins_url( 'assets/js/widget'.$min.'.js', Wunderground_Plugin::$file ), array('jquery-ui-autocomplete'), Wunderground_Plugin::version );
46
 
47
  wp_localize_script( 'wunderground-widget', 'WuWidget', array(
48
+ 'apiKey' => esc_attr( Wunderground_Plugin::$api_key ),
49
  '_wpnonce' => wp_create_nonce('wunderground-aq'),
50
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
51
  'is_admin' => is_admin(),
inc/class-request.php CHANGED
@@ -2,12 +2,6 @@
2
 
3
  class Wunderground_Request {
4
 
5
- /**
6
- * Your Wunderground.com API key
7
- * @var string
8
- */
9
- private $apiKey = '3ffab52910ec1a0e';
10
-
11
  /**
12
  * What features should be fetched by the request?
13
  *
@@ -174,24 +168,35 @@ class Wunderground_Request {
174
 
175
  $location = $this->location;
176
 
 
 
177
  // We've got a PWS!
178
  // Match both pws:KCASANFR70 and KCASANFR70 formats
179
  // I716, MBGLA2, M41101, MRNDA2, MBGLA2
180
  if( preg_match( '/(pws\:)?([A-Z]{1,11}[0-9]{1,11})/', $location, $matches ) ) {
181
  $location = isset( $matches[2] ) ? $matches[2] : $location;
182
  $location = '/q/pws:'.urlencode($location);
 
183
  }
184
 
185
- /*
 
 
 
 
 
 
 
186
  http://www.wunderground.com/weather-forecast/FR/Paris.html
187
  http://www.wunderground.com/q/FR/Paris.html
188
- http://www.wunderground.com/personal-weather-station/dashboard?ID=I75003PA1*/
 
189
 
190
  // If the location is a link, we don't need to turn it...wait for it...into a link.
191
  $location_path = preg_match( '/\/q\//ism', $location ) ? $location : '/q/'.rawurlencode($location);
192
 
193
  // Combine into one URL
194
- $url = sprintf('%s/%s/v:2.0/%s/%s/%s%s.json', $this->apiUrl, $this->apiKey, $language, $units, $features, $location_path );
195
 
196
  return $url;
197
  }
@@ -213,7 +218,7 @@ class Wunderground_Request {
213
  // Generate a cache key based on the result. Only get the first 44 characters because of
214
  // the transient key length limit.
215
  $cache_key = substr( 'wu_'.sha1($url) , 0, 44 );
216
-
217
  $response = get_transient( $cache_key );
218
 
219
  // If there's no cached result or caching is disabled
@@ -229,21 +234,28 @@ class Wunderground_Request {
229
 
230
  $request = wp_remote_request( $url , $atts );
231
 
232
- $response = wp_remote_retrieve_body( $request );
 
 
 
233
 
234
- /**
235
- * Modify the number of seconds to cache the request for.
236
- *
237
- * Default: cache the request for one hour, since we're dealing with changing conditions
238
- *
239
- * @var int
240
- */
241
- $cache_time = apply_filters( 'wunderground_cache_time', HOUR_IN_SECONDS );
 
 
242
 
243
- // Backward compatible with 1.x
244
- $cache_time = apply_filters( 'wp_wunderground_forecast_cache', $cache_time );
245
 
246
- set_transient( $cache_key, $response, (int)$cache_time );
 
 
247
  }
248
 
249
  return $response;
2
 
3
  class Wunderground_Request {
4
 
 
 
 
 
 
 
5
  /**
6
  * What features should be fetched by the request?
7
  *
168
 
169
  $location = $this->location;
170
 
171
+ $include_pws = false;
172
+
173
  // We've got a PWS!
174
  // Match both pws:KCASANFR70 and KCASANFR70 formats
175
  // I716, MBGLA2, M41101, MRNDA2, MBGLA2
176
  if( preg_match( '/(pws\:)?([A-Z]{1,11}[0-9]{1,11})/', $location, $matches ) ) {
177
  $location = isset( $matches[2] ) ? $matches[2] : $location;
178
  $location = '/q/pws:'.urlencode($location);
179
+ $include_pws = true;
180
  }
181
 
182
+ /**
183
+ * Include PWS stations in the results?
184
+ * @since TODO
185
+ * @param int `0` for no, `1` for yes. Default: `0`
186
+ */
187
+ $pws = sprintf( 'pws:%d', intval( apply_filters( 'wunderground_include_pws', $include_pws ) ) );
188
+
189
+ /*
190
  http://www.wunderground.com/weather-forecast/FR/Paris.html
191
  http://www.wunderground.com/q/FR/Paris.html
192
+ http://www.wunderground.com/personal-weather-station/dashboard?ID=I75003PA1
193
+ */
194
 
195
  // If the location is a link, we don't need to turn it...wait for it...into a link.
196
  $location_path = preg_match( '/\/q\//ism', $location ) ? $location : '/q/'.rawurlencode($location);
197
 
198
  // Combine into one URL
199
+ $url = sprintf('%s/%s/v:2.0/%s/%s/%s/%s%s.json', $this->apiUrl, Wunderground_Plugin::$api_key, $language, $units, $pws, $features, $location_path );
200
 
201
  return $url;
202
  }
218
  // Generate a cache key based on the result. Only get the first 44 characters because of
219
  // the transient key length limit.
220
  $cache_key = substr( 'wu_'.sha1($url) , 0, 44 );
221
+
222
  $response = get_transient( $cache_key );
223
 
224
  // If there's no cached result or caching is disabled
234
 
235
  $request = wp_remote_request( $url , $atts );
236
 
237
+ if( is_wp_error( $request ) ) {
238
+ $response = false;
239
+
240
+ } else {
241
 
242
+ $response = wp_remote_retrieve_body( $request );
243
+
244
+ /**
245
+ * Modify the number of seconds to cache the request for.
246
+ *
247
+ * Default: cache the request for one hour, since we're dealing with changing conditions
248
+ *
249
+ * @var int
250
+ */
251
+ $cache_time = apply_filters( 'wunderground_cache_time', HOUR_IN_SECONDS );
252
 
253
+ // Backward compatible with 1.x
254
+ $cache_time = apply_filters( 'wp_wunderground_forecast_cache', $cache_time );
255
 
256
+ set_transient( $cache_key, $response, (int)$cache_time );
257
+
258
+ }
259
  }
260
 
261
  return $response;
inc/class-template.php CHANGED
@@ -79,8 +79,12 @@ class Wunderground_Template {
79
 
80
  }
81
 
 
 
 
 
82
  function render( $template = NULL, $data = array() ) {
83
-
84
  // The translation text
85
  $data['strings'] = $this->strings();
86
 
@@ -97,7 +101,6 @@ class Wunderground_Template {
97
 
98
  // Map the keys so that they are consistent instead of having some
99
  // using key => key and others using index => key
100
- $showdata = array();
101
  foreach ( (array)$data['showdata'] as $key => $value ) {
102
  $data['showdata'][$value] = $value;
103
  }
@@ -134,6 +137,12 @@ class Wunderground_Template {
134
  set_transient( $cache_key, $output, ( $cache_time * 2 ) );
135
  }
136
 
 
 
 
 
 
 
137
  $output = apply_filters( 'wp_wunderground_forecast', $output, $template, $data );
138
 
139
  echo $output;
79
 
80
  }
81
 
82
+ /**
83
+ * @param string $template Template slug based on value passed by `wunderground_render_template` filter
84
+ * @param array $data
85
+ */
86
  function render( $template = NULL, $data = array() ) {
87
+
88
  // The translation text
89
  $data['strings'] = $this->strings();
90
 
101
 
102
  // Map the keys so that they are consistent instead of having some
103
  // using key => key and others using index => key
 
104
  foreach ( (array)$data['showdata'] as $key => $value ) {
105
  $data['showdata'][$value] = $value;
106
  }
137
  set_transient( $cache_key, $output, ( $cache_time * 2 ) );
138
  }
139
 
140
+ /**
141
+ * Modify the HTML output of the forecast
142
+ * @param string $output HTML of the forecast
143
+ * @param string $template Template slug based on value passed by `wunderground_render_template` filter
144
+ * @param array $data Template data array, with keys `strings`, `showdata`, `subdomain`, `logo`, `user_icon_url`, `language`
145
+ */
146
  $output = apply_filters( 'wp_wunderground_forecast', $output, $template, $data );
147
 
148
  echo $output;
inc/class-widget.php CHANGED
@@ -45,7 +45,7 @@ class Wunderground_Forecast_Widget extends WP_Widget {
45
 
46
  $control_options = array( 'width' => 450 ); // Min-width of widgets config with expanded sidebar
47
 
48
- parent::__construct( 'wunderground', __('Wunderground', 'wunderground'), $widget_ops, $control_options );
49
  }
50
 
51
  /**
45
 
46
  $control_options = array( 'width' => 450 ); // Min-width of widgets config with expanded sidebar
47
 
48
+ parent::__construct( false, __('Wunderground', 'wunderground'), $widget_ops, $control_options );
49
  }
50
 
51
  /**
inc/functions.php CHANGED
@@ -221,7 +221,7 @@ function wunderground_get_autocomplete_country_code() {
221
  /**
222
  * Get the date format for the output.
223
  *
224
- * Backward compatibile with 1.x by converting %%weekday%%, %%day%%, %%month%% and %%year%% into PHP date formats. Also supports converting `date('d/m/Y')` to `d/m/Y`
225
  *
226
  * @link http://codex.wordpress.org/Formatting_Date_and_Time Learn more about formatting datetime
227
  * @filter wunderground_date_format Filter the date format sitewide.
221
  /**
222
  * Get the date format for the output.
223
  *
224
+ * Backward compatible with 1.x by converting %%weekday%%, %%day%%, %%month%% and %%year%% into PHP date formats. Also supports converting `date('d/m/Y')` to `d/m/Y`
225
  *
226
  * @link http://codex.wordpress.org/Formatting_Date_and_Time Learn more about formatting datetime
227
  * @filter wunderground_date_format Filter the date format sitewide.
readme.txt CHANGED
@@ -1,7 +1,7 @@
1
  === Weather Underground ===
2
  Tags: weather, weather.com, wunderground, weather underground, weatherbug, forecast, Yahoo! Weather, wp-weather, wp weather, local weather, weather man, weather widget, cool weather, accuweather, get weather, wordpress weather
3
  Requires at least: 3.6
4
- Tested up to: 4.3
5
  Stable tag: trunk
6
  Contributors: katzwebdesign, katzwebservices
7
  Donate link: https://gravityview.co
@@ -64,6 +64,29 @@ If your location isn't working any more, follow the steps below:
64
  * Use that as your location in the shortcode, like this: `[wunderground location="zmw:00000.4.17340" /]`
65
  * That should work!
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  = How do I use my own icons? =
68
 
69
  If you want to use your own icons, you would add a filter to the bottom of your theme's <code>functions.php</code> file. See a [list of icons you should have available](http://www.wunderground.com/weather/api/d/docs?d=resources/icon-sets). Here's sample code:
@@ -97,6 +120,13 @@ Weather Underground has been very gracious and has provided the plugin with free
97
 
98
  == Changelog ==
99
 
 
 
 
 
 
 
 
100
  = 2.1.1 on August 25, 2015 =
101
  * Fixed: WordPress 4.3 compatibility
102
  * Added: Display any errors while fetching forecasts to administrators
1
  === Weather Underground ===
2
  Tags: weather, weather.com, wunderground, weather underground, weatherbug, forecast, Yahoo! Weather, wp-weather, wp weather, local weather, weather man, weather widget, cool weather, accuweather, get weather, wordpress weather
3
  Requires at least: 3.6
4
+ Tested up to: 4.5.2
5
  Stable tag: trunk
6
  Contributors: katzwebdesign, katzwebservices
7
  Donate link: https://gravityview.co
64
  * Use that as your location in the shortcode, like this: `[wunderground location="zmw:00000.4.17340" /]`
65
  * That should work!
66
 
67
+ = How do I use my own API key? =
68
+ Weather Underground has generously donated free API access to users of this plugin.
69
+
70
+ If you prefer, you can define your own API key in your installation's `wp-config.php` file by setting a `WUNDERGROUND_API_KEY` constant, like so:
71
+
72
+ <pre>
73
+ define( 'WUNDERGROUND_API_KEY', 'myapikey' );
74
+ </pre>
75
+
76
+ You can also override the API key using the `wunderground_api_key` filter, like so:
77
+
78
+ <pre>
79
+ add_filter( 'wunderground_api_key', 'my_custom_wunderground_api_key' );
80
+
81
+ /**
82
+ * Use my own API key!
83
+ * @return string My API key
84
+ */
85
+ function wunderground_api_key( $old_api_key = '' ) {
86
+ return 'myapikey';
87
+ }
88
+ </pre>
89
+
90
  = How do I use my own icons? =
91
 
92
  If you want to use your own icons, you would add a filter to the bottom of your theme's <code>functions.php</code> file. See a [list of icons you should have available](http://www.wunderground.com/weather/api/d/docs?d=resources/icon-sets). Here's sample code:
120
 
121
  == Changelog ==
122
 
123
+ = 2.1.2 and 2.1.3 on June 30, 2016 =
124
+ * Added: Ability to override API key using the `wunderground_api_key` filter or the `WUNDERGROUND_API_KEY` constant
125
+ * Fixed: Location autocomplete issue on HTTPS websites
126
+ * Fixed: Don't cache responses if they result in errors (good idea, eh?)
127
+ * Added: `wunderground_include_pws` filter to toggle whether to include Personal Weather Stations as data sources (Default: false, unless the location requested is specifically a PWS station)
128
+ * Updated: Twig template framework from 1.21.0 to 1.24.1
129
+
130
  = 2.1.1 on August 25, 2015 =
131
  * Fixed: WordPress 4.3 compatibility
132
  * Added: Display any errors while fetching forecasts to administrators
vendor/composer/ClassLoader.php CHANGED
@@ -13,9 +13,7 @@
13
  namespace Composer\Autoload;
14
 
15
  /**
16
- * ClassLoader implements a PSR-0 class loader
17
- *
18
- * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
19
  *
20
  * $loader = new \Composer\Autoload\ClassLoader();
21
  *
@@ -39,6 +37,8 @@ namespace Composer\Autoload;
39
  *
40
  * @author Fabien Potencier <fabien@symfony.com>
41
  * @author Jordi Boggiano <j.boggiano@seld.be>
 
 
42
  */
43
  class ClassLoader
44
  {
@@ -147,7 +147,7 @@ class ClassLoader
147
  * appending or prepending to the ones previously set for this namespace.
148
  *
149
  * @param string $prefix The prefix/namespace, with trailing '\\'
150
- * @param array|string $paths The PSR-0 base directories
151
  * @param bool $prepend Whether to prepend the directories
152
  *
153
  * @throws \InvalidArgumentException
13
  namespace Composer\Autoload;
14
 
15
  /**
16
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
 
 
17
  *
18
  * $loader = new \Composer\Autoload\ClassLoader();
19
  *
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see http://www.php-fig.org/psr/psr-0/
41
+ * @see http://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
147
  * appending or prepending to the ones previously set for this namespace.
148
  *
149
  * @param string $prefix The prefix/namespace, with trailing '\\'
150
+ * @param array|string $paths The PSR-4 base directories
151
  * @param bool $prepend Whether to prepend the directories
152
  *
153
  * @throws \InvalidArgumentException
vendor/composer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Copyright (c) 2015 Nils Adermann, Jordi Boggiano
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
vendor/composer/autoload_real.php CHANGED
@@ -43,8 +43,3 @@ class ComposerAutoloaderInit7374dd036509d2ffae2282c2a10a41ce
43
  return $loader;
44
  }
45
  }
46
-
47
- function composerRequire7374dd036509d2ffae2282c2a10a41ce($file)
48
- {
49
- require $file;
50
- }
43
  return $loader;
44
  }
45
  }
 
 
 
 
 
vendor/composer/installed.json CHANGED
@@ -1,17 +1,17 @@
1
  [
2
  {
3
  "name": "twig/twig",
4
- "version": "v1.21.0",
5
- "version_normalized": "1.21.0.0",
6
  "source": {
7
  "type": "git",
8
  "url": "https://github.com/twigphp/Twig.git",
9
- "reference": "913d282caca9ee0e8d05940c6caa486d58810dd4"
10
  },
11
  "dist": {
12
  "type": "zip",
13
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/913d282caca9ee0e8d05940c6caa486d58810dd4",
14
- "reference": "913d282caca9ee0e8d05940c6caa486d58810dd4",
15
  "shasum": ""
16
  },
17
  "require": {
@@ -21,11 +21,11 @@
21
  "symfony/debug": "~2.7",
22
  "symfony/phpunit-bridge": "~2.7"
23
  },
24
- "time": "2015-08-24 09:51:18",
25
  "type": "library",
26
  "extra": {
27
  "branch-alias": {
28
- "dev-master": "1.21-dev"
29
  }
30
  },
31
  "installation-source": "dist",
1
  [
2
  {
3
  "name": "twig/twig",
4
+ "version": "v1.24.1",
5
+ "version_normalized": "1.24.1.0",
6
  "source": {
7
  "type": "git",
8
  "url": "https://github.com/twigphp/Twig.git",
9
+ "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512"
10
  },
11
  "dist": {
12
  "type": "zip",
13
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/3566d311a92aae4deec6e48682dc5a4528c4a512",
14
+ "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512",
15
  "shasum": ""
16
  },
17
  "require": {
21
  "symfony/debug": "~2.7",
22
  "symfony/phpunit-bridge": "~2.7"
23
  },
24
+ "time": "2016-05-30 09:11:59",
25
  "type": "library",
26
  "extra": {
27
  "branch-alias": {
28
+ "dev-master": "1.24-dev"
29
  }
30
  },
31
  "installation-source": "dist",
vendor/twig/twig/CHANGELOG CHANGED
@@ -1,3 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  * 1.21.0 (2015-08-24)
2
 
3
  * added deprecation notices for deprecated features
1
+ * 1.24.1 (2016-05-30)
2
+
3
+ * fixed reserved keywords (forbids true, false, null and none keywords for variables names)
4
+ * fixed support for PHP7 (Throwable support)
5
+ * marked the following methods as being internals on Twig_Environment:
6
+ getFunctions(), getFilters(), getTests(), getFunction(), getFilter(), getTest(),
7
+ getTokenParsers(), getTags(), getNodeVisitors(), getUnaryOperators(), getBinaryOperators(),
8
+ getFunctions(), getFilters(), getGlobals(), initGlobals(), initExtensions(), and initExtension()
9
+
10
+ * 1.24.0 (2016-01-25)
11
+
12
+ * adding support for the ?? operator
13
+ * fixed the defined test when used on a constant, a map, or a sequence
14
+ * undeprecated _self (should only be used to get the template name, not the template instance)
15
+ * fixed parsing on PHP7
16
+
17
+ * 1.23.3 (2016-01-11)
18
+
19
+ * fixed typo
20
+
21
+ * 1.23.2 (2015-01-11)
22
+
23
+ * added versions in deprecated messages
24
+ * made file cache tolerant for trailing (back)slashes on directory configuration
25
+ * deprecated unused Twig_Node_Expression_ExtensionReference class
26
+
27
+ * 1.23.1 (2015-11-05)
28
+
29
+ * fixed some exception messages which triggered PHP warnings
30
+ * fixed BC on Twig_Test_NodeTestCase
31
+
32
+ * 1.23.0 (2015-10-29)
33
+
34
+ * deprecated the possibility to override an extension by registering another one with the same name
35
+ * deprecated Twig_ExtensionInterface::getGlobals() (added Twig_Extension_GlobalsInterface for BC)
36
+ * deprecated Twig_ExtensionInterface::initRuntime() (added Twig_Extension_InitRuntimeInterface for BC)
37
+ * deprecated Twig_Environment::computeAlternatives()
38
+
39
+ * 1.22.3 (2015-10-13)
40
+
41
+ * fixed regression when using null as a cache strategy
42
+ * improved performance when checking template freshness
43
+ * fixed warnings when loaded templates do not exist
44
+ * fixed template class name generation to prevent possible collisions
45
+ * fixed logic for custom escapers to call them even on integers and null values
46
+ * changed template cache names to take into account the Twig C extension
47
+
48
+ * 1.22.2 (2015-09-22)
49
+
50
+ * fixed a race condition in template loading
51
+
52
+ * 1.22.1 (2015-09-15)
53
+
54
+ * fixed regression in template_from_string
55
+
56
+ * 1.22.0 (2015-09-13)
57
+
58
+ * made Twig_Test_IntegrationTestCase more flexible
59
+ * added an option to force PHP bytecode invalidation when writing a compiled template into the cache
60
+ * fixed the profiler duration for the root node
61
+ * changed template cache names to take into account enabled extensions
62
+ * deprecated Twig_Environment::clearCacheFiles(), Twig_Environment::getCacheFilename(),
63
+ Twig_Environment::writeCacheFile(), and Twig_Environment::getTemplateClassPrefix()
64
+ * added a way to override the filesystem template cache system
65
+ * added a way to get the original template source from Twig_Template
66
+
67
+ * 1.21.2 (2015-09-09)
68
+
69
+ * fixed variable names for the deprecation triggering code
70
+ * fixed escaping strategy detection based on filename
71
+ * added Traversable support for replace, merge, and sort
72
+ * deprecated support for character by character replacement for the "replace" filter
73
+
74
+ * 1.21.1 (2015-08-26)
75
+
76
+ * fixed regression when using the deprecated Twig_Test_* classes
77
+
78
  * 1.21.0 (2015-08-24)
79
 
80
  * added deprecation notices for deprecated features
vendor/twig/twig/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009-2014 by the Twig Team.
2
 
3
  Some rights reserved.
4
 
1
+ Copyright (c) 2009-2016 by the Twig Team.
2
 
3
  Some rights reserved.
4
 
vendor/twig/twig/composer.json CHANGED
@@ -40,7 +40,7 @@
40
  },
41
  "extra": {
42
  "branch-alias": {
43
- "dev-master": "1.21-dev"
44
  }
45
  }
46
  }
40
  },
41
  "extra": {
42
  "branch-alias": {
43
+ "dev-master": "1.24-dev"
44
  }
45
  }
46
  }
vendor/twig/twig/doc/advanced.rst CHANGED
@@ -553,6 +553,8 @@ An extension is a class that implements the following interface::
553
  * This is where you can load some file that contains filter functions for instance.
554
  *
555
  * @param Twig_Environment $environment The current Twig_Environment instance
 
 
556
  */
557
  function initRuntime(Twig_Environment $environment);
558
 
@@ -602,6 +604,8 @@ An extension is a class that implements the following interface::
602
  * Returns a list of global variables to add to the existing list.
603
  *
604
  * @return array An array of global variables
 
 
605
  */
606
  function getGlobals();
607
 
@@ -645,9 +649,6 @@ main ``Environment`` object::
645
  $twig = new Twig_Environment($loader);
646
  $twig->addExtension(new Project_Twig_Extension());
647
 
648
- Of course, you need to first load the extension file by either using
649
- ``require_once()`` or by using an autoloader (see `spl_autoload_register()`_).
650
-
651
  .. tip::
652
 
653
  The bundled extensions are great examples of how extensions work.
@@ -658,7 +659,7 @@ Globals
658
  Global variables can be registered in an extension via the ``getGlobals()``
659
  method::
660
 
661
- class Project_Twig_Extension extends Twig_Extension
662
  {
663
  public function getGlobals()
664
  {
@@ -866,7 +867,6 @@ Testing the node visitors can be complex, so extend your test cases from
866
  ``Twig_Test_NodeTestCase``. Examples can be found in the Twig repository
867
  `tests/Twig/Node`_ directory.
868
 
869
- .. _`spl_autoload_register()`: http://www.php.net/spl_autoload_register
870
  .. _`rot13`: http://www.php.net/manual/en/function.str-rot13.php
871
  .. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Fixtures
872
  .. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Node
553
  * This is where you can load some file that contains filter functions for instance.
554
  *
555
  * @param Twig_Environment $environment The current Twig_Environment instance
556
+ *
557
+ * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
558
  */
559
  function initRuntime(Twig_Environment $environment);
560
 
604
  * Returns a list of global variables to add to the existing list.
605
  *
606
  * @return array An array of global variables
607
+ *
608
+ * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_GlobalsInterface instead
609
  */
610
  function getGlobals();
611
 
649
  $twig = new Twig_Environment($loader);
650
  $twig->addExtension(new Project_Twig_Extension());
651
 
 
 
 
652
  .. tip::
653
 
654
  The bundled extensions are great examples of how extensions work.
659
  Global variables can be registered in an extension via the ``getGlobals()``
660
  method::
661
 
662
+ class Project_Twig_Extension extends Twig_Extension implements Twig_Extension_GlobalsInterface
663
  {
664
  public function getGlobals()
665
  {
867
  ``Twig_Test_NodeTestCase``. Examples can be found in the Twig repository
868
  `tests/Twig/Node`_ directory.
869
 
 
870
  .. _`rot13`: http://www.php.net/manual/en/function.str-rot13.php
871
  .. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Fixtures
872
  .. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Node
vendor/twig/twig/doc/deprecated.rst CHANGED
@@ -26,6 +26,17 @@ Extensions
26
  * As of Twig 1.x, the ability to remove an extension is deprecated and the
27
  ``Twig_Environment::removeExtension()`` method will be removed in 2.0.
28
 
 
 
 
 
 
 
 
 
 
 
 
29
  PEAR
30
  ----
31
 
@@ -117,13 +128,13 @@ Loaders
117
  -------
118
 
119
  * As of Twig 1.x, ``Twig_Loader_String`` is deprecated and will be removed in
120
- 2.0.
121
 
122
  Node Visitors
123
  -------------
124
 
125
  * Because of the removal of ``Twig_NodeInterface`` in 2.0, you need to extend
126
- ``Twig_BaseNodeVistor`` instead of implementing ``Twig_NodeVisitorInterface``
127
  directly to make your node visitors compatible with both Twig 1.x and 2.x.
128
 
129
  Globals
@@ -133,15 +144,18 @@ Globals
133
  or the extensions have been initialized is not possible anymore (but
134
  changing the value of an already registered global is possible).
135
 
136
- * As of Twig 1.x, the ``_self`` global variable is deprecated except for usage
137
- in the ``from`` and the ``import`` tags. In Twig 2.0, ``_self`` is not
138
- exposed anymore but still usable in the ``from`` and the ``import`` tags.
 
 
139
 
140
  Miscellaneous
141
  -------------
142
 
143
- * As of Twig 1.x, ``Twig_Environment::clearTemplateCache()`` is deprecated and
144
- will be removed in 2.0.
 
145
 
146
  * As of Twig 1.x, ``Twig_Template::getEnvironment()`` and
147
  ``Twig_TemplateInterface::getEnvironment()`` are deprecated and will be
26
  * As of Twig 1.x, the ability to remove an extension is deprecated and the
27
  ``Twig_Environment::removeExtension()`` method will be removed in 2.0.
28
 
29
+ * As of Twig 1.23, the ``Twig_ExtensionInterface::initRuntime()`` method is
30
+ deprecated. You have two options to avoid the deprecation notice: if you
31
+ implement this method to store the environment for your custom filters,
32
+ functions, or tests, use the ``needs_environment`` option instead; if you
33
+ have more complex needs, explicitly implement
34
+ ``Twig_Extension_InitRuntimeInterface`` (not recommended).
35
+
36
+ * As of Twig 1.23, the ``Twig_ExtensionInterface::getGlobals()`` method is
37
+ deprecated. Implement ``Twig_Extension_GlobalsInterface`` to avoid
38
+ deprecation notices.
39
+
40
  PEAR
41
  ----
42
 
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
 
136
  * Because of the removal of ``Twig_NodeInterface`` in 2.0, you need to extend
137
+ ``Twig_BaseNodeVisitor`` instead of implementing ``Twig_NodeVisitorInterface``
138
  directly to make your node visitors compatible with both Twig 1.x and 2.x.
139
 
140
  Globals
144
  or the extensions have been initialized is not possible anymore (but
145
  changing the value of an already registered global is possible).
146
 
147
+ * As of Twig 1.x, using the ``_self`` global variable to get access to the
148
+ current ``Twig_Template`` instance is deprecated; most usages only need the
149
+ current template name, which will continue to work in Twig 2.0. In Twig 2.0,
150
+ ``_self`` returns the current template name instead of the current
151
+ ``Twig_Template`` instance.
152
 
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
vendor/twig/twig/doc/filters/merge.rst CHANGED
@@ -42,6 +42,7 @@ overridden.
42
 
43
  .. note::
44
 
45
- Internally, Twig uses the PHP `array_merge`_ function.
 
46
 
47
  .. _`array_merge`: http://php.net/array_merge
42
 
43
  .. note::
44
 
45
+ Internally, Twig uses the PHP `array_merge`_ function. It supports
46
+ Traversable objects by transforming those to arrays.
47
 
48
  .. _`array_merge`: http://php.net/array_merge
vendor/twig/twig/doc/filters/sort.rst CHANGED
@@ -12,6 +12,7 @@ The ``sort`` filter sorts an array:
12
  .. note::
13
 
14
  Internally, Twig uses the PHP `asort`_ function to maintain index
15
- association.
 
16
 
17
  .. _`asort`: http://php.net/asort
12
  .. note::
13
 
14
  Internally, Twig uses the PHP `asort`_ function to maintain index
15
+ association. It supports Traversable objects by transforming
16
+ those to arrays.
17
 
18
  .. _`asort`: http://php.net/asort
vendor/twig/twig/doc/intro.rst CHANGED
@@ -19,11 +19,11 @@ The key-features are...
19
  may modify the template design.
20
 
21
  * *Flexible*: Twig is powered by a flexible lexer and parser. This allows the
22
- developer to define its own custom tags and filters, and create its own DSL.
23
 
24
  Twig is used by many Open-Source projects like Symfony, Drupal8, eZPublish,
25
- phpBB, Piwik, OroCRM, and many frameworks have support for it as well like
26
- Slim, Yii, Laravel, Codeigniter, and Kohana, just to name a few.
27
 
28
  Prerequisites
29
  -------------
19
  may modify the template design.
20
 
21
  * *Flexible*: Twig is powered by a flexible lexer and parser. This allows the
22
+ developer to define their own custom tags and filters, and to create their own DSL.
23
 
24
  Twig is used by many Open-Source projects like Symfony, Drupal8, eZPublish,
25
+ phpBB, Piwik, OroCRM; and many frameworks have support for it as well like
26
+ Slim, Yii, Laravel, Codeigniter and Kohana just to name a few.
27
 
28
  Prerequisites
29
  -------------
vendor/twig/twig/doc/recipes.rst CHANGED
@@ -280,7 +280,7 @@ For functions, use ``registerUndefinedFunctionCallback()``::
280
  // don't try this at home as it's not secure at all!
281
  $twig->registerUndefinedFunctionCallback(function ($name) {
282
  if (function_exists($name)) {
283
- return new Twig_Function_Function($name);
284
  }
285
 
286
  return false;
@@ -337,24 +337,33 @@ Refreshing modified Templates when OPcache or APC is enabled
337
 
338
  When using OPcache with ``opcache.validate_timestamps`` set to ``0`` or APC
339
  with ``apc.stat`` set to ``0`` and Twig cache enabled, clearing the template
340
- cache won't update the cache. To get around this, one can extend
341
- ``Twig_Environment`` and force the update of the cache when Twig rewrites the
342
- cache::
343
 
344
- class Twig_Environment_APC extends Twig_Environment
345
- {
346
- protected function writeCacheFile($file, $content)
347
- {
348
- parent::writeCacheFile($file, $content);
 
349
 
350
- // Compile cached file into bytecode cache
351
- if (extension_loaded('Zend OPcache') && ini_get('opcache.enable')) {
352
- opcache_compile_file($file);
353
- } elseif (extension_loaded('apc') && ini_get('apc.enabled')) {
354
- apc_compile_file($file);
 
 
 
 
 
 
 
 
 
 
 
355
  }
356
  }
357
- }
358
 
359
  Reusing a stateful Node Visitor
360
  -------------------------------
@@ -485,4 +494,25 @@ logical name, and not the path from the filesystem::
485
  Now that the ``base.twig`` templates is defined in an array loader, you can
486
  remove it from the database, and everything else will still work as before.
487
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  .. _callback: http://www.php.net/manual/en/function.is-callable.php
280
  // don't try this at home as it's not secure at all!
281
  $twig->registerUndefinedFunctionCallback(function ($name) {
282
  if (function_exists($name)) {
283
+ return new Twig_SimpleFunction($name, $name);
284
  }
285
 
286
  return false;
337
 
338
  When using OPcache with ``opcache.validate_timestamps`` set to ``0`` or APC
339
  with ``apc.stat`` set to ``0`` and Twig cache enabled, clearing the template
340
+ cache won't update the cache.
 
 
341
 
342
+ To get around this, force Twig to invalidate the bytecode cache::
343
+
344
+ $twig = new Twig_Environment($loader, array(
345
+ 'cache' => new Twig_Cache_Filesystem('/some/cache/path', Twig_Cache_Filesystem::FORCE_BYTECODE_INVALIDATION),
346
+ // ...
347
+ ));
348
 
349
+ .. note::
350
+
351
+ Before Twig 1.22, you should extend ``Twig_Environment`` instead::
352
+
353
+ class OpCacheAwareTwigEnvironment extends Twig_Environment
354
+ {
355
+ protected function writeCacheFile($file, $content)
356
+ {
357
+ parent::writeCacheFile($file, $content);
358
+
359
+ // Compile cached file into bytecode cache
360
+ if (function_exists('opcache_invalidate')) {
361
+ opcache_invalidate($file, true);
362
+ } elseif (function_exists('apc_compile_file')) {
363
+ apc_compile_file($file);
364
+ }
365
  }
366
  }
 
367
 
368
  Reusing a stateful Node Visitor
369
  -------------------------------
494
  Now that the ``base.twig`` templates is defined in an array loader, you can
495
  remove it from the database, and everything else will still work as before.
496
 
497
+ Loading a Template from a String
498
+ --------------------------------
499
+
500
+ From a template, you can easily load a template stored in a string via the
501
+ ``template_from_string`` function (available as of Twig 1.11 via the
502
+ ``Twig_Extension_StringLoader`` extension):
503
+
504
+ .. code-block:: jinja
505
+
506
+ {{ include(template_from_string("Hello {{ name }}")) }}
507
+
508
+ From PHP, it's also possible to load a template stored in a string via
509
+ ``Twig_Environment::createTemplate()`` (available as of Twig 1.18)::
510
+
511
+ $template = $twig->createTemplate('hello {{ name }}');
512
+ echo $template->render(array('name' => 'Fabien'));
513
+
514
+ .. note::
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
vendor/twig/twig/doc/tags/extends.rst CHANGED
@@ -131,8 +131,8 @@ to variables from outer scopes:
131
  Block Shortcuts
132
  ---------------
133
 
134
- For blocks with few content, it's possible to use a shortcut syntax. The
135
- following constructs do the same:
136
 
137
  .. code-block:: jinja
138
 
131
  Block Shortcuts
132
  ---------------
133
 
134
+ For blocks with little content, it's possible to use a shortcut syntax. The
135
+ following constructs do the same thing:
136
 
137
  .. code-block:: jinja
138
 
vendor/twig/twig/doc/templates.rst CHANGED
@@ -127,7 +127,7 @@ Global Variables
127
 
128
  The following variables are always available in templates:
129
 
130
- * ``_self``: references the current template (deprecated since Twig 1.20);
131
  * ``_context``: references the current context;
132
  * ``_charset``: references the current charset.
133
 
@@ -293,25 +293,24 @@ designers or yourself:
293
  Including other Templates
294
  -------------------------
295
 
296
- The :doc:`include<tags/include>` tag is useful to include a template and
297
- return the rendered content of that template into the current one:
298
 
299
  .. code-block:: jinja
300
 
301
- {% include 'sidebar.html' %}
302
 
303
- Per default included templates are passed the current context.
304
-
305
- The context that is passed to the included template includes variables defined
306
- in the template:
307
 
308
  .. code-block:: jinja
309
 
310
  {% for box in boxes %}
311
- {% include "render_box.html" %}
312
  {% endfor %}
313
 
314
- The included template ``render_box.html`` is able to access ``box``.
315
 
316
  The filename of the template depends on the template loader. For instance, the
317
  ``Twig_Loader_Filesystem`` allows you to access other templates by giving the
@@ -319,7 +318,7 @@ filename. You can access templates in subdirectories with a slash:
319
 
320
  .. code-block:: jinja
321
 
322
- {% include "sections/articles/sidebar.html" %}
323
 
324
  This behavior depends on the application embedding Twig.
325
 
@@ -587,7 +586,9 @@ exist:
587
  string. They are useful whenever you need a string in the template (for
588
  example as arguments to function calls, filters or just to extend or include
589
  a template). A string can contain a delimiter if it is preceded by a
590
- backslash (``\``) -- like in ``'It\'s good'``.
 
 
591
 
592
  * ``42`` / ``42.23``: Integers and floating point numbers are created by just
593
  writing the number down. If a dot is present the number is a float,
@@ -771,15 +772,27 @@ Other Operators
771
  .. versionadded:: 1.12.0
772
  Support for the extended ternary operator was added in Twig 1.12.0.
773
 
774
- The following operators are very useful but don't fit into any of the other
775
- categories:
776
-
777
- * ``..``: Creates a sequence based on the operand before and after the
778
- operator (this is just syntactic sugar for the :doc:`range<functions/range>`
779
- function).
780
 
781
  * ``|``: Applies a filter.
782
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
783
  * ``~``: Converts all operands into strings and concatenates them. ``{{ "Hello
784
  " ~ name ~ "!" }}`` would return (assuming ``name`` is ``'John'``) ``Hello
785
  John!``.
@@ -796,13 +809,20 @@ categories:
796
  {{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }}
797
  {{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }}
798
 
 
 
 
 
 
 
 
799
  String Interpolation
800
  ~~~~~~~~~~~~~~~~~~~~
801
 
802
  .. versionadded:: 1.5
803
  String interpolation was added in Twig 1.5.
804
 
805
- String interpolation (`#{expression}`) allows any valid expression to appear
806
  within a *double-quoted string*. The result of evaluating that expression is
807
  inserted into the string:
808
 
@@ -850,7 +870,7 @@ leading and or trailing whitespace:
850
  {# output 'no spaces' #}
851
 
852
  The above sample shows the default whitespace control modifier, and how you can
853
- use it to remove whitespace around tags. Trimming space will consume all whitespace
854
  for that side of the tag. It is possible to use whitespace trimming on one side
855
  of a tag:
856
 
127
 
128
  The following variables are always available in templates:
129
 
130
+ * ``_self``: references the current template;
131
  * ``_context``: references the current context;
132
  * ``_charset``: references the current charset.
133
 
293
  Including other Templates
294
  -------------------------
295
 
296
+ The :doc:`include<functions/include>` function is useful to include a template
297
+ and return the rendered content of that template into the current one:
298
 
299
  .. code-block:: jinja
300
 
301
+ {{ include('sidebar.html') }}
302
 
303
+ By default, included templates have access to the same context as the template
304
+ which includes them. This means that any variable defined in the main template
305
+ will be available in the included template too:
 
306
 
307
  .. code-block:: jinja
308
 
309
  {% for box in boxes %}
310
+ {{ include('render_box.html') }}
311
  {% endfor %}
312
 
313
+ The included template ``render_box.html`` is able to access the ``box`` variable.
314
 
315
  The filename of the template depends on the template loader. For instance, the
316
  ``Twig_Loader_Filesystem`` allows you to access other templates by giving the
318
 
319
  .. code-block:: jinja
320
 
321
+ {{ include('sections/articles/sidebar.html') }}
322
 
323
  This behavior depends on the application embedding Twig.
324
 
586
  string. They are useful whenever you need a string in the template (for
587
  example as arguments to function calls, filters or just to extend or include
588
  a template). A string can contain a delimiter if it is preceded by a
589
+ backslash (``\``) -- like in ``'It\'s good'``. If the string contains a
590
+ backslash (e.g. ``'c:\Program Files'``) escape it by doubling it
591
+ (e.g. ``'c:\\Program Files'``).
592
 
593
  * ``42`` / ``42.23``: Integers and floating point numbers are created by just
594
  writing the number down. If a dot is present the number is a float,
772
  .. versionadded:: 1.12.0
773
  Support for the extended ternary operator was added in Twig 1.12.0.
774
 
775
+ The following operators don't fit into any of the other categories:
 
 
 
 
 
776
 
777
  * ``|``: Applies a filter.
778
 
779
+ * ``..``: Creates a sequence based on the operand before and after the operator
780
+ (this is just syntactic sugar for the :doc:`range<functions/range>` function):
781
+
782
+ .. code-block:: jinja
783
+
784
+ {{ 1..5 }}
785
+
786
+ {# equivalent to #}
787
+ {{ range(1, 5) }}
788
+
789
+ Note that you must use parentheses when combining it with the filter operator
790
+ due to the :ref:`operator precedence rules <twig-expressions>`:
791
+
792
+ .. code-block:: jinja
793
+
794
+ (1..5)|join(', ')
795
+
796
  * ``~``: Converts all operands into strings and concatenates them. ``{{ "Hello
797
  " ~ name ~ "!" }}`` would return (assuming ``name`` is ``'John'``) ``Hello
798
  John!``.
809
  {{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }}
810
  {{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }}
811
 
812
+ * ``??``: The null-coalescing operator:
813
+
814
+ .. code-block:: jinja
815
+
816
+ {# returns the value of foo if it is defined and not null, 'no' otherwise #}
817
+ {{ foo ?? 'no' }}
818
+
819
  String Interpolation
820
  ~~~~~~~~~~~~~~~~~~~~
821
 
822
  .. versionadded:: 1.5
823
  String interpolation was added in Twig 1.5.
824
 
825
+ String interpolation (``#{expression}``) allows any valid expression to appear
826
  within a *double-quoted string*. The result of evaluating that expression is
827
  inserted into the string:
828
 
870
  {# output 'no spaces' #}
871
 
872
  The above sample shows the default whitespace control modifier, and how you can
873
+ use it to remove whitespace around tags. Trimming space will consume all whitespace
874
  for that side of the tag. It is possible to use whitespace trimming on one side
875
  of a tag:
876
 
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.21.0"
19
 
20
  #include "php.h"
21
 
15
  #ifndef PHP_TWIG_H
16
  #define PHP_TWIG_H
17
 
18
+ #define PHP_TWIG_VERSION "1.24.1"
19
 
20
  #include "php.h"
21
 
vendor/twig/twig/ext/twig/twig.c CHANGED
@@ -1040,7 +1040,7 @@ PHP_FUNCTION(twig_template_get_attributes)
1040
  efree(item);
1041
  return;
1042
  }
1043
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Method \"%s\" for object \"%s\" does not exist", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
1044
  efree(item);
1045
  return;
1046
  }
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
  }
vendor/twig/twig/lib/Twig/Autoloader.php CHANGED
@@ -9,14 +9,14 @@
9
  * file that was distributed with this source code.
10
  */
11
 
12
- @trigger_error('The Twig_Autoloader class is deprecated and will be removed in 2.0. Use Composer instead.', E_USER_DEPRECATED);
13
 
14
  /**
15
  * Autoloads Twig classes.
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  *
19
- * @deprecated Use Composer instead. Will be removed in Twig 2.0.
20
  */
21
  class Twig_Autoloader
22
  {
@@ -27,7 +27,7 @@ class Twig_Autoloader
27
  */
28
  public static function register($prepend = false)
29
  {
30
- @trigger_error('Using Twig_Autoloader is deprecated. Use Composer instead.', E_USER_DEPRECATED);
31
 
32
  if (PHP_VERSION_ID < 50300) {
33
  spl_autoload_register(array(__CLASS__, 'autoload'));
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ @trigger_error('The Twig_Autoloader class is deprecated since version 1.21 and will be removed in 2.0. Use Composer instead.', E_USER_DEPRECATED);
13
 
14
  /**
15
  * Autoloads Twig classes.
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  *
19
+ * @deprecated since 1.21 and will be removed in 2.0. Use Composer instead. 2.0.
20
  */
21
  class Twig_Autoloader
22
  {
27
  */
28
  public static function register($prepend = false)
29
  {
30
+ @trigger_error('Using Twig_Autoloader is deprecated since version 1.21. Use Composer instead.', E_USER_DEPRECATED);
31
 
32
  if (PHP_VERSION_ID < 50300) {
33
  spl_autoload_register(array(__CLASS__, 'autoload'));
vendor/twig/twig/lib/Twig/Cache/Filesystem.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) 2015 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
+ * Implements a cache on the filesystem.
14
+ *
15
+ * @author Andrew Tch <andrew@noop.lv>
16
+ */
17
+ class Twig_Cache_Filesystem implements Twig_CacheInterface
18
+ {
19
+ const FORCE_BYTECODE_INVALIDATION = 1;
20
+
21
+ private $directory;
22
+ private $options;
23
+
24
+ /**
25
+ * @param $directory string The root cache directory
26
+ * @param $options int A set of options
27
+ */
28
+ public function __construct($directory, $options = 0)
29
+ {
30
+ $this->directory = rtrim($directory, '\/').'/';
31
+ $this->options = $options;
32
+ }
33
+
34
+ /**
35
+ * {@inheritdoc}
36
+ */
37
+ public function generateKey($name, $className)
38
+ {
39
+ $hash = hash('sha256', $className);
40
+
41
+ return $this->directory.$hash[0].$hash[1].'/'.$hash.'.php';
42
+ }
43
+
44
+ /**
45
+ * {@inheritdoc}
46
+ */
47
+ public function load($key)
48
+ {
49
+ @include_once $key;
50
+ }
51
+
52
+ /**
53
+ * {@inheritdoc}
54
+ */
55
+ public function write($key, $content)
56
+ {
57
+ $dir = dirname($key);
58
+ if (!is_dir($dir)) {
59
+ if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
60
+ throw new RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir));
61
+ }
62
+ } elseif (!is_writable($dir)) {
63
+ throw new RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir));
64
+ }
65
+
66
+ $tmpFile = tempnam($dir, basename($key));
67
+ if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $key)) {
68
+ @chmod($key, 0666 & ~umask());
69
+
70
+ if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {
71
+ // Compile cached file into bytecode cache
72
+ if (function_exists('opcache_invalidate')) {
73
+ opcache_invalidate($key, true);
74
+ } elseif (function_exists('apc_compile_file')) {
75
+ apc_compile_file($key);
76
+ }
77
+ }
78
+
79
+ return;
80
+ }
81
+
82
+ throw new RuntimeException(sprintf('Failed to write cache file "%s".', $key));
83
+ }
84
+
85
+ /**
86
+ * {@inheritdoc}
87
+ */
88
+ public function getTimestamp($key)
89
+ {
90
+ if (!file_exists($key)) {
91
+ return 0;
92
+ }
93
+
94
+ return (int) @filemtime($key);
95
+ }
96
+ }
vendor/twig/twig/lib/Twig/Cache/Null.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) 2015 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
+ * Implements a no-cache strategy.
14
+ *
15
+ * @author Fabien Potencier <fabien@symfony.com>
16
+ */
17
+ class Twig_Cache_Null implements Twig_CacheInterface
18
+ {
19
+ /**
20
+ * {@inheritdoc}
21
+ */
22
+ public function generateKey($name, $className)
23
+ {
24
+ return '';
25
+ }
26
+
27
+ /**
28
+ * {@inheritdoc}
29
+ */
30
+ public function write($key, $content)
31
+ {
32
+ }
33
+
34
+ /**
35
+ * {@inheritdoc}
36
+ */
37
+ public function load($key)
38
+ {
39
+ }
40
+
41
+ /**
42
+ * {@inheritdoc}
43
+ */
44
+ public function getTimestamp($key)
45
+ {
46
+ return 0;
47
+ }
48
+ }
vendor/twig/twig/lib/Twig/CacheInterface.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) 2015 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
+ * Interface implemented by cache classes.
14
+ *
15
+ * It is highly recommended to always store templates on the filesystem to
16
+ * benefit from the PHP opcode cache. This interface is mostly useful if you
17
+ * need to implement a custom strategy for storing templates on the filesystem.
18
+ *
19
+ * @author Andrew Tch <andrew@noop.lv>
20
+ */
21
+ interface Twig_CacheInterface
22
+ {
23
+ /**
24
+ * Generates a cache key for the given template class name.
25
+ *
26
+ * @param string $name The template name
27
+ * @param string $className The template class name
28
+ *
29
+ * @return string
30
+ */
31
+ public function generateKey($name, $className);
32
+
33
+ /**
34
+ * Writes the compiled template to cache.
35
+ *
36
+ * @param string $key The cache key
37
+ * @param string $content The template representation as a PHP class
38
+ */
39
+ public function write($key, $content);
40
+
41
+ /**
42
+ * Loads a template from the cache.
43
+ *
44
+ * @param string $key The cache key
45
+ */
46
+ public function load($key);
47
+
48
+ /**
49
+ * Returns the modification timestamp of a key.
50
+ *
51
+ * @param string $key The cache key
52
+ *
53
+ * @return int
54
+ */
55
+ public function getTimestamp($key);
56
+ }
vendor/twig/twig/lib/Twig/Environment.php CHANGED
@@ -16,7 +16,7 @@
16
  */
17
  class Twig_Environment
18
  {
19
- const VERSION = '1.21.0';
20
 
21
  protected $charset;
22
  protected $loader;
@@ -45,6 +45,11 @@ class Twig_Environment
45
  protected $filterCallbacks = array();
46
  protected $staging;
47
 
 
 
 
 
 
48
  /**
49
  * Constructor.
50
  *
@@ -58,8 +63,9 @@ class Twig_Environment
58
  * * base_template_class: The base template class to use for generated
59
  * templates (default to Twig_Template).
60
  *
61
- * * cache: An absolute path where to store the compiled templates, or
62
- * false to disable compilation cache (default).
 
63
  *
64
  * * auto_reload: Whether to reload the template if the original source changed.
65
  * If you don't provide the auto_reload option, it will be
@@ -87,7 +93,7 @@ class Twig_Environment
87
  if (null !== $loader) {
88
  $this->setLoader($loader);
89
  } else {
90
- @trigger_error('Not passing a Twig_LoaderInterface as the first constructor argument of Twig_Environment is deprecated.', E_USER_DEPRECATED);
91
  }
92
 
93
  $options = array_merge(array(
@@ -112,6 +118,23 @@ class Twig_Environment
112
  $this->addExtension(new Twig_Extension_Escaper($options['autoescape']));
113
  $this->addExtension(new Twig_Extension_Optimizer($options['optimizations']));
114
  $this->staging = new Twig_Extension_Staging();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  }
116
 
117
  /**
@@ -213,24 +236,43 @@ class Twig_Environment
213
  }
214
 
215
  /**
216
- * Gets the cache directory or false if cache is disabled.
 
 
217
  *
218
- * @return string|false
 
 
219
  */
220
- public function getCache()
221
  {
222
- return $this->cache;
223
  }
224
 
225
  /**
226
- * Sets the cache directory or false if cache is disabled.
227
  *
228
- * @param string|false $cache The absolute path to the compiled templates,
229
- * or false to disable cache
 
230
  */
231
  public function setCache($cache)
232
  {
233
- $this->cache = $cache ? $cache : false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  }
235
 
236
  /**
@@ -239,38 +281,52 @@ class Twig_Environment
239
  * @param string $name The template name
240
  *
241
  * @return string|false The cache file name or false when caching is disabled
 
 
242
  */
243
  public function getCacheFilename($name)
244
  {
245
- if (false === $this->cache) {
246
- return false;
247
- }
248
 
249
- $class = substr($this->getTemplateClass($name), strlen($this->templateClassPrefix));
250
 
251
- return $this->getCache().'/'.$class[0].'/'.$class[1].'/'.$class.'.php';
252
  }
253
 
254
  /**
255
  * Gets the template class associated with the given string.
256
  *
257
- * @param string $name The name for which to calculate the template class name
258
- * @param int $index The index if it is an embedded template
 
 
 
 
 
 
259
  *
260
  * @return string The template class name
261
  */
262
  public function getTemplateClass($name, $index = null)
263
  {
264
- return $this->templateClassPrefix.hash('sha256', $this->getLoader()->getCacheKey($name)).(null === $index ? '' : '_'.$index);
 
 
 
 
265
  }
266
 
267
  /**
268
  * Gets the template class prefix.
269
  *
270
  * @return string The template class prefix
 
 
271
  */
272
  public function getTemplateClassPrefix()
273
  {
 
 
274
  return $this->templateClassPrefix;
275
  }
276
 
@@ -326,14 +382,25 @@ class Twig_Environment
326
  }
327
 
328
  if (!class_exists($cls, false)) {
329
- if (false === $cache = $this->getCacheFilename($name)) {
330
- eval('?>'.$this->compileSource($this->getLoader()->getSource($name), $name));
331
  } else {
332
- if (!is_file($cache) || ($this->isAutoReload() && !$this->isTemplateFresh($name, filemtime($cache)))) {
333
- $this->writeCacheFile($cache, $this->compileSource($this->getLoader()->getSource($name), $name));
 
 
 
 
 
 
 
 
 
 
 
334
  }
335
 
336
- require_once $cache;
337
  }
338
  }
339
 
@@ -371,6 +438,10 @@ class Twig_Environment
371
  } catch (Exception $e) {
372
  $this->setLoader($current);
373
 
 
 
 
 
374
  throw $e;
375
  }
376
  $this->setLoader($current);
@@ -392,14 +463,16 @@ class Twig_Environment
392
  */
393
  public function isTemplateFresh($name, $time)
394
  {
395
- foreach ($this->extensions as $extension) {
396
- $r = new ReflectionObject($extension);
397
- if (filemtime($r->getFileName()) > $time) {
398
- return false;
 
 
399
  }
400
  }
401
 
402
- return $this->getLoader()->isFresh($name, $time);
403
  }
404
 
405
  /**
@@ -446,23 +519,25 @@ class Twig_Environment
446
  */
447
  public function clearTemplateCache()
448
  {
449
- @trigger_error(sprintf('The %s method is deprecated and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
450
 
451
  $this->loadedTemplates = array();
452
  }
453
 
454
  /**
455
  * Clears the template cache files on the filesystem.
 
 
456
  */
457
  public function clearCacheFiles()
458
  {
459
- if (false === $this->cache) {
460
- return;
461
- }
462
 
463
- foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->cache), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
464
- if ($file->isFile()) {
465
- @unlink($file->getPathname());
 
 
466
  }
467
  }
468
  }
@@ -593,7 +668,13 @@ class Twig_Environment
593
  public function compileSource($source, $name = null)
594
  {
595
  try {
596
- return $this->compile($this->parse($this->tokenize($source, $name)));
 
 
 
 
 
 
597
  } catch (Twig_Error $e) {
598
  $e->setTemplateFile($name);
599
  throw $e;
@@ -648,12 +729,22 @@ class Twig_Environment
648
 
649
  /**
650
  * Initializes the runtime environment.
 
 
651
  */
652
  public function initRuntime()
653
  {
654
  $this->runtimeInitialized = true;
655
 
656
- foreach ($this->getExtensions() as $extension) {
 
 
 
 
 
 
 
 
657
  $extension->initRuntime($this);
658
  }
659
  }
@@ -693,11 +784,19 @@ class Twig_Environment
693
  */
694
  public function addExtension(Twig_ExtensionInterface $extension)
695
  {
 
 
696
  if ($this->extensionInitialized) {
697
- throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName()));
698
  }
699
 
700
- $this->extensions[$extension->getName()] = $extension;
 
 
 
 
 
 
701
  }
702
 
703
  /**
@@ -711,7 +810,7 @@ class Twig_Environment
711
  */
712
  public function removeExtension($name)
713
  {
714
- @trigger_error(sprintf('The %s method is deprecated and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
715
 
716
  if ($this->extensionInitialized) {
717
  throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
@@ -760,6 +859,8 @@ class Twig_Environment
760
  * Gets the registered Token Parsers.
761
  *
762
  * @return Twig_TokenParserBrokerInterface A broker containing token parsers
 
 
763
  */
764
  public function getTokenParsers()
765
  {
@@ -776,6 +877,8 @@ class Twig_Environment
776
  * Be warned that this method cannot return tags defined by Twig_TokenParserBrokerInterface classes.
777
  *
778
  * @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances
 
 
779
  */
780
  public function getTags()
781
  {
@@ -807,6 +910,8 @@ class Twig_Environment
807
  * Gets the registered Node Visitors.
808
  *
809
  * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
 
 
810
  */
811
  public function getNodeVisitors()
812
  {
@@ -833,7 +938,7 @@ class Twig_Environment
833
  $filter = $name;
834
  $name = $filter->getName();
835
  } else {
836
- @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated. Pass an instance of "Twig_SimpleFilter" instead when defining filter "%s".', __METHOD__, $name), E_USER_DEPRECATED);
837
  }
838
 
839
  if ($this->extensionInitialized) {
@@ -852,6 +957,8 @@ class Twig_Environment
852
  * @param string $name The filter name
853
  *
854
  * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exist
 
 
855
  */
856
  public function getFilter($name)
857
  {
@@ -893,11 +1000,13 @@ class Twig_Environment
893
  /**
894
  * Gets the registered Filters.
895
  *
896
- * Be warned that this method cannot return filters defined with registerUndefinedFunctionCallback.
897
  *
898
  * @return Twig_FilterInterface[] An array of Twig_FilterInterface instances
899
  *
900
  * @see registerUndefinedFilterCallback
 
 
901
  */
902
  public function getFilters()
903
  {
@@ -924,7 +1033,7 @@ class Twig_Environment
924
  $test = $name;
925
  $name = $test->getName();
926
  } else {
927
- @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated. Pass an instance of "Twig_SimpleTest" instead when defining test "%s".', __METHOD__, $name), E_USER_DEPRECATED);
928
  }
929
 
930
  if ($this->extensionInitialized) {
@@ -938,6 +1047,8 @@ class Twig_Environment
938
  * Gets the registered Tests.
939
  *
940
  * @return Twig_TestInterface[] An array of Twig_TestInterface instances
 
 
941
  */
942
  public function getTests()
943
  {
@@ -954,6 +1065,8 @@ class Twig_Environment
954
  * @param string $name The test name
955
  *
956
  * @return Twig_Test|false A Twig_Test instance or false if the test does not exist
 
 
957
  */
958
  public function getTest($name)
959
  {
@@ -984,7 +1097,7 @@ class Twig_Environment
984
  $function = $name;
985
  $name = $function->getName();
986
  } else {
987
- @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated. Pass an instance of "Twig_SimpleFunction" instead when defining function "%s".', __METHOD__, $name), E_USER_DEPRECATED);
988
  }
989
 
990
  if ($this->extensionInitialized) {
@@ -1003,6 +1116,8 @@ class Twig_Environment
1003
  * @param string $name function name
1004
  *
1005
  * @return Twig_Function|false A Twig_Function instance or false if the function does not exist
 
 
1006
  */
1007
  public function getFunction($name)
1008
  {
@@ -1049,6 +1164,8 @@ class Twig_Environment
1049
  * @return Twig_FunctionInterface[] An array of Twig_FunctionInterface instances
1050
  *
1051
  * @see registerUndefinedFunctionCallback
 
 
1052
  */
1053
  public function getFunctions()
1054
  {
@@ -1077,7 +1194,7 @@ class Twig_Environment
1077
 
1078
  if (!array_key_exists($name, $this->globals)) {
1079
  // The deprecation notice must be turned into the following exception in Twig 2.0
1080
- @trigger_error(sprintf('Registering global variable "%s" at runtime or when the extensions have already been initialized is deprecated.', $name), E_USER_DEPRECATED);
1081
  //throw new LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name));
1082
  }
1083
  }
@@ -1094,6 +1211,8 @@ class Twig_Environment
1094
  * Gets the registered Globals.
1095
  *
1096
  * @return array An array of globals
 
 
1097
  */
1098
  public function getGlobals()
1099
  {
@@ -1132,6 +1251,8 @@ class Twig_Environment
1132
  * Gets the registered unary Operators.
1133
  *
1134
  * @return array An array of unary operators
 
 
1135
  */
1136
  public function getUnaryOperators()
1137
  {
@@ -1146,6 +1267,8 @@ class Twig_Environment
1146
  * Gets the registered binary Operators.
1147
  *
1148
  * @return array An array of binary operators
 
 
1149
  */
1150
  public function getBinaryOperators()
1151
  {
@@ -1156,24 +1279,31 @@ class Twig_Environment
1156
  return $this->binaryOperators;
1157
  }
1158
 
 
 
 
1159
  public function computeAlternatives($name, $items)
1160
  {
1161
- $alternatives = array();
1162
- foreach ($items as $item) {
1163
- $lev = levenshtein($name, $item);
1164
- if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
1165
- $alternatives[$item] = $lev;
1166
- }
1167
- }
1168
- asort($alternatives);
1169
 
1170
- return array_keys($alternatives);
1171
  }
1172
 
 
 
 
1173
  protected function initGlobals()
1174
  {
1175
  $globals = array();
1176
- foreach ($this->extensions as $extension) {
 
 
 
 
 
 
 
 
1177
  $extGlob = $extension->getGlobals();
1178
  if (!is_array($extGlob)) {
1179
  throw new UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', get_class($extension)));
@@ -1187,6 +1317,9 @@ class Twig_Environment
1187
  return call_user_func_array('array_merge', $globals);
1188
  }
1189
 
 
 
 
1190
  protected function initExtensions()
1191
  {
1192
  if ($this->extensionInitialized) {
@@ -1208,6 +1341,9 @@ class Twig_Environment
1208
  $this->initExtension($this->staging);
1209
  }
1210
 
 
 
 
1211
  protected function initExtension(Twig_ExtensionInterface $extension)
1212
  {
1213
  // filters
@@ -1215,7 +1351,7 @@ class Twig_Environment
1215
  if ($filter instanceof Twig_SimpleFilter) {
1216
  $name = $filter->getName();
1217
  } else {
1218
- @trigger_error(sprintf('Using an instance of "%s" for filter "%s" is deprecated. Use Twig_SimpleFilter instead.', get_class($filter), $name), E_USER_DEPRECATED);
1219
  }
1220
 
1221
  $this->filters[$name] = $filter;
@@ -1226,7 +1362,7 @@ class Twig_Environment
1226
  if ($function instanceof Twig_SimpleFunction) {
1227
  $name = $function->getName();
1228
  } else {
1229
- @trigger_error(sprintf('Using an instance of "%s" for function "%s" is deprecated. Use Twig_SimpleFunction instead.', get_class($function), $name), E_USER_DEPRECATED);
1230
  }
1231
 
1232
  $this->functions[$name] = $function;
@@ -1237,7 +1373,7 @@ class Twig_Environment
1237
  if ($test instanceof Twig_SimpleTest) {
1238
  $name = $test->getName();
1239
  } else {
1240
- @trigger_error(sprintf('Using an instance of "%s" for test "%s" is deprecated. Use Twig_SimpleTest instead.', get_class($test), $name), E_USER_DEPRECATED);
1241
  }
1242
 
1243
  $this->tests[$name] = $test;
@@ -1248,7 +1384,7 @@ class Twig_Environment
1248
  if ($parser instanceof Twig_TokenParserInterface) {
1249
  $this->parsers->addTokenParser($parser);
1250
  } elseif ($parser instanceof Twig_TokenParserBrokerInterface) {
1251
- @trigger_error('Registering a Twig_TokenParserBrokerInterface instance is deprecated.', E_USER_DEPRECATED);
1252
 
1253
  $this->parsers->addTokenParserBroker($parser);
1254
  } else {
@@ -1272,30 +1408,11 @@ class Twig_Environment
1272
  }
1273
  }
1274
 
 
 
 
1275
  protected function writeCacheFile($file, $content)
1276
  {
1277
- $dir = dirname($file);
1278
- if (!is_dir($dir)) {
1279
- if (false === @mkdir($dir, 0777, true)) {
1280
- clearstatcache(false, $dir);
1281
- if (!is_dir($dir)) {
1282
- throw new RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir));
1283
- }
1284
- }
1285
- } elseif (!is_writable($dir)) {
1286
- throw new RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir));
1287
- }
1288
-
1289
- $tmpFile = tempnam($dir, basename($file));
1290
- if (false !== @file_put_contents($tmpFile, $content)) {
1291
- // rename does not work on Win32 before 5.2.6
1292
- if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) {
1293
- @chmod($file, 0666 & ~umask());
1294
-
1295
- return;
1296
- }
1297
- }
1298
-
1299
- throw new RuntimeException(sprintf('Failed to write cache file "%s".', $file));
1300
  }
1301
  }
16
  */
17
  class Twig_Environment
18
  {
19
+ const VERSION = '1.24.1';
20
 
21
  protected $charset;
22
  protected $loader;
45
  protected $filterCallbacks = array();
46
  protected $staging;
47
 
48
+ private $originalCache;
49
+ private $bcWriteCacheFile = false;
50
+ private $bcGetCacheFilename = false;
51
+ private $lastModifiedExtension = 0;
52
+
53
  /**
54
  * Constructor.
55
  *
63
  * * base_template_class: The base template class to use for generated
64
  * templates (default to Twig_Template).
65
  *
66
+ * * cache: An absolute path where to store the compiled templates,
67
+ * a Twig_Cache_Interface implementation,
68
+ * or false to disable compilation cache (default).
69
  *
70
  * * auto_reload: Whether to reload the template if the original source changed.
71
  * If you don't provide the auto_reload option, it will be
93
  if (null !== $loader) {
94
  $this->setLoader($loader);
95
  } else {
96
+ @trigger_error('Not passing a Twig_LoaderInterface as the first constructor argument of Twig_Environment is deprecated since version 1.21.', E_USER_DEPRECATED);
97
  }
98
 
99
  $options = array_merge(array(
118
  $this->addExtension(new Twig_Extension_Escaper($options['autoescape']));
119
  $this->addExtension(new Twig_Extension_Optimizer($options['optimizations']));
120
  $this->staging = new Twig_Extension_Staging();
121
+
122
+ // For BC
123
+ if (is_string($this->originalCache)) {
124
+ $r = new ReflectionMethod($this, 'writeCacheFile');
125
+ if ($r->getDeclaringClass()->getName() !== __CLASS__) {
126
+ @trigger_error('The Twig_Environment::writeCacheFile method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
127
+
128
+ $this->bcWriteCacheFile = true;
129
+ }
130
+
131
+ $r = new ReflectionMethod($this, 'getCacheFilename');
132
+ if ($r->getDeclaringClass()->getName() !== __CLASS__) {
133
+ @trigger_error('The Twig_Environment::getCacheFilename method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
134
+
135
+ $this->bcGetCacheFilename = true;
136
+ }
137
+ }
138
  }
139
 
140
  /**
236
  }
237
 
238
  /**
239
+ * Gets the current cache implementation.
240
+ *
241
+ * @param bool $original Whether to return the original cache option or the real cache instance
242
  *
243
+ * @return Twig_CacheInterface|string|false A Twig_CacheInterface implementation,
244
+ * an absolute path to the compiled templates,
245
+ * or false to disable cache
246
  */
247
+ public function getCache($original = true)
248
  {
249
+ return $original ? $this->originalCache : $this->cache;
250
  }
251
 
252
  /**
253
+ * Sets the current cache implementation.
254
  *
255
+ * @param Twig_CacheInterface|string|false $cache A Twig_CacheInterface implementation,
256
+ * an absolute path to the compiled templates,
257
+ * or false to disable cache
258
  */
259
  public function setCache($cache)
260
  {
261
+ if (is_string($cache)) {
262
+ $this->originalCache = $cache;
263
+ $this->cache = new Twig_Cache_Filesystem($cache);
264
+ } elseif (false === $cache) {
265
+ $this->originalCache = $cache;
266
+ $this->cache = new Twig_Cache_Null();
267
+ } elseif (null === $cache) {
268
+ @trigger_error('Using "null" as the cache strategy is deprecated since version 1.23 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
269
+ $this->originalCache = false;
270
+ $this->cache = new Twig_Cache_Null();
271
+ } elseif ($cache instanceof Twig_CacheInterface) {
272
+ $this->originalCache = $this->cache = $cache;
273
+ } else {
274
+ throw new LogicException(sprintf('Cache can only be a string, false, or a Twig_CacheInterface implementation.'));
275
+ }
276
  }
277
 
278
  /**
281
  * @param string $name The template name
282
  *
283
  * @return string|false The cache file name or false when caching is disabled
284
+ *
285
+ * @deprecated since 1.22 (to be removed in 2.0)
286
  */
287
  public function getCacheFilename($name)
288
  {
289
+ @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
 
 
290
 
291
+ $key = $this->cache->generateKey($name, $this->getTemplateClass($name));
292
 
293
+ return !$key ? false : $key;
294
  }
295
 
296
  /**
297
  * Gets the template class associated with the given string.
298
  *
299
+ * The generated template class is based on the following parameters:
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
307
  *
308
  * @return string The template class name
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
  }
318
 
319
  /**
320
  * Gets the template class prefix.
321
  *
322
  * @return string The template class prefix
323
+ *
324
+ * @deprecated since 1.22 (to be removed in 2.0)
325
  */
326
  public function getTemplateClassPrefix()
327
  {
328
+ @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
329
+
330
  return $this->templateClassPrefix;
331
  }
332
 
382
  }
383
 
384
  if (!class_exists($cls, false)) {
385
+ if ($this->bcGetCacheFilename) {
386
+ $key = $this->getCacheFilename($name);
387
  } else {
388
+ $key = $this->cache->generateKey($name, $cls);
389
+ }
390
+
391
+ if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) {
392
+ $this->cache->load($key);
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 {
400
+ $this->cache->write($key, $content);
401
  }
402
 
403
+ eval('?>'.$content);
404
  }
405
  }
406
 
438
  } catch (Exception $e) {
439
  $this->setLoader($current);
440
 
441
+ throw $e;
442
+ } catch (Throwable $e) {
443
+ $this->setLoader($current);
444
+
445
  throw $e;
446
  }
447
  $this->setLoader($current);
463
  */
464
  public function isTemplateFresh($name, $time)
465
  {
466
+ if (0 === $this->lastModifiedExtension) {
467
+ foreach ($this->extensions as $extension) {
468
+ $r = new ReflectionObject($extension);
469
+ if (file_exists($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModifiedExtension) {
470
+ $this->lastModifiedExtension = $extensionTime;
471
+ }
472
  }
473
  }
474
 
475
+ return $this->lastModifiedExtension <= $time && $this->getLoader()->isFresh($name, $time);
476
  }
477
 
478
  /**
519
  */
520
  public function clearTemplateCache()
521
  {
522
+ @trigger_error(sprintf('The %s method is deprecated since version 1.18.3 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
523
 
524
  $this->loadedTemplates = array();
525
  }
526
 
527
  /**
528
  * Clears the template cache files on the filesystem.
529
+ *
530
+ * @deprecated since 1.22 (to be removed in 2.0)
531
  */
532
  public function clearCacheFiles()
533
  {
534
+ @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
 
 
535
 
536
+ if (is_string($this->originalCache)) {
537
+ foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->originalCache), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
538
+ if ($file->isFile()) {
539
+ @unlink($file->getPathname());
540
+ }
541
  }
542
  }
543
  }
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;
729
 
730
  /**
731
  * Initializes the runtime environment.
732
+ *
733
+ * @deprecated since 1.23 (to be removed in 2.0)
734
  */
735
  public function initRuntime()
736
  {
737
  $this->runtimeInitialized = true;
738
 
739
+ foreach ($this->getExtensions() as $name => $extension) {
740
+ if (!$extension instanceof Twig_Extension_InitRuntimeInterface) {
741
+ $m = new ReflectionMethod($extension, 'initRuntime');
742
+
743
+ if ('Twig_Extension' !== $m->getDeclaringClass()->getName()) {
744
+ @trigger_error(sprintf('Defining the initRuntime() method in the "%s" extension is deprecated since version 1.23. Use the `needs_environment` option to get the Twig_Environment instance in filters, functions, or tests; or explicitly implement Twig_Extension_InitRuntimeInterface if needed (not recommended).', $name), E_USER_DEPRECATED);
745
+ }
746
+ }
747
+
748
  $extension->initRuntime($this);
749
  }
750
  }
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
  /**
810
  */
811
  public function removeExtension($name)
812
  {
813
+ @trigger_error(sprintf('The %s method is deprecated since version 1.12 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
814
 
815
  if ($this->extensionInitialized) {
816
  throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
859
  * Gets the registered Token Parsers.
860
  *
861
  * @return Twig_TokenParserBrokerInterface A broker containing token parsers
862
+ *
863
+ * @internal
864
  */
865
  public function getTokenParsers()
866
  {
877
  * Be warned that this method cannot return tags defined by Twig_TokenParserBrokerInterface classes.
878
  *
879
  * @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances
880
+ *
881
+ * @internal
882
  */
883
  public function getTags()
884
  {
910
  * Gets the registered Node Visitors.
911
  *
912
  * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
913
+ *
914
+ * @internal
915
  */
916
  public function getNodeVisitors()
917
  {
938
  $filter = $name;
939
  $name = $filter->getName();
940
  } else {
941
+ @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFilter" instead when defining filter "%s".', __METHOD__, $name), E_USER_DEPRECATED);
942
  }
943
 
944
  if ($this->extensionInitialized) {
957
  * @param string $name The filter name
958
  *
959
  * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exist
960
+ *
961
+ * @internal
962
  */
963
  public function getFilter($name)
964
  {
1000
  /**
1001
  * Gets the registered Filters.
1002
  *
1003
+ * Be warned that this method cannot return filters defined with registerUndefinedFilterCallback.
1004
  *
1005
  * @return Twig_FilterInterface[] An array of Twig_FilterInterface instances
1006
  *
1007
  * @see registerUndefinedFilterCallback
1008
+ *
1009
+ * @internal
1010
  */
1011
  public function getFilters()
1012
  {
1033
  $test = $name;
1034
  $name = $test->getName();
1035
  } else {
1036
+ @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleTest" instead when defining test "%s".', __METHOD__, $name), E_USER_DEPRECATED);
1037
  }
1038
 
1039
  if ($this->extensionInitialized) {
1047
  * Gets the registered Tests.
1048
  *
1049
  * @return Twig_TestInterface[] An array of Twig_TestInterface instances
1050
+ *
1051
+ * @internal
1052
  */
1053
  public function getTests()
1054
  {
1065
  * @param string $name The test name
1066
  *
1067
  * @return Twig_Test|false A Twig_Test instance or false if the test does not exist
1068
+ *
1069
+ * @internal
1070
  */
1071
  public function getTest($name)
1072
  {
1097
  $function = $name;
1098
  $name = $function->getName();
1099
  } else {
1100
+ @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFunction" instead when defining function "%s".', __METHOD__, $name), E_USER_DEPRECATED);
1101
  }
1102
 
1103
  if ($this->extensionInitialized) {
1116
  * @param string $name function name
1117
  *
1118
  * @return Twig_Function|false A Twig_Function instance or false if the function does not exist
1119
+ *
1120
+ * @internal
1121
  */
1122
  public function getFunction($name)
1123
  {
1164
  * @return Twig_FunctionInterface[] An array of Twig_FunctionInterface instances
1165
  *
1166
  * @see registerUndefinedFunctionCallback
1167
+ *
1168
+ * @internal
1169
  */
1170
  public function getFunctions()
1171
  {
1194
 
1195
  if (!array_key_exists($name, $this->globals)) {
1196
  // The deprecation notice must be turned into the following exception in Twig 2.0
1197
+ @trigger_error(sprintf('Registering global variable "%s" at runtime or when the extensions have already been initialized is deprecated since version 1.21.', $name), E_USER_DEPRECATED);
1198
  //throw new LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name));
1199
  }
1200
  }
1211
  * Gets the registered Globals.
1212
  *
1213
  * @return array An array of globals
1214
+ *
1215
+ * @internal
1216
  */
1217
  public function getGlobals()
1218
  {
1251
  * Gets the registered unary Operators.
1252
  *
1253
  * @return array An array of unary operators
1254
+ *
1255
+ * @internal
1256
  */
1257
  public function getUnaryOperators()
1258
  {
1267
  * Gets the registered binary Operators.
1268
  *
1269
  * @return array An array of binary operators
1270
+ *
1271
+ * @internal
1272
  */
1273
  public function getBinaryOperators()
1274
  {
1279
  return $this->binaryOperators;
1280
  }
1281
 
1282
+ /**
1283
+ * @deprecated since 1.23 (to be removed in 2.0)
1284
+ */
1285
  public function computeAlternatives($name, $items)
1286
  {
1287
+ @trigger_error(sprintf('The %s method is deprecated since version 1.23 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
 
 
 
 
 
 
 
1288
 
1289
+ return Twig_Error_Syntax::computeAlternatives($name, $items);
1290
  }
1291
 
1292
+ /**
1293
+ * @internal
1294
+ */
1295
  protected function initGlobals()
1296
  {
1297
  $globals = array();
1298
+ foreach ($this->extensions as $name => $extension) {
1299
+ if (!$extension instanceof Twig_Extension_GlobalsInterface) {
1300
+ $m = new ReflectionMethod($extension, 'getGlobals');
1301
+
1302
+ if ('Twig_Extension' !== $m->getDeclaringClass()->getName()) {
1303
+ @trigger_error(sprintf('Defining the getGlobals() method in the "%s" extension without explicitly implementing Twig_Extension_GlobalsInterface is deprecated since version 1.23.', $name), E_USER_DEPRECATED);
1304
+ }
1305
+ }
1306
+
1307
  $extGlob = $extension->getGlobals();
1308
  if (!is_array($extGlob)) {
1309
  throw new UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', get_class($extension)));
1317
  return call_user_func_array('array_merge', $globals);
1318
  }
1319
 
1320
+ /**
1321
+ * @internal
1322
+ */
1323
  protected function initExtensions()
1324
  {
1325
  if ($this->extensionInitialized) {
1341
  $this->initExtension($this->staging);
1342
  }
1343
 
1344
+ /**
1345
+ * @internal
1346
+ */
1347
  protected function initExtension(Twig_ExtensionInterface $extension)
1348
  {
1349
  // filters
1351
  if ($filter instanceof Twig_SimpleFilter) {
1352
  $name = $filter->getName();
1353
  } else {
1354
+ @trigger_error(sprintf('Using an instance of "%s" for filter "%s" is deprecated since version 1.21. Use Twig_SimpleFilter instead.', get_class($filter), $name), E_USER_DEPRECATED);
1355
  }
1356
 
1357
  $this->filters[$name] = $filter;
1362
  if ($function instanceof Twig_SimpleFunction) {
1363
  $name = $function->getName();
1364
  } else {
1365
+ @trigger_error(sprintf('Using an instance of "%s" for function "%s" is deprecated since version 1.21. Use Twig_SimpleFunction instead.', get_class($function), $name), E_USER_DEPRECATED);
1366
  }
1367
 
1368
  $this->functions[$name] = $function;
1373
  if ($test instanceof Twig_SimpleTest) {
1374
  $name = $test->getName();
1375
  } else {
1376
+ @trigger_error(sprintf('Using an instance of "%s" for test "%s" is deprecated since version 1.21. Use Twig_SimpleTest instead.', get_class($test), $name), E_USER_DEPRECATED);
1377
  }
1378
 
1379
  $this->tests[$name] = $test;
1384
  if ($parser instanceof Twig_TokenParserInterface) {
1385
  $this->parsers->addTokenParser($parser);
1386
  } elseif ($parser instanceof Twig_TokenParserBrokerInterface) {
1387
+ @trigger_error('Registering a Twig_TokenParserBrokerInterface instance is deprecated since version 1.21.', E_USER_DEPRECATED);
1388
 
1389
  $this->parsers->addTokenParserBroker($parser);
1390
  } else {
1408
  }
1409
  }
1410
 
1411
+ /**
1412
+ * @deprecated since 1.22 (to be removed in 2.0)
1413
+ */
1414
  protected function writeCacheFile($file, $content)
1415
  {
1416
+ $this->cache->write($file, $content);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1417
  }
1418
  }
vendor/twig/twig/lib/Twig/Error.php CHANGED
@@ -155,6 +155,15 @@ class Twig_Error extends Exception
155
  throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method));
156
  }
157
 
 
 
 
 
 
 
 
 
 
158
  protected function updateRepr()
159
  {
160
  $this->message = $this->rawMessage;
@@ -165,6 +174,12 @@ class Twig_Error extends Exception
165
  $dot = true;
166
  }
167
 
 
 
 
 
 
 
168
  if ($this->filename) {
169
  if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) {
170
  $filename = sprintf('"%s"', $this->filename);
@@ -181,8 +196,15 @@ class Twig_Error extends Exception
181
  if ($dot) {
182
  $this->message .= '.';
183
  }
 
 
 
 
184
  }
185
 
 
 
 
186
  protected function guessTemplateInfo()
187
  {
188
  $template = null;
155
  throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method));
156
  }
157
 
158
+ public function appendMessage($rawMessage)
159
+ {
160
+ $this->rawMessage .= $rawMessage;
161
+ $this->updateRepr();
162
+ }
163
+
164
+ /**
165
+ * @internal
166
+ */
167
  protected function updateRepr()
168
  {
169
  $this->message = $this->rawMessage;
174
  $dot = true;
175
  }
176
 
177
+ $questionMark = false;
178
+ if ('?' === substr($this->message, -1)) {
179
+ $this->message = substr($this->message, 0, -1);
180
+ $questionMark = true;
181
+ }
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);
196
  if ($dot) {
197
  $this->message .= '.';
198
  }
199
+
200
+ if ($questionMark) {
201
+ $this->message .= '?';
202
+ }
203
  }
204
 
205
+ /**
206
+ * @internal
207
+ */
208
  protected function guessTemplateInfo()
209
  {
210
  $template = null;
vendor/twig/twig/lib/Twig/Error/Syntax.php CHANGED
@@ -17,4 +17,37 @@
17
  */
18
  class Twig_Error_Syntax extends Twig_Error
19
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
17
  */
18
  class Twig_Error_Syntax extends Twig_Error
19
  {
20
+ /**
21
+ * Tweaks the error message to include suggestions.
22
+ *
23
+ * @param string $name The original name of the item that does not exist
24
+ * @param array $items An array of possible items
25
+ */
26
+ public function addSuggestions($name, array $items)
27
+ {
28
+ if (!$alternatives = self::computeAlternatives($name, $items)) {
29
+ return;
30
+ }
31
+
32
+ $this->appendMessage(sprintf(' Did you mean "%s"?', implode('", "', $alternatives)));
33
+ }
34
+
35
+ /**
36
+ * @internal
37
+ *
38
+ * To be merged with the addSuggestions() method in 2.0.
39
+ */
40
+ public static function computeAlternatives($name, $items)
41
+ {
42
+ $alternatives = array();
43
+ foreach ($items as $item) {
44
+ $lev = levenshtein($name, $item);
45
+ if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
46
+ $alternatives[$item] = $lev;
47
+ }
48
+ }
49
+ asort($alternatives);
50
+
51
+ return array_keys($alternatives);
52
+ }
53
  }
vendor/twig/twig/lib/Twig/ExpressionParser.php CHANGED
@@ -171,7 +171,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 +187,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
 
@@ -278,7 +278,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 +317,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 +330,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);
@@ -373,7 +373,7 @@ class Twig_ExpressionParser
373
  $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
374
 
375
  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
376
- $type = Twig_TemplateInterface::METHOD_CALL;
377
  foreach ($this->parseArguments() as $n) {
378
  $arguments->addElement($n);
379
  }
@@ -384,13 +384,13 @@ class Twig_ExpressionParser
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 +500,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
 
@@ -539,10 +539,11 @@ class Twig_ExpressionParser
539
  $targets = array();
540
  while (true) {
541
  $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
542
- if (in_array($token->getValue(), array('true', 'false', 'none'))) {
543
- throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $token->getValue()), $token->getLine(), $this->parser->getFilename());
 
544
  }
545
- $targets[] = new Twig_Node_Expression_AssignName($token->getValue(), $token->getLine());
546
 
547
  if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
548
  break;
@@ -570,17 +571,18 @@ class Twig_ExpressionParser
570
  $env = $this->parser->getEnvironment();
571
 
572
  if (false === $function = $env->getFunction($name)) {
573
- $message = sprintf('The function "%s" does not exist', $name);
574
- if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFunctions()))) {
575
- $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
576
- }
577
 
578
- throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename());
579
  }
580
 
581
  if ($function instanceof Twig_SimpleFunction && $function->isDeprecated()) {
582
  $message = sprintf('Twig Function "%s" is deprecated', $function->getName());
583
- if ($test->getAlternative()) {
 
 
 
584
  $message .= sprintf('. Use "%s" instead', $function->getAlternative());
585
  }
586
  $message .= sprintf(' in %s at line %d.', $this->parser->getFilename(), $line);
@@ -600,17 +602,18 @@ class Twig_ExpressionParser
600
  $env = $this->parser->getEnvironment();
601
 
602
  if (false === $filter = $env->getFilter($name)) {
603
- $message = sprintf('The filter "%s" does not exist', $name);
604
- if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFilters()))) {
605
- $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
606
- }
607
 
608
- throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename());
609
  }
610
 
611
  if ($filter instanceof Twig_SimpleFilter && $filter->isDeprecated()) {
612
  $message = sprintf('Twig Filter "%s" is deprecated', $filter->getName());
613
- if ($test->getAlternative()) {
 
 
 
614
  $message .= sprintf('. Use "%s" instead', $filter->getAlternative());
615
  }
616
  $message .= sprintf(' in %s at line %d.', $this->parser->getFilename(), $line);
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
  } 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
 
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
  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
  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);
373
  $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
374
 
375
  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
376
+ $type = Twig_Template::METHOD_CALL;
377
  foreach ($this->parseArguments() as $n) {
378
  $arguments->addElement($n);
379
  }
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
  $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
 
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;
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
  }
579
 
580
  if ($function instanceof Twig_SimpleFunction && $function->isDeprecated()) {
581
  $message = sprintf('Twig Function "%s" is deprecated', $function->getName());
582
+ if (!is_bool($function->getDeprecatedVersion())) {
583
+ $message .= sprintf(' since version %s', $function->getDeprecatedVersion());
584
+ }
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);
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
  }
610
 
611
  if ($filter instanceof Twig_SimpleFilter && $filter->isDeprecated()) {
612
  $message = sprintf('Twig Filter "%s" is deprecated', $filter->getName());
613
+ if (!is_bool($filter->getDeprecatedVersion())) {
614
+ $message .= sprintf(' since version %s', $filter->getDeprecatedVersion());
615
+ }
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);
vendor/twig/twig/lib/Twig/Extension.php CHANGED
@@ -11,20 +11,16 @@
11
  abstract class Twig_Extension implements Twig_ExtensionInterface
12
  {
13
  /**
14
- * Initializes the runtime environment.
15
  *
16
- * This is where you can load some file that contains filter functions for instance.
17
- *
18
- * @param Twig_Environment $environment The current Twig_Environment instance
19
  */
20
  public function initRuntime(Twig_Environment $environment)
21
  {
22
  }
23
 
24
  /**
25
- * Returns the token parser instances to add to the existing list.
26
- *
27
- * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
28
  */
29
  public function getTokenParsers()
30
  {
@@ -32,9 +28,7 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
32
  }
33
 
34
  /**
35
- * Returns the node visitor instances to add to the existing list.
36
- *
37
- * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
38
  */
39
  public function getNodeVisitors()
40
  {
@@ -42,9 +36,7 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
42
  }
43
 
44
  /**
45
- * Returns a list of filters to add to the existing list.
46
- *
47
- * @return array An array of filters
48
  */
49
  public function getFilters()
50
  {
@@ -52,9 +44,7 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
52
  }
53
 
54
  /**
55
- * Returns a list of tests to add to the existing list.
56
- *
57
- * @return array An array of tests
58
  */
59
  public function getTests()
60
  {
@@ -62,9 +52,7 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
62
  }
63
 
64
  /**
65
- * Returns a list of functions to add to the existing list.
66
- *
67
- * @return array An array of functions
68
  */
69
  public function getFunctions()
70
  {
@@ -72,9 +60,7 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
72
  }
73
 
74
  /**
75
- * Returns a list of operators to add to the existing list.
76
- *
77
- * @return array An array of operators
78
  */
79
  public function getOperators()
80
  {
@@ -82,9 +68,9 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
82
  }
83
 
84
  /**
85
- * Returns a list of global variables to add to the existing list.
86
  *
87
- * @return array An array of global variables
88
  */
89
  public function getGlobals()
90
  {
11
  abstract class Twig_Extension implements Twig_ExtensionInterface
12
  {
13
  /**
14
+ * {@inheritdoc}
15
  *
16
+ * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
 
 
17
  */
18
  public function initRuntime(Twig_Environment $environment)
19
  {
20
  }
21
 
22
  /**
23
+ * {@inheritdoc}
 
 
24
  */
25
  public function getTokenParsers()
26
  {
28
  }
29
 
30
  /**
31
+ * {@inheritdoc}
 
 
32
  */
33
  public function getNodeVisitors()
34
  {
36
  }
37
 
38
  /**
39
+ * {@inheritdoc}
 
 
40
  */
41
  public function getFilters()
42
  {
44
  }
45
 
46
  /**
47
+ * {@inheritdoc}
 
 
48
  */
49
  public function getTests()
50
  {
52
  }
53
 
54
  /**
55
+ * {@inheritdoc}
 
 
56
  */
57
  public function getFunctions()
58
  {
60
  }
61
 
62
  /**
63
+ * {@inheritdoc}
 
 
64
  */
65
  public function getOperators()
66
  {
68
  }
69
 
70
  /**
71
+ * {@inheritdoc}
72
  *
73
+ * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_GlobalsInterface instead
74
  */
75
  public function getGlobals()
76
  {
vendor/twig/twig/lib/Twig/Extension/Core.php CHANGED
@@ -114,11 +114,6 @@ class Twig_Extension_Core extends Twig_Extension
114
  return $this->numberFormat;
115
  }
116
 
117
- /**
118
- * Returns the token parser instance to add to the existing list.
119
- *
120
- * @return Twig_TokenParser[] An array of Twig_TokenParser instances
121
- */
122
  public function getTokenParsers()
123
  {
124
  return array(
@@ -140,11 +135,6 @@ class Twig_Extension_Core extends Twig_Extension
140
  );
141
  }
142
 
143
- /**
144
- * Returns a list of filters to add to the existing list.
145
- *
146
- * @return array An array of filters
147
- */
148
  public function getFilters()
149
  {
150
  $filters = array(
@@ -152,7 +142,7 @@ class Twig_Extension_Core extends Twig_Extension
152
  new Twig_SimpleFilter('date', 'twig_date_format_filter', array('needs_environment' => true)),
153
  new Twig_SimpleFilter('date_modify', 'twig_date_modify_filter', array('needs_environment' => true)),
154
  new Twig_SimpleFilter('format', 'sprintf'),
155
- new Twig_SimpleFilter('replace', 'strtr'),
156
  new Twig_SimpleFilter('number_format', 'twig_number_format_filter', array('needs_environment' => true)),
157
  new Twig_SimpleFilter('abs', 'abs'),
158
  new Twig_SimpleFilter('round', 'twig_round'),
@@ -202,11 +192,6 @@ class Twig_Extension_Core extends Twig_Extension
202
  return $filters;
203
  }
204
 
205
- /**
206
- * Returns a list of global functions to add to the existing list.
207
- *
208
- * @return array An array of global functions
209
- */
210
  public function getFunctions()
211
  {
212
  return array(
@@ -222,22 +207,17 @@ class Twig_Extension_Core extends Twig_Extension
222
  );
223
  }
224
 
225
- /**
226
- * Returns a list of tests to add to the existing list.
227
- *
228
- * @return array An array of tests
229
- */
230
  public function getTests()
231
  {
232
  return array(
233
  new Twig_SimpleTest('even', null, array('node_class' => 'Twig_Node_Expression_Test_Even')),
234
  new Twig_SimpleTest('odd', null, array('node_class' => 'Twig_Node_Expression_Test_Odd')),
235
  new Twig_SimpleTest('defined', null, array('node_class' => 'Twig_Node_Expression_Test_Defined')),
236
- new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas', 'deprecated' => true, 'alternative' => 'same as')),
237
  new Twig_SimpleTest('same as', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')),
238
  new Twig_SimpleTest('none', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
239
  new Twig_SimpleTest('null', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
240
- new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby', 'deprecated' => true, 'alternative' => 'divisible by')),
241
  new Twig_SimpleTest('divisible by', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')),
242
  new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')),
243
  new Twig_SimpleTest('empty', 'twig_test_empty'),
@@ -245,11 +225,6 @@ class Twig_Extension_Core extends Twig_Extension
245
  );
246
  }
247
 
248
- /**
249
- * Returns a list of operators to add to the existing list.
250
- *
251
- * @return array An array of operators
252
- */
253
  public function getOperators()
254
  {
255
  return array(
@@ -286,6 +261,7 @@ class Twig_Extension_Core extends Twig_Extension
286
  'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
287
  'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
288
  '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
 
289
  ),
290
  );
291
  }
@@ -298,10 +274,13 @@ class Twig_Extension_Core extends Twig_Extension
298
  public function parseTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
299
  {
300
  $stream = $parser->getStream();
301
- $test = $this->getTest($parser, $node->getLine());
302
 
303
  if ($test instanceof Twig_SimpleTest && $test->isDeprecated()) {
304
- $message = sprintf('Twig Test "%s" is deprecated', $test->getName());
 
 
 
305
  if ($test->getAlternative()) {
306
  $message .= sprintf('. Use "%s" instead', $test->getAlternative());
307
  }
@@ -316,7 +295,7 @@ class Twig_Extension_Core extends Twig_Extension
316
  $arguments = $parser->getExpressionParser()->parseArguments(true);
317
  }
318
 
319
- return new $class($node, $test->getName(), $arguments, $parser->getCurrentToken()->getLine());
320
  }
321
 
322
  protected function getTest(Twig_Parser $parser, $line)
@@ -324,29 +303,26 @@ class Twig_Extension_Core extends Twig_Extension
324
  $stream = $parser->getStream();
325
  $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
326
  $env = $parser->getEnvironment();
327
- $testMap = $env->getTests();
328
 
329
- if (isset($testMap[$name])) {
330
- return $testMap[$name];
331
  }
332
 
333
  if ($stream->test(Twig_Token::NAME_TYPE)) {
334
  // try 2-words tests
335
  $name = $name.' '.$parser->getCurrentToken()->getValue();
336
 
337
- if (isset($testMap[$name])) {
338
  $parser->getStream()->next();
339
 
340
- return $testMap[$name];
341
  }
342
  }
343
 
344
- $message = sprintf('The test "%s" does not exist', $name);
345
- if ($alternatives = $env->computeAlternatives($name, array_keys($testMap))) {
346
- $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
347
- }
348
 
349
- throw new Twig_Error_Syntax($message, $line, $parser->getFilename());
350
  }
351
 
352
  protected function getTestNodeClass(Twig_Parser $parser, $test)
@@ -358,11 +334,6 @@ class Twig_Extension_Core extends Twig_Extension
358
  return $test instanceof Twig_Test_Node ? $test->getClass() : 'Twig_Node_Expression_Test';
359
  }
360
 
361
- /**
362
- * Returns the name of the extension.
363
- *
364
- * @return string The extension name
365
- */
366
  public function getName()
367
  {
368
  return 'core';
@@ -416,7 +387,7 @@ function twig_random(Twig_Environment $env, $values = null)
416
  return '';
417
  }
418
  if (null !== $charset = $env->getCharset()) {
419
- if ('UTF-8' != $charset) {
420
  $values = twig_convert_encoding($values, 'UTF-8', $charset);
421
  }
422
 
@@ -424,7 +395,7 @@ function twig_random(Twig_Environment $env, $values = null)
424
  // split at all positions, but not after the start and not before the end
425
  $values = preg_split('/(?<!^)(?!$)/u', $values);
426
 
427
- if ('UTF-8' != $charset) {
428
  foreach ($values as $i => $value) {
429
  $values[$i] = twig_convert_encoding($value, $charset, 'UTF-8');
430
  }
@@ -537,12 +508,17 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
537
  return $date;
538
  }
539
 
 
 
 
 
540
  $asString = (string) $date;
541
  if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
542
- $date = '@'.$date;
 
 
543
  }
544
 
545
- $date = new DateTime($date, $env->getExtension('core')->getTimezone());
546
  if (false !== $timezone) {
547
  $date->setTimezone($timezone);
548
  }
@@ -550,6 +526,30 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
550
  return $date;
551
  }
552
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
553
  /**
554
  * Rounds a number.
555
  *
@@ -683,15 +683,23 @@ function _twig_markup2string(&$value)
683
  * {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car' } #}
684
  * </pre>
685
  *
686
- * @param array $arr1 An array
687
- * @param array $arr2 An array
688
  *
689
  * @return array The merged array
690
  */
691
  function twig_array_merge($arr1, $arr2)
692
  {
693
- if (!is_array($arr1) || !is_array($arr2)) {
694
- throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or hashes; %s and %s given.', gettype($arr1), gettype($arr2)));
 
 
 
 
 
 
 
 
695
  }
696
 
697
  return array_merge($arr1, $arr2);
@@ -813,9 +821,10 @@ function twig_join_filter($value, $glue = '')
813
  * {# returns [aa, bb, cc] #}
814
  * </pre>
815
  *
816
- * @param string $value A string
817
- * @param string $delimiter The delimiter
818
- * @param int $limit The limit
 
819
  *
820
  * @return array The split string as an array
821
  */
@@ -849,6 +858,9 @@ function twig_split_filter(Twig_Environment $env, $value, $delimiter, $limit = n
849
  // The '_default' filter is used internally to avoid using the ternary operator
850
  // which costs a lot for big contexts (before PHP 5.4). So, on average,
851
  // a function call is cheaper.
 
 
 
852
  function _twig_default_filter($value, $default = '')
853
  {
854
  if (twig_test_empty($value)) {
@@ -875,7 +887,7 @@ function _twig_default_filter($value, $default = '')
875
  */
876
  function twig_get_array_keys_filter($array)
877
  {
878
- if (is_object($array) && $array instanceof Traversable) {
879
  return array_keys(iterator_to_array($array));
880
  }
881
 
@@ -897,7 +909,7 @@ function twig_get_array_keys_filter($array)
897
  */
898
  function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false)
899
  {
900
- if (is_object($item) && $item instanceof Traversable) {
901
  return array_reverse(iterator_to_array($item), $preserveKeys);
902
  }
903
 
@@ -908,7 +920,7 @@ function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false
908
  if (null !== $charset = $env->getCharset()) {
909
  $string = (string) $item;
910
 
911
- if ('UTF-8' != $charset) {
912
  $item = twig_convert_encoding($string, 'UTF-8', $charset);
913
  }
914
 
@@ -916,7 +928,7 @@ function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false
916
 
917
  $string = implode('', array_reverse($matches[0]));
918
 
919
- if ('UTF-8' != $charset) {
920
  $string = twig_convert_encoding($string, $charset, 'UTF-8');
921
  }
922
 
@@ -929,18 +941,26 @@ function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false
929
  /**
930
  * Sorts an array.
931
  *
932
- * @param array $array
933
  *
934
  * @return array
935
  */
936
  function twig_sort_filter($array)
937
  {
 
 
 
 
 
 
938
  asort($array);
939
 
940
  return $array;
941
  }
942
 
943
- /* used internally */
 
 
944
  function twig_in_filter($value, $compare)
945
  {
946
  if (is_array($compare)) {
@@ -974,7 +994,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
974
  if (!is_string($string)) {
975
  if (is_object($string) && method_exists($string, '__toString')) {
976
  $string = (string) $string;
977
- } else {
978
  return $string;
979
  }
980
  }
@@ -1034,7 +1054,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1034
  case 'js':
1035
  // escape all non-alphanumeric characters
1036
  // into their \xHH or \uHHHH representations
1037
- if ('UTF-8' != $charset) {
1038
  $string = twig_convert_encoding($string, 'UTF-8', $charset);
1039
  }
1040
 
@@ -1044,14 +1064,14 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1044
 
1045
  $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string);
1046
 
1047
- if ('UTF-8' != $charset) {
1048
  $string = twig_convert_encoding($string, $charset, 'UTF-8');
1049
  }
1050
 
1051
  return $string;
1052
 
1053
  case 'css':
1054
- if ('UTF-8' != $charset) {
1055
  $string = twig_convert_encoding($string, 'UTF-8', $charset);
1056
  }
1057
 
@@ -1061,14 +1081,14 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1061
 
1062
  $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string);
1063
 
1064
- if ('UTF-8' != $charset) {
1065
  $string = twig_convert_encoding($string, $charset, 'UTF-8');
1066
  }
1067
 
1068
  return $string;
1069
 
1070
  case 'html_attr':
1071
- if ('UTF-8' != $charset) {
1072
  $string = twig_convert_encoding($string, 'UTF-8', $charset);
1073
  }
1074
 
@@ -1078,7 +1098,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1078
 
1079
  $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string);
1080
 
1081
- if ('UTF-8' != $charset) {
1082
  $string = twig_convert_encoding($string, $charset, 'UTF-8');
1083
  }
1084
 
@@ -1108,7 +1128,9 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1108
  }
1109
  }
1110
 
1111
- /* used internally */
 
 
1112
  function twig_escape_filter_is_safe(Twig_Node $filterArgs)
1113
  {
1114
  foreach ($filterArgs as $arg) {
@@ -1254,7 +1276,7 @@ if (function_exists('mb_get_info')) {
1254
  */
1255
  function twig_upper_filter(Twig_Environment $env, $string)
1256
  {
1257
- if (null !== ($charset = $env->getCharset())) {
1258
  return mb_strtoupper($string, $charset);
1259
  }
1260
 
@@ -1271,7 +1293,7 @@ if (function_exists('mb_get_info')) {
1271
  */
1272
  function twig_lower_filter(Twig_Environment $env, $string)
1273
  {
1274
- if (null !== ($charset = $env->getCharset())) {
1275
  return mb_strtolower($string, $charset);
1276
  }
1277
 
@@ -1288,7 +1310,7 @@ if (function_exists('mb_get_info')) {
1288
  */
1289
  function twig_title_string_filter(Twig_Environment $env, $string)
1290
  {
1291
- if (null !== ($charset = $env->getCharset())) {
1292
  return mb_convert_case($string, MB_CASE_TITLE, $charset);
1293
  }
1294
 
@@ -1305,9 +1327,8 @@ if (function_exists('mb_get_info')) {
1305
  */
1306
  function twig_capitalize_string_filter(Twig_Environment $env, $string)
1307
  {
1308
- if (null !== ($charset = $env->getCharset())) {
1309
- return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).
1310
- mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset);
1311
  }
1312
 
1313
  return ucfirst(strtolower($string));
@@ -1355,7 +1376,9 @@ else {
1355
  }
1356
  }
1357
 
1358
- /* used internally */
 
 
1359
  function twig_ensure_traversable($seq)
1360
  {
1361
  if ($seq instanceof Traversable || is_array($seq)) {
@@ -1458,8 +1481,9 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
1458
  /**
1459
  * Returns a template content without rendering it.
1460
  *
1461
- * @param string $name The template name
1462
- * @param bool $ignoreMissing Whether to ignore missing templates or not
 
1463
  *
1464
  * @return string The template source
1465
  */
114
  return $this->numberFormat;
115
  }
116
 
 
 
 
 
 
117
  public function getTokenParsers()
118
  {
119
  return array(
135
  );
136
  }
137
 
 
 
 
 
 
138
  public function getFilters()
139
  {
140
  $filters = array(
142
  new Twig_SimpleFilter('date', 'twig_date_format_filter', array('needs_environment' => true)),
143
  new Twig_SimpleFilter('date_modify', 'twig_date_modify_filter', array('needs_environment' => true)),
144
  new Twig_SimpleFilter('format', 'sprintf'),
145
+ new Twig_SimpleFilter('replace', 'twig_replace_filter'),
146
  new Twig_SimpleFilter('number_format', 'twig_number_format_filter', array('needs_environment' => true)),
147
  new Twig_SimpleFilter('abs', 'abs'),
148
  new Twig_SimpleFilter('round', 'twig_round'),
192
  return $filters;
193
  }
194
 
 
 
 
 
 
195
  public function getFunctions()
196
  {
197
  return array(
207
  );
208
  }
209
 
 
 
 
 
 
210
  public function getTests()
211
  {
212
  return array(
213
  new Twig_SimpleTest('even', null, array('node_class' => 'Twig_Node_Expression_Test_Even')),
214
  new Twig_SimpleTest('odd', null, array('node_class' => 'Twig_Node_Expression_Test_Odd')),
215
  new Twig_SimpleTest('defined', null, array('node_class' => 'Twig_Node_Expression_Test_Defined')),
216
+ new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas', 'deprecated' => '1.21', 'alternative' => 'same as')),
217
  new Twig_SimpleTest('same as', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')),
218
  new Twig_SimpleTest('none', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
219
  new Twig_SimpleTest('null', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
220
+ new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby', 'deprecated' => '1.21', 'alternative' => 'divisible by')),
221
  new Twig_SimpleTest('divisible by', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')),
222
  new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')),
223
  new Twig_SimpleTest('empty', 'twig_test_empty'),
225
  );
226
  }
227
 
 
 
 
 
 
228
  public function getOperators()
229
  {
230
  return array(
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
  }
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
  }
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)
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)
334
  return $test instanceof Twig_Test_Node ? $test->getClass() : 'Twig_Node_Expression_Test';
335
  }
336
 
 
 
 
 
 
337
  public function getName()
338
  {
339
  return 'core';
387
  return '';
388
  }
389
  if (null !== $charset = $env->getCharset()) {
390
+ if ('UTF-8' !== $charset) {
391
  $values = twig_convert_encoding($values, 'UTF-8', $charset);
392
  }
393
 
395
  // split at all positions, but not after the start and not before the end
396
  $values = preg_split('/(?<!^)(?!$)/u', $values);
397
 
398
+ if ('UTF-8' !== $charset) {
399
  foreach ($values as $i => $value) {
400
  $values[$i] = twig_convert_encoding($value, $charset, 'UTF-8');
401
  }
508
  return $date;
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) {
523
  $date->setTimezone($timezone);
524
  }
526
  return $date;
527
  }
528
 
529
+ /**
530
+ * Replaces strings within a string.
531
+ *
532
+ * @param string $str String to replace in
533
+ * @param array|Traversable $from Replace values
534
+ * @param string|null $to Replace to, deprecated (@see http://php.net/manual/en/function.strtr.php)
535
+ *
536
+ * @return string
537
+ */
538
+ function twig_replace_filter($str, $from, $to = null)
539
+ {
540
+ if ($from instanceof Traversable) {
541
+ $from = iterator_to_array($from);
542
+ } elseif (is_string($from) && is_string($to)) {
543
+ @trigger_error('Using "replace" with character by character replacement is deprecated since version 1.22 and will be removed in Twig 2.0', E_USER_DEPRECATED);
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);
551
+ }
552
+
553
  /**
554
  * Rounds a number.
555
  *
683
  * {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car' } #}
684
  * </pre>
685
  *
686
+ * @param array|Traversable $arr1 An array
687
+ * @param array|Traversable $arr2 An array
688
  *
689
  * @return array The merged array
690
  */
691
  function twig_array_merge($arr1, $arr2)
692
  {
693
+ if ($arr1 instanceof Traversable) {
694
+ $arr1 = iterator_to_array($arr1);
695
+ } elseif (!is_array($arr1)) {
696
+ throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as first argument.', gettype($arr1)));
697
+ }
698
+
699
+ if ($arr2 instanceof Traversable) {
700
+ $arr2 = iterator_to_array($arr2);
701
+ } elseif (!is_array($arr2)) {
702
+ throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as second argument.', gettype($arr2)));
703
  }
704
 
705
  return array_merge($arr1, $arr2);
821
  * {# returns [aa, bb, cc] #}
822
  * </pre>
823
  *
824
+ * @param Twig_Environment $env A Twig_Environment instance
825
+ * @param string $value A string
826
+ * @param string $delimiter The delimiter
827
+ * @param int $limit The limit
828
  *
829
  * @return array The split string as an array
830
  */
858
  // The '_default' filter is used internally to avoid using the ternary operator
859
  // which costs a lot for big contexts (before PHP 5.4). So, on average,
860
  // a function call is cheaper.
861
+ /**
862
+ * @internal
863
+ */
864
  function _twig_default_filter($value, $default = '')
865
  {
866
  if (twig_test_empty($value)) {
887
  */
888
  function twig_get_array_keys_filter($array)
889
  {
890
+ if ($array instanceof Traversable) {
891
  return array_keys(iterator_to_array($array));
892
  }
893
 
909
  */
910
  function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false)
911
  {
912
+ if ($item instanceof Traversable) {
913
  return array_reverse(iterator_to_array($item), $preserveKeys);
914
  }
915
 
920
  if (null !== $charset = $env->getCharset()) {
921
  $string = (string) $item;
922
 
923
+ if ('UTF-8' !== $charset) {
924
  $item = twig_convert_encoding($string, 'UTF-8', $charset);
925
  }
926
 
928
 
929
  $string = implode('', array_reverse($matches[0]));
930
 
931
+ if ('UTF-8' !== $charset) {
932
  $string = twig_convert_encoding($string, $charset, 'UTF-8');
933
  }
934
 
941
  /**
942
  * Sorts an array.
943
  *
944
+ * @param array|Traversable $array
945
  *
946
  * @return array
947
  */
948
  function twig_sort_filter($array)
949
  {
950
+ if ($array instanceof Traversable) {
951
+ $array = iterator_to_array($array);
952
+ } elseif (!is_array($array)) {
953
+ throw new Twig_Error_Runtime(sprintf('The sort filter only works with arrays or "Traversable", got "%s".', gettype($array)));
954
+ }
955
+
956
  asort($array);
957
 
958
  return $array;
959
  }
960
 
961
+ /**
962
+ * @internal
963
+ */
964
  function twig_in_filter($value, $compare)
965
  {
966
  if (is_array($compare)) {
994
  if (!is_string($string)) {
995
  if (is_object($string) && method_exists($string, '__toString')) {
996
  $string = (string) $string;
997
+ } elseif (in_array($strategy, array('html', 'js', 'css', 'html_attr', 'url'))) {
998
  return $string;
999
  }
1000
  }
1054
  case 'js':
1055
  // escape all non-alphanumeric characters
1056
  // into their \xHH or \uHHHH representations
1057
+ if ('UTF-8' !== $charset) {
1058
  $string = twig_convert_encoding($string, 'UTF-8', $charset);
1059
  }
1060
 
1064
 
1065
  $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string);
1066
 
1067
+ if ('UTF-8' !== $charset) {
1068
  $string = twig_convert_encoding($string, $charset, 'UTF-8');
1069
  }
1070
 
1071
  return $string;
1072
 
1073
  case 'css':
1074
+ if ('UTF-8' !== $charset) {
1075
  $string = twig_convert_encoding($string, 'UTF-8', $charset);
1076
  }
1077
 
1081
 
1082
  $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string);
1083
 
1084
+ if ('UTF-8' !== $charset) {
1085
  $string = twig_convert_encoding($string, $charset, 'UTF-8');
1086
  }
1087
 
1088
  return $string;
1089
 
1090
  case 'html_attr':
1091
+ if ('UTF-8' !== $charset) {
1092
  $string = twig_convert_encoding($string, 'UTF-8', $charset);
1093
  }
1094
 
1098
 
1099
  $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string);
1100
 
1101
+ if ('UTF-8' !== $charset) {
1102
  $string = twig_convert_encoding($string, $charset, 'UTF-8');
1103
  }
1104
 
1128
  }
1129
  }
1130
 
1131
+ /**
1132
+ * @internal
1133
+ */
1134
  function twig_escape_filter_is_safe(Twig_Node $filterArgs)
1135
  {
1136
  foreach ($filterArgs as $arg) {
1276
  */
1277
  function twig_upper_filter(Twig_Environment $env, $string)
1278
  {
1279
+ if (null !== $charset = $env->getCharset()) {
1280
  return mb_strtoupper($string, $charset);
1281
  }
1282
 
1293
  */
1294
  function twig_lower_filter(Twig_Environment $env, $string)
1295
  {
1296
+ if (null !== $charset = $env->getCharset()) {
1297
  return mb_strtolower($string, $charset);
1298
  }
1299
 
1310
  */
1311
  function twig_title_string_filter(Twig_Environment $env, $string)
1312
  {
1313
+ if (null !== $charset = $env->getCharset()) {
1314
  return mb_convert_case($string, MB_CASE_TITLE, $charset);
1315
  }
1316
 
1327
  */
1328
  function twig_capitalize_string_filter(Twig_Environment $env, $string)
1329
  {
1330
+ if (null !== $charset = $env->getCharset()) {
1331
+ return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset);
 
1332
  }
1333
 
1334
  return ucfirst(strtolower($string));
1376
  }
1377
  }
1378
 
1379
+ /**
1380
+ * @internal
1381
+ */
1382
  function twig_ensure_traversable($seq)
1383
  {
1384
  if ($seq instanceof Traversable || is_array($seq)) {
1481
  /**
1482
  * Returns a template content without rendering it.
1483
  *
1484
+ * @param Twig_Environment $env
1485
+ * @param string $name The template name
1486
+ * @param bool $ignoreMissing Whether to ignore missing templates or not
1487
  *
1488
  * @return string The template source
1489
  */
vendor/twig/twig/lib/Twig/Extension/Debug.php CHANGED
@@ -10,11 +10,6 @@
10
  */
11
  class Twig_Extension_Debug extends Twig_Extension
12
  {
13
- /**
14
- * Returns a list of global functions to add to the existing list.
15
- *
16
- * @return array An array of global functions
17
- */
18
  public function getFunctions()
19
  {
20
  // dump is safe if var_dump is overridden by xdebug
@@ -32,11 +27,6 @@ class Twig_Extension_Debug extends Twig_Extension
32
  );
33
  }
34
 
35
- /**
36
- * Returns the name of the extension.
37
- *
38
- * @return string The extension name
39
- */
40
  public function getName()
41
  {
42
  return 'debug';
10
  */
11
  class Twig_Extension_Debug extends Twig_Extension
12
  {
 
 
 
 
 
13
  public function getFunctions()
14
  {
15
  // dump is safe if var_dump is overridden by xdebug
27
  );
28
  }
29
 
 
 
 
 
 
30
  public function getName()
31
  {
32
  return 'debug';
vendor/twig/twig/lib/Twig/Extension/Escaper.php CHANGED
@@ -24,31 +24,16 @@ class Twig_Extension_Escaper extends Twig_Extension
24
  $this->setDefaultStrategy($defaultStrategy);
25
  }
26
 
27
- /**
28
- * Returns the token parser instances to add to the existing list.
29
- *
30
- * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
31
- */
32
  public function getTokenParsers()
33
  {
34
  return array(new Twig_TokenParser_AutoEscape());
35
  }
36
 
37
- /**
38
- * Returns the node visitor instances to add to the existing list.
39
- *
40
- * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
41
- */
42
  public function getNodeVisitors()
43
  {
44
  return array(new Twig_NodeVisitor_Escaper());
45
  }
46
 
47
- /**
48
- * Returns a list of filters to add to the existing list.
49
- *
50
- * @return array An array of filters
51
- */
52
  public function getFilters()
53
  {
54
  return array(
@@ -68,7 +53,7 @@ class Twig_Extension_Escaper extends Twig_Extension
68
  {
69
  // for BC
70
  if (true === $defaultStrategy) {
71
- @trigger_error('Using "true" as the default strategy is deprecated. Use "html" instead.', E_USER_DEPRECATED);
72
 
73
  $defaultStrategy = 'html';
74
  }
@@ -98,11 +83,6 @@ class Twig_Extension_Escaper extends Twig_Extension
98
  return $this->defaultStrategy;
99
  }
100
 
101
- /**
102
- * Returns the name of the extension.
103
- *
104
- * @return string The extension name
105
- */
106
  public function getName()
107
  {
108
  return 'escaper';
24
  $this->setDefaultStrategy($defaultStrategy);
25
  }
26
 
 
 
 
 
 
27
  public function getTokenParsers()
28
  {
29
  return array(new Twig_TokenParser_AutoEscape());
30
  }
31
 
 
 
 
 
 
32
  public function getNodeVisitors()
33
  {
34
  return array(new Twig_NodeVisitor_Escaper());
35
  }
36
 
 
 
 
 
 
37
  public function getFilters()
38
  {
39
  return array(
53
  {
54
  // for BC
55
  if (true === $defaultStrategy) {
56
+ @trigger_error('Using "true" as the default strategy is deprecated since version 1.21. Use "html" instead.', E_USER_DEPRECATED);
57
 
58
  $defaultStrategy = 'html';
59
  }
83
  return $this->defaultStrategy;
84
  }
85
 
 
 
 
 
 
86
  public function getName()
87
  {
88
  return 'escaper';
vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Enables usage of the deprecated Twig_Extension::getGlobals() method.
14
+ *
15
+ * Explicitly implement this interface if you really need to implement the
16
+ * deprecated getGlobals() method in your extensions.
17
+ *
18
+ * @author Fabien Potencier <fabien@symfony.com>
19
+ */
20
+ interface Twig_Extension_GlobalsInterface
21
+ {
22
+ }
vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Enables usage of the deprecated Twig_Extension::initRuntime() method.
14
+ *
15
+ * Explicitly implement this interface if you really need to implement the
16
+ * deprecated initRuntime() method in your extensions.
17
+ *
18
+ * @author Fabien Potencier <fabien@symfony.com>
19
+ */
20
+ interface Twig_Extension_InitRuntimeInterface
21
+ {
22
+ }
vendor/twig/twig/lib/Twig/Extension/Optimizer.php CHANGED
@@ -17,17 +17,11 @@ class Twig_Extension_Optimizer extends Twig_Extension
17
  $this->optimizers = $optimizers;
18
  }
19
 
20
- /**
21
- * {@inheritdoc}
22
- */
23
  public function getNodeVisitors()
24
  {
25
  return array(new Twig_NodeVisitor_Optimizer($this->optimizers));
26
  }
27
 
28
- /**
29
- * {@inheritdoc}
30
- */
31
  public function getName()
32
  {
33
  return 'optimizer';
17
  $this->optimizers = $optimizers;
18
  }
19
 
 
 
 
20
  public function getNodeVisitors()
21
  {
22
  return array(new Twig_NodeVisitor_Optimizer($this->optimizers));
23
  }
24
 
 
 
 
25
  public function getName()
26
  {
27
  return 'optimizer';
vendor/twig/twig/lib/Twig/Extension/Profiler.php CHANGED
@@ -34,17 +34,11 @@ class Twig_Extension_Profiler extends Twig_Extension
34
  }
35
  }
36
 
37
- /**
38
- * {@inheritdoc}
39
- */
40
  public function getNodeVisitors()
41
  {
42
  return array(new Twig_Profiler_NodeVisitor_Profiler($this->getName()));
43
  }
44
 
45
- /**
46
- * {@inheritdoc}
47
- */
48
  public function getName()
49
  {
50
  return 'profiler';
34
  }
35
  }
36
 
 
 
 
37
  public function getNodeVisitors()
38
  {
39
  return array(new Twig_Profiler_NodeVisitor_Profiler($this->getName()));
40
  }
41
 
 
 
 
42
  public function getName()
43
  {
44
  return 'profiler';
vendor/twig/twig/lib/Twig/Extension/Sandbox.php CHANGED
@@ -20,21 +20,11 @@ class Twig_Extension_Sandbox extends Twig_Extension
20
  $this->sandboxedGlobally = $sandboxed;
21
  }
22
 
23
- /**
24
- * Returns the token parser instances to add to the existing list.
25
- *
26
- * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
27
- */
28
  public function getTokenParsers()
29
  {
30
  return array(new Twig_TokenParser_Sandbox());
31
  }
32
 
33
- /**
34
- * Returns the node visitor instances to add to the existing list.
35
- *
36
- * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
37
- */
38
  public function getNodeVisitors()
39
  {
40
  return array(new Twig_NodeVisitor_Sandbox());
@@ -100,11 +90,6 @@ class Twig_Extension_Sandbox extends Twig_Extension
100
  return $obj;
101
  }
102
 
103
- /**
104
- * Returns the name of the extension.
105
- *
106
- * @return string The extension name
107
- */
108
  public function getName()
109
  {
110
  return 'sandbox';
20
  $this->sandboxedGlobally = $sandboxed;
21
  }
22
 
 
 
 
 
 
23
  public function getTokenParsers()
24
  {
25
  return array(new Twig_TokenParser_Sandbox());
26
  }
27
 
 
 
 
 
 
28
  public function getNodeVisitors()
29
  {
30
  return array(new Twig_NodeVisitor_Sandbox());
90
  return $obj;
91
  }
92
 
 
 
 
 
 
93
  public function getName()
94
  {
95
  return 'sandbox';
vendor/twig/twig/lib/Twig/Extension/Staging.php CHANGED
@@ -15,6 +15,8 @@
15
  * This class is used by Twig_Environment as a staging area and must not be used directly.
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
 
 
18
  */
19
  class Twig_Extension_Staging extends Twig_Extension
20
  {
@@ -30,9 +32,6 @@ class Twig_Extension_Staging extends Twig_Extension
30
  $this->functions[$name] = $function;
31
  }
32
 
33
- /**
34
- * {@inheritdoc}
35
- */
36
  public function getFunctions()
37
  {
38
  return $this->functions;
@@ -43,9 +42,6 @@ class Twig_Extension_Staging extends Twig_Extension
43
  $this->filters[$name] = $filter;
44
  }
45
 
46
- /**
47
- * {@inheritdoc}
48
- */
49
  public function getFilters()
50
  {
51
  return $this->filters;
@@ -56,9 +52,6 @@ class Twig_Extension_Staging extends Twig_Extension
56
  $this->visitors[] = $visitor;
57
  }
58
 
59
- /**
60
- * {@inheritdoc}
61
- */
62
  public function getNodeVisitors()
63
  {
64
  return $this->visitors;
@@ -69,9 +62,6 @@ class Twig_Extension_Staging extends Twig_Extension
69
  $this->tokenParsers[] = $parser;
70
  }
71
 
72
- /**
73
- * {@inheritdoc}
74
- */
75
  public function getTokenParsers()
76
  {
77
  return $this->tokenParsers;
@@ -82,9 +72,6 @@ class Twig_Extension_Staging extends Twig_Extension
82
  $this->globals[$name] = $value;
83
  }
84
 
85
- /**
86
- * {@inheritdoc}
87
- */
88
  public function getGlobals()
89
  {
90
  return $this->globals;
@@ -95,17 +82,11 @@ class Twig_Extension_Staging extends Twig_Extension
95
  $this->tests[$name] = $test;
96
  }
97
 
98
- /**
99
- * {@inheritdoc}
100
- */
101
  public function getTests()
102
  {
103
  return $this->tests;
104
  }
105
 
106
- /**
107
- * {@inheritdoc}
108
- */
109
  public function getName()
110
  {
111
  return 'staging';
15
  * This class is used by Twig_Environment as a staging area and must not be used directly.
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
+ *
19
+ * @internal
20
  */
21
  class Twig_Extension_Staging extends Twig_Extension
22
  {
32
  $this->functions[$name] = $function;
33
  }
34
 
 
 
 
35
  public function getFunctions()
36
  {
37
  return $this->functions;
42
  $this->filters[$name] = $filter;
43
  }
44
 
 
 
 
45
  public function getFilters()
46
  {
47
  return $this->filters;
52
  $this->visitors[] = $visitor;
53
  }
54
 
 
 
 
55
  public function getNodeVisitors()
56
  {
57
  return $this->visitors;
62
  $this->tokenParsers[] = $parser;
63
  }
64
 
 
 
 
65
  public function getTokenParsers()
66
  {
67
  return $this->tokenParsers;
72
  $this->globals[$name] = $value;
73
  }
74
 
 
 
 
75
  public function getGlobals()
76
  {
77
  return $this->globals;
82
  $this->tests[$name] = $test;
83
  }
84
 
 
 
 
85
  public function getTests()
86
  {
87
  return $this->tests;
88
  }
89
 
 
 
 
90
  public function getName()
91
  {
92
  return 'staging';
vendor/twig/twig/lib/Twig/Extension/StringLoader.php CHANGED
@@ -10,9 +10,6 @@
10
  */
11
  class Twig_Extension_StringLoader extends Twig_Extension
12
  {
13
- /**
14
- * {@inheritdoc}
15
- */
16
  public function getFunctions()
17
  {
18
  return array(
@@ -20,9 +17,6 @@ class Twig_Extension_StringLoader extends Twig_Extension
20
  );
21
  }
22
 
23
- /**
24
- * {@inheritdoc}
25
- */
26
  public function getName()
27
  {
28
  return 'string_loader';
@@ -37,11 +31,11 @@ class Twig_Extension_StringLoader extends Twig_Extension
37
  * </pre>
38
  *
39
  * @param Twig_Environment $env A Twig_Environment instance
40
- * @param string $template A template as a string
41
  *
42
  * @return Twig_Template A Twig_Template instance
43
  */
44
  function twig_template_from_string(Twig_Environment $env, $template)
45
  {
46
- return $env->createTemplate($template);
47
  }
10
  */
11
  class Twig_Extension_StringLoader extends Twig_Extension
12
  {
 
 
 
13
  public function getFunctions()
14
  {
15
  return array(
17
  );
18
  }
19
 
 
 
 
20
  public function getName()
21
  {
22
  return 'string_loader';
31
  * </pre>
32
  *
33
  * @param Twig_Environment $env A Twig_Environment instance
34
+ * @param string $template A template as a string or object implementing __toString()
35
  *
36
  * @return Twig_Template A Twig_Template instance
37
  */
38
  function twig_template_from_string(Twig_Environment $env, $template)
39
  {
40
+ return $env->createTemplate((string) $template);
41
  }
vendor/twig/twig/lib/Twig/ExtensionInterface.php CHANGED
@@ -22,13 +22,15 @@ interface Twig_ExtensionInterface
22
  * This is where you can load some file that contains filter functions for instance.
23
  *
24
  * @param Twig_Environment $environment The current Twig_Environment instance
 
 
25
  */
26
  public function initRuntime(Twig_Environment $environment);
27
 
28
  /**
29
  * Returns the token parser instances to add to the existing list.
30
  *
31
- * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
32
  */
33
  public function getTokenParsers();
34
 
@@ -42,21 +44,21 @@ interface Twig_ExtensionInterface
42
  /**
43
  * Returns a list of filters to add to the existing list.
44
  *
45
- * @return array An array of filters
46
  */
47
  public function getFilters();
48
 
49
  /**
50
  * Returns a list of tests to add to the existing list.
51
  *
52
- * @return array An array of tests
53
  */
54
  public function getTests();
55
 
56
  /**
57
  * Returns a list of functions to add to the existing list.
58
  *
59
- * @return array An array of functions
60
  */
61
  public function getFunctions();
62
 
@@ -71,6 +73,8 @@ interface Twig_ExtensionInterface
71
  * Returns a list of global variables to add to the existing list.
72
  *
73
  * @return array An array of global variables
 
 
74
  */
75
  public function getGlobals();
76
 
22
  * This is where you can load some file that contains filter functions for instance.
23
  *
24
  * @param Twig_Environment $environment The current Twig_Environment instance
25
+ *
26
+ * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
27
  */
28
  public function initRuntime(Twig_Environment $environment);
29
 
30
  /**
31
  * Returns the token parser instances to add to the existing list.
32
  *
33
+ * @return Twig_TokenParserInterface[]
34
  */
35
  public function getTokenParsers();
36
 
44
  /**
45
  * Returns a list of filters to add to the existing list.
46
  *
47
+ * @return Twig_SimpleFilter[]
48
  */
49
  public function getFilters();
50
 
51
  /**
52
  * Returns a list of tests to add to the existing list.
53
  *
54
+ * @return Twig_SimpleTest[]
55
  */
56
  public function getTests();
57
 
58
  /**
59
  * Returns a list of functions to add to the existing list.
60
  *
61
+ * @return Twig_SimpleFunction[]
62
  */
63
  public function getFunctions();
64
 
73
  * Returns a list of global variables to add to the existing list.
74
  *
75
  * @return array An array of global variables
76
+ *
77
+ * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_GlobalsInterface instead
78
  */
79
  public function getGlobals();
80
 
vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php CHANGED
@@ -27,15 +27,21 @@ class Twig_FileExtensionEscapingStrategy
27
  *
28
  * @param string $filename The template file name
29
  *
30
- * @return string The escaping strategy name to use
31
  */
32
  public static function guess($filename)
33
  {
34
- if (!preg_match('{\.(js|css|txt)(?:\.[^/\\\\]+)?$}', $filename, $match)) {
35
- return 'html';
36
  }
37
 
38
- switch ($match[1]) {
 
 
 
 
 
 
39
  case 'js':
40
  return 'js';
41
 
@@ -44,6 +50,9 @@ class Twig_FileExtensionEscapingStrategy
44
 
45
  case 'txt':
46
  return false;
 
 
 
47
  }
48
  }
49
  }
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':
46
  return 'js';
47
 
50
 
51
  case 'txt':
52
  return false;
53
+
54
+ default:
55
+ return 'html';
56
  }
57
  }
58
  }
vendor/twig/twig/lib/Twig/Lexer.php CHANGED
@@ -129,7 +129,7 @@ class Twig_Lexer implements Twig_LexerInterface
129
 
130
  if (!empty($this->brackets)) {
131
  list($expect, $lineno) = array_pop($this->brackets);
132
- throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
133
  }
134
 
135
  if ($mbEncoding) {
@@ -224,7 +224,7 @@ class Twig_Lexer implements Twig_LexerInterface
224
  $this->moveCursor($match[0]);
225
 
226
  if ($this->cursor >= $this->end) {
227
- throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $this->state === self::STATE_BLOCK ? 'block' : 'variable'), $this->currentVarBlockLine, $this->filename);
228
  }
229
  }
230
 
@@ -256,12 +256,12 @@ class Twig_Lexer implements Twig_LexerInterface
256
  // closing bracket
257
  elseif (false !== strpos(')]}', $this->code[$this->cursor])) {
258
  if (empty($this->brackets)) {
259
- throw new Twig_Error_Syntax(sprintf('Unexpected "%s"', $this->code[$this->cursor]), $this->lineno, $this->filename);
260
  }
261
 
262
  list($expect, $lineno) = array_pop($this->brackets);
263
  if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) {
264
- throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
265
  }
266
  }
267
 
@@ -281,18 +281,18 @@ class Twig_Lexer implements Twig_LexerInterface
281
  }
282
  // unlexable
283
  else {
284
- throw new Twig_Error_Syntax(sprintf('Unexpected character "%s"', $this->code[$this->cursor]), $this->lineno, $this->filename);
285
  }
286
  }
287
 
288
  protected function lexRawData($tag)
289
  {
290
  if ('raw' === $tag) {
291
- @trigger_error(sprintf('Twig Tag "raw" is deprecated. Use "verbatim" instead in %s at line %d.', $this->filename, $this->lineno), E_USER_DEPRECATED);
292
  }
293
 
294
  if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
295
- throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s" block', $tag), $this->lineno, $this->filename);
296
  }
297
 
298
  $text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
@@ -308,7 +308,7 @@ class Twig_Lexer implements Twig_LexerInterface
308
  protected function lexComment()
309
  {
310
  if (!preg_match($this->regexes['lex_comment'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
311
- throw new Twig_Error_Syntax('Unclosed comment', $this->lineno, $this->filename);
312
  }
313
 
314
  $this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]);
@@ -327,7 +327,7 @@ class Twig_Lexer implements Twig_LexerInterface
327
  } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) {
328
  list($expect, $lineno) = array_pop($this->brackets);
329
  if ($this->code[$this->cursor] != '"') {
330
- throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
331
  }
332
 
333
  $this->popState();
129
 
130
  if (!empty($this->brackets)) {
131
  list($expect, $lineno) = array_pop($this->brackets);
132
+ throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->filename);
133
  }
134
 
135
  if ($mbEncoding) {
224
  $this->moveCursor($match[0]);
225
 
226
  if ($this->cursor >= $this->end) {
227
+ throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $this->state === self::STATE_BLOCK ? 'block' : 'variable'), $this->currentVarBlockLine, $this->filename);
228
  }
229
  }
230
 
256
  // closing bracket
257
  elseif (false !== strpos(')]}', $this->code[$this->cursor])) {
258
  if (empty($this->brackets)) {
259
+ throw new Twig_Error_Syntax(sprintf('Unexpected "%s".', $this->code[$this->cursor]), $this->lineno, $this->filename);
260
  }
261
 
262
  list($expect, $lineno) = array_pop($this->brackets);
263
  if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) {
264
+ throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->filename);
265
  }
266
  }
267
 
281
  }
282
  // unlexable
283
  else {
284
+ throw new Twig_Error_Syntax(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->filename);
285
  }
286
  }
287
 
288
  protected function lexRawData($tag)
289
  {
290
  if ('raw' === $tag) {
291
+ @trigger_error(sprintf('Twig Tag "raw" is deprecated since version 1.21. Use "verbatim" instead in %s at line %d.', $this->filename, $this->lineno), E_USER_DEPRECATED);
292
  }
293
 
294
  if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
295
+ throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s" block.', $tag), $this->lineno, $this->filename);
296
  }
297
 
298
  $text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
308
  protected function lexComment()
309
  {
310
  if (!preg_match($this->regexes['lex_comment'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
311
+ throw new Twig_Error_Syntax('Unclosed comment.', $this->lineno, $this->filename);
312
  }
313
 
314
  $this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]);
327
  } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) {
328
  list($expect, $lineno) = array_pop($this->brackets);
329
  if ($this->code[$this->cursor] != '"') {
330
+ throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->filename);
331
  }
332
 
333
  $this->popState();
vendor/twig/twig/lib/Twig/Loader/Chain.php CHANGED
@@ -60,7 +60,7 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
60
  }
61
  }
62
 
63
- throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(', ', $exceptions)));
64
  }
65
 
66
  /**
@@ -112,7 +112,7 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
112
  }
113
  }
114
 
115
- throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions)));
116
  }
117
 
118
  /**
@@ -133,6 +133,6 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
133
  }
134
  }
135
 
136
- throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions)));
137
  }
138
  }
60
  }
61
  }
62
 
63
+ throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
64
  }
65
 
66
  /**
112
  }
113
  }
114
 
115
+ throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
116
  }
117
 
118
  /**
133
  }
134
  }
135
 
136
+ throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
137
  }
138
  }
vendor/twig/twig/lib/Twig/Loader/Filesystem.php CHANGED
@@ -233,7 +233,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
233
 
234
  protected function normalizeName($name)
235
  {
236
- return preg_replace('#/{2,}#', '/', strtr((string) $name, '\\', '/'));
237
  }
238
 
239
  protected function validateName($name)
233
 
234
  protected function normalizeName($name)
235
  {
236
+ return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
237
  }
238
 
239
  protected function validateName($name)
vendor/twig/twig/lib/Twig/Loader/String.php CHANGED
@@ -9,7 +9,7 @@
9
  * file that was distributed with this source code.
10
  */
11
 
12
- @trigger_error('The Twig_Loader_String class is deprecated since version 1.18.1 and will be removed in 2.0. Use Twig_Loader_Array instead.', E_USER_DEPRECATED);
13
 
14
  /**
15
  * Loads a template from a string.
@@ -23,6 +23,8 @@
23
  *
24
  * @deprecated since 1.18.1 (to be removed in 2.0)
25
  *
 
 
26
  * @author Fabien Potencier <fabien@symfony.com>
27
  */
28
  class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ @trigger_error('The Twig_Loader_String class is deprecated since version 1.18.1 and will be removed in 2.0. Use Twig_Loader_Array instead or Twig_Environment::createTemplate().', E_USER_DEPRECATED);
13
 
14
  /**
15
  * Loads a template from a string.
23
  *
24
  * @deprecated since 1.18.1 (to be removed in 2.0)
25
  *
26
+ * @internal
27
+ *
28
  * @author Fabien Potencier <fabien@symfony.com>
29
  */
30
  class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
vendor/twig/twig/lib/Twig/Node.php CHANGED
@@ -74,7 +74,7 @@ class Twig_Node implements Twig_NodeInterface
74
  */
75
  public function toXml($asDom = false)
76
  {
77
- @trigger_error(sprintf('%s is deprecated.', __METHOD__), E_USER_DEPRECATED);
78
 
79
  $dom = new DOMDocument('1.0', 'UTF-8');
80
  $dom->formatOutput = true;
@@ -101,7 +101,7 @@ class Twig_Node implements Twig_NodeInterface
101
  $node->appendChild($child);
102
  }
103
 
104
- return $asDom ? $dom : $dom->saveXml();
105
  }
106
 
107
  public function compile(Twig_Compiler $compiler)
74
  */
75
  public function toXml($asDom = false)
76
  {
77
+ @trigger_error(sprintf('%s is deprecated since version 1.16.1 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
78
 
79
  $dom = new DOMDocument('1.0', 'UTF-8');
80
  $dom->formatOutput = true;
101
  $node->appendChild($child);
102
  }
103
 
104
+ return $asDom ? $dom : $dom->saveXML();
105
  }
106
 
107
  public function compile(Twig_Compiler $compiler)
vendor/twig/twig/lib/Twig/Node/AutoEscape.php CHANGED
@@ -27,11 +27,6 @@ class Twig_Node_AutoEscape extends Twig_Node
27
  parent::__construct(array('body' => $body), array('value' => $value), $lineno, $tag);
28
  }
29
 
30
- /**
31
- * Compiles the node to PHP.
32
- *
33
- * @param Twig_Compiler $compiler A Twig_Compiler instance
34
- */
35
  public function compile(Twig_Compiler $compiler)
36
  {
37
  $compiler->subcompile($this->getNode('body'));
27
  parent::__construct(array('body' => $body), array('value' => $value), $lineno, $tag);
28
  }
29
 
 
 
 
 
 
30
  public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler->subcompile($this->getNode('body'));
vendor/twig/twig/lib/Twig/Node/Block.php CHANGED
@@ -22,11 +22,6 @@ class Twig_Node_Block extends Twig_Node
22
  parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag);
23
  }
24
 
25
- /**
26
- * Compiles the node to PHP.
27
- *
28
- * @param Twig_Compiler $compiler A Twig_Compiler instance
29
- */
30
  public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler
22
  parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag);
23
  }
24
 
 
 
 
 
 
25
  public function compile(Twig_Compiler $compiler)
26
  {
27
  $compiler
vendor/twig/twig/lib/Twig/Node/BlockReference.php CHANGED
@@ -22,11 +22,6 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter
22
  parent::__construct(array(), array('name' => $name), $lineno, $tag);
23
  }
24
 
25
- /**
26
- * Compiles the node to PHP.
27
- *
28
- * @param Twig_Compiler $compiler A Twig_Compiler instance
29
- */
30
  public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler
22
  parent::__construct(array(), array('name' => $name), $lineno, $tag);
23
  }
24
 
 
 
 
 
 
25
  public function compile(Twig_Compiler $compiler)
26
  {
27
  $compiler
vendor/twig/twig/lib/Twig/Node/Do.php CHANGED
@@ -21,11 +21,6 @@ class Twig_Node_Do extends Twig_Node
21
  parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
22
  }
23
 
24
- /**
25
- * Compiles the node to PHP.
26
- *
27
- * @param Twig_Compiler $compiler A Twig_Compiler instance
28
- */
29
  public function compile(Twig_Compiler $compiler)
30
  {
31
  $compiler
21
  parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
22
  }
23
 
 
 
 
 
 
24
  public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
vendor/twig/twig/lib/Twig/Node/Expression/Array.php CHANGED
@@ -60,11 +60,6 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
60
  array_push($this->nodes, $key, $value);
61
  }
62
 
63
- /**
64
- * Compiles the node to PHP.
65
- *
66
- * @param Twig_Compiler $compiler A Twig_Compiler instance
67
- */
68
  public function compile(Twig_Compiler $compiler)
69
  {
70
  $compiler->raw('array(');
60
  array_push($this->nodes, $key, $value);
61
  }
62
 
 
 
 
 
 
63
  public function compile(Twig_Compiler $compiler)
64
  {
65
  $compiler->raw('array(');
vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php CHANGED
@@ -12,11 +12,6 @@
12
 
13
  class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
14
  {
15
- /**
16
- * Compiles the node to PHP.
17
- *
18
- * @param Twig_Compiler $compiler A Twig_Compiler instance
19
- */
20
  public function compile(Twig_Compiler $compiler)
21
  {
22
  $compiler
12
 
13
  class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
14
  {
 
 
 
 
 
15
  public function compile(Twig_Compiler $compiler)
16
  {
17
  $compiler
vendor/twig/twig/lib/Twig/Node/Expression/Binary.php CHANGED
@@ -16,11 +16,6 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
16
  parent::__construct(array('left' => $left, 'right' => $right), array(), $lineno);
17
  }
18
 
19
- /**
20
- * Compiles the node to PHP.
21
- *
22
- * @param Twig_Compiler $compiler A Twig_Compiler instance
23
- */
24
  public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
16
  parent::__construct(array('left' => $left, 'right' => $right), array(), $lineno);
17
  }
18
 
 
 
 
 
 
19
  public function compile(Twig_Compiler $compiler)
20
  {
21
  $compiler
vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php CHANGED
@@ -10,11 +10,6 @@
10
  */
11
  class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
12
  {
13
- /**
14
- * Compiles the node to PHP.
15
- *
16
- * @param Twig_Compiler $compiler A Twig_Compiler instance
17
- */
18
  public function compile(Twig_Compiler $compiler)
19
  {
20
  $compiler->raw('intval(floor(');
10
  */
11
  class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
12
  {
 
 
 
 
 
13
  public function compile(Twig_Compiler $compiler)
14
  {
15
  $compiler->raw('intval(floor(');
vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php CHANGED
@@ -10,11 +10,6 @@
10
  */
11
  class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
12
  {
13
- /**
14
- * Compiles the node to PHP.
15
- *
16
- * @param Twig_Compiler $compiler A Twig_Compiler instance
17
- */
18
  public function compile(Twig_Compiler $compiler)
19
  {
20
  $compiler
10
  */
11
  class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
12
  {
 
 
 
 
 
13
  public function compile(Twig_Compiler $compiler)
14
  {
15
  $compiler
vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php CHANGED
@@ -10,11 +10,6 @@
10
  */
11
  class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
12
  {
13
- /**
14
- * Compiles the node to PHP.
15
- *
16
- * @param Twig_Compiler $compiler A Twig_Compiler instance
17
- */
18
  public function compile(Twig_Compiler $compiler)
19
  {
20
  $compiler
10
  */
11
  class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
12
  {
 
 
 
 
 
13
  public function compile(Twig_Compiler $compiler)
14
  {
15
  $compiler
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php CHANGED
@@ -10,11 +10,6 @@
10
  */
11
  class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
12
  {
13
- /**
14
- * Compiles the node to PHP.
15
- *
16
- * @param Twig_Compiler $compiler A Twig_Compiler instance
17
- */
18
  public function compile(Twig_Compiler $compiler)
19
  {
20
  $compiler
10
  */
11
  class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
12
  {
 
 
 
 
 
13
  public function compile(Twig_Compiler $compiler)
14
  {
15
  $compiler
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php CHANGED
@@ -10,11 +10,6 @@
10
  */
11
  class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
12
  {
13
- /**
14
- * Compiles the node to PHP.
15
- *
16
- * @param Twig_Compiler $compiler A Twig_Compiler instance
17
- */
18
  public function compile(Twig_Compiler $compiler)
19
  {
20
  $compiler
10
  */
11
  class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
12
  {
 
 
 
 
 
13
  public function compile(Twig_Compiler $compiler)
14
  {
15
  $compiler
vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php CHANGED
@@ -22,11 +22,6 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
22
  parent::__construct(array('name' => $name), array('as_string' => $asString, 'output' => false), $lineno, $tag);
23
  }
24
 
25
- /**
26
- * Compiles the node to PHP.
27
- *
28
- * @param Twig_Compiler $compiler A Twig_Compiler instance
29
- */
30
  public function compile(Twig_Compiler $compiler)
31
  {
32
  if ($this->getAttribute('as_string')) {
22
  parent::__construct(array('name' => $name), array('as_string' => $asString, 'output' => false), $lineno, $tag);
23
  }
24
 
 
 
 
 
 
25
  public function compile(Twig_Compiler $compiler)
26
  {
27
  if ($this->getAttribute('as_string')) {
vendor/twig/twig/lib/Twig/Node/Expression/Call.php CHANGED
@@ -122,53 +122,14 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
122
  }
123
 
124
  // manage named arguments
125
- if (is_array($callable)) {
126
- $r = new ReflectionMethod($callable[0], $callable[1]);
127
- } elseif (is_object($callable) && !$callable instanceof Closure) {
128
- $r = new ReflectionObject($callable);
129
- $r = $r->getMethod('__invoke');
130
- } elseif (is_string($callable) && false !== strpos($callable, '::')) {
131
- $r = new ReflectionMethod($callable);
132
- } else {
133
- $r = new ReflectionFunction($callable);
134
- }
135
-
136
- $definition = $r->getParameters();
137
- if ($this->hasNode('node')) {
138
- array_shift($definition);
139
- }
140
- if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
141
- array_shift($definition);
142
- }
143
- if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
144
- array_shift($definition);
145
- }
146
- if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
147
- foreach ($this->getAttribute('arguments') as $argument) {
148
- array_shift($definition);
149
- }
150
- }
151
- if ($isVariadic) {
152
- $argument = end($definition);
153
- if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && array() === $argument->getDefaultValue()) {
154
- array_pop($definition);
155
- } else {
156
- $callableName = $r->name;
157
- if ($r->getDeclaringClass()) {
158
- $callableName = $r->getDeclaringClass()->name.'::'.$callableName;
159
- }
160
-
161
- throw new LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = array()".', $callableName, $callType, $callName));
162
- }
163
- }
164
-
165
  $arguments = array();
166
  $names = array();
167
  $missingArguments = array();
168
  $optionalArguments = array();
169
  $pos = 0;
170
- foreach ($definition as $param) {
171
- $names[] = $name = $this->normalizeName($param->name);
172
 
173
  if (array_key_exists($name, $parameters)) {
174
  if (array_key_exists($pos, $parameters)) {
@@ -192,9 +153,9 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
192
  unset($parameters[$pos]);
193
  $optionalArguments = array();
194
  ++$pos;
195
- } elseif ($param->isDefaultValueAvailable()) {
196
- $optionalArguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1);
197
- } elseif ($param->isOptional()) {
198
  if (empty($parameters)) {
199
  break;
200
  } else {
@@ -244,4 +205,49 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
244
  {
245
  return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $name));
246
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
122
  }
123
 
124
  // manage named arguments
125
+ $callableParameters = $this->getCallableParameters($callable, $isVariadic);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  $arguments = array();
127
  $names = array();
128
  $missingArguments = array();
129
  $optionalArguments = array();
130
  $pos = 0;
131
+ foreach ($callableParameters as $callableParameter) {
132
+ $names[] = $name = $this->normalizeName($callableParameter->name);
133
 
134
  if (array_key_exists($name, $parameters)) {
135
  if (array_key_exists($pos, $parameters)) {
153
  unset($parameters[$pos]);
154
  $optionalArguments = array();
155
  ++$pos;
156
+ } elseif ($callableParameter->isDefaultValueAvailable()) {
157
+ $optionalArguments[] = new Twig_Node_Expression_Constant($callableParameter->getDefaultValue(), -1);
158
+ } elseif ($callableParameter->isOptional()) {
159
  if (empty($parameters)) {
160
  break;
161
  } else {
205
  {
206
  return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $name));
207
  }
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();
223
+ if ($this->hasNode('node')) {
224
+ array_shift($parameters);
225
+ }
226
+ if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
227
+ array_shift($parameters);
228
+ }
229
+ if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
230
+ array_shift($parameters);
231
+ }
232
+ if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
233
+ foreach ($this->getAttribute('arguments') as $argument) {
234
+ array_shift($parameters);
235
+ }
236
+ }
237
+ if ($isVariadic) {
238
+ $argument = end($parameters);
239
+ if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && array() === $argument->getDefaultValue()) {
240
+ array_pop($parameters);
241
+ } else {
242
+ $callableName = $r->name;
243
+ if ($r->getDeclaringClass()) {
244
+ $callableName = $r->getDeclaringClass()->name.'::'.$callableName;
245
+ }
246
+
247
+ throw new LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = array()".', $callableName, $this->getAttribute('type'), $this->getAttribute('name')));
248
+ }
249
+ }
250
+
251
+ return $parameters;
252
+ }
253
  }
vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php CHANGED
@@ -9,10 +9,14 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Represents an extension call node.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
 
 
16
  */
17
  class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
18
  {
@@ -21,11 +25,6 @@ class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
21
  parent::__construct(array(), array('name' => $name), $lineno, $tag);
22
  }
23
 
24
- /**
25
- * Compiles the node to PHP.
26
- *
27
- * @param Twig_Compiler $compiler A Twig_Compiler instance
28
- */
29
  public function compile(Twig_Compiler $compiler)
30
  {
31
  $compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name')));
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ @trigger_error('The Twig_Node_Expression_ExtensionReference class is deprecated since version 1.23 and will be removed in 2.0.', E_USER_DEPRECATED);
13
+
14
  /**
15
  * Represents an extension call node.
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
+ *
19
+ * @deprecated since 1.23 and will be removed in 2.0.
20
  */
21
  class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
22
  {
25
  parent::__construct(array(), array('name' => $name), $lineno, $tag);
26
  }
27
 
 
 
 
 
 
28
  public function compile(Twig_Compiler $compiler)
29
  {
30
  $compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name')));
vendor/twig/twig/lib/Twig/Node/Expression/Name.php CHANGED
@@ -30,19 +30,11 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
30
 
31
  if ($this->getAttribute('is_defined_test')) {
32
  if ($this->isSpecial()) {
33
- if ('_self' === $name) {
34
- @trigger_error(sprintf('Global variable "_self" is deprecated in %s at line %d', '?', $this->getLine()), E_USER_DEPRECATED);
35
- }
36
-
37
  $compiler->repr(true);
38
  } else {
39
  $compiler->raw('array_key_exists(')->repr($name)->raw(', $context)');
40
  }
41
  } elseif ($this->isSpecial()) {
42
- if ('_self' === $name) {
43
- @trigger_error(sprintf('Global variable "_self" is deprecated in %s at line %d', '?', $this->getLine()), E_USER_DEPRECATED);
44
- }
45
-
46
  $compiler->raw($this->specialVars[$name]);
47
  } elseif ($this->getAttribute('always_defined')) {
48
  $compiler
30
 
31
  if ($this->getAttribute('is_defined_test')) {
32
  if ($this->isSpecial()) {
 
 
 
 
33
  $compiler->repr(true);
34
  } else {
35
  $compiler->raw('array_key_exists(')->repr($name)->raw(', $context)');
36
  }
37
  } elseif ($this->isSpecial()) {
 
 
 
 
38
  $compiler->raw($this->specialVars[$name]);
39
  } elseif ($this->getAttribute('always_defined')) {
40
  $compiler
vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class Twig_Node_Expression_NullCoalesce extends Twig_Node_Expression_Conditional
12
+ {
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);
22
+ }
23
+ }
vendor/twig/twig/lib/Twig/Node/Expression/Parent.php CHANGED
@@ -22,11 +22,6 @@ class Twig_Node_Expression_Parent extends Twig_Node_Expression
22
  parent::__construct(array(), array('output' => false, 'name' => $name), $lineno, $tag);
23
  }
24
 
25
- /**
26
- * Compiles the node to PHP.
27
- *
28
- * @param Twig_Compiler $compiler A Twig_Compiler instance
29
- */
30
  public function compile(Twig_Compiler $compiler)
31
  {
32
  if ($this->getAttribute('output')) {
22
  parent::__construct(array(), array('output' => false, 'name' => $name), $lineno, $tag);
23
  }
24
 
 
 
 
 
 
25
  public function compile(Twig_Compiler $compiler)
26
  {
27
  if ($this->getAttribute('output')) {
vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php CHANGED
@@ -25,17 +25,19 @@ class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test
25
  {
26
  public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
27
  {
28
- parent::__construct($node, $name, $arguments, $lineno);
29
-
30
  if ($node instanceof Twig_Node_Expression_Name) {
31
  $node->setAttribute('is_defined_test', true);
32
  } elseif ($node instanceof Twig_Node_Expression_GetAttr) {
33
  $node->setAttribute('is_defined_test', true);
34
 
35
  $this->changeIgnoreStrictCheck($node);
 
 
36
  } else {
37
- throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine());
38
  }
 
 
39
  }
40
 
41
  protected function changeIgnoreStrictCheck(Twig_Node_Expression_GetAttr $node)
25
  {
26
  public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
27
  {
 
 
28
  if ($node instanceof Twig_Node_Expression_Name) {
29
  $node->setAttribute('is_defined_test', true);
30
  } elseif ($node instanceof Twig_Node_Expression_GetAttr) {
31
  $node->setAttribute('is_defined_test', true);
32
 
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);
41
  }
42
 
43
  protected function changeIgnoreStrictCheck(Twig_Node_Expression_GetAttr $node)
vendor/twig/twig/lib/Twig/Node/Flush.php CHANGED
@@ -21,11 +21,6 @@ class Twig_Node_Flush extends Twig_Node
21
  parent::__construct(array(), array(), $lineno, $tag);
22
  }
23
 
24
- /**
25
- * Compiles the node to PHP.
26
- *
27
- * @param Twig_Compiler $compiler A Twig_Compiler instance
28
- */
29
  public function compile(Twig_Compiler $compiler)
30
  {
31
  $compiler
21
  parent::__construct(array(), array(), $lineno, $tag);
22
  }
23
 
 
 
 
 
 
24
  public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
vendor/twig/twig/lib/Twig/Node/For.php CHANGED
@@ -30,17 +30,11 @@ class Twig_Node_For extends Twig_Node
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
- /**
34
- * Compiles the node to PHP.
35
- *
36
- * @param Twig_Compiler $compiler A Twig_Compiler instance
37
- */
38
  public function compile(Twig_Compiler $compiler)
39
  {
40
  $compiler
41
  ->addDebugInfo($this)
42
- // the (array) cast bypasses a PHP 5.2.6 bug
43
- ->write("\$context['_parent'] = (array) \$context;\n")
44
  ->write("\$context['_seq'] = twig_ensure_traversable(")
45
  ->subcompile($this->getNode('seq'))
46
  ->raw(");\n")
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)
34
  {
35
  $compiler
36
  ->addDebugInfo($this)
37
+ ->write("\$context['_parent'] = \$context;\n")
 
38
  ->write("\$context['_seq'] = twig_ensure_traversable(")
39
  ->subcompile($this->getNode('seq'))
40
  ->raw(");\n")
vendor/twig/twig/lib/Twig/Node/ForLoop.php CHANGED
@@ -21,11 +21,6 @@ class Twig_Node_ForLoop extends Twig_Node
21
  parent::__construct(array(), array('with_loop' => false, 'ifexpr' => false, 'else' => false), $lineno, $tag);
22
  }
23
 
24
- /**
25
- * Compiles the node to PHP.
26
- *
27
- * @param Twig_Compiler $compiler A Twig_Compiler instance
28
- */
29
  public function compile(Twig_Compiler $compiler)
30
  {
31
  if ($this->getAttribute('else')) {
21
  parent::__construct(array(), array('with_loop' => false, 'ifexpr' => false, 'else' => false), $lineno, $tag);
22
  }
23
 
 
 
 
 
 
24
  public function compile(Twig_Compiler $compiler)
25
  {
26
  if ($this->getAttribute('else')) {
vendor/twig/twig/lib/Twig/Node/If.php CHANGED
@@ -22,11 +22,6 @@ class Twig_Node_If extends Twig_Node
22
  parent::__construct(array('tests' => $tests, 'else' => $else), array(), $lineno, $tag);
23
  }
24
 
25
- /**
26
- * Compiles the node to PHP.
27
- *
28
- * @param Twig_Compiler $compiler A Twig_Compiler instance
29
- */
30
  public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler->addDebugInfo($this);
22
  parent::__construct(array('tests' => $tests, 'else' => $else), array(), $lineno, $tag);
23
  }
24
 
 
 
 
 
 
25
  public function compile(Twig_Compiler $compiler)
26
  {
27
  $compiler->addDebugInfo($this);
vendor/twig/twig/lib/Twig/Node/Import.php CHANGED
@@ -21,11 +21,6 @@ class Twig_Node_Import extends Twig_Node
21
  parent::__construct(array('expr' => $expr, 'var' => $var), array(), $lineno, $tag);
22
  }
23
 
24
- /**
25
- * Compiles the node to PHP.
26
- *
27
- * @param Twig_Compiler $compiler A Twig_Compiler instance
28
- */
29
  public function compile(Twig_Compiler $compiler)
30
  {
31
  $compiler
21
  parent::__construct(array('expr' => $expr, 'var' => $var), array(), $lineno, $tag);
22
  }
23
 
 
 
 
 
 
24
  public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
vendor/twig/twig/lib/Twig/Node/Include.php CHANGED
@@ -22,11 +22,6 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
22
  parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag);
23
  }
24
 
25
- /**
26
- * Compiles the node to PHP.
27
- *
28
- * @param Twig_Compiler $compiler A Twig_Compiler instance
29
- */
30
  public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler->addDebugInfo($this);
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)
26
  {
27
  $compiler->addDebugInfo($this);
vendor/twig/twig/lib/Twig/Node/Macro.php CHANGED
@@ -22,18 +22,13 @@ 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
 
29
  parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag);
30
  }
31
 
32
- /**
33
- * Compiles the node to PHP.
34
- *
35
- * @param Twig_Compiler $compiler A Twig_Compiler instance
36
- */
37
  public function compile(Twig_Compiler $compiler)
38
  {
39
  $compiler
@@ -114,6 +109,11 @@ class Twig_Node_Macro extends Twig_Node
114
  ->write("ob_end_clean();\n\n")
115
  ->write("throw \$e;\n")
116
  ->outdent()
 
 
 
 
 
117
  ->write("}\n\n")
118
  ->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n")
119
  ->outdent()
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
 
29
  parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag);
30
  }
31
 
 
 
 
 
 
32
  public function compile(Twig_Compiler $compiler)
33
  {
34
  $compiler
109
  ->write("ob_end_clean();\n\n")
110
  ->write("throw \$e;\n")
111
  ->outdent()
112
+ ->write("} catch (Throwable \$e) {\n")
113
+ ->indent()
114
+ ->write("ob_end_clean();\n\n")
115
+ ->write("throw \$e;\n")
116
+ ->outdent()
117
  ->write("}\n\n")
118
  ->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n")
119
  ->outdent()
vendor/twig/twig/lib/Twig/Node/Module.php CHANGED
@@ -47,11 +47,6 @@ class Twig_Node_Module extends Twig_Node
47
  $this->setAttribute('index', $index);
48
  }
49
 
50
- /**
51
- * Compiles the node to PHP.
52
- *
53
- * @param Twig_Compiler $compiler A Twig_Compiler instance
54
- */
55
  public function compile(Twig_Compiler $compiler)
56
  {
57
  $this->compileTemplate($compiler);
47
  $this->setAttribute('index', $index);
48
  }
49
 
 
 
 
 
 
50
  public function compile(Twig_Compiler $compiler)
51
  {
52
  $this->compileTemplate($compiler);
vendor/twig/twig/lib/Twig/Node/Print.php CHANGED
@@ -22,11 +22,6 @@ class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface
22
  parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
23
  }
24
 
25
- /**
26
- * Compiles the node to PHP.
27
- *
28
- * @param Twig_Compiler $compiler A Twig_Compiler instance
29
- */
30
  public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler
22
  parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
23
  }
24
 
 
 
 
 
 
25
  public function compile(Twig_Compiler $compiler)
26
  {
27
  $compiler
vendor/twig/twig/lib/Twig/Node/Sandbox.php CHANGED
@@ -21,11 +21,6 @@ class Twig_Node_Sandbox extends Twig_Node
21
  parent::__construct(array('body' => $body), array(), $lineno, $tag);
22
  }
23
 
24
- /**
25
- * Compiles the node to PHP.
26
- *
27
- * @param Twig_Compiler $compiler A Twig_Compiler instance
28
- */
29
  public function compile(Twig_Compiler $compiler)
30
  {
31
  $compiler
21
  parent::__construct(array('body' => $body), array(), $lineno, $tag);
22
  }
23
 
 
 
 
 
 
24
  public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php CHANGED
@@ -21,16 +21,6 @@
21
  */
22
  class Twig_Node_SandboxedPrint extends Twig_Node_Print
23
  {
24
- public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null)
25
- {
26
- parent::__construct($expr, $lineno, $tag);
27
- }
28
-
29
- /**
30
- * Compiles the node to PHP.
31
- *
32
- * @param Twig_Compiler $compiler A Twig_Compiler instance
33
- */
34
  public function compile(Twig_Compiler $compiler)
35
  {
36
  $compiler
21
  */
22
  class Twig_Node_SandboxedPrint extends Twig_Node_Print
23
  {
 
 
 
 
 
 
 
 
 
 
24
  public function compile(Twig_Compiler $compiler)
25
  {
26
  $compiler
vendor/twig/twig/lib/Twig/Node/Set.php CHANGED
@@ -36,11 +36,6 @@ class Twig_Node_Set extends Twig_Node
36
  }
37
  }
38
 
39
- /**
40
- * Compiles the node to PHP.
41
- *
42
- * @param Twig_Compiler $compiler A Twig_Compiler instance
43
- */
44
  public function compile(Twig_Compiler $compiler)
45
  {
46
  $compiler->addDebugInfo($this);
36
  }
37
  }
38
 
 
 
 
 
 
39
  public function compile(Twig_Compiler $compiler)
40
  {
41
  $compiler->addDebugInfo($this);
vendor/twig/twig/lib/Twig/Node/Spaceless.php CHANGED
@@ -23,11 +23,6 @@ class Twig_Node_Spaceless extends Twig_Node
23
  parent::__construct(array('body' => $body), array(), $lineno, $tag);
24
  }
25
 
26
- /**
27
- * Compiles the node to PHP.
28
- *
29
- * @param Twig_Compiler $compiler A Twig_Compiler instance
30
- */
31
  public function compile(Twig_Compiler $compiler)
32
  {
33
  $compiler
23
  parent::__construct(array('body' => $body), array(), $lineno, $tag);
24
  }
25
 
 
 
 
 
 
26
  public function compile(Twig_Compiler $compiler)
27
  {
28
  $compiler
vendor/twig/twig/lib/Twig/Node/Text.php CHANGED
@@ -22,11 +22,6 @@ class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface
22
  parent::__construct(array(), array('data' => $data), $lineno);
23
  }
24
 
25
- /**
26
- * Compiles the node to PHP.
27
- *
28
- * @param Twig_Compiler $compiler A Twig_Compiler instance
29
- */
30
  public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler
22
  parent::__construct(array(), array('data' => $data), $lineno);
23
  }
24
 
 
 
 
 
 
25
  public function compile(Twig_Compiler $compiler)
26
  {
27
  $compiler
vendor/twig/twig/lib/Twig/Parser.php CHANGED
@@ -63,7 +63,12 @@ class Twig_Parser implements Twig_ParserInterface
63
  public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false)
64
  {
65
  // push all variables into the stack to keep the current state of the parser
66
- $vars = get_object_vars($this);
 
 
 
 
 
67
  unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser'], $vars['reservedMacroNames']);
68
  $this->stack[] = $vars;
69
 
@@ -94,10 +99,8 @@ class Twig_Parser implements Twig_ParserInterface
94
  try {
95
  $body = $this->subparse($test, $dropNeedle);
96
 
97
- if (null !== $this->parent) {
98
- if (null === $body = $this->filterBodyNodes($body)) {
99
- $body = new Twig_Node();
100
- }
101
  }
102
  } catch (Twig_Error_Syntax $e) {
103
  if (!$e->getTemplateFile()) {
@@ -148,7 +151,7 @@ class Twig_Parser implements Twig_ParserInterface
148
  $token = $this->getCurrentToken();
149
 
150
  if ($token->getType() !== Twig_Token::NAME_TYPE) {
151
- throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine(), $this->getFilename());
152
  }
153
 
154
  if (null !== $test && call_user_func($test, $token)) {
@@ -166,20 +169,17 @@ class Twig_Parser implements Twig_ParserInterface
166
  $subparser = $this->handlers->getTokenParser($token->getValue());
167
  if (null === $subparser) {
168
  if (null !== $test) {
169
- $error = sprintf('Unexpected tag name "%s"', $token->getValue());
 
170
  if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) {
171
- $error .= sprintf(' (expecting closing tag for the "%s" tag defined near line %s)', $test[0]->getTag(), $lineno);
172
  }
173
-
174
- throw new Twig_Error_Syntax($error, $token->getLine(), $this->getFilename());
175
- }
176
-
177
- $message = sprintf('Unknown tag name "%s"', $token->getValue());
178
- if ($alternatives = $this->env->computeAlternatives($token->getValue(), array_keys($this->env->getTags()))) {
179
- $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
180
  }
181
 
182
- throw new Twig_Error_Syntax($message, $token->getLine(), $this->getFilename());
183
  }
184
 
185
  $this->stream->next();
@@ -255,7 +255,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;
63
  public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false)
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;
70
+ }
71
+
72
  unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser'], $vars['reservedMacroNames']);
73
  $this->stack[] = $vars;
74
 
99
  try {
100
  $body = $this->subparse($test, $dropNeedle);
101
 
102
+ if (null !== $this->parent && null === $body = $this->filterBodyNodes($body)) {
103
+ $body = new Twig_Node();
 
 
104
  }
105
  } catch (Twig_Error_Syntax $e) {
106
  if (!$e->getTemplateFile()) {
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
  $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
 
182
+ throw $e;
183
  }
184
 
185
  $this->stream->next();
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;
vendor/twig/twig/lib/Twig/Profiler/Profile.php CHANGED
@@ -86,6 +86,16 @@ class Twig_Profiler_Profile implements IteratorAggregate, Serializable
86
  */
87
  public function getDuration()
88
  {
 
 
 
 
 
 
 
 
 
 
89
  return isset($this->ends['wt']) && isset($this->starts['wt']) ? $this->ends['wt'] - $this->starts['wt'] : 0;
90
  }
91
 
86
  */
87
  public function getDuration()
88
  {
89
+ if ($this->isRoot() && $this->profiles) {
90
+ // for the root node with children, duration is the sum of all child durations
91
+ $duration = 0;
92
+ foreach ($this->profiles as $profile) {
93
+ $duration += $profile->getDuration();
94
+ }
95
+
96
+ return $duration;
97
+ }
98
+
99
  return isset($this->ends['wt']) && isset($this->starts['wt']) ? $this->ends['wt'] - $this->starts['wt'] : 0;
100
  }
101
 
vendor/twig/twig/lib/Twig/SimpleFilter.php CHANGED
@@ -101,6 +101,11 @@ class Twig_SimpleFilter
101
  }
102
 
103
  public function isDeprecated()
 
 
 
 
 
104
  {
105
  return $this->options['deprecated'];
106
  }
101
  }
102
 
103
  public function isDeprecated()
104
+ {
105
+ return (bool) $this->options['deprecated'];
106
+ }
107
+
108
+ public function getDeprecatedVersion()
109
  {
110
  return $this->options['deprecated'];
111
  }
vendor/twig/twig/lib/Twig/SimpleFunction.php CHANGED
@@ -91,6 +91,11 @@ class Twig_SimpleFunction
91
  }
92
 
93
  public function isDeprecated()
 
 
 
 
 
94
  {
95
  return $this->options['deprecated'];
96
  }
91
  }
92
 
93
  public function isDeprecated()
94
+ {
95
+ return (bool) $this->options['deprecated'];
96
+ }
97
+
98
+ public function getDeprecatedVersion()
99
  {
100
  return $this->options['deprecated'];
101
  }
vendor/twig/twig/lib/Twig/SimpleTest.php CHANGED
@@ -53,6 +53,11 @@ class Twig_SimpleTest
53
  }
54
 
55
  public function isDeprecated()
 
 
 
 
 
56
  {
57
  return $this->options['deprecated'];
58
  }
53
  }
54
 
55
  public function isDeprecated()
56
+ {
57
+ return (bool) $this->options['deprecated'];
58
+ }
59
+
60
+ public function getDeprecatedVersion()
61
  {
62
  return $this->options['deprecated'];
63
  }
vendor/twig/twig/lib/Twig/Template.php CHANGED
@@ -61,6 +61,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
61
  * @param array $context
62
  *
63
  * @return Twig_TemplateInterface|false The parent template or false if there is no parent
 
 
64
  */
65
  public function getParent(array $context)
66
  {
@@ -111,6 +113,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
111
  * @param string $name The block name to display from the parent
112
  * @param array $context The context
113
  * @param array $blocks The current set of blocks
 
 
114
  */
115
  public function displayParentBlock($name, array $context, array $blocks = array())
116
  {
@@ -135,6 +139,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
135
  * @param array $context The context
136
  * @param array $blocks The current set of blocks
137
  * @param bool $useBlocks Whether to use the current set of blocks
 
 
138
  */
139
  public function displayBlock($name, array $context, array $blocks = array(), $useBlocks = true)
140
  {
@@ -191,6 +197,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
191
  * @param array $blocks The current set of blocks
192
  *
193
  * @return string The rendered block
 
 
194
  */
195
  public function renderParentBlock($name, array $context, array $blocks = array())
196
  {
@@ -212,6 +220,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
212
  * @param bool $useBlocks Whether to use the current set of blocks
213
  *
214
  * @return string The rendered block
 
 
215
  */
216
  public function renderBlock($name, array $context, array $blocks = array(), $useBlocks = true)
217
  {
@@ -237,6 +247,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
237
  * @param string $name The block name
238
  *
239
  * @return bool true if the block exists, false otherwise
 
 
240
  */
241
  public function hasBlock($name)
242
  {
@@ -252,6 +264,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
252
  * @return array An array of block names
253
  *
254
  * @see hasBlock
 
 
255
  */
256
  public function getBlockNames()
257
  {
@@ -298,12 +312,41 @@ abstract class Twig_Template implements Twig_TemplateInterface
298
  * @return array An array of blocks
299
  *
300
  * @see hasBlock
 
 
301
  */
302
  public function getBlocks()
303
  {
304
  return $this->blocks;
305
  }
306
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  /**
308
  * {@inheritdoc}
309
  */
@@ -326,6 +369,12 @@ abstract class Twig_Template implements Twig_TemplateInterface
326
  ob_end_clean();
327
  }
328
 
 
 
 
 
 
 
329
  throw $e;
330
  }
331
 
@@ -380,6 +429,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
380
  * @return mixed The content of the context variable
381
  *
382
  * @throws Twig_Error_Runtime if the variable does not exist and Twig is running in strict mode
 
 
383
  */
384
  final protected function getContext($context, $item, $ignoreStrictCheck = false)
385
  {
@@ -536,7 +587,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
536
  return;
537
  }
538
 
539
- throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName());
540
  }
541
 
542
  if ($isDefinedTest) {
61
  * @param array $context
62
  *
63
  * @return Twig_TemplateInterface|false The parent template or false if there is no parent
64
+ *
65
+ * @internal
66
  */
67
  public function getParent(array $context)
68
  {
113
  * @param string $name The block name to display from the parent
114
  * @param array $context The context
115
  * @param array $blocks The current set of blocks
116
+ *
117
+ * @internal
118
  */
119
  public function displayParentBlock($name, array $context, array $blocks = array())
120
  {
139
  * @param array $context The context
140
  * @param array $blocks The current set of blocks
141
  * @param bool $useBlocks Whether to use the current set of blocks
142
+ *
143
+ * @internal
144
  */
145
  public function displayBlock($name, array $context, array $blocks = array(), $useBlocks = true)
146
  {
197
  * @param array $blocks The current set of blocks
198
  *
199
  * @return string The rendered block
200
+ *
201
+ * @internal
202
  */
203
  public function renderParentBlock($name, array $context, array $blocks = array())
204
  {
220
  * @param bool $useBlocks Whether to use the current set of blocks
221
  *
222
  * @return string The rendered block
223
+ *
224
+ * @internal
225
  */
226
  public function renderBlock($name, array $context, array $blocks = array(), $useBlocks = true)
227
  {
247
  * @param string $name The block name
248
  *
249
  * @return bool true if the block exists, false otherwise
250
+ *
251
+ * @internal
252
  */
253
  public function hasBlock($name)
254
  {
264
  * @return array An array of block names
265
  *
266
  * @see hasBlock
267
+ *
268
+ * @internal
269
  */
270
  public function getBlockNames()
271
  {
312
  * @return array An array of blocks
313
  *
314
  * @see hasBlock
315
+ *
316
+ * @internal
317
  */
318
  public function getBlocks()
319
  {
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
  */
369
  ob_end_clean();
370
  }
371
 
372
+ throw $e;
373
+ } catch (Throwable $e) {
374
+ while (ob_get_level() > $level) {
375
+ ob_end_clean();
376
+ }
377
+
378
  throw $e;
379
  }
380
 
429
  * @return mixed The content of the context variable
430
  *
431
  * @throws Twig_Error_Runtime if the variable does not exist and Twig is running in strict mode
432
+ *
433
+ * @internal
434
  */
435
  final protected function getContext($context, $item, $ignoreStrictCheck = false)
436
  {
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) {
vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php CHANGED
@@ -17,9 +17,43 @@
17
  */
18
  abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
19
  {
20
- abstract protected function getExtensions();
 
 
21
  abstract protected function getFixturesDir();
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  /**
24
  * @dataProvider getTests
25
  */
@@ -34,7 +68,7 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
34
  */
35
  public function testLegacyIntegration($file, $message, $condition, $templates, $exception, $outputs)
36
  {
37
- $this->testIntegration($file, $message, $condition, $templates, $exception, $outputs);
38
  }
39
 
40
  public function getTests($name, $legacyTests = false)
@@ -56,13 +90,13 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
56
  if (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)\s*(?:--DATA--\s*(.*))?\s*--EXCEPTION--\s*(.*)/sx', $test, $match)) {
57
  $message = $match[1];
58
  $condition = $match[2];
59
- $templates = $this->parseTemplates($match[3]);
60
  $exception = $match[5];
61
  $outputs = array(array(null, $match[4], null, ''));
62
  } elseif (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) {
63
  $message = $match[1];
64
  $condition = $match[2];
65
- $templates = $this->parseTemplates($match[3]);
66
  $exception = false;
67
  preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, PREG_SET_ORDER);
68
  } else {
@@ -72,7 +106,7 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
72
  $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs);
73
  }
74
 
75
- if (!$tests) {
76
  // add a dummy test to avoid a PHPUnit message
77
  return array(array('not', '-', '', array(), '', array()));
78
  }
@@ -107,6 +141,18 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
107
  $twig->addExtension($extension);
108
  }
109
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  // avoid using the same PHP class name for different cases
111
  // only for PHP 5.2+
112
  if (PHP_VERSION_ID >= 50300) {
@@ -119,7 +165,9 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
119
  $template = $twig->loadTemplate('index.twig');
120
  } catch (Exception $e) {
121
  if (false !== $exception) {
122
- $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
 
 
123
 
124
  return;
125
  }
@@ -137,7 +185,7 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
137
  $output = trim($template->render(eval($match[1].';')), "\n ");
138
  } catch (Exception $e) {
139
  if (false !== $exception) {
140
- $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
141
 
142
  return;
143
  }
@@ -158,7 +206,7 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
158
 
159
  $expected = trim($match[3], "\n ");
160
 
161
- if ($expected != $output) {
162
  printf("Compiled templates that failed on case %d:\n", $i + 1);
163
 
164
  foreach (array_keys($templates) as $name) {
17
  */
18
  abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
19
  {
20
+ /**
21
+ * @return string
22
+ */
23
  abstract protected function getFixturesDir();
24
 
25
+ /**
26
+ * @return Twig_ExtensionInterface[]
27
+ */
28
+ protected function getExtensions()
29
+ {
30
+ return array();
31
+ }
32
+
33
+ /**
34
+ * @return Twig_SimpleFilter[]
35
+ */
36
+ protected function getTwigFilters()
37
+ {
38
+ return array();
39
+ }
40
+
41
+ /**
42
+ * @return Twig_SimpleFunction[]
43
+ */
44
+ protected function getTwigFunctions()
45
+ {
46
+ return array();
47
+ }
48
+
49
+ /**
50
+ * @return Twig_SimpleTest[]
51
+ */
52
+ protected function getTwigTests()
53
+ {
54
+ return array();
55
+ }
56
+
57
  /**
58
  * @dataProvider getTests
59
  */
68
  */
69
  public function testLegacyIntegration($file, $message, $condition, $templates, $exception, $outputs)
70
  {
71
+ $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs);
72
  }
73
 
74
  public function getTests($name, $legacyTests = false)
90
  if (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)\s*(?:--DATA--\s*(.*))?\s*--EXCEPTION--\s*(.*)/sx', $test, $match)) {
91
  $message = $match[1];
92
  $condition = $match[2];
93
+ $templates = self::parseTemplates($match[3]);
94
  $exception = $match[5];
95
  $outputs = array(array(null, $match[4], null, ''));
96
  } elseif (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) {
97
  $message = $match[1];
98
  $condition = $match[2];
99
+ $templates = self::parseTemplates($match[3]);
100
  $exception = false;
101
  preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, PREG_SET_ORDER);
102
  } else {
106
  $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs);
107
  }
108
 
109
+ if ($legacyTests && empty($tests)) {
110
  // add a dummy test to avoid a PHPUnit message
111
  return array(array('not', '-', '', array(), '', array()));
112
  }
141
  $twig->addExtension($extension);
142
  }
143
 
144
+ foreach ($this->getTwigFilters() as $filter) {
145
+ $twig->addFilter($filter);
146
+ }
147
+
148
+ foreach ($this->getTwigTests() as $test) {
149
+ $twig->addTest($test);
150
+ }
151
+
152
+ foreach ($this->getTwigFunctions() as $function) {
153
+ $twig->addFunction($function);
154
+ }
155
+
156
  // avoid using the same PHP class name for different cases
157
  // only for PHP 5.2+
158
  if (PHP_VERSION_ID >= 50300) {
165
  $template = $twig->loadTemplate('index.twig');
166
  } catch (Exception $e) {
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
  }
185
  $output = trim($template->render(eval($match[1].';')), "\n ");
186
  } catch (Exception $e) {
187
  if (false !== $exception) {
188
+ $this->assertSame(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
189
 
190
  return;
191
  }
206
 
207
  $expected = trim($match[3], "\n ");
208
 
209
+ if ($expected !== $output) {
210
  printf("Compiled templates that failed on case %d:\n", $i + 1);
211
 
212
  foreach (array_keys($templates) as $name) {
vendor/twig/twig/lib/Twig/Test/NodeTestCase.php CHANGED
@@ -15,17 +15,21 @@ abstract class Twig_Test_NodeTestCase extends PHPUnit_Framework_TestCase
15
  /**
16
  * @dataProvider getTests
17
  */
18
- public function testCompile($node, $source, $environment = null)
19
  {
20
- $this->assertNodeCompilation($source, $node, $environment);
21
  }
22
 
23
- public function assertNodeCompilation($source, Twig_Node $node, Twig_Environment $environment = null)
24
  {
25
  $compiler = $this->getCompiler($environment);
26
  $compiler->compile($node);
27
 
28
- $this->assertEquals($source, trim($compiler->getSource()));
 
 
 
 
29
  }
30
 
31
  protected function getCompiler(Twig_Environment $environment = null)
15
  /**
16
  * @dataProvider getTests
17
  */
18
+ public function testCompile($node, $source, $environment = null, $isPattern = false)
19
  {
20
+ $this->assertNodeCompilation($source, $node, $environment, $isPattern);
21
  }
22
 
23
+ public function assertNodeCompilation($source, Twig_Node $node, Twig_Environment $environment = null, $isPattern = false)
24
  {
25
  $compiler = $this->getCompiler($environment);
26
  $compiler->compile($node);
27
 
28
+ if ($isPattern) {
29
+ $this->assertStringMatchesFormat($source, trim($compiler->getSource()));
30
+ } else {
31
+ $this->assertEquals($source, trim($compiler->getSource()));
32
+ }
33
  }
34
 
35
  protected function getCompiler(Twig_Environment $environment = null)
vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php CHANGED
@@ -29,13 +29,6 @@
29
  */
30
  class Twig_TokenParser_AutoEscape extends Twig_TokenParser
31
  {
32
- /**
33
- * Parses a token and returns a node.
34
- *
35
- * @param Twig_Token $token A Twig_Token instance
36
- *
37
- * @return Twig_NodeInterface A Twig_NodeInterface instance
38
- */
39
  public function parse(Twig_Token $token)
40
  {
41
  $lineno = $token->getLine();
@@ -46,7 +39,7 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser
46
  } else {
47
  $expr = $this->parser->getExpressionParser()->parseExpression();
48
  if (!$expr instanceof Twig_Node_Expression_Constant) {
49
- throw new Twig_Error_Syntax('An escaping strategy must be a string or a Boolean.', $stream->getCurrent()->getLine(), $stream->getFilename());
50
  }
51
  $value = $expr->getAttribute('value');
52
 
@@ -57,7 +50,7 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser
57
  }
58
 
59
  if ($compat && $stream->test(Twig_Token::NAME_TYPE)) {
60
- @trigger_error('Using the autoescape tag with "true" or "false" before the strategy name is deprecated.', E_USER_DEPRECATED);
61
 
62
  if (false === $value) {
63
  throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getFilename());
@@ -79,11 +72,6 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser
79
  return $token->test('endautoescape');
80
  }
81
 
82
- /**
83
- * Gets the tag name associated with this token parser.
84
- *
85
- * @return string The tag name
86
- */
87
  public function getTag()
88
  {
89
  return 'autoescape';
29
  */
30
  class Twig_TokenParser_AutoEscape extends Twig_TokenParser
31
  {
 
 
 
 
 
 
 
32
  public function parse(Twig_Token $token)
33
  {
34
  $lineno = $token->getLine();
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
 
50
  }
51
 
52
  if ($compat && $stream->test(Twig_Token::NAME_TYPE)) {
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());
72
  return $token->test('endautoescape');
73
  }
74
 
 
 
 
 
 
75
  public function getTag()
76
  {
77
  return 'autoescape';
vendor/twig/twig/lib/Twig/TokenParser/Block.php CHANGED
@@ -22,20 +22,13 @@
22
  */
23
  class Twig_TokenParser_Block extends Twig_TokenParser
24
  {
25
- /**
26
- * Parses a token and returns a node.
27
- *
28
- * @param Twig_Token $token A Twig_Token instance
29
- *
30
- * @return Twig_NodeInterface A Twig_NodeInterface instance
31
- */
32
  public function parse(Twig_Token $token)
33
  {
34
  $lineno = $token->getLine();
35
  $stream = $this->parser->getStream();
36
  $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
37
  if ($this->parser->hasBlock($name)) {
38
- throw new Twig_Error_Syntax(sprintf("The block '$name' has already been defined line %d", $this->parser->getBlock($name)->getLine()), $stream->getCurrent()->getLine(), $stream->getFilename());
39
  }
40
  $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno));
41
  $this->parser->pushLocalScope();
@@ -47,7 +40,7 @@ class Twig_TokenParser_Block extends Twig_TokenParser
47
  $value = $token->getValue();
48
 
49
  if ($value != $name) {
50
- throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given)', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename());
51
  }
52
  }
53
  } else {
@@ -69,11 +62,6 @@ class Twig_TokenParser_Block extends Twig_TokenParser
69
  return $token->test('endblock');
70
  }
71
 
72
- /**
73
- * Gets the tag name associated with this token parser.
74
- *
75
- * @return string The tag name
76
- */
77
  public function getTag()
78
  {
79
  return 'block';
22
  */
23
  class Twig_TokenParser_Block extends Twig_TokenParser
24
  {
 
 
 
 
 
 
 
25
  public function parse(Twig_Token $token)
26
  {
27
  $lineno = $token->getLine();
28
  $stream = $this->parser->getStream();
29
  $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
30
  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
  $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 {
62
  return $token->test('endblock');
63
  }
64
 
 
 
 
 
 
65
  public function getTag()
66
  {
67
  return 'block';
vendor/twig/twig/lib/Twig/TokenParser/Do.php CHANGED
@@ -14,13 +14,6 @@
14
  */
15
  class Twig_TokenParser_Do extends Twig_TokenParser
16
  {
17
- /**
18
- * Parses a token and returns a node.
19
- *
20
- * @param Twig_Token $token A Twig_Token instance
21
- *
22
- * @return Twig_NodeInterface A Twig_NodeInterface instance
23
- */
24
  public function parse(Twig_Token $token)
25
  {
26
  $expr = $this->parser->getExpressionParser()->parseExpression();
@@ -30,11 +23,6 @@ class Twig_TokenParser_Do extends Twig_TokenParser
30
  return new Twig_Node_Do($expr, $token->getLine(), $this->getTag());
31
  }
32
 
33
- /**
34
- * Gets the tag name associated with this token parser.
35
- *
36
- * @return string The tag name
37
- */
38
  public function getTag()
39
  {
40
  return 'do';
14
  */
15
  class Twig_TokenParser_Do extends Twig_TokenParser
16
  {
 
 
 
 
 
 
 
17
  public function parse(Twig_Token $token)
18
  {
19
  $expr = $this->parser->getExpressionParser()->parseExpression();
23
  return new Twig_Node_Do($expr, $token->getLine(), $this->getTag());
24
  }
25
 
 
 
 
 
 
26
  public function getTag()
27
  {
28
  return 'do';
vendor/twig/twig/lib/Twig/TokenParser/Embed.php CHANGED
@@ -14,13 +14,6 @@
14
  */
15
  class Twig_TokenParser_Embed extends Twig_TokenParser_Include
16
  {
17
- /**
18
- * Parses a token and returns a node.
19
- *
20
- * @param Twig_Token $token A Twig_Token instance
21
- *
22
- * @return Twig_NodeInterface A Twig_NodeInterface instance
23
- */
24
  public function parse(Twig_Token $token)
25
  {
26
  $stream = $this->parser->getStream();
@@ -54,11 +47,6 @@ class Twig_TokenParser_Embed extends Twig_TokenParser_Include
54
  return $token->test('endembed');
55
  }
56
 
57
- /**
58
- * Gets the tag name associated with this token parser.
59
- *
60
- * @return string The tag name
61
- */
62
  public function getTag()
63
  {
64
  return 'embed';
14
  */
15
  class Twig_TokenParser_Embed extends Twig_TokenParser_Include
16
  {
 
 
 
 
 
 
 
17
  public function parse(Twig_Token $token)
18
  {
19
  $stream = $this->parser->getStream();
47
  return $token->test('endembed');
48
  }
49
 
 
 
 
 
 
50
  public function getTag()
51
  {
52
  return 'embed';
vendor/twig/twig/lib/Twig/TokenParser/Extends.php CHANGED
@@ -19,32 +19,20 @@
19
  */
20
  class Twig_TokenParser_Extends extends Twig_TokenParser
21
  {
22
- /**
23
- * Parses a token and returns a node.
24
- *
25
- * @param Twig_Token $token A Twig_Token instance
26
- *
27
- * @return Twig_NodeInterface A Twig_NodeInterface instance
28
- */
29
  public function parse(Twig_Token $token)
30
  {
31
  if (!$this->parser->isMainScope()) {
32
- throw new Twig_Error_Syntax('Cannot extend from a block', $token->getLine(), $this->parser->getFilename());
33
  }
34
 
35
  if (null !== $this->parser->getParent()) {
36
- throw new Twig_Error_Syntax('Multiple extends tags are forbidden', $token->getLine(), $this->parser->getFilename());
37
  }
38
  $this->parser->setParent($this->parser->getExpressionParser()->parseExpression());
39
 
40
  $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
41
  }
42
 
43
- /**
44
- * Gets the tag name associated with this token parser.
45
- *
46
- * @return string The tag name
47
- */
48
  public function getTag()
49
  {
50
  return 'extends';
19
  */
20
  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()
37
  {
38
  return 'extends';
vendor/twig/twig/lib/Twig/TokenParser/Filter.php CHANGED
@@ -20,13 +20,6 @@
20
  */
21
  class Twig_TokenParser_Filter extends Twig_TokenParser
22
  {
23
- /**
24
- * Parses a token and returns a node.
25
- *
26
- * @param Twig_Token $token A Twig_Token instance
27
- *
28
- * @return Twig_NodeInterface A Twig_NodeInterface instance
29
- */
30
  public function parse(Twig_Token $token)
31
  {
32
  $name = $this->parser->getVarName();
@@ -49,11 +42,6 @@ class Twig_TokenParser_Filter extends Twig_TokenParser
49
  return $token->test('endfilter');
50
  }
51
 
52
- /**
53
- * Gets the tag name associated with this token parser.
54
- *
55
- * @return string The tag name
56
- */
57
  public function getTag()
58
  {
59
  return 'filter';
20
  */
21
  class Twig_TokenParser_Filter extends Twig_TokenParser
22
  {
 
 
 
 
 
 
 
23
  public function parse(Twig_Token $token)
24
  {
25
  $name = $this->parser->getVarName();
42
  return $token->test('endfilter');
43
  }
44
 
 
 
 
 
 
45
  public function getTag()
46
  {
47
  return 'filter';
vendor/twig/twig/lib/Twig/TokenParser/Flush.php CHANGED
@@ -16,13 +16,6 @@
16
  */
17
  class Twig_TokenParser_Flush extends Twig_TokenParser
18
  {
19
- /**
20
- * Parses a token and returns a node.
21
- *
22
- * @param Twig_Token $token A Twig_Token instance
23
- *
24
- * @return Twig_NodeInterface A Twig_NodeInterface instance
25
- */
26
  public function parse(Twig_Token $token)
27
  {
28
  $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
@@ -30,11 +23,6 @@ class Twig_TokenParser_Flush extends Twig_TokenParser
30
  return new Twig_Node_Flush($token->getLine(), $this->getTag());
31
  }
32
 
33
- /**
34
- * Gets the tag name associated with this token parser.
35
- *
36
- * @return string The tag name
37
- */
38
  public function getTag()
39
  {
40
  return 'flush';
16
  */
17
  class Twig_TokenParser_Flush extends Twig_TokenParser
18
  {
 
 
 
 
 
 
 
19
  public function parse(Twig_Token $token)
20
  {
21
  $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
23
  return new Twig_Node_Flush($token->getLine(), $this->getTag());
24
  }
25
 
 
 
 
 
 
26
  public function getTag()
27
  {
28
  return 'flush';
vendor/twig/twig/lib/Twig/TokenParser/For.php CHANGED
@@ -23,13 +23,6 @@
23
  */
24
  class Twig_TokenParser_For extends Twig_TokenParser
25
  {
26
- /**
27
- * Parses a token and returns a node.
28
- *
29
- * @param Twig_Token $token A Twig_Token instance
30
- *
31
- * @return Twig_NodeInterface A Twig_NodeInterface instance
32
- */
33
  public function parse(Twig_Token $token)
34
  {
35
  $lineno = $token->getLine();
@@ -86,7 +79,7 @@ class Twig_TokenParser_For extends Twig_TokenParser
86
  protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node)
87
  {
88
  if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
89
- throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition', $node->getLine(), $stream->getFilename());
90
  }
91
 
92
  foreach ($node as $n) {
@@ -105,7 +98,7 @@ class Twig_TokenParser_For extends Twig_TokenParser
105
  if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
106
  $attribute = $node->getNode('attribute');
107
  if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) {
108
- 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());
109
  }
110
  }
111
 
@@ -123,11 +116,6 @@ class Twig_TokenParser_For extends Twig_TokenParser
123
  }
124
  }
125
 
126
- /**
127
- * Gets the tag name associated with this token parser.
128
- *
129
- * @return string The tag name
130
- */
131
  public function getTag()
132
  {
133
  return 'for';
23
  */
24
  class Twig_TokenParser_For extends Twig_TokenParser
25
  {
 
 
 
 
 
 
 
26
  public function parse(Twig_Token $token)
27
  {
28
  $lineno = $token->getLine();
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
  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
 
116
  }
117
  }
118
 
 
 
 
 
 
119
  public function getTag()
120
  {
121
  return 'for';
vendor/twig/twig/lib/Twig/TokenParser/From.php CHANGED
@@ -18,13 +18,6 @@
18
  */
19
  class Twig_TokenParser_From extends Twig_TokenParser
20
  {
21
- /**
22
- * Parses a token and returns a node.
23
- *
24
- * @param Twig_Token $token A Twig_Token instance
25
- *
26
- * @return Twig_NodeInterface A Twig_NodeInterface instance
27
- */
28
  public function parse(Twig_Token $token)
29
  {
30
  $macro = $this->parser->getExpressionParser()->parseExpression();
@@ -53,7 +46,7 @@ class Twig_TokenParser_From extends Twig_TokenParser
53
 
54
  foreach ($targets as $name => $alias) {
55
  if ($this->parser->isReservedMacroName($name)) {
56
- throw new Twig_Error_Syntax(sprintf('"%s" cannot be an imported macro as it is a reserved keyword', $name), $token->getLine(), $stream->getFilename());
57
  }
58
 
59
  $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var'));
@@ -62,11 +55,6 @@ class Twig_TokenParser_From extends Twig_TokenParser
62
  return $node;
63
  }
64
 
65
- /**
66
- * Gets the tag name associated with this token parser.
67
- *
68
- * @return string The tag name
69
- */
70
  public function getTag()
71
  {
72
  return 'from';
18
  */
19
  class Twig_TokenParser_From extends Twig_TokenParser
20
  {
 
 
 
 
 
 
 
21
  public function parse(Twig_Token $token)
22
  {
23
  $macro = $this->parser->getExpressionParser()->parseExpression();
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'));
55
  return $node;
56
  }
57
 
 
 
 
 
 
58
  public function getTag()
59
  {
60
  return 'from';
vendor/twig/twig/lib/Twig/TokenParser/If.php CHANGED
@@ -25,13 +25,6 @@
25
  */
26
  class Twig_TokenParser_If extends Twig_TokenParser
27
  {
28
- /**
29
- * Parses a token and returns a node.
30
- *
31
- * @param Twig_Token $token A Twig_Token instance
32
- *
33
- * @return Twig_NodeInterface A Twig_NodeInterface instance
34
- */
35
  public function parse(Twig_Token $token)
36
  {
37
  $lineno = $token->getLine();
@@ -63,7 +56,7 @@ class Twig_TokenParser_If extends Twig_TokenParser
63
  break;
64
 
65
  default:
66
- 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());
67
  }
68
  }
69
 
@@ -82,11 +75,6 @@ class Twig_TokenParser_If extends Twig_TokenParser
82
  return $token->test(array('endif'));
83
  }
84
 
85
- /**
86
- * Gets the tag name associated with this token parser.
87
- *
88
- * @return string The tag name
89
- */
90
  public function getTag()
91
  {
92
  return 'if';
25
  */
26
  class Twig_TokenParser_If extends Twig_TokenParser
27
  {
 
 
 
 
 
 
 
28
  public function parse(Twig_Token $token)
29
  {
30
  $lineno = $token->getLine();
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
 
75
  return $token->test(array('endif'));
76
  }
77
 
 
 
 
 
 
78
  public function getTag()
79
  {
80
  return 'if';
vendor/twig/twig/lib/Twig/TokenParser/Import.php CHANGED
@@ -18,13 +18,6 @@
18
  */
19
  class Twig_TokenParser_Import extends Twig_TokenParser
20
  {
21
- /**
22
- * Parses a token and returns a node.
23
- *
24
- * @param Twig_Token $token A Twig_Token instance
25
- *
26
- * @return Twig_NodeInterface A Twig_NodeInterface instance
27
- */
28
  public function parse(Twig_Token $token)
29
  {
30
  $macro = $this->parser->getExpressionParser()->parseExpression();
@@ -37,11 +30,6 @@ class Twig_TokenParser_Import extends Twig_TokenParser
37
  return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag());
38
  }
39
 
40
- /**
41
- * Gets the tag name associated with this token parser.
42
- *
43
- * @return string The tag name
44
- */
45
  public function getTag()
46
  {
47
  return 'import';
18
  */
19
  class Twig_TokenParser_Import extends Twig_TokenParser
20
  {
 
 
 
 
 
 
 
21
  public function parse(Twig_Token $token)
22
  {
23
  $macro = $this->parser->getExpressionParser()->parseExpression();
30
  return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag());
31
  }
32
 
 
 
 
 
 
33
  public function getTag()
34
  {
35
  return 'import';
vendor/twig/twig/lib/Twig/TokenParser/Include.php CHANGED
@@ -21,13 +21,6 @@
21
  */
22
  class Twig_TokenParser_Include extends Twig_TokenParser
23
  {
24
- /**
25
- * Parses a token and returns a node.
26
- *
27
- * @param Twig_Token $token A Twig_Token instance
28
- *
29
- * @return Twig_NodeInterface A Twig_NodeInterface instance
30
- */
31
  public function parse(Twig_Token $token)
32
  {
33
  $expr = $this->parser->getExpressionParser()->parseExpression();
@@ -63,11 +56,6 @@ class Twig_TokenParser_Include extends Twig_TokenParser
63
  return array($variables, $only, $ignoreMissing);
64
  }
65
 
66
- /**
67
- * Gets the tag name associated with this token parser.
68
- *
69
- * @return string The tag name
70
- */
71
  public function getTag()
72
  {
73
  return 'include';
21
  */
22
  class Twig_TokenParser_Include extends Twig_TokenParser
23
  {
 
 
 
 
 
 
 
24
  public function parse(Twig_Token $token)
25
  {
26
  $expr = $this->parser->getExpressionParser()->parseExpression();
56
  return array($variables, $only, $ignoreMissing);
57
  }
58
 
 
 
 
 
 
59
  public function getTag()
60
  {
61
  return 'include';
vendor/twig/twig/lib/Twig/TokenParser/Macro.php CHANGED
@@ -20,13 +20,6 @@
20
  */
21
  class Twig_TokenParser_Macro extends Twig_TokenParser
22
  {
23
- /**
24
- * Parses a token and returns a node.
25
- *
26
- * @param Twig_Token $token A Twig_Token instance
27
- *
28
- * @return Twig_NodeInterface A Twig_NodeInterface instance
29
- */
30
  public function parse(Twig_Token $token)
31
  {
32
  $lineno = $token->getLine();
@@ -42,7 +35,7 @@ class Twig_TokenParser_Macro extends Twig_TokenParser
42
  $value = $token->getValue();
43
 
44
  if ($value != $name) {
45
- throw new Twig_Error_Syntax(sprintf('Expected endmacro for macro "%s" (but "%s" given)', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename());
46
  }
47
  }
48
  $this->parser->popLocalScope();
@@ -56,11 +49,6 @@ class Twig_TokenParser_Macro extends Twig_TokenParser
56
  return $token->test('endmacro');
57
  }
58
 
59
- /**
60
- * Gets the tag name associated with this token parser.
61
- *
62
- * @return string The tag name
63
- */
64
  public function getTag()
65
  {
66
  return 'macro';
20
  */
21
  class Twig_TokenParser_Macro extends Twig_TokenParser
22
  {
 
 
 
 
 
 
 
23
  public function parse(Twig_Token $token)
24
  {
25
  $lineno = $token->getLine();
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();
49
  return $token->test('endmacro');
50
  }
51
 
 
 
 
 
 
52
  public function getTag()
53
  {
54
  return 'macro';
vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php CHANGED
@@ -22,13 +22,6 @@
22
  */
23
  class Twig_TokenParser_Sandbox extends Twig_TokenParser
24
  {
25
- /**
26
- * Parses a token and returns a node.
27
- *
28
- * @param Twig_Token $token A Twig_Token instance
29
- *
30
- * @return Twig_NodeInterface A Twig_NodeInterface instance
31
- */
32
  public function parse(Twig_Token $token)
33
  {
34
  $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
@@ -43,7 +36,7 @@ class Twig_TokenParser_Sandbox extends Twig_TokenParser
43
  }
44
 
45
  if (!$node instanceof Twig_Node_Include) {
46
- throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section', $node->getLine(), $this->parser->getFilename());
47
  }
48
  }
49
  }
@@ -56,11 +49,6 @@ class Twig_TokenParser_Sandbox extends Twig_TokenParser
56
  return $token->test('endsandbox');
57
  }
58
 
59
- /**
60
- * Gets the tag name associated with this token parser.
61
- *
62
- * @return string The tag name
63
- */
64
  public function getTag()
65
  {
66
  return 'sandbox';
22
  */
23
  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);
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
  }
49
  return $token->test('endsandbox');
50
  }
51
 
 
 
 
 
 
52
  public function getTag()
53
  {
54
  return 'sandbox';
vendor/twig/twig/lib/Twig/TokenParser/Set.php CHANGED
@@ -28,13 +28,6 @@
28
  */
29
  class Twig_TokenParser_Set extends Twig_TokenParser
30
  {
31
- /**
32
- * Parses a token and returns a node.
33
- *
34
- * @param Twig_Token $token A Twig_Token instance
35
- *
36
- * @return Twig_NodeInterface A Twig_NodeInterface instance
37
- */
38
  public function parse(Twig_Token $token)
39
  {
40
  $lineno = $token->getLine();
@@ -71,11 +64,6 @@ class Twig_TokenParser_Set extends Twig_TokenParser
71
  return $token->test('endset');
72
  }
73
 
74
- /**
75
- * Gets the tag name associated with this token parser.
76
- *
77
- * @return string The tag name
78
- */
79
  public function getTag()
80
  {
81
  return 'set';
28
  */
29
  class Twig_TokenParser_Set extends Twig_TokenParser
30
  {
 
 
 
 
 
 
 
31
  public function parse(Twig_Token $token)
32
  {
33
  $lineno = $token->getLine();
64
  return $token->test('endset');
65
  }
66
 
 
 
 
 
 
67
  public function getTag()
68
  {
69
  return 'set';
vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php CHANGED
@@ -24,13 +24,6 @@
24
  */
25
  class Twig_TokenParser_Spaceless extends Twig_TokenParser
26
  {
27
- /**
28
- * Parses a token and returns a node.
29
- *
30
- * @param Twig_Token $token A Twig_Token instance
31
- *
32
- * @return Twig_NodeInterface A Twig_NodeInterface instance
33
- */
34
  public function parse(Twig_Token $token)
35
  {
36
  $lineno = $token->getLine();
@@ -47,11 +40,6 @@ class Twig_TokenParser_Spaceless extends Twig_TokenParser
47
  return $token->test('endspaceless');
48
  }
49
 
50
- /**
51
- * Gets the tag name associated with this token parser.
52
- *
53
- * @return string The tag name
54
- */
55
  public function getTag()
56
  {
57
  return 'spaceless';
24
  */
25
  class Twig_TokenParser_Spaceless extends Twig_TokenParser
26
  {
 
 
 
 
 
 
 
27
  public function parse(Twig_Token $token)
28
  {
29
  $lineno = $token->getLine();
40
  return $token->test('endspaceless');
41
  }
42
 
 
 
 
 
 
43
  public function getTag()
44
  {
45
  return 'spaceless';
vendor/twig/twig/lib/Twig/TokenParser/Use.php CHANGED
@@ -25,13 +25,6 @@
25
  */
26
  class Twig_TokenParser_Use extends Twig_TokenParser
27
  {
28
- /**
29
- * Parses a token and returns a node.
30
- *
31
- * @param Twig_Token $token A Twig_Token instance
32
- *
33
- * @return Twig_NodeInterface A Twig_NodeInterface instance
34
- */
35
  public function parse(Twig_Token $token)
36
  {
37
  $template = $this->parser->getExpressionParser()->parseExpression();
@@ -64,11 +57,6 @@ class Twig_TokenParser_Use extends Twig_TokenParser
64
  $this->parser->addTrait(new Twig_Node(array('template' => $template, 'targets' => new Twig_Node($targets))));
65
  }
66
 
67
- /**
68
- * Gets the tag name associated with this token parser.
69
- *
70
- * @return string The tag name
71
- */
72
  public function getTag()
73
  {
74
  return 'use';
25
  */
26
  class Twig_TokenParser_Use extends Twig_TokenParser
27
  {
 
 
 
 
 
 
 
28
  public function parse(Twig_Token $token)
29
  {
30
  $template = $this->parser->getExpressionParser()->parseExpression();
57
  $this->parser->addTrait(new Twig_Node(array('template' => $template, 'targets' => new Twig_Node($targets))));
58
  }
59
 
 
 
 
 
 
60
  public function getTag()
61
  {
62
  return 'use';
vendor/twig/twig/lib/Twig/TokenParserBroker.php CHANGED
@@ -26,8 +26,9 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
26
  /**
27
  * Constructor.
28
  *
29
- * @param array|Traversable $parsers A Traversable of Twig_TokenParserInterface instances
30
- * @param array|Traversable $brokers A Traversable of Twig_TokenParserBrokerInterface instances
 
31
  */
32
  public function __construct($parsers = array(), $brokers = array(), $triggerDeprecationError = true)
33
  {
@@ -37,13 +38,13 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
37
 
38
  foreach ($parsers as $parser) {
39
  if (!$parser instanceof Twig_TokenParserInterface) {
40
- throw new LogicException('$parsers must a an array of Twig_TokenParserInterface');
41
  }
42
  $this->parsers[$parser->getTag()] = $parser;
43
  }
44
  foreach ($brokers as $broker) {
45
  if (!$broker instanceof Twig_TokenParserBrokerInterface) {
46
- throw new LogicException('$brokers must a an array of Twig_TokenParserBrokerInterface');
47
  }
48
  $this->brokers[] = $broker;
49
  }
26
  /**
27
  * Constructor.
28
  *
29
+ * @param array|Traversable $parsers A Traversable of Twig_TokenParserInterface instances
30
+ * @param array|Traversable $brokers A Traversable of Twig_TokenParserBrokerInterface instances
31
+ * @param bool $triggerDeprecationError
32
  */
33
  public function __construct($parsers = array(), $brokers = array(), $triggerDeprecationError = true)
34
  {
38
 
39
  foreach ($parsers as $parser) {
40
  if (!$parser instanceof Twig_TokenParserInterface) {
41
+ throw new LogicException('$parsers must a an array of Twig_TokenParserInterface.');
42
  }
43
  $this->parsers[$parser->getTag()] = $parser;
44
  }
45
  foreach ($brokers as $broker) {
46
  if (!$broker instanceof Twig_TokenParserBrokerInterface) {
47
+ throw new LogicException('$brokers must a an array of Twig_TokenParserBrokerInterface.');
48
  }
49
  $this->brokers[] = $broker;
50
  }
vendor/twig/twig/lib/Twig/TokenStream.php CHANGED
@@ -56,7 +56,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];
@@ -84,7 +84,7 @@ class Twig_TokenStream
84
  $token = $this->tokens[$this->current];
85
  if (!$token->test($type, $value)) {
86
  $line = $token->getLine();
87
- throw new Twig_Error_Syntax(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s)',
88
  $message ? $message.'. ' : '',
89
  Twig_Token::typeToEnglish($token->getType()), $token->getValue(),
90
  Twig_Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
@@ -107,7 +107,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];
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];
84
  $token = $this->tokens[$this->current];
85
  if (!$token->test($type, $value)) {
86
  $line = $token->getLine();
87
+ throw new Twig_Error_Syntax(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s).',
88
  $message ? $message.'. ' : '',
89
  Twig_Token::typeToEnglish($token->getType()), $token->getValue(),
90
  Twig_Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
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];
vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php CHANGED
@@ -9,8 +9,12 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
13
  {
 
 
14
  /**
15
  * @expectedException LogicException
16
  * @expectedExceptionMessage You must set a loader first.
@@ -54,11 +58,11 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
54
  $globals = $twig->getGlobals();
55
  $this->assertEquals('bar', $globals['foo']);
56
 
57
- // globals can be modified after runtime init
58
  $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
59
  $twig->addGlobal('foo', 'foo');
60
  $twig->getGlobals();
61
- $twig->initRuntime();
62
  $twig->addGlobal('foo', 'bar');
63
  $globals = $twig->getGlobals();
64
  $this->assertEquals('bar', $globals['foo']);
@@ -72,12 +76,12 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
72
  $globals = $twig->getGlobals();
73
  $this->assertEquals('bar', $globals['foo']);
74
 
75
- // globals can be modified after extensions and runtime init
76
  $twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{foo}}')));
77
  $twig->addGlobal('foo', 'foo');
78
  $twig->getGlobals();
79
  $twig->getFunctions();
80
- $twig->initRuntime();
81
  $twig->addGlobal('foo', 'bar');
82
  $globals = $twig->getGlobals();
83
  $this->assertEquals('bar', $globals['foo']);
@@ -89,11 +93,11 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
89
  $this->assertEquals('bar', $template->render(array()));
90
 
91
  /* to be uncomment in Twig 2.0
92
- // globals cannot be added after runtime init
93
  $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
94
  $twig->addGlobal('foo', 'foo');
95
  $twig->getGlobals();
96
- $twig->initRuntime();
97
  try {
98
  $twig->addGlobal('bar', 'bar');
99
  $this->fail();
@@ -113,12 +117,12 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
113
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
114
  }
115
 
116
- // globals cannot be added after extensions and runtime init
117
  $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
118
  $twig->addGlobal('foo', 'foo');
119
  $twig->getGlobals();
120
  $twig->getFunctions();
121
- $twig->initRuntime();
122
  try {
123
  $twig->addGlobal('bar', 'bar');
124
  $this->fail();
@@ -126,9 +130,9 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
126
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
127
  }
128
 
129
- // test adding globals after initRuntime without call to getGlobals
130
  $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
131
- $twig->initRuntime();
132
  try {
133
  $twig->addGlobal('bar', 'bar');
134
  $this->fail();
@@ -138,17 +142,28 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
138
  */
139
  }
140
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  public function testExtensionsAreNotInitializedWhenRenderingACompiledTemplate()
142
  {
143
- $options = array('cache' => sys_get_temp_dir().'/twig', 'auto_reload' => false, 'debug' => false);
 
144
 
145
  // force compilation
146
  $twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{ foo }}')), $options);
147
- $cache = $twig->getCacheFilename('index');
148
- if (!is_dir(dirname($cache))) {
149
- mkdir(dirname($cache), 0777, true);
150
- }
151
- file_put_contents($cache, $twig->compileSource('{{ foo }}', 'index'));
152
 
153
  // check that extensions won't be initialized when rendering a template that is already in the cache
154
  $twig = $this
@@ -164,7 +179,86 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
164
  $output = $twig->render('index', array('foo' => 'bar'));
165
  $this->assertEquals('bar', $output);
166
 
167
- unlink($cache);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  }
169
 
170
  public function testAddExtension()
@@ -183,6 +277,25 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
183
  $this->assertEquals('Twig_Tests_EnvironmentTest_NodeVisitor', get_class($visitors[2]));
184
  }
185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  /**
187
  * @group legacy
188
  */
@@ -201,9 +314,109 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
201
  $this->assertFalse(array_key_exists('foo_global', $twig->getGlobals()));
202
  $this->assertCount(2, $twig->getNodeVisitors());
203
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  }
205
 
206
- class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  {
208
  public function getTokenParsers()
209
  {
@@ -290,3 +503,27 @@ class Twig_Tests_EnvironmentTest_NodeVisitor implements Twig_NodeVisitorInterfac
290
  return 0;
291
  }
292
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ require_once dirname(__FILE__).'/FilesystemHelper.php';
13
+
14
  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.
58
  $globals = $twig->getGlobals();
59
  $this->assertEquals('bar', $globals['foo']);
60
 
61
+ // globals can be modified after a template has been loaded
62
  $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
63
  $twig->addGlobal('foo', 'foo');
64
  $twig->getGlobals();
65
+ $twig->loadTemplate('index');
66
  $twig->addGlobal('foo', 'bar');
67
  $globals = $twig->getGlobals();
68
  $this->assertEquals('bar', $globals['foo']);
76
  $globals = $twig->getGlobals();
77
  $this->assertEquals('bar', $globals['foo']);
78
 
79
+ // globals can be modified after extensions and a template has been loaded
80
  $twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{foo}}')));
81
  $twig->addGlobal('foo', 'foo');
82
  $twig->getGlobals();
83
  $twig->getFunctions();
84
+ $twig->loadTemplate('index');
85
  $twig->addGlobal('foo', 'bar');
86
  $globals = $twig->getGlobals();
87
  $this->assertEquals('bar', $globals['foo']);
93
  $this->assertEquals('bar', $template->render(array()));
94
 
95
  /* to be uncomment in Twig 2.0
96
+ // globals cannot be added after a template has been loaded
97
  $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
98
  $twig->addGlobal('foo', 'foo');
99
  $twig->getGlobals();
100
+ $twig->loadTemplate('index');
101
  try {
102
  $twig->addGlobal('bar', 'bar');
103
  $this->fail();
117
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
118
  }
119
 
120
+ // globals cannot be added after extensions and a template has been loaded
121
  $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
122
  $twig->addGlobal('foo', 'foo');
123
  $twig->getGlobals();
124
  $twig->getFunctions();
125
+ $twig->loadTemplate('index');
126
  try {
127
  $twig->addGlobal('bar', 'bar');
128
  $this->fail();
130
  $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
131
  }
132
 
133
+ // test adding globals after a template has been loaded without call to getGlobals
134
  $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
135
+ $twig->loadTemplate('index');
136
  try {
137
  $twig->addGlobal('bar', 'bar');
138
  $this->fail();
142
  */
143
  }
144
 
145
+ public function testCompileSourceInlinesSource()
146
+ {
147
+ $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
148
+
149
+ $source = "<? */*foo*/ ?>\r\nbar\n";
150
+ $expected = "/* <? *//* *foo*//* ?>*/\n/* bar*/\n/* */\n";
151
+ $compiled = $twig->compileSource($source, 'index');
152
+
153
+ $this->assertContains($expected, $compiled);
154
+ $this->assertNotContains('/**', $compiled);
155
+ }
156
+
157
  public function testExtensionsAreNotInitializedWhenRenderingACompiledTemplate()
158
  {
159
+ $cache = new Twig_Cache_Filesystem($dir = sys_get_temp_dir().'/twig');
160
+ $options = array('cache' => $cache, 'auto_reload' => false, 'debug' => false);
161
 
162
  // force compilation
163
  $twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{ foo }}')), $options);
164
+
165
+ $key = $cache->generateKey('index', $twig->getTemplateClass('index'));
166
+ $cache->write($key, $twig->compileSource('{{ foo }}', 'index'));
 
 
167
 
168
  // check that extensions won't be initialized when rendering a template that is already in the cache
169
  $twig = $this
179
  $output = $twig->render('index', array('foo' => 'bar'));
180
  $this->assertEquals('bar', $output);
181
 
182
+ Twig_Tests_FilesystemHelper::removeDir($dir);
183
+ }
184
+
185
+ public function testAutoReloadCacheMiss()
186
+ {
187
+ $templateName = __FUNCTION__;
188
+ $templateContent = __FUNCTION__;
189
+
190
+ $cache = $this->getMock('Twig_CacheInterface');
191
+ $loader = $this->getMockLoader($templateName, $templateContent);
192
+ $twig = new Twig_Environment($loader, array('cache' => $cache, 'auto_reload' => true, 'debug' => false));
193
+
194
+ // Cache miss: getTimestamp returns 0 and as a result the load() is
195
+ // skipped.
196
+ $cache->expects($this->once())
197
+ ->method('generateKey')
198
+ ->will($this->returnValue('key'));
199
+ $cache->expects($this->once())
200
+ ->method('getTimestamp')
201
+ ->will($this->returnValue(0));
202
+ $loader->expects($this->never())
203
+ ->method('isFresh');
204
+ $cache->expects($this->never())
205
+ ->method('load');
206
+
207
+ $twig->loadTemplate($templateName);
208
+ }
209
+
210
+ public function testAutoReloadCacheHit()
211
+ {
212
+ $templateName = __FUNCTION__;
213
+ $templateContent = __FUNCTION__;
214
+
215
+ $cache = $this->getMock('Twig_CacheInterface');
216
+ $loader = $this->getMockLoader($templateName, $templateContent);
217
+ $twig = new Twig_Environment($loader, array('cache' => $cache, 'auto_reload' => true, 'debug' => false));
218
+
219
+ $now = time();
220
+
221
+ // Cache hit: getTimestamp returns something > extension timestamps and
222
+ // the loader returns true for isFresh().
223
+ $cache->expects($this->once())
224
+ ->method('generateKey')
225
+ ->will($this->returnValue('key'));
226
+ $cache->expects($this->once())
227
+ ->method('getTimestamp')
228
+ ->will($this->returnValue($now));
229
+ $loader->expects($this->once())
230
+ ->method('isFresh')
231
+ ->will($this->returnValue(true));
232
+ $cache->expects($this->once())
233
+ ->method('load');
234
+
235
+ $twig->loadTemplate($templateName);
236
+ }
237
+
238
+ public function testAutoReloadOutdatedCacheHit()
239
+ {
240
+ $templateName = __FUNCTION__;
241
+ $templateContent = __FUNCTION__;
242
+
243
+ $cache = $this->getMock('Twig_CacheInterface');
244
+ $loader = $this->getMockLoader($templateName, $templateContent);
245
+ $twig = new Twig_Environment($loader, array('cache' => $cache, 'auto_reload' => true, 'debug' => false));
246
+
247
+ $now = time();
248
+
249
+ $cache->expects($this->once())
250
+ ->method('generateKey')
251
+ ->will($this->returnValue('key'));
252
+ $cache->expects($this->once())
253
+ ->method('getTimestamp')
254
+ ->will($this->returnValue($now));
255
+ $loader->expects($this->once())
256
+ ->method('isFresh')
257
+ ->will($this->returnValue(false));
258
+ $cache->expects($this->never())
259
+ ->method('load');
260
+
261
+ $twig->loadTemplate($templateName);
262
  }
263
 
264
  public function testAddExtension()
277
  $this->assertEquals('Twig_Tests_EnvironmentTest_NodeVisitor', get_class($visitors[2]));
278
  }
279
 
280
+ /**
281
+ * @requires PHP 5.3
282
+ */
283
+ public function testAddExtensionWithDeprecatedGetGlobals()
284
+ {
285
+ $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
286
+ $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithGlobals());
287
+
288
+ $this->deprecations = array();
289
+ set_error_handler(array($this, 'handleError'));
290
+
291
+ $this->assertArrayHasKey('foo_global', $twig->getGlobals());
292
+
293
+ $this->assertCount(1, $this->deprecations);
294
+ $this->assertContains('Defining the getGlobals() method in the "environment_test" extension ', $this->deprecations[0]);
295
+
296
+ restore_error_handler();
297
+ }
298
+
299
  /**
300
  * @group legacy
301
  */
314
  $this->assertFalse(array_key_exists('foo_global', $twig->getGlobals()));
315
  $this->assertCount(2, $twig->getNodeVisitors());
316
  }
317
+
318
+ public function testAddMockExtension()
319
+ {
320
+ $extension = $this->getMock('Twig_ExtensionInterface');
321
+ $extension->expects($this->once())
322
+ ->method('getName')
323
+ ->will($this->returnValue('mock'));
324
+
325
+ $loader = new Twig_Loader_Array(array('page' => 'hey'));
326
+
327
+ $twig = new Twig_Environment($loader);
328
+ $twig->addExtension($extension);
329
+
330
+ $this->assertInstanceOf('Twig_ExtensionInterface', $twig->getExtension('mock'));
331
+ $this->assertTrue($twig->isTemplateFresh('page', time()));
332
+ }
333
+
334
+ public function testInitRuntimeWithAnExtensionUsingInitRuntimeNoDeprecation()
335
+ {
336
+ $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
337
+ $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithoutDeprecationInitRuntime());
338
+
339
+ $twig->initRuntime();
340
+ }
341
+
342
+ /**
343
+ * @requires PHP 5.3
344
+ */
345
+ public function testInitRuntimeWithAnExtensionUsingInitRuntimeDeprecation()
346
+ {
347
+ $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
348
+ $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime());
349
+
350
+ $this->deprecations = array();
351
+ set_error_handler(array($this, 'handleError'));
352
+
353
+ $twig->initRuntime();
354
+
355
+ $this->assertCount(1, $this->deprecations);
356
+ $this->assertContains('Defining the initRuntime() method in the "with_deprecation" extension is deprecated since version 1.23.', $this->deprecations[0]);
357
+
358
+ restore_error_handler();
359
+ }
360
+
361
+ public function handleError($type, $msg)
362
+ {
363
+ if (E_USER_DEPRECATED === $type) {
364
+ $this->deprecations[] = $msg;
365
+ }
366
+ }
367
+
368
+ /**
369
+ * @requires PHP 5.3
370
+ */
371
+ public function testOverrideExtension()
372
+ {
373
+ $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
374
+ $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime());
375
+
376
+ $this->deprecations = array();
377
+ set_error_handler(array($this, 'handleError'));
378
+
379
+ $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension());
380
+ $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension());
381
+
382
+ $this->assertCount(1, $this->deprecations);
383
+ $this->assertContains('The possibility to register the same extension twice', $this->deprecations[0]);
384
+
385
+ restore_error_handler();
386
+ }
387
+
388
+ protected function getMockLoader($templateName, $templateContent)
389
+ {
390
+ $loader = $this->getMock('Twig_LoaderInterface');
391
+ $loader->expects($this->any())
392
+ ->method('getSource')
393
+ ->with($templateName)
394
+ ->will($this->returnValue($templateContent));
395
+ $loader->expects($this->any())
396
+ ->method('getCacheKey')
397
+ ->with($templateName)
398
+ ->will($this->returnValue($templateName));
399
+
400
+ return $loader;
401
+ }
402
  }
403
 
404
+ class Twig_Tests_EnvironmentTest_Extension_WithGlobals extends Twig_Extension
405
+ {
406
+ public function getGlobals()
407
+ {
408
+ return array(
409
+ 'foo_global' => 'foo_global',
410
+ );
411
+ }
412
+
413
+ public function getName()
414
+ {
415
+ return 'environment_test';
416
+ }
417
+ }
418
+
419
+ class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension implements Twig_Extension_GlobalsInterface
420
  {
421
  public function getTokenParsers()
422
  {
503
  return 0;
504
  }
505
  }
506
+
507
+ class Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime extends Twig_Extension
508
+ {
509
+ public function initRuntime(Twig_Environment $env)
510
+ {
511
+ }
512
+
513
+ public function getName()
514
+ {
515
+ return 'with_deprecation';
516
+ }
517
+ }
518
+
519
+ class Twig_Tests_EnvironmentTest_ExtensionWithoutDeprecationInitRuntime extends Twig_Extension implements Twig_Extension_InitRuntimeInterface
520
+ {
521
+ public function initRuntime(Twig_Environment $env)
522
+ {
523
+ }
524
+
525
+ public function getName()
526
+ {
527
+ return 'without_deprecation';
528
+ }
529
+ }
vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php CHANGED
@@ -27,8 +27,13 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
27
  {
28
  return array(
29
  array('{% set false = "foo" %}'),
 
30
  array('{% set true = "foo" %}'),
 
31
  array('{% set none = "foo" %}'),
 
 
 
32
  array('{% set 3 = "foo" %}'),
33
  array('{% set 1 + 2 = "foo" %}'),
34
  array('{% set "bar" = "foo" %}'),
@@ -239,7 +244,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
239
 
240
  /**
241
  * @expectedException Twig_Error_Syntax
242
- * @expectedExceptionMessage An argument must be a name. Unexpected token "string" of value "a" ("name" expected) in "index" at line 1
243
  */
244
  public function testMacroDefinitionDoesNotSupportNonNameVariableName()
245
  {
@@ -296,7 +301,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
296
 
297
  /**
298
  * @expectedException Twig_Error_Syntax
299
- * @expectedExceptionMessage The function "cycl" does not exist. Did you mean "cycle" in "index" at line 1
300
  */
301
  public function testUnknownFunction()
302
  {
@@ -308,7 +313,19 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
308
 
309
  /**
310
  * @expectedException Twig_Error_Syntax
311
- * @expectedExceptionMessage The filter "lowe" does not exist. Did you mean "lower" in "index" at line 1
 
 
 
 
 
 
 
 
 
 
 
 
312
  */
313
  public function testUnknownFilter()
314
  {
@@ -320,7 +337,19 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
320
 
321
  /**
322
  * @expectedException Twig_Error_Syntax
323
- * @expectedExceptionMessage The test "nul" does not exist. Did you mean "null" in "index" at line 1
 
 
 
 
 
 
 
 
 
 
 
 
324
  */
325
  public function testUnknownTest()
326
  {
@@ -329,4 +358,16 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
329
 
330
  $parser->parse($env->tokenize('{{ 1 is nul }}', 'index'));
331
  }
 
 
 
 
 
 
 
 
 
 
 
 
332
  }
27
  {
28
  return array(
29
  array('{% set false = "foo" %}'),
30
+ array('{% set FALSE = "foo" %}'),
31
  array('{% set true = "foo" %}'),
32
+ array('{% set TRUE = "foo" %}'),
33
  array('{% set none = "foo" %}'),
34
+ array('{% set NONE = "foo" %}'),
35
+ array('{% set null = "foo" %}'),
36
+ array('{% set NULL = "foo" %}'),
37
  array('{% set 3 = "foo" %}'),
38
  array('{% set 1 + 2 = "foo" %}'),
39
  array('{% set "bar" = "foo" %}'),
244
 
245
  /**
246
  * @expectedException Twig_Error_Syntax
247
+ * @expectedExceptionMessage An argument must be a name. Unexpected token "string" of value "a" ("name" expected) in "index" at line 1.
248
  */
249
  public function testMacroDefinitionDoesNotSupportNonNameVariableName()
250
  {
301
 
302
  /**
303
  * @expectedException Twig_Error_Syntax
304
+ * @expectedExceptionMessage Unknown "cycl" function. Did you mean "cycle" in "index" at line 1?
305
  */
306
  public function testUnknownFunction()
307
  {
313
 
314
  /**
315
  * @expectedException Twig_Error_Syntax
316
+ * @expectedExceptionMessage Unknown "foobar" function in "index" at line 1.
317
+ */
318
+ public function testUnknownFunctionWithoutSuggestions()
319
+ {
320
+ $env = new Twig_Environment($this->getMock('Twig_LoaderInterface'), array('cache' => false, 'autoescape' => false));
321
+ $parser = new Twig_Parser($env);
322
+
323
+ $parser->parse($env->tokenize('{{ foobar() }}', 'index'));
324
+ }
325
+
326
+ /**
327
+ * @expectedException Twig_Error_Syntax
328
+ * @expectedExceptionMessage Unknown "lowe" filter. Did you mean "lower" in "index" at line 1?
329
  */
330
  public function testUnknownFilter()
331
  {
337
 
338
  /**
339
  * @expectedException Twig_Error_Syntax
340
+ * @expectedExceptionMessage Unknown "foobar" filter in "index" at line 1.
341
+ */
342
+ public function testUnknownFilterWithoutSuggestions()
343
+ {
344
+ $env = new Twig_Environment($this->getMock('Twig_LoaderInterface'), array('cache' => false, 'autoescape' => false));
345
+ $parser = new Twig_Parser($env);
346
+
347
+ $parser->parse($env->tokenize('{{ 1|foobar }}', 'index'));
348
+ }
349
+
350
+ /**
351
+ * @expectedException Twig_Error_Syntax
352
+ * @expectedExceptionMessage Unknown "nul" test. Did you mean "null" in "index" at line 1
353
  */
354
  public function testUnknownTest()
355
  {
358
 
359
  $parser->parse($env->tokenize('{{ 1 is nul }}', 'index'));
360
  }
361
+
362
+ /**
363
+ * @expectedException Twig_Error_Syntax
364
+ * @expectedExceptionMessage Unknown "foobar" test in "index" at line 1.
365
+ */
366
+ public function testUnknownTestWithoutSuggestions()
367
+ {
368
+ $env = new Twig_Environment($this->getMock('Twig_LoaderInterface'), array('cache' => false, 'autoescape' => false));
369
+ $parser = new Twig_Parser($env);
370
+
371
+ $parser->parse($env->tokenize('{{ 1 is foobar }}', 'index'));
372
+ }
373
  }
vendor/twig/twig/test/Twig/Tests/Extension/CoreTest.php CHANGED
@@ -121,6 +121,8 @@ class Twig_Tests_Extension_CoreTest extends PHPUnit_Framework_TestCase
121
  $twig->getExtension('core')->setEscaper('foo', 'foo_escaper_for_test');
122
 
123
  $this->assertEquals('fooUTF-8', twig_escape_filter($twig, 'foo', 'foo'));
 
 
124
  }
125
 
126
  /**
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'));
125
+ $this->assertEquals('42UTF-8', twig_escape_filter($twig, 42, 'foo'));
126
  }
127
 
128
  /**
vendor/twig/twig/test/Twig/Tests/Extension/SandboxTest.php CHANGED
@@ -13,7 +13,7 @@ class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase
13
  {
14
  protected static $params, $templates;
15
 
16
- public function setUp()
17
  {
18
  self::$params = array(
19
  'name' => 'Fabien',
13
  {
14
  protected static $params, $templates;
15
 
16
+ protected function setUp()
17
  {
18
  self::$params = array(
19
  'name' => 'Fabien',
vendor/twig/twig/test/Twig/Tests/FileCachingTest.php CHANGED
@@ -9,13 +9,14 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  class Twig_Tests_FileCachingTest extends PHPUnit_Framework_TestCase
13
  {
14
- protected $fileName;
15
- protected $env;
16
- protected $tmpDir;
17
 
18
- public function setUp()
19
  {
20
  $this->tmpDir = sys_get_temp_dir().'/TwigTests';
21
  if (!file_exists($this->tmpDir)) {
@@ -29,15 +30,14 @@ class Twig_Tests_FileCachingTest extends PHPUnit_Framework_TestCase
29
  $this->env = new Twig_Environment(new Twig_Loader_Array(array('index' => 'index', 'index2' => 'index2')), array('cache' => $this->tmpDir));
30
  }
31
 
32
- public function tearDown()
33
  {
34
- if ($this->fileName) {
35
- unlink($this->fileName);
36
- }
37
-
38
- $this->removeDir($this->tmpDir);
39
  }
40
 
 
 
 
41
  public function testWritingCacheFiles()
42
  {
43
  $name = 'index';
@@ -45,9 +45,11 @@ class Twig_Tests_FileCachingTest extends PHPUnit_Framework_TestCase
45
  $cacheFileName = $this->env->getCacheFilename($name);
46
 
47
  $this->assertTrue(file_exists($cacheFileName), 'Cache file does not exist.');
48
- $this->fileName = $cacheFileName;
49
  }
50
 
 
 
 
51
  public function testClearingCacheFiles()
52
  {
53
  $name = 'index2';
@@ -58,22 +60,4 @@ class Twig_Tests_FileCachingTest extends PHPUnit_Framework_TestCase
58
  $this->env->clearCacheFiles();
59
  $this->assertFalse(file_exists($cacheFileName), 'Cache file was not cleared.');
60
  }
61
-
62
- private function removeDir($target)
63
- {
64
- $fp = opendir($target);
65
- while (false !== $file = readdir($fp)) {
66
- if (in_array($file, array('.', '..'))) {
67
- continue;
68
- }
69
-
70
- if (is_dir($target.'/'.$file)) {
71
- self::removeDir($target.'/'.$file);
72
- } else {
73
- unlink($target.'/'.$file);
74
- }
75
- }
76
- closedir($fp);
77
- rmdir($target);
78
- }
79
  }
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ require_once dirname(__FILE__).'/FilesystemHelper.php';
13
+
14
  class Twig_Tests_FileCachingTest extends PHPUnit_Framework_TestCase
15
  {
16
+ private $env;
17
+ private $tmpDir;
 
18
 
19
+ protected function setUp()
20
  {
21
  $this->tmpDir = sys_get_temp_dir().'/TwigTests';
22
  if (!file_exists($this->tmpDir)) {
30
  $this->env = new Twig_Environment(new Twig_Loader_Array(array('index' => 'index', 'index2' => 'index2')), array('cache' => $this->tmpDir));
31
  }
32
 
33
+ protected function tearDown()
34
  {
35
+ Twig_Tests_FilesystemHelper::removeDir($this->tmpDir);
 
 
 
 
36
  }
37
 
38
+ /**
39
+ * @group legacy
40
+ */
41
  public function testWritingCacheFiles()
42
  {
43
  $name = 'index';
45
  $cacheFileName = $this->env->getCacheFilename($name);
46
 
47
  $this->assertTrue(file_exists($cacheFileName), 'Cache file does not exist.');
 
48
  }
49
 
50
+ /**
51
+ * @group legacy
52
+ */
53
  public function testClearingCacheFiles()
54
  {
55
  $name = 'index2';
60
  $this->env->clearCacheFiles();
61
  $this->assertFalse(file_exists($cacheFileName), 'Cache file was not cleared.');
62
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
vendor/twig/twig/test/Twig/Tests/FileExtensionEscapingStrategyTest.php CHANGED
@@ -16,7 +16,7 @@ class Twig_Tests_FileExtensionEscapingStrategyTest extends PHPUnit_Framework_Tes
16
  */
17
  public function testGuess($strategy, $filename)
18
  {
19
- $this->assertEquals($strategy, Twig_FileExtensionEscapingStrategy::guess($filename));
20
  }
21
 
22
  public function getGuessData()
@@ -34,6 +34,8 @@ class Twig_Tests_FileExtensionEscapingStrategyTest extends PHPUnit_Framework_Tes
34
  array('css', 'foo.css'),
35
  array('css', 'foo.css.twig'),
36
  array('css', 'foo.twig.css'),
 
 
37
 
38
  // js
39
  array('js', 'foo.js'),
16
  */
17
  public function testGuess($strategy, $filename)
18
  {
19
+ $this->assertSame($strategy, Twig_FileExtensionEscapingStrategy::guess($filename));
20
  }
21
 
22
  public function getGuessData()
34
  array('css', 'foo.css'),
35
  array('css', 'foo.css.twig'),
36
  array('css', 'foo.twig.css'),
37
+ array('css', 'foo.js.css'),
38
+ array('css', 'foo.js.css.twig'),
39
 
40
  // js
41
  array('js', 'foo.js'),
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/syntax_error_in_reused_template.test ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ Exception for syntax error in reused template
3
+ --TEMPLATE--
4
+ {% use 'foo.twig' %}
5
+ --TEMPLATE(foo.twig)--
6
+ {% block bar %}
7
+ {% do node.data = 5 %}
8
+ {% endblock %}
9
+ --EXCEPTION--
10
+ Twig_Error_Syntax: Unexpected token "operator" of value "=" ("end of statement block" expected) in "foo.twig" at line 3.
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/unclosed_tag.test CHANGED
@@ -17,4 +17,4 @@ Exception for an unclosed tag
17
 
18
  {% endblock %}
19
  --EXCEPTION--
20
- Twig_Error_Syntax: Unexpected tag name "endblock" (expecting closing tag for the "if" tag defined near line 4) in "index.twig" at line 16
17
 
18
  {% endblock %}
19
  --EXCEPTION--
20
+ Twig_Error_Syntax: Unexpected "endblock" tag (expecting closing tag for the "if" tag defined near line 4) in "index.twig" at line 16.
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_template_in_child_template.test ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ Exception for an undefined template in a child template
3
+ --TEMPLATE--
4
+ {% extends 'base.twig' %}
5
+
6
+ {% block sidebar %}
7
+ {{ include('include.twig') }}
8
+ {% endblock %}
9
+ --TEMPLATE(base.twig)--
10
+ {% block sidebar %}
11
+ {% endblock %}
12
+ --DATA--
13
+ return array()
14
+ --EXCEPTION--
15
+ Twig_Error_Loader: Template "include.twig" is not defined in "index.twig" at line 5.
vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/two_word_operators_as_variables.test CHANGED
@@ -5,4 +5,4 @@ Twig does not allow to use two-word named operators as variable names
5
  --DATA--
6
  return array()
7
  --EXCEPTION--
8
- Twig_Error_Syntax: Unexpected token "operator" of value "starts with" in "index.twig" at line 2
5
  --DATA--
6
  return array()
7
  --EXCEPTION--
8
+ Twig_Error_Syntax: Unexpected token "operator" of value "starts with" in "index.twig" at line 2.
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_keys.test ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ "batch" filter preserves array keys
3
+ --TEMPLATE--
4
+ {{ {'foo': 'bar', 'key': 'value'}|batch(4)|first|keys|join(',') }}
5
+ {{ {'foo': 'bar', 'key': 'value'}|batch(4, 'fill')|first|keys|join(',') }}
6
+ --DATA--
7
+ return array()
8
+ --EXPECT--
9
+ foo,key
10
+ foo,key,0,1
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_zero_elements.test ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ "batch" filter with zero elements
3
+ --TEMPLATE--
4
+ {{ []|batch(3)|length }}
5
+ {{ []|batch(3, 'fill')|length }}
6
+ --DATA--
7
+ return array()
8
+ --EXPECT--
9
+ 0
10
+ 0
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/merge.test CHANGED
@@ -6,11 +6,13 @@
6
  {{ {'bar': 'foo'}|merge(items)|join }}
7
  {{ {'bar': 'foo'}|merge(items)|keys|join }}
8
  {{ numerics|merge([4, 5, 6])|join }}
 
9
  --DATA--
10
- return array('items' => array('foo' => 'bar'), 'numerics' => array(1, 2, 3))
11
  --EXPECT--
12
  barfoo
13
  foobar
14
  foobar
15
  barfoo
16
  123456
 
6
  {{ {'bar': 'foo'}|merge(items)|join }}
7
  {{ {'bar': 'foo'}|merge(items)|keys|join }}
8
  {{ numerics|merge([4, 5, 6])|join }}
9
+ {{ traversable.a|merge(traversable.b)|join }}
10
  --DATA--
11
+ return array('items' => array('foo' => 'bar'), 'numerics' => array(1, 2, 3), 'traversable' => array('a' => new ArrayObject(array(0 => 1, 1 => 2, 2 => 3)), 'b' => new ArrayObject(array('a' => 'b'))))
12
  --EXPECT--
13
  barfoo
14
  foobar
15
  foobar
16
  barfoo
17
  123456
18
+ 123b
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/replace.test CHANGED
@@ -1,8 +1,12 @@
1
  --TEST--
2
  "replace" filter
3
  --TEMPLATE--
4
- {{ "I like %this% and %that%."|replace({'%this%': "foo", '%that%': "bar"}) }}
 
 
5
  --DATA--
6
- return array()
7
  --EXPECT--
 
 
8
  I like foo and bar.
1
  --TEST--
2
  "replace" filter
3
  --TEMPLATE--
4
+ {{ "I liké %this% and %that%."|replace({'%this%': "foo", '%that%': "bar"}) }}
5
+ {{ 'I like single replace operation only %that%'|replace({'%that%' : '%that%1'}) }}
6
+ {{ 'I like %this% and %that%.'|replace(traversable) }}
7
  --DATA--
8
+ return array('traversable' => new ArrayObject(array('%this%' => 'foo', '%that%' => 'bar')))
9
  --EXPECT--
10
+ I liké foo and bar.
11
+ I like single replace operation only %that%1
12
  I like foo and bar.
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/sort.test CHANGED
@@ -3,8 +3,10 @@
3
  --TEMPLATE--
4
  {{ array1|sort|join }}
5
  {{ array2|sort|join }}
 
6
  --DATA--
7
- return array('array1' => array(4, 1), 'array2' => array('foo', 'bar'))
8
  --EXPECT--
9
  14
10
  barfoo
 
3
  --TEMPLATE--
4
  {{ array1|sort|join }}
5
  {{ array2|sort|join }}
6
+ {{ traversable|sort|join }}
7
  --DATA--
8
+ return array('array1' => array(4, 1), 'array2' => array('foo', 'bar'), 'traversable' => new ArrayObject(array(0 => 3, 1 => 2, 2 => 1)))
9
  --EXPECT--
10
  14
11
  barfoo
12
+ 123
vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling.test ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ "include" tag sandboxed
3
+ --TEMPLATE--
4
+ {{ include("foo.twig", sandboxed = true) }}
5
+ {{ include("bar.twig") }}
6
+ --TEMPLATE(foo.twig)--
7
+ foo
8
+ --TEMPLATE(bar.twig)--
9
+ {{ foo|e }}
10
+ --DATA--
11
+ return array('foo' => 'bar<br />')
12
+ --EXPECT--
13
+ foo
14
+
15
+
16
+ bar&lt;br /&gt;
vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling_ignore_missing.test ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ "include" tag sandboxed
3
+ --TEMPLATE--
4
+ {{ include("unknown.twig", sandboxed = true, ignore_missing = true) }}
5
+ {{ include("bar.twig") }}
6
+ --TEMPLATE(bar.twig)--
7
+ {{ foo|e }}
8
+ --DATA--
9
+ return array('foo' => 'bar<br />')
10
+ --EXPECT--
11
+
12
+
13
+ bar&lt;br /&gt;
vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs.test ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ macro with arbitrary arguments
3
+ --TEMPLATE--
4
+ {% from _self import test1, test2 %}
5
+
6
+ {% macro test1(var) %}
7
+ {{- var }}: {{ varargs|join(", ") }}
8
+ {% endmacro %}
9
+
10
+ {% macro test2() %}
11
+ {{- varargs|join(", ") }}
12
+ {% endmacro %}
13
+
14
+ {{ test1("foo", "bar", "foobar") }}
15
+ {{ test2("foo", "bar", "foobar") }}
16
+ --DATA--
17
+ return array();
18
+ --EXPECT--
19
+ foo: bar, foobar
20
+
21
+ foo, bar, foobar
vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs_argument.test ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ macro with varargs argument
3
+ --TEMPLATE--
4
+ {% macro test(varargs) %}
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
+
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.legacy.test ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ --TEST--
2
+ "autoescape" tag accepts an escaping strategy
3
+ --TEMPLATE--
4
+ {% autoescape true js %}{{ var }}{% endautoescape %}
5
+
6
+ {% autoescape true html %}{{ var }}{% endautoescape %}
7
+ --DATA--
8
+ return array('var' => '<br />"')
9
+ --EXPECT--
10
+ \x3Cbr\x20\x2F\x3E\x22
11
+ &lt;br /&gt;&quot;
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/block_unique_name.test CHANGED
@@ -8,4 +8,4 @@
8
  --DATA--
9
  return array()
10
  --EXCEPTION--
11
- Twig_Error_Syntax: The block 'content' has already been defined line 2 in "index.twig" at line 3
8
  --DATA--
9
  return array()
10
  --EXCEPTION--
11
+ Twig_Error_Syntax: The block 'content' has already been defined line 2 in "index.twig" at line 3.
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/with_extends.test CHANGED
@@ -17,6 +17,7 @@
17
  block1extended
18
  {% endblock %}
19
  {% endembed %}
 
20
  {% endblock %}
21
  --TEMPLATE(base.twig)--
22
  A
@@ -54,4 +55,6 @@ A
54
  block1extended
55
  B
56
  block2
57
- CB
 
 
17
  block1extended
18
  {% endblock %}
19
  {% endembed %}
20
+ {{ parent() }}
21
  {% endblock %}
22
  --TEMPLATE(base.twig)--
23
  A
55
  block1extended
56
  B
57
  block2
58
+ C blockc2base
59
+
60
+ B
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined.test CHANGED
@@ -7,4 +7,4 @@
7
  --DATA--
8
  return array('items' => array('a', 'b'))
9
  --EXCEPTION--
10
- Twig_Error_Syntax: The "loop.last" variable is not defined when looping with a condition in "index.twig" at line 3
7
  --DATA--
8
  return array('items' => array('a', 'b'))
9
  --EXCEPTION--
10
+ Twig_Error_Syntax: The "loop.last" variable is not defined when looping with a condition in "index.twig" at line 3.
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined_cond.test CHANGED
@@ -6,4 +6,4 @@
6
  --DATA--
7
  return array('items' => array('a', 'b'))
8
  --EXCEPTION--
9
- Twig_Error_Syntax: The "loop" variable cannot be used in a looping condition in "index.twig" at line 2
6
  --DATA--
7
  return array('items' => array('a', 'b'))
8
  --EXCEPTION--
9
+ Twig_Error_Syntax: The "loop" variable cannot be used in a looping condition in "index.twig" at line 2.
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_in_a_block.test CHANGED
@@ -5,4 +5,4 @@
5
  {% extends "foo.twig" %}
6
  {% endblock %}
7
  --EXCEPTION--
8
- Twig_Error_Syntax: Cannot extend from a block in "index.twig" at line 3
5
  {% extends "foo.twig" %}
6
  {% endblock %}
7
  --EXCEPTION--
8
+ Twig_Error_Syntax: Cannot extend from a block in "index.twig" at line 3.
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends.test CHANGED
@@ -5,4 +5,4 @@
5
  {{ parent() }}
6
  {% endblock %}
7
  --EXCEPTION--
8
- Twig_Error_Syntax: Calling "parent" on a template that does not extend nor "use" another template is forbidden in "index.twig" at line 3
5
  {{ parent() }}
6
  {% endblock %}
7
  --EXCEPTION--
8
+ Twig_Error_Syntax: Calling "parent" on a template that does not extend nor "use" another template is forbidden in "index.twig" at line 3.
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid1.test CHANGED
@@ -8,4 +8,4 @@ sandbox tag
8
  --TEMPLATE(foo.twig)--
9
  foo
10
  --EXCEPTION--
11
- Twig_Error_Syntax: Only "include" tags are allowed within a "sandbox" section in "index.twig" at line 4
8
  --TEMPLATE(foo.twig)--
9
  foo
10
  --EXCEPTION--
11
+ Twig_Error_Syntax: Only "include" tags are allowed within a "sandbox" section in "index.twig" at line 4.
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid2.test CHANGED
@@ -11,4 +11,4 @@ sandbox tag
11
  --TEMPLATE(foo.twig)--
12
  foo
13
  --EXCEPTION--
14
- Twig_Error_Syntax: Only "include" tags are allowed within a "sandbox" section in "index.twig" at line 5
11
  --TEMPLATE(foo.twig)--
12
  foo
13
  --EXCEPTION--
14
+ Twig_Error_Syntax: Only "include" tags are allowed within a "sandbox" section in "index.twig" at line 5.
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance.test CHANGED
@@ -8,7 +8,7 @@
8
  {% use "ancestor.twig" %}
9
 
10
  {% block sub_container %}
11
- <div class="overriden_sub_container">overriden sub_container</div>
12
  {% endblock %}
13
  --TEMPLATE(ancestor.twig)--
14
  {% block container %}
@@ -21,5 +21,5 @@
21
  --DATA--
22
  return array()
23
  --EXPECT--
24
- <div class="container"> <div class="overriden_sub_container">overriden sub_container</div>
25
  </div>
8
  {% use "ancestor.twig" %}
9
 
10
  {% block sub_container %}
11
+ <div class="overridden_sub_container">overridden sub_container</div>
12
  {% endblock %}
13
  --TEMPLATE(ancestor.twig)--
14
  {% block container %}
21
  --DATA--
22
  return array()
23
  --EXPECT--
24
+ <div class="container"> <div class="overridden_sub_container">overridden sub_container</div>
25
  </div>
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance2.test CHANGED
@@ -7,7 +7,7 @@
7
  {{ block('container') }}
8
  --TEMPLATE(parent.twig)--
9
  {% block sub_container %}
10
- <div class="overriden_sub_container">overriden sub_container</div>
11
  {% endblock %}
12
  --TEMPLATE(ancestor.twig)--
13
  {% block container %}
@@ -20,5 +20,5 @@
20
  --DATA--
21
  return array()
22
  --EXPECT--
23
- <div class="container"> <div class="overriden_sub_container">overriden sub_container</div>
24
  </div>
7
  {{ block('container') }}
8
  --TEMPLATE(parent.twig)--
9
  {% block sub_container %}
10
+ <div class="overridden_sub_container">overridden sub_container</div>
11
  {% endblock %}
12
  --TEMPLATE(ancestor.twig)--
13
  {% block container %}
20
  --DATA--
21
  return array()
22
  --EXPECT--
23
+ <div class="container"> <div class="overridden_sub_container">overridden sub_container</div>
24
  </div>
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/mixed_usage_with_raw.test CHANGED
@@ -7,4 +7,4 @@
7
  --DATA--
8
  return array()
9
  --EXCEPTION--
10
- Twig_Error_Syntax: Unexpected end of file: Unclosed "verbatim" block in "index.twig" at line 2
7
  --DATA--
8
  return array()
9
  --EXCEPTION--
10
+ Twig_Error_Syntax: Unexpected end of file: Unclosed "verbatim" block in "index.twig" at line 2.
vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined.test CHANGED
@@ -26,6 +26,13 @@
26
  {{ object.self.foo is defined ? 'ok' : 'ko' }}
27
  {{ object.self.undefinedMethod is defined ? 'ko' : 'ok' }}
28
  {{ object.undefinedMethod.self is defined ? 'ko' : 'ok' }}
 
 
 
 
 
 
 
29
  --DATA--
30
  return array(
31
  'definedVar' => 'defined',
@@ -65,6 +72,13 @@ ok
65
  ok
66
  ok
67
  ok
 
 
 
 
 
 
 
68
  --DATA--
69
  return array(
70
  'definedVar' => 'defined',
@@ -106,3 +120,10 @@ ok
106
  ok
107
  ok
108
  ok
 
 
 
 
 
 
 
26
  {{ object.self.foo is defined ? 'ok' : 'ko' }}
27
  {{ object.self.undefinedMethod is defined ? 'ko' : 'ok' }}
28
  {{ object.undefinedMethod.self is defined ? 'ko' : 'ok' }}
29
+ {{ 0 is defined ? 'ok' : 'ko' }}
30
+ {{ "foo" is defined ? 'ok' : 'ko' }}
31
+ {{ true is defined ? 'ok' : 'ko' }}
32
+ {{ false is defined ? 'ok' : 'ko' }}
33
+ {{ null is defined ? 'ok' : 'ko' }}
34
+ {{ [1, 2] is defined ? 'ok' : 'ko' }}
35
+ {{ { foo: "bar" } is defined ? 'ok' : 'ko' }}
36
  --DATA--
37
  return array(
38
  'definedVar' => 'defined',
72
  ok
73
  ok
74
  ok
75
+ ok
76
+ ok
77
+ ok
78
+ ok
79
+ ok
80
+ ok
81
+ ok
82
  --DATA--
83
  return array(
84
  'definedVar' => 'defined',
120
  ok
121
  ok
122
  ok
123
+ ok
124
+ ok
125
+ ok
126
+ ok
127
+ ok
128
+ ok
129
+ ok
vendor/twig/twig/test/Twig/Tests/Node/ForTest.php CHANGED
@@ -51,7 +51,7 @@ class Twig_Tests_Node_ForTest extends Twig_Test_NodeTestCase
51
 
52
  $tests[] = array($node, <<<EOF
53
  // line 1
54
- \$context['_parent'] = (array) \$context;
55
  \$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('items')});
56
  foreach (\$context['_seq'] as \$context["key"] => \$context["item"]) {
57
  echo {$this->getVariableGetter('foo')};
@@ -73,7 +73,7 @@ EOF
73
 
74
  $tests[] = array($node, <<<EOF
75
  // line 1
76
- \$context['_parent'] = (array) \$context;
77
  \$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('values')});
78
  \$context['loop'] = array(
79
  'parent' => \$context['_parent'],
@@ -116,7 +116,7 @@ EOF
116
 
117
  $tests[] = array($node, <<<EOF
118
  // line 1
119
- \$context['_parent'] = (array) \$context;
120
  \$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('values')});
121
  \$context['loop'] = array(
122
  'parent' => \$context['_parent'],
@@ -149,7 +149,7 @@ EOF
149
 
150
  $tests[] = array($node, <<<EOF
151
  // line 1
152
- \$context['_parent'] = (array) \$context;
153
  \$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('values')});
154
  \$context['_iterated'] = false;
155
  \$context['loop'] = array(
51
 
52
  $tests[] = array($node, <<<EOF
53
  // line 1
54
+ \$context['_parent'] = \$context;
55
  \$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('items')});
56
  foreach (\$context['_seq'] as \$context["key"] => \$context["item"]) {
57
  echo {$this->getVariableGetter('foo')};
73
 
74
  $tests[] = array($node, <<<EOF
75
  // line 1
76
+ \$context['_parent'] = \$context;
77
  \$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('values')});
78
  \$context['loop'] = array(
79
  'parent' => \$context['_parent'],
116
 
117
  $tests[] = array($node, <<<EOF
118
  // line 1
119
+ \$context['_parent'] = \$context;
120
  \$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('values')});
121
  \$context['loop'] = array(
122
  'parent' => \$context['_parent'],
149
 
150
  $tests[] = array($node, <<<EOF
151
  // line 1
152
+ \$context['_parent'] = \$context;
153
  \$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('values')});
154
  \$context['_iterated'] = false;
155
  \$context['loop'] = array(
vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php CHANGED
@@ -58,6 +58,10 @@ public function getfoo(\$__foo__ = null, \$__bar__ = "Foo"$declaration)
58
  } catch (Exception \$e) {
59
  ob_end_clean();
60
 
 
 
 
 
61
  throw \$e;
62
  }
63
 
58
  } catch (Exception \$e) {
59
  ob_end_clean();
60
 
61
+ throw \$e;
62
+ } catch (Throwable \$e) {
63
+ ob_end_clean();
64
+
65
  throw \$e;
66
  }
67
 
vendor/twig/twig/test/Twig/Tests/Node/ModuleTest.php CHANGED
@@ -46,7 +46,7 @@ class Twig_Tests_Node_ModuleTest extends Twig_Test_NodeTestCase
46
  <?php
47
 
48
  /* foo.twig */
49
- class __TwigTemplate_e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 extends Twig_Template
50
  {
51
  public function __construct(Twig_Environment \$env)
52
  {
@@ -75,7 +75,7 @@ class __TwigTemplate_e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b785
75
  }
76
  }
77
  EOF
78
- , $twig);
79
 
80
  $import = new Twig_Node_Import(new Twig_Node_Expression_Constant('foo.twig', 1), new Twig_Node_Expression_AssignName('macro', 1), 2);
81
 
@@ -87,7 +87,7 @@ EOF
87
  <?php
88
 
89
  /* foo.twig */
90
- class __TwigTemplate_e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 extends Twig_Template
91
  {
92
  public function __construct(Twig_Environment \$env)
93
  {
@@ -128,7 +128,7 @@ class __TwigTemplate_e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b785
128
  }
129
  }
130
  EOF
131
- , $twig);
132
 
133
  $set = new Twig_Node_Set(false, new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 4))), new Twig_Node(array(new Twig_Node_Expression_Constant('foo', 4))), 4);
134
  $body = new Twig_Node(array($set));
@@ -144,7 +144,7 @@ EOF
144
  <?php
145
 
146
  /* foo.twig */
147
- class __TwigTemplate_e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 extends Twig_Template
148
  {
149
  protected function doGetParent(array \$context)
150
  {
@@ -176,7 +176,7 @@ class __TwigTemplate_e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b785
176
  }
177
  }
178
  EOF
179
- , $twig);
180
 
181
  return $tests;
182
  }
46
  <?php
47
 
48
  /* foo.twig */
49
+ class __TwigTemplate_%x extends Twig_Template
50
  {
51
  public function __construct(Twig_Environment \$env)
52
  {
75
  }
76
  }
77
  EOF
78
+ , $twig, true);
79
 
80
  $import = new Twig_Node_Import(new Twig_Node_Expression_Constant('foo.twig', 1), new Twig_Node_Expression_AssignName('macro', 1), 2);
81
 
87
  <?php
88
 
89
  /* foo.twig */
90
+ class __TwigTemplate_%x extends Twig_Template
91
  {
92
  public function __construct(Twig_Environment \$env)
93
  {
128
  }
129
  }
130
  EOF
131
+ , $twig, true);
132
 
133
  $set = new Twig_Node_Set(false, new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 4))), new Twig_Node(array(new Twig_Node_Expression_Constant('foo', 4))), 4);
134
  $body = new Twig_Node(array($set));
144
  <?php
145
 
146
  /* foo.twig */
147
+ class __TwigTemplate_%x extends Twig_Template
148
  {
149
  protected function doGetParent(array \$context)
150
  {
176
  }
177
  }
178
  EOF
179
+ , $twig, true);
180
 
181
  return $tests;
182
  }
vendor/twig/twig/test/Twig/Tests/ParserTest.php CHANGED
@@ -21,7 +21,7 @@ class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase
21
 
22
  /**
23
  * @expectedException Twig_Error_Syntax
24
- * @expectedExceptionMessage Unknown tag name "foo". Did you mean "for" at line 1
25
  */
26
  public function testUnknownTag()
27
  {
@@ -35,6 +35,22 @@ class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase
35
  $parser->parse($stream);
36
  }
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  /**
39
  * @dataProvider getFilterBodyNodesData
40
  */
21
 
22
  /**
23
  * @expectedException Twig_Error_Syntax
24
+ * @expectedExceptionMessage Unknown "foo" tag. Did you mean "for" at line 1?
25
  */
26
  public function testUnknownTag()
27
  {
35
  $parser->parse($stream);
36
  }
37
 
38
+ /**
39
+ * @expectedException Twig_Error_Syntax
40
+ * @expectedExceptionMessage Unknown "foobar" tag at line 1.
41
+ */
42
+ public function testUnknownTagWithoutSuggestions()
43
+ {
44
+ $stream = new Twig_TokenStream(array(
45
+ new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 1),
46
+ new Twig_Token(Twig_Token::NAME_TYPE, 'foobar', 1),
47
+ new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 1),
48
+ new Twig_Token(Twig_Token::EOF_TYPE, '', 1),
49
+ ));
50
+ $parser = new Twig_Parser(new Twig_Environment($this->getMock('Twig_LoaderInterface')));
51
+ $parser->parse($stream);
52
+ }
53
+
54
  /**
55
  * @dataProvider getFilterBodyNodesData
56
  */
vendor/twig/twig/test/Twig/Tests/TemplateTest.php CHANGED
@@ -68,8 +68,8 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
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 }}', 'Method "a" for object "Twig_TemplateArrayAccessObject" does not exist in "%s" at line 1', false),
72
- array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', 'Method "missing_method" for object "Twig_TemplateArrayAccessObject" does not exist 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
  );
@@ -84,6 +84,13 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
84
  return $tests;
85
  }
86
 
 
 
 
 
 
 
 
87
  /**
88
  * @dataProvider getGetAttributeWithSandbox
89
  */
@@ -463,6 +470,8 @@ class Twig_TemplateTest extends Twig_Template
463
  }
464
  }
465
  }
 
 
466
 
467
  class Twig_TemplateArrayAccessObject implements ArrayAccess
468
  {
@@ -657,7 +666,7 @@ class Twig_TemplateMagicMethodExceptionObject
657
  {
658
  public function __call($method, $arguments)
659
  {
660
- throw new BadMethodCallException(sprintf('Unkown method %s', $method));
661
  }
662
  }
663
 
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
  );
84
  return $tests;
85
  }
86
 
87
+ public function testGetSource()
88
+ {
89
+ $template = new Twig_TemplateTest(new Twig_Environment($this->getMock('Twig_LoaderInterface')), false);
90
+
91
+ $this->assertSame("<? */*bar*/ ?>\n", $template->getSource());
92
+ }
93
+
94
  /**
95
  * @dataProvider getGetAttributeWithSandbox
96
  */
470
  }
471
  }
472
  }
473
+ /* <? *//* *bar*//* ?>*/
474
+ /* */
475
 
476
  class Twig_TemplateArrayAccessObject implements ArrayAccess
477
  {
666
  {
667
  public function __call($method, $arguments)
668
  {
669
+ throw new BadMethodCallException(sprintf('Unknown method "%s".', $method));
670
  }
671
  }
672
 
vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php CHANGED
@@ -13,7 +13,7 @@ class Twig_Tests_TokenStreamTest extends PHPUnit_Framework_TestCase
13
  {
14
  protected static $tokens;
15
 
16
- public function setUp()
17
  {
18
  self::$tokens = array(
19
  new Twig_Token(Twig_Token::TEXT_TYPE, 1, 1),
13
  {
14
  protected static $tokens;
15
 
16
+ protected function setUp()
17
  {
18
  self::$tokens = array(
19
  new Twig_Token(Twig_Token::TEXT_TYPE, 1, 1),
vendor/twig/twig/test/Twig/Tests/escapingTest.php CHANGED
@@ -144,7 +144,7 @@ class Twig_Test_EscapingTest extends PHPUnit_Framework_TestCase
144
 
145
  protected $env;
146
 
147
- public function setUp()
148
  {
149
  $this->env = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
150
  }
144
 
145
  protected $env;
146
 
147
+ protected function setUp()
148
  {
149
  $this->env = new Twig_Environment($this->getMock('Twig_LoaderInterface'));
150
  }
wunderground.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Weather Underground
4
  * Plugin URI: https://github.com/katzwebservices/Wunderground#setting-up-the-plugin
5
  * Description: Get accurate and beautiful weather forecasts powered by Wunderground.com for your content or your sidebar.
6
- * Version: 2.1.1
7
  * License: GPLv2 or later
8
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  * Author: Katz Web Services, Inc.
@@ -18,21 +18,37 @@ class Wunderground_Plugin {
18
  * Version used to prime style and script caches
19
  * @var string
20
  */
21
- const version = '2.1.1';
22
-
23
- var $logger;
24
- var $is_debug = false;
25
 
 
 
 
26
  static $file;
27
 
 
 
 
28
  static $dir_path;
29
 
 
 
 
 
 
 
 
30
  function __construct() {
31
 
32
  self::$file = __FILE__;
33
 
34
  self::$dir_path = plugin_dir_path( __FILE__ );
35
 
 
 
 
 
 
 
36
  // Fire AJAX requests immediately
37
  include_once self::$dir_path.'inc/class-ajax.php';
38
 
@@ -45,6 +61,32 @@ class Wunderground_Plugin {
45
  add_action( 'wunderground_log_debug', array( 'Wunderground_Plugin', 'log_debug'), 10, 2 );
46
  }
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  function init() {
49
 
50
  // Add translation support
3
  * Plugin Name: Weather Underground
4
  * Plugin URI: https://github.com/katzwebservices/Wunderground#setting-up-the-plugin
5
  * Description: Get accurate and beautiful weather forecasts powered by Wunderground.com for your content or your sidebar.
6
+ * Version: 2.1.3
7
  * License: GPLv2 or later
8
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  * Author: Katz Web Services, Inc.
18
  * Version used to prime style and script caches
19
  * @var string
20
  */
21
+ const version = '2.1.3';
 
 
 
22
 
23
+ /**
24
+ * @var string The full path and filename of the main plugin file
25
+ */
26
  static $file;
27
 
28
+ /**
29
+ * @var string Filesystem path to main plugin file, with trailing slash
30
+ */
31
  static $dir_path;
32
 
33
+ /**
34
+ * Filter the Weather Underground API key used by the plugin
35
+ * Modify using the `wunderground_api_key` filter
36
+ * @since 2.1.2
37
+ */
38
+ static $api_key = '3ffab52910ec1a0e';
39
+
40
  function __construct() {
41
 
42
  self::$file = __FILE__;
43
 
44
  self::$dir_path = plugin_dir_path( __FILE__ );
45
 
46
+ /**
47
+ * Filter the Weather Underground API key used by the plugin
48
+ * @since 2.1.2
49
+ */
50
+ self::$api_key = $this->get_api_key();
51
+
52
  // Fire AJAX requests immediately
53
  include_once self::$dir_path.'inc/class-ajax.php';
54
 
61
  add_action( 'wunderground_log_debug', array( 'Wunderground_Plugin', 'log_debug'), 10, 2 );
62
  }
63
 
64
+ /**
65
+ * Get the Weather Underground API key used by the plugin
66
+ *
67
+ * You can define your own Weather Underground API key using the `WUNDERGROUND_API_KEY` constant in wp-config.php,
68
+ * or you can filter the key using the `wunderground_api_key` filter.
69
+ *
70
+ * @since 2.1.2
71
+ *
72
+ * @return string The Weather Underground API key. Default: the plugin key ("3ffab52910ec1a0e")
73
+ */
74
+ private function get_api_key() {
75
+
76
+ $api_key = self::$api_key;
77
+
78
+ if( defined( 'WUNDERGROUND_API_KEY' ) ) {
79
+ $api_key = WUNDERGROUND_API_KEY;
80
+ }
81
+
82
+ $api_key = apply_filters( 'wunderground_api_key', $api_key );
83
+
84
+ return $api_key;
85
+ }
86
+
87
+ /**
88
+ * Load the textdomain, add the [wunderground] and [forecast] shortcodes, add do_shortcode() to widgets
89
+ */
90
  function init() {
91
 
92
  // Add translation support