Version Description
- Timber now retrieves native term meta info #824
- Added site icon support in Theme #1210
- Fixes to menu getting by slug #1237 (thanks @motia)
- Fix to off-site image URLs! #1234 (thanks @njbarrett)
- Fix inconsistency with Post::get_terms #1222 (thanks @haroldangenent)
Download this release
Release Info
Developer | jarednova |
Plugin | Timber |
Version | 1.1.9 |
Comparing to | |
See all releases |
Code changes from version 1.1.8 to 1.1.9
- lib/Helper.php +2 -2
- lib/ImageHelper.php +9 -9
- lib/Loader.php +2 -1
- lib/Menu.php +9 -7
- lib/Post.php +2 -2
- lib/PostCollection.php +0 -5
- lib/PostQuery.php +9 -7
- lib/Site.php +21 -0
- lib/Term.php +6 -3
- lib/Timber.php +1 -1
- readme.txt +9 -1
- timber-starter-theme/functions.php +7 -2
- timber-starter-theme/index.php +0 -4
- timber-starter-theme/static/no-timber.html +10 -0
- timber.php +1 -1
- vendor/autoload.php +1 -1
- vendor/composer/autoload_real.php +3 -3
- vendor/composer/installed.json +7 -7
- vendor/twig/twig/.travis.yml +1 -1
- vendor/twig/twig/CHANGELOG +43 -1
- vendor/twig/twig/composer.json +1 -1
- vendor/twig/twig/doc/advanced.rst +113 -26
- vendor/twig/twig/doc/api.rst +27 -5
- vendor/twig/twig/doc/deprecated.rst +51 -3
- vendor/twig/twig/doc/filters/date.rst +6 -0
- vendor/twig/twig/doc/filters/escape.rst +3 -0
- vendor/twig/twig/doc/filters/number_format.rst +3 -0
- vendor/twig/twig/doc/functions/date.rst +3 -0
- vendor/twig/twig/doc/internals.rst +5 -1
- vendor/twig/twig/doc/recipes.rst +53 -3
- vendor/twig/twig/doc/tags/embed.rst +4 -4
- vendor/twig/twig/doc/tests/empty.rst +2 -2
- vendor/twig/twig/ext/twig/php_twig.h +1 -1
- vendor/twig/twig/ext/twig/twig.c +22 -22
- vendor/twig/twig/lib/Twig/Compiler.php +18 -9
- vendor/twig/twig/lib/Twig/Environment.php +177 -46
- vendor/twig/twig/lib/Twig/Error.php +49 -18
- vendor/twig/twig/lib/Twig/ExpressionParser.php +114 -31
- vendor/twig/twig/lib/Twig/Extension.php +10 -0
- vendor/twig/twig/lib/Twig/Extension/Core.php +18 -81
- vendor/twig/twig/lib/Twig/Extension/Escaper.php +10 -4
- vendor/twig/twig/lib/Twig/Extension/Profiler.php +1 -1
- vendor/twig/twig/lib/Twig/ExtensionInterface.php +2 -0
- vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php +7 -7
- vendor/twig/twig/lib/Twig/Filter/Method.php +1 -1
- vendor/twig/twig/lib/Twig/Function/Method.php +1 -1
- vendor/twig/twig/lib/Twig/Lexer.php +13 -5
- vendor/twig/twig/lib/Twig/LexerInterface.php +3 -3
- vendor/twig/twig/lib/Twig/Loader/Array.php +16 -1
- vendor/twig/twig/lib/Twig/Loader/Chain.php +33 -2
- vendor/twig/twig/lib/Twig/Loader/Filesystem.php +55 -10
- vendor/twig/twig/lib/Twig/Loader/String.php +11 -1
- vendor/twig/twig/lib/Twig/LoaderInterface.php +2 -0
- vendor/twig/twig/lib/Twig/Node.php +56 -0
- vendor/twig/twig/lib/Twig/Node/CheckSecurity.php +3 -3
- vendor/twig/twig/lib/Twig/Node/Embed.php +7 -5
- vendor/twig/twig/lib/Twig/Node/Expression/Array.php +1 -1
- vendor/twig/twig/lib/Twig/Node/Expression/Call.php +54 -18
- vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php +4 -4
- vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php +8 -3
- vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php +3 -3
- vendor/twig/twig/lib/Twig/Node/Expression/Test.php +6 -1
- vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php +2 -2
- vendor/twig/twig/lib/Twig/Node/For.php +9 -4
- vendor/twig/twig/lib/Twig/Node/If.php +7 -2
- vendor/twig/twig/lib/Twig/Node/Import.php +2 -2
- vendor/twig/twig/lib/Twig/Node/Include.php +9 -4
- vendor/twig/twig/lib/Twig/Node/Macro.php +3 -3
- vendor/twig/twig/lib/Twig/Node/Module.php +79 -23
- vendor/twig/twig/lib/Twig/Node/Sandbox.php +1 -1
- vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php +1 -1
- vendor/twig/twig/lib/Twig/Node/Set.php +1 -1
- vendor/twig/twig/lib/Twig/NodeInterface.php +3 -0
- vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php +3 -3
- vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php +4 -4
- vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php +1 -1
- vendor/twig/twig/lib/Twig/Parser.php +34 -13
- vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php +3 -3
- vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php +27 -0
- vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php +38 -0
- vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php +38 -0
- vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php +4 -2
- vendor/twig/twig/lib/Twig/Source.php +49 -0
- vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php +31 -0
- vendor/twig/twig/lib/Twig/Template.php +60 -51
- vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php +11 -5
- vendor/twig/twig/lib/Twig/Test/Method.php +1 -1
- vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php +2 -2
- vendor/twig/twig/lib/Twig/TokenParser/Block.php +2 -2
- vendor/twig/twig/lib/Twig/TokenParser/Embed.php +12 -3
- vendor/twig/twig/lib/Twig/TokenParser/Extends.php +5 -3
- vendor/twig/twig/lib/Twig/TokenParser/For.php +5 -5
- vendor/twig/twig/lib/Twig/TokenParser/From.php +1 -1
- vendor/twig/twig/lib/Twig/TokenParser/If.php +1 -1
- vendor/twig/twig/lib/Twig/TokenParser/Macro.php +1 -1
- vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php +4 -3
- vendor/twig/twig/lib/Twig/TokenParser/Set.php +2 -2
- vendor/twig/twig/lib/Twig/TokenParser/Use.php +1 -1
- vendor/twig/twig/lib/Twig/TokenStream.php +56 -10
- vendor/twig/twig/test/Twig/Tests/Cache/FilesystemTest.php +1 -1
- vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php +165 -48
- vendor/twig/twig/test/Twig/Tests/ErrorTest.php +8 -8
- vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php +17 -17
- vendor/twig/twig/test/Twig/Tests/Extension/CoreTest.php +1 -1
- vendor/twig/twig/test/Twig/Tests/Extension/SandboxTest.php +65 -0
- vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/block.test +1 -1
- vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/name.test +18 -0
- vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/child_contents_outside_blocks.test +15 -0
- vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable.test +1 -1
- vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable_again.test +1 -1
- vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_undefined_variable.test +1 -1
- vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_tag_with_undefined_variable.test +1 -1
- vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/magic_call.test +11 -11
- vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format.test +1 -1
- vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format_interval.test +1 -1
- vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format_default.test +1 -1
- vendor/twig/twig/test/Twig/Tests/Fixtures/filters/static_calls.test +10 -0
- vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call.test +8 -0
- vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call53.test +12 -0
- vendor/twig/twig/test/Twig/Tests/Fixtures/functions/static_calls.test +10 -0
- vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs_argument.test +0 -1
- vendor/twig/twig/test/Twig/Tests/Fixtures/regression/combined_debug_info.test +1 -1
- vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/complex_dynamic_parent.test +35 -0
- vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/dynamic_parent.test +35 -0
- vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/error_line.test +1 -1
- vendor/twig/twig/test/Twig/Tests/IntegrationTest.php +27 -2
- vendor/twig/twig/test/Twig/Tests/{Fixtures/autoescape/filename.test → LegacyFixtures/autoescape/filename.legacy.test} +0 -0
- vendor/twig/twig/test/Twig/Tests/LexerTest.php +33 -22
- vendor/twig/twig/test/Twig/Tests/Loader/ArrayTest.php +16 -2
- vendor/twig/twig/test/Twig/Tests/Loader/ChainTest.php +46 -5
- vendor/twig/twig/test/Twig/Tests/Loader/FilesystemTest.php +64 -13
- vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/phar/phar-sample.phar +0 -0
- vendor/twig/twig/test/Twig/Tests/Node/ForTest.php +1 -1
- vendor/twig/twig/test/Twig/Tests/Node/IfTest.php +1 -1
- vendor/twig/twig/test/Twig/Tests/Node/IncludeTest.php +1 -1
- vendor/twig/twig/test/Twig/Tests/Node/ModuleTest.php +47 -7
- vendor/twig/twig/test/Twig/Tests/Node/SandboxTest.php +1 -1
- vendor/twig/twig/test/Twig/Tests/Node/SandboxedPrintTest.php +1 -1
- vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php +4 -4
- vendor/twig/twig/test/Twig/Tests/ParserTest.php +4 -3
- vendor/twig/twig/test/Twig/Tests/TemplateTest.php +23 -27
- vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php +12 -0
- vendor/twig/twig/test/Twig/Tests/escapingTest.php +1 -1
lib/Helper.php
CHANGED
@@ -15,11 +15,11 @@ class Helper {
|
|
15 |
* @api
|
16 |
* @example
|
17 |
* ```php
|
18 |
-
* $
|
|
|
19 |
* //some expensive query here that's doing something you want to store to a transient
|
20 |
* return $favorites;
|
21 |
* }, 600);
|
22 |
-
* Timber::context['favorites'] = $favorites;
|
23 |
* Timber::render('single.twig', $context);
|
24 |
* ```
|
25 |
*
|
15 |
* @api
|
16 |
* @example
|
17 |
* ```php
|
18 |
+
* $context = Timber::get_context();
|
19 |
+
* $context['favorites'] = Timber\Helper::transient('user-' .$uid. '-favorites', function() use ($uid) {
|
20 |
* //some expensive query here that's doing something you want to store to a transient
|
21 |
* return $favorites;
|
22 |
* }, 600);
|
|
|
23 |
* Timber::render('single.twig', $context);
|
24 |
* ```
|
25 |
*
|
lib/ImageHelper.php
CHANGED
@@ -185,7 +185,7 @@ class ImageHelper {
|
|
185 |
*/
|
186 |
protected static function add_constants() {
|
187 |
if ( !defined('WP_CONTENT_SUBDIR') ) {
|
188 |
-
$wp_content_path = str_replace(
|
189 |
define('WP_CONTENT_SUBDIR', $wp_content_path);
|
190 |
}
|
191 |
}
|
@@ -197,14 +197,14 @@ class ImageHelper {
|
|
197 |
*/
|
198 |
static function add_filters() {
|
199 |
add_filter('upload_dir', function( $arr ) {
|
200 |
-
$arr['relative'] = str_replace(
|
201 |
return $arr;
|
202 |
} );
|
203 |
}
|
204 |
|
205 |
//-- end of public methods --//
|
206 |
|
207 |
-
|
208 |
/**
|
209 |
* Checks if attachment is an image before deleting generated files
|
210 |
*
|
@@ -219,8 +219,8 @@ class ImageHelper {
|
|
219 |
}
|
220 |
}
|
221 |
}
|
222 |
-
|
223 |
-
|
224 |
/**
|
225 |
* Deletes the auto-generated files for resize and letterboxing created by Timber
|
226 |
* @param string $local_file ex: /var/www/wp-content/uploads/2015/my-pic.jpg
|
@@ -312,7 +312,7 @@ class ImageHelper {
|
|
312 |
public static function sideload_image( $file ) {
|
313 |
$loc = self::get_sideloaded_file_loc($file);
|
314 |
if ( file_exists($loc) ) {
|
315 |
-
return URLHelper::
|
316 |
}
|
317 |
// Download file to temp location
|
318 |
if ( !function_exists('download_url') ) {
|
@@ -355,7 +355,7 @@ class ImageHelper {
|
|
355 |
$upload_dir = wp_upload_dir();
|
356 |
$tmp = $url;
|
357 |
if ( 0 === strpos($tmp, ABSPATH) ) {
|
358 |
-
// we've been given a dir, not an url
|
359 |
$result['absolute'] = true;
|
360 |
if ( 0 === strpos($tmp, $upload_dir['basedir']) ) {
|
361 |
$result['base'] = self::BASE_UPLOADS; // upload based
|
@@ -484,10 +484,10 @@ class ImageHelper {
|
|
484 |
$au['subdir'],
|
485 |
$au['basename']
|
486 |
);
|
487 |
-
|
488 |
$new_url = apply_filters('timber/image/new_url', $new_url);
|
489 |
$destination_path = apply_filters('timber/image/new_path', $destination_path);
|
490 |
-
|
491 |
// if already exists...
|
492 |
if ( file_exists($destination_path) ) {
|
493 |
if ( $force || filemtime($source_path) > filemtime($destination_path) ) {
|
185 |
*/
|
186 |
protected static function add_constants() {
|
187 |
if ( !defined('WP_CONTENT_SUBDIR') ) {
|
188 |
+
$wp_content_path = str_replace(get_home_url(), '', WP_CONTENT_URL);
|
189 |
define('WP_CONTENT_SUBDIR', $wp_content_path);
|
190 |
}
|
191 |
}
|
197 |
*/
|
198 |
static function add_filters() {
|
199 |
add_filter('upload_dir', function( $arr ) {
|
200 |
+
$arr['relative'] = str_replace(get_home_url(), '', $arr['baseurl']);
|
201 |
return $arr;
|
202 |
} );
|
203 |
}
|
204 |
|
205 |
//-- end of public methods --//
|
206 |
|
207 |
+
|
208 |
/**
|
209 |
* Checks if attachment is an image before deleting generated files
|
210 |
*
|
219 |
}
|
220 |
}
|
221 |
}
|
222 |
+
|
223 |
+
|
224 |
/**
|
225 |
* Deletes the auto-generated files for resize and letterboxing created by Timber
|
226 |
* @param string $local_file ex: /var/www/wp-content/uploads/2015/my-pic.jpg
|
312 |
public static function sideload_image( $file ) {
|
313 |
$loc = self::get_sideloaded_file_loc($file);
|
314 |
if ( file_exists($loc) ) {
|
315 |
+
return URLHelper::file_system_to_url($loc);
|
316 |
}
|
317 |
// Download file to temp location
|
318 |
if ( !function_exists('download_url') ) {
|
355 |
$upload_dir = wp_upload_dir();
|
356 |
$tmp = $url;
|
357 |
if ( 0 === strpos($tmp, ABSPATH) ) {
|
358 |
+
// we've been given a dir, not an url
|
359 |
$result['absolute'] = true;
|
360 |
if ( 0 === strpos($tmp, $upload_dir['basedir']) ) {
|
361 |
$result['base'] = self::BASE_UPLOADS; // upload based
|
484 |
$au['subdir'],
|
485 |
$au['basename']
|
486 |
);
|
487 |
+
|
488 |
$new_url = apply_filters('timber/image/new_url', $new_url);
|
489 |
$destination_path = apply_filters('timber/image/new_path', $destination_path);
|
490 |
+
|
491 |
// if already exists...
|
492 |
if ( file_exists($destination_path) ) {
|
493 |
if ( $force || filemtime($source_path) > filemtime($destination_path) ) {
|
lib/Loader.php
CHANGED
@@ -124,7 +124,8 @@ class Loader {
|
|
124 |
public function get_loader() {
|
125 |
$paths = array_merge($this->locations, array(ini_get('open_basedir') ? ABSPATH : '/'));
|
126 |
$paths = apply_filters('timber/loader/paths', $paths);
|
127 |
-
|
|
|
128 |
}
|
129 |
|
130 |
|
124 |
public function get_loader() {
|
125 |
$paths = array_merge($this->locations, array(ini_get('open_basedir') ? ABSPATH : '/'));
|
126 |
$paths = apply_filters('timber/loader/paths', $paths);
|
127 |
+
$fs = new \Twig_Loader_Filesystem($paths, '/');
|
128 |
+
return $fs;
|
129 |
}
|
130 |
|
131 |
|
lib/Menu.php
CHANGED
@@ -80,6 +80,7 @@ class Menu extends Core {
|
|
80 |
* @param integer|string $slug
|
81 |
*/
|
82 |
public function __construct( $slug = 0 ) {
|
|
|
83 |
$locations = get_nav_menu_locations();
|
84 |
if ( $slug != 0 && is_numeric($slug) ) {
|
85 |
$menu_id = $slug;
|
@@ -87,7 +88,8 @@ class Menu extends Core {
|
|
87 |
$menu_id = $this->get_menu_id_from_locations($slug, $locations);
|
88 |
} else if ( $slug === false ) {
|
89 |
$menu_id = false;
|
90 |
-
}
|
|
|
91 |
$menu_id = $this->get_menu_id_from_terms($slug);
|
92 |
}
|
93 |
if ( $menu_id ) {
|
@@ -161,13 +163,13 @@ class Menu extends Core {
|
|
161 |
protected function get_menu_id_from_terms( $slug = 0 ) {
|
162 |
if ( !is_numeric($slug) && is_string($slug) ) {
|
163 |
//we have a string so lets search for that
|
164 |
-
$
|
165 |
-
if ( $
|
166 |
-
return $
|
167 |
}
|
168 |
-
$
|
169 |
-
if ( $
|
170 |
-
return $
|
171 |
}
|
172 |
}
|
173 |
$menus = get_terms('nav_menu', array('hide_empty' => true));
|
80 |
* @param integer|string $slug
|
81 |
*/
|
82 |
public function __construct( $slug = 0 ) {
|
83 |
+
$menu_id = false;
|
84 |
$locations = get_nav_menu_locations();
|
85 |
if ( $slug != 0 && is_numeric($slug) ) {
|
86 |
$menu_id = $slug;
|
88 |
$menu_id = $this->get_menu_id_from_locations($slug, $locations);
|
89 |
} else if ( $slug === false ) {
|
90 |
$menu_id = false;
|
91 |
+
}
|
92 |
+
if ( !$menu_id ) {
|
93 |
$menu_id = $this->get_menu_id_from_terms($slug);
|
94 |
}
|
95 |
if ( $menu_id ) {
|
163 |
protected function get_menu_id_from_terms( $slug = 0 ) {
|
164 |
if ( !is_numeric($slug) && is_string($slug) ) {
|
165 |
//we have a string so lets search for that
|
166 |
+
$menu = get_term_by('slug', $slug, 'nav_menu');
|
167 |
+
if ( $menu ) {
|
168 |
+
return $menu->term_id;
|
169 |
}
|
170 |
+
$menu = get_term_by('name', $slug, 'nav_menu');
|
171 |
+
if ( $menu ) {
|
172 |
+
return $menu->term_id;
|
173 |
}
|
174 |
}
|
175 |
$menus = get_terms('nav_menu', array('hide_empty' => true));
|
lib/Post.php
CHANGED
@@ -1459,8 +1459,8 @@ class Post extends Core implements CoreInterface {
|
|
1459 |
* @param bool $merge Should the resulting array be one big one (true)? Or should it be an array of sub-arrays for each taxonomy (false)?
|
1460 |
* @return array
|
1461 |
*/
|
1462 |
-
public function get_terms( $tax = '', $merge = true ) {
|
1463 |
-
return $this->terms($tax, $merge);
|
1464 |
}
|
1465 |
|
1466 |
/**
|
1459 |
* @param bool $merge Should the resulting array be one big one (true)? Or should it be an array of sub-arrays for each taxonomy (false)?
|
1460 |
* @return array
|
1461 |
*/
|
1462 |
+
public function get_terms( $tax = '', $merge = true, $TermClass = '' ) {
|
1463 |
+
return $this->terms($tax, $merge, $TermClass);
|
1464 |
}
|
1465 |
|
1466 |
/**
|
lib/PostCollection.php
CHANGED
@@ -5,11 +5,6 @@ namespace Timber;
|
|
5 |
use Timber\Helper;
|
6 |
use Timber\Post;
|
7 |
|
8 |
-
// Exit if accessed directly
|
9 |
-
if ( !defined('ABSPATH') ) {
|
10 |
-
exit;
|
11 |
-
}
|
12 |
-
|
13 |
/**
|
14 |
* PostCollections are internal objects used to hold a collection of posts
|
15 |
*/
|
5 |
use Timber\Helper;
|
6 |
use Timber\Post;
|
7 |
|
|
|
|
|
|
|
|
|
|
|
8 |
/**
|
9 |
* PostCollections are internal objects used to hold a collection of posts
|
10 |
*/
|
lib/PostQuery.php
CHANGED
@@ -6,25 +6,23 @@ use Timber\Helper;
|
|
6 |
use Timber\Post;
|
7 |
use Timber\PostGetter;
|
8 |
|
9 |
-
// Exit if accessed directly
|
10 |
-
if ( !defined('ABSPATH') ) {
|
11 |
-
exit;
|
12 |
-
}
|
13 |
-
|
14 |
/**
|
15 |
* A PostQuery allows a user to query for a Collection of WordPress Posts.
|
16 |
* PostCollections are used directly in Twig templates to iterate through and retrieve
|
17 |
* meta information about the collection of posts
|
18 |
* @api
|
|
|
19 |
*/
|
20 |
class PostQuery extends PostCollection {
|
21 |
-
|
22 |
-
//maintain reference to $query object to generate pagination
|
23 |
|
24 |
protected $userQuery;
|
25 |
protected $queryIterator;
|
26 |
protected $pagination = null;
|
27 |
|
|
|
|
|
|
|
|
|
28 |
public function __construct( $query = false, $post_class = '\Timber\Post' ) {
|
29 |
$this->userQuery = $query;
|
30 |
$this->queryIterator = PostGetter::query_posts($query, $post_class);
|
@@ -34,6 +32,10 @@ class PostQuery extends PostCollection {
|
|
34 |
parent::__construct($posts, $post_class);
|
35 |
}
|
36 |
|
|
|
|
|
|
|
|
|
37 |
protected function get_query() {
|
38 |
return $this->userQuery;
|
39 |
}
|
6 |
use Timber\Post;
|
7 |
use Timber\PostGetter;
|
8 |
|
|
|
|
|
|
|
|
|
|
|
9 |
/**
|
10 |
* A PostQuery allows a user to query for a Collection of WordPress Posts.
|
11 |
* PostCollections are used directly in Twig templates to iterate through and retrieve
|
12 |
* meta information about the collection of posts
|
13 |
* @api
|
14 |
+
* @package Timber
|
15 |
*/
|
16 |
class PostQuery extends PostCollection {
|
|
|
|
|
17 |
|
18 |
protected $userQuery;
|
19 |
protected $queryIterator;
|
20 |
protected $pagination = null;
|
21 |
|
22 |
+
/**
|
23 |
+
* @param mixed $query
|
24 |
+
* @param string $post_class
|
25 |
+
*/
|
26 |
public function __construct( $query = false, $post_class = '\Timber\Post' ) {
|
27 |
$this->userQuery = $query;
|
28 |
$this->queryIterator = PostGetter::query_posts($query, $post_class);
|
32 |
parent::__construct($posts, $post_class);
|
33 |
}
|
34 |
|
35 |
+
/**
|
36 |
+
* @return mixed the query the user orignally passed
|
37 |
+
* to the pagination object
|
38 |
+
*/
|
39 |
protected function get_query() {
|
40 |
return $this->userQuery;
|
41 |
}
|
lib/Site.php
CHANGED
@@ -205,6 +205,27 @@ class Site extends Core implements CoreInterface {
|
|
205 |
return $this->$field;
|
206 |
}
|
207 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
/**
|
209 |
* Returns the link to the site's home.
|
210 |
* @example
|
205 |
return $this->$field;
|
206 |
}
|
207 |
|
208 |
+
public function icon() {
|
209 |
+
if ( is_multisite() ) {
|
210 |
+
return $this->icon_multisite($this->ID);
|
211 |
+
}
|
212 |
+
$iid = get_option('site_icon');
|
213 |
+
if ( $iid ) {
|
214 |
+
return new Image($iid);
|
215 |
+
}
|
216 |
+
}
|
217 |
+
|
218 |
+
protected function icon_multisite( $site_id ) {
|
219 |
+
$image = null;
|
220 |
+
$blog_ids = self::switch_to_blog($site_id);
|
221 |
+
$iid = get_blog_option($blog_ids['new'], 'site_icon');
|
222 |
+
if ( $iid ) {
|
223 |
+
$image = new Image($iid);
|
224 |
+
}
|
225 |
+
switch_to_blog($blog_ids['old']);
|
226 |
+
return $image;
|
227 |
+
}
|
228 |
+
|
229 |
/**
|
230 |
* Returns the link to the site's home.
|
231 |
* @example
|
lib/Term.php
CHANGED
@@ -217,10 +217,13 @@ class Term extends Core implements CoreInterface {
|
|
217 |
*/
|
218 |
public function get_meta_field( $field_name ) {
|
219 |
if ( !isset($this->$field_name) ) {
|
220 |
-
$field_value =
|
221 |
-
|
222 |
-
|
|
|
|
|
223 |
$this->$field_name = $field_value;
|
|
|
224 |
}
|
225 |
return $this->$field_name;
|
226 |
}
|
217 |
*/
|
218 |
public function get_meta_field( $field_name ) {
|
219 |
if ( !isset($this->$field_name) ) {
|
220 |
+
$field_value = get_term_meta($this->ID, $field_name, true);
|
221 |
+
if ( !$field_value ) {
|
222 |
+
$field_value = apply_filters('timber_term_get_meta_field', '', $this->ID, $field_name, $this);
|
223 |
+
$field_value = apply_filters('timber/term/meta/field', $field_value, $this->ID, $field_name, $this);
|
224 |
+
}
|
225 |
$this->$field_name = $field_value;
|
226 |
+
|
227 |
}
|
228 |
return $this->$field_name;
|
229 |
}
|
lib/Timber.php
CHANGED
@@ -35,7 +35,7 @@ use Timber\Loader;
|
|
35 |
*/
|
36 |
class Timber {
|
37 |
|
38 |
-
public static $version = '1.1.
|
39 |
public static $locations;
|
40 |
public static $dirname = 'views';
|
41 |
public static $twig_cache = false;
|
35 |
*/
|
36 |
class Timber {
|
37 |
|
38 |
+
public static $version = '1.1.9';
|
39 |
public static $locations;
|
40 |
public static $dirname = 'views';
|
41 |
public static $twig_cache = false;
|
readme.txt
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
Contributors: jarednova, connorjburton, lggorman
|
3 |
Tags: template engine, templates, twig
|
4 |
Requires at least: 3.7
|
5 |
-
Stable tag: 1.1.
|
6 |
Tested up to: 4.6
|
7 |
PHP version: 5.3.0 or greater
|
8 |
License: GPLv2 or later
|
@@ -41,6 +41,14 @@ Timber is great for any WordPress developer who cares about writing good, mainta
|
|
41 |
|
42 |
== Changelog ==
|
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
= 1.1.8 =
|
45 |
* Fixed image generation when images are updated/deleted by WordPress (thanks @dudewithamood)
|
46 |
|
2 |
Contributors: jarednova, connorjburton, lggorman
|
3 |
Tags: template engine, templates, twig
|
4 |
Requires at least: 3.7
|
5 |
+
Stable tag: 1.1.9
|
6 |
Tested up to: 4.6
|
7 |
PHP version: 5.3.0 or greater
|
8 |
License: GPLv2 or later
|
41 |
|
42 |
== Changelog ==
|
43 |
|
44 |
+
= 1.1.9 =
|
45 |
+
* Timber now retrieves native term meta info #824
|
46 |
+
* Added site icon support in Theme #1210
|
47 |
+
* Fixes to menu getting by slug #1237 (thanks @motia)
|
48 |
+
* Fix to off-site image URLs! #1234 (thanks @njbarrett)
|
49 |
+
* Fix inconsistency with Post::get_terms #1222 (thanks @haroldangenent)
|
50 |
+
|
51 |
+
|
52 |
= 1.1.8 =
|
53 |
* Fixed image generation when images are updated/deleted by WordPress (thanks @dudewithamood)
|
54 |
|
timber-starter-theme/functions.php
CHANGED
@@ -2,8 +2,13 @@
|
|
2 |
|
3 |
if ( ! class_exists( 'Timber' ) ) {
|
4 |
add_action( 'admin_notices', function() {
|
5 |
-
|
6 |
-
|
|
|
|
|
|
|
|
|
|
|
7 |
return;
|
8 |
}
|
9 |
|
2 |
|
3 |
if ( ! class_exists( 'Timber' ) ) {
|
4 |
add_action( 'admin_notices', function() {
|
5 |
+
echo '<div class="error"><p>Timber not activated. Make sure you activate the plugin in <a href="' . esc_url( admin_url( 'plugins.php#timber' ) ) . '">' . esc_url( admin_url( 'plugins.php') ) . '</a></p></div>';
|
6 |
+
});
|
7 |
+
|
8 |
+
add_filter('template_include', function($template) {
|
9 |
+
return get_stylesheet_directory() . '/static/no-timber.html';
|
10 |
+
});
|
11 |
+
|
12 |
return;
|
13 |
}
|
14 |
|
timber-starter-theme/index.php
CHANGED
@@ -13,10 +13,6 @@
|
|
13 |
* @since Timber 0.1
|
14 |
*/
|
15 |
|
16 |
-
if ( ! class_exists( 'Timber' ) ) {
|
17 |
-
echo 'Timber not activated. Make sure you activate the plugin in <a href="/wp-admin/plugins.php#timber">/wp-admin/plugins.php</a>';
|
18 |
-
return;
|
19 |
-
}
|
20 |
$context = Timber::get_context();
|
21 |
$context['posts'] = Timber::get_posts();
|
22 |
$context['foo'] = 'bar';
|
13 |
* @since Timber 0.1
|
14 |
*/
|
15 |
|
|
|
|
|
|
|
|
|
16 |
$context = Timber::get_context();
|
17 |
$context['posts'] = Timber::get_posts();
|
18 |
$context['foo'] = 'bar';
|
timber-starter-theme/static/no-timber.html
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<title>Timber not active</title>
|
5 |
+
</head>
|
6 |
+
|
7 |
+
<body>
|
8 |
+
<p>Timber not activated</p>
|
9 |
+
</body>
|
10 |
+
</html>
|
timber.php
CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Timber
|
|
4 |
Description: The WordPress Timber Library allows you to write themes using the power Twig templates.
|
5 |
Plugin URI: http://timber.upstatement.com
|
6 |
Author: Jared Novack + Upstatement
|
7 |
-
Version: 1.1.
|
8 |
Author URI: http://upstatement.com/
|
9 |
*/
|
10 |
// we look for Composer files first in the plugins dir.
|
4 |
Description: The WordPress Timber Library allows you to write themes using the power Twig templates.
|
5 |
Plugin URI: http://timber.upstatement.com
|
6 |
Author: Jared Novack + Upstatement
|
7 |
+
Version: 1.1.9
|
8 |
Author URI: http://upstatement.com/
|
9 |
*/
|
10 |
// we look for Composer files first in the plugins dir.
|
vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInit05219471bb425701949f68630de707ca::getLoader();
|
vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -19,9 +19,9 @@ class ComposerAutoloaderInita8a20583fdb84a7c5284a224ce4e2214
|
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
-
spl_autoload_register(array('
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
-
spl_autoload_unregister(array('
|
25 |
|
26 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
27 |
foreach ($map as $namespace => $path) {
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInit05219471bb425701949f68630de707ca
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
+
spl_autoload_register(array('ComposerAutoloaderInit05219471bb425701949f68630de707ca', 'loadClassLoader'), true, true);
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit05219471bb425701949f68630de707ca', 'loadClassLoader'));
|
25 |
|
26 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
27 |
foreach ($map as $namespace => $path) {
|
vendor/composer/installed.json
CHANGED
@@ -110,17 +110,17 @@
|
|
110 |
},
|
111 |
{
|
112 |
"name": "twig/twig",
|
113 |
-
"version": "v1.
|
114 |
-
"version_normalized": "1.
|
115 |
"source": {
|
116 |
"type": "git",
|
117 |
"url": "https://github.com/twigphp/Twig.git",
|
118 |
-
"reference": "
|
119 |
},
|
120 |
"dist": {
|
121 |
"type": "zip",
|
122 |
-
"url": "https://api.github.com/repos/twigphp/Twig/zipball/
|
123 |
-
"reference": "
|
124 |
"shasum": ""
|
125 |
},
|
126 |
"require": {
|
@@ -130,11 +130,11 @@
|
|
130 |
"symfony/debug": "~2.7",
|
131 |
"symfony/phpunit-bridge": "~2.7"
|
132 |
},
|
133 |
-
"time": "2016-
|
134 |
"type": "library",
|
135 |
"extra": {
|
136 |
"branch-alias": {
|
137 |
-
"dev-master": "1.
|
138 |
}
|
139 |
},
|
140 |
"installation-source": "dist",
|
110 |
},
|
111 |
{
|
112 |
"name": "twig/twig",
|
113 |
+
"version": "v1.27.0",
|
114 |
+
"version_normalized": "1.27.0.0",
|
115 |
"source": {
|
116 |
"type": "git",
|
117 |
"url": "https://github.com/twigphp/Twig.git",
|
118 |
+
"reference": "3c6c0033fd3b5679c6e1cb60f4f9766c2b424d97"
|
119 |
},
|
120 |
"dist": {
|
121 |
"type": "zip",
|
122 |
+
"url": "https://api.github.com/repos/twigphp/Twig/zipball/3c6c0033fd3b5679c6e1cb60f4f9766c2b424d97",
|
123 |
+
"reference": "3c6c0033fd3b5679c6e1cb60f4f9766c2b424d97",
|
124 |
"shasum": ""
|
125 |
},
|
126 |
"require": {
|
130 |
"symfony/debug": "~2.7",
|
131 |
"symfony/phpunit-bridge": "~2.7"
|
132 |
},
|
133 |
+
"time": "2016-10-25 19:17:17",
|
134 |
"type": "library",
|
135 |
"extra": {
|
136 |
"branch-alias": {
|
137 |
+
"dev-master": "1.27-dev"
|
138 |
}
|
139 |
},
|
140 |
"installation-source": "dist",
|
vendor/twig/twig/.travis.yml
CHANGED
@@ -5,7 +5,7 @@ sudo: false
|
|
5 |
cache:
|
6 |
directories:
|
7 |
- vendor
|
8 |
-
- $HOME/.composer/cache
|
9 |
|
10 |
php:
|
11 |
- 5.2
|
5 |
cache:
|
6 |
directories:
|
7 |
- vendor
|
8 |
+
- $HOME/.composer/cache/files
|
9 |
|
10 |
php:
|
11 |
- 5.2
|
vendor/twig/twig/CHANGELOG
CHANGED
@@ -1,7 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
* 1.24.2 (2016-09-01)
|
2 |
|
3 |
* fixed static callables
|
4 |
-
* fixed a potential PHP warning when
|
5 |
* fixed a case where the autoescaping does not work as expected
|
6 |
|
7 |
* 1.24.1 (2016-05-30)
|
1 |
+
* 1.27.0 (2016-10-25)
|
2 |
+
|
3 |
+
* deprecated Twig_Parser::getEnvironment()
|
4 |
+
* deprecated Twig_Parser::addHandler() and Twig_Parser::addNodeVisitor()
|
5 |
+
* deprecated Twig_Compiler::addIndentation()
|
6 |
+
* fixed regression when registering two extensions having the same class name
|
7 |
+
* deprecated Twig_LoaderInterface::getSource() (implement Twig_SourceContextLoaderInterface instead)
|
8 |
+
* fixed the filesystem loader with relative paths
|
9 |
+
* deprecated Twig_Node::getLine() in favor of Twig_Node::getTemplateLine()
|
10 |
+
* deprecated Twig_Template::getSource() in favor of Twig_Template::getSourceContext()
|
11 |
+
* deprecated Twig_Node::getFilename() in favor of Twig_Node::getTemplateName()
|
12 |
+
* deprecated the "filename" escaping strategy (use "name" instead)
|
13 |
+
* added Twig_Source to hold information about the original template
|
14 |
+
* deprecated Twig_Error::getTemplateFile() and Twig_Error::setTemplateFile() in favor of Twig_Error::getTemplateName() and Twig_Error::setTemplateName()
|
15 |
+
* deprecated Parser::getFilename()
|
16 |
+
* fixed template paths when a template name contains a protocol like vfs://
|
17 |
+
* improved debugging with Twig_Sandbox_SecurityError exceptions for disallowed methods and properties
|
18 |
+
|
19 |
+
* 1.26.1 (2016-10-05)
|
20 |
+
|
21 |
+
* removed template source code from generated template classes when debug is disabled
|
22 |
+
* fixed default implementation of Twig_Template::getDebugInfo() for better BC
|
23 |
+
* fixed regression on static calls for functions/filters/tests
|
24 |
+
|
25 |
+
* 1.26.0 (2016-10-02)
|
26 |
+
|
27 |
+
* added template cache invalidation based on more environment options
|
28 |
+
* added a missing deprecation notice
|
29 |
+
* fixed template paths when a template is stored in a PHAR file
|
30 |
+
* allowed filters/functions/tests implementation to use a different class than the extension they belong to
|
31 |
+
* deprecated Twig_ExtensionInterface::getName()
|
32 |
+
|
33 |
+
* 1.25.0 (2016-09-21)
|
34 |
+
|
35 |
+
* changed the way we store template source in template classes
|
36 |
+
* removed usage of realpath in cache keys
|
37 |
+
* fixed Twig cache sharing when used with different versions of PHP
|
38 |
+
* removed embed parent workaround for simple use cases
|
39 |
+
* deprecated the ability to store non Node instances in Node::$nodes
|
40 |
+
* deprecated Twig_Environment::getLexer(), Twig_Environment::getParser(), Twig_Environment::getCompiler()
|
41 |
+
* deprecated Twig_Compiler::getFilename()
|
42 |
+
|
43 |
* 1.24.2 (2016-09-01)
|
44 |
|
45 |
* fixed static callables
|
46 |
+
* fixed a potential PHP warning when loading the cache
|
47 |
* fixed a case where the autoescaping does not work as expected
|
48 |
|
49 |
* 1.24.1 (2016-05-30)
|
vendor/twig/twig/composer.json
CHANGED
@@ -40,7 +40,7 @@
|
|
40 |
},
|
41 |
"extra": {
|
42 |
"branch-alias": {
|
43 |
-
"dev-master": "1.
|
44 |
}
|
45 |
}
|
46 |
}
|
40 |
},
|
41 |
"extra": {
|
42 |
"branch-alias": {
|
43 |
+
"dev-master": "1.27-dev"
|
44 |
}
|
45 |
}
|
46 |
}
|
vendor/twig/twig/doc/advanced.rst
CHANGED
@@ -136,7 +136,13 @@ Creating a filter is as simple as associating a name with a PHP callable::
|
|
136 |
// or a simple PHP function
|
137 |
$filter = new Twig_SimpleFilter('rot13', 'str_rot13');
|
138 |
|
|
|
|
|
|
|
|
|
139 |
// or a class method
|
|
|
|
|
140 |
$filter = new Twig_SimpleFilter('rot13', array('SomeClass', 'rot13Filter'));
|
141 |
|
142 |
The first argument passed to the ``Twig_SimpleFilter`` constructor is the name
|
@@ -525,10 +531,6 @@ reusable class like adding support for internationalization. An extension can
|
|
525 |
define tags, filters, tests, operators, global variables, functions, and node
|
526 |
visitors.
|
527 |
|
528 |
-
Creating an extension also makes for a better separation of code that is
|
529 |
-
executed at compilation time and code needed at runtime. As such, it makes
|
530 |
-
your code faster.
|
531 |
-
|
532 |
Most of the time, it is useful to create a single extension for your project,
|
533 |
to host all the specific tags and filters you want to add to Twig.
|
534 |
|
@@ -613,32 +615,27 @@ An extension is a class that implements the following interface::
|
|
613 |
* Returns the name of the extension.
|
614 |
*
|
615 |
* @return string The extension name
|
|
|
|
|
616 |
*/
|
617 |
function getName();
|
618 |
}
|
619 |
|
620 |
-
To keep your extension class clean and lean,
|
621 |
-
``Twig_Extension`` class instead of implementing the
|
622 |
-
|
623 |
-
``Twig_Extension`` provides empty implementations for all other methods.
|
624 |
-
|
625 |
-
The ``getName()`` method must return a unique identifier for your extension.
|
626 |
-
|
627 |
-
Now, with this information in mind, let's create the most basic extension
|
628 |
-
possible::
|
629 |
|
630 |
class Project_Twig_Extension extends Twig_Extension
|
631 |
{
|
632 |
-
public function getName()
|
633 |
-
{
|
634 |
-
return 'project';
|
635 |
-
}
|
636 |
}
|
637 |
|
|
|
|
|
|
|
638 |
.. note::
|
639 |
|
640 |
-
|
641 |
-
the
|
642 |
|
643 |
Twig does not care where you save your extension on the filesystem, as all
|
644 |
extensions must be registered explicitly to be available in your templates.
|
@@ -651,7 +648,7 @@ main ``Environment`` object::
|
|
651 |
|
652 |
.. tip::
|
653 |
|
654 |
-
The
|
655 |
|
656 |
Globals
|
657 |
~~~~~~~
|
@@ -770,6 +767,101 @@ The ``getTests()`` method lets you add new test functions::
|
|
770 |
// ...
|
771 |
}
|
772 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
773 |
Overloading
|
774 |
-----------
|
775 |
|
@@ -790,11 +882,6 @@ possible** (order matters)::
|
|
790 |
{
|
791 |
// do something different from the built-in date filter
|
792 |
}
|
793 |
-
|
794 |
-
public function getName()
|
795 |
-
{
|
796 |
-
return 'project';
|
797 |
-
}
|
798 |
}
|
799 |
|
800 |
$twig = new Twig_Environment($loader);
|
@@ -802,7 +889,7 @@ possible** (order matters)::
|
|
802 |
|
803 |
Here, we have overloaded the built-in ``date`` filter with a custom one.
|
804 |
|
805 |
-
If you do the same on the Twig_Environment itself, beware that it takes
|
806 |
precedence over any other registered extensions::
|
807 |
|
808 |
$twig = new Twig_Environment($loader);
|
136 |
// or a simple PHP function
|
137 |
$filter = new Twig_SimpleFilter('rot13', 'str_rot13');
|
138 |
|
139 |
+
// or a class static method
|
140 |
+
$filter = new Twig_SimpleFilter('rot13', array('SomeClass', 'rot13Filter'));
|
141 |
+
$filter = new Twig_SimpleFilter('rot13', 'SomeClass::rot13Filter');
|
142 |
+
|
143 |
// or a class method
|
144 |
+
$filter = new Twig_SimpleFilter('rot13', array($this, 'rot13Filter'));
|
145 |
+
// the one below needs a runtime implementation (see below for more information)
|
146 |
$filter = new Twig_SimpleFilter('rot13', array('SomeClass', 'rot13Filter'));
|
147 |
|
148 |
The first argument passed to the ``Twig_SimpleFilter`` constructor is the name
|
531 |
define tags, filters, tests, operators, global variables, functions, and node
|
532 |
visitors.
|
533 |
|
|
|
|
|
|
|
|
|
534 |
Most of the time, it is useful to create a single extension for your project,
|
535 |
to host all the specific tags and filters you want to add to Twig.
|
536 |
|
615 |
* Returns the name of the extension.
|
616 |
*
|
617 |
* @return string The extension name
|
618 |
+
*
|
619 |
+
* @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
|
620 |
*/
|
621 |
function getName();
|
622 |
}
|
623 |
|
624 |
+
To keep your extension class clean and lean, inherit from the built-in
|
625 |
+
``Twig_Extension`` class instead of implementing the interface as it provides
|
626 |
+
empty implementations for all methods:
|
|
|
|
|
|
|
|
|
|
|
|
|
627 |
|
628 |
class Project_Twig_Extension extends Twig_Extension
|
629 |
{
|
|
|
|
|
|
|
|
|
630 |
}
|
631 |
|
632 |
+
Of course, this extension does nothing for now. We will customize it in the
|
633 |
+
next sections.
|
634 |
+
|
635 |
.. note::
|
636 |
|
637 |
+
Prior to Twig 1.26, you must implement the ``getName()`` method which must
|
638 |
+
return a unique identifier for the extension.
|
639 |
|
640 |
Twig does not care where you save your extension on the filesystem, as all
|
641 |
extensions must be registered explicitly to be available in your templates.
|
648 |
|
649 |
.. tip::
|
650 |
|
651 |
+
The Twig core extensions are great examples of how extensions work.
|
652 |
|
653 |
Globals
|
654 |
~~~~~~~
|
767 |
// ...
|
768 |
}
|
769 |
|
770 |
+
Definition vs Runtime
|
771 |
+
~~~~~~~~~~~~~~~~~~~~~
|
772 |
+
|
773 |
+
Twig filters, functions, and tests runtime implementations can be defined as
|
774 |
+
any valid PHP callable:
|
775 |
+
|
776 |
+
* **functions/static methods**: Simple to implement and fast (used by all Twig
|
777 |
+
core extensions); but it is hard for the runtime to depend on external
|
778 |
+
objects;
|
779 |
+
|
780 |
+
* **closures**: Simple to implement;
|
781 |
+
|
782 |
+
* **object methods**: More flexible and required if your runtime code depends
|
783 |
+
on external objects.
|
784 |
+
|
785 |
+
The simplest way to use methods is to define them on the extension itself::
|
786 |
+
|
787 |
+
class Project_Twig_Extension extends Twig_Extension
|
788 |
+
{
|
789 |
+
private $rot13Provider;
|
790 |
+
|
791 |
+
public function __construct($rot13Provider)
|
792 |
+
{
|
793 |
+
$this->rot13Provider = $rot13Provider;
|
794 |
+
}
|
795 |
+
|
796 |
+
public function getFunctions()
|
797 |
+
{
|
798 |
+
return array(
|
799 |
+
new Twig_SimpleFunction('rot13', array($this, 'rot13')),
|
800 |
+
);
|
801 |
+
}
|
802 |
+
|
803 |
+
public function rot13($value)
|
804 |
+
{
|
805 |
+
return $rot13Provider->rot13($value);
|
806 |
+
}
|
807 |
+
}
|
808 |
+
|
809 |
+
This is very convenient but not recommended as it makes template compilation
|
810 |
+
depend on runtime dependencies even if they are not needed (think for instance
|
811 |
+
as a dependency that connects to a database engine).
|
812 |
+
|
813 |
+
As of Twig 1.26, you can easily decouple the extension definitions from their
|
814 |
+
runtime implementations by registering a ``Twig_RuntimeLoaderInterface``
|
815 |
+
instance on the environment that knows how to instantiate such runtime classes
|
816 |
+
(runtime classes must be autoload-able)::
|
817 |
+
|
818 |
+
class RuntimeLoader implements Twig_RuntimeLoaderInterface
|
819 |
+
{
|
820 |
+
public function load($class)
|
821 |
+
{
|
822 |
+
// implement the logic to create an instance of $class
|
823 |
+
// and inject its dependencies
|
824 |
+
// most of the time, it means using your dependency injection container
|
825 |
+
if ('Project_Twig_RuntimeExtension' === $class) {
|
826 |
+
return new $class(new Rot13Provider());
|
827 |
+
} else {
|
828 |
+
// ...
|
829 |
+
}
|
830 |
+
}
|
831 |
+
}
|
832 |
+
|
833 |
+
$twig->addRuntimeLoader(new RuntimeLoader());
|
834 |
+
|
835 |
+
It is now possible to move the runtime logic to a new
|
836 |
+
``Project_Twig_RuntimeExtension`` class and use it directly in the extension::
|
837 |
+
|
838 |
+
class Project_Twig_RuntimeExtension extends Twig_Extension
|
839 |
+
{
|
840 |
+
private $rot13Provider;
|
841 |
+
|
842 |
+
public function __construct($rot13Provider)
|
843 |
+
{
|
844 |
+
$this->rot13Provider = $rot13Provider;
|
845 |
+
}
|
846 |
+
|
847 |
+
public function rot13($value)
|
848 |
+
{
|
849 |
+
return $rot13Provider->rot13($value);
|
850 |
+
}
|
851 |
+
}
|
852 |
+
|
853 |
+
class Project_Twig_Extension extends Twig_Extension
|
854 |
+
{
|
855 |
+
public function getFunctions()
|
856 |
+
{
|
857 |
+
return array(
|
858 |
+
new Twig_SimpleFunction('rot13', array('Project_Twig_RuntimeExtension', 'rot13')),
|
859 |
+
// or
|
860 |
+
new Twig_SimpleFunction('rot13', 'Project_Twig_RuntimeExtension::rot13'),
|
861 |
+
);
|
862 |
+
}
|
863 |
+
}
|
864 |
+
|
865 |
Overloading
|
866 |
-----------
|
867 |
|
882 |
{
|
883 |
// do something different from the built-in date filter
|
884 |
}
|
|
|
|
|
|
|
|
|
|
|
885 |
}
|
886 |
|
887 |
$twig = new Twig_Environment($loader);
|
889 |
|
890 |
Here, we have overloaded the built-in ``date`` filter with a custom one.
|
891 |
|
892 |
+
If you do the same on the ``Twig_Environment`` itself, beware that it takes
|
893 |
precedence over any other registered extensions::
|
894 |
|
895 |
$twig = new Twig_Environment($loader);
|
vendor/twig/twig/doc/api.rst
CHANGED
@@ -115,14 +115,14 @@ The following options are available:
|
|
115 |
``false`` to disable).
|
116 |
|
117 |
As of Twig 1.9, you can set the escaping strategy to use (``css``, ``url``,
|
118 |
-
``html_attr``, or a PHP callback that takes the template
|
119 |
return the escaping strategy to use -- the callback cannot be a function name
|
120 |
to avoid collision with built-in escaping strategies).
|
121 |
|
122 |
-
As of Twig 1.17, the ``filename`` escaping strategy
|
123 |
-
strategy to use for a template based on
|
124 |
-
strategy does not incur any overhead at
|
125 |
-
compilation time.)
|
126 |
|
127 |
* ``optimizations`` *integer*
|
128 |
|
@@ -156,6 +156,9 @@ Here is a list of the built-in loaders Twig provides:
|
|
156 |
.. versionadded:: 1.10
|
157 |
The ``prependPath()`` and support for namespaces were added in Twig 1.10.
|
158 |
|
|
|
|
|
|
|
159 |
``Twig_Loader_Filesystem`` loads templates from the file system. This loader
|
160 |
can find templates in folders on the file system and is the preferred way to
|
161 |
load them::
|
@@ -190,6 +193,18 @@ Namespaced templates can be accessed via the special
|
|
190 |
|
191 |
$twig->render('@admin/index.html', array());
|
192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
``Twig_Loader_Array``
|
194 |
.....................
|
195 |
|
@@ -256,6 +271,8 @@ All loaders implement the ``Twig_LoaderInterface``::
|
|
256 |
* @param string $name string The name of the template to load
|
257 |
*
|
258 |
* @return string The template source code
|
|
|
|
|
259 |
*/
|
260 |
function getSource($name);
|
261 |
|
@@ -280,6 +297,11 @@ All loaders implement the ``Twig_LoaderInterface``::
|
|
280 |
The ``isFresh()`` method must return ``true`` if the current cached template
|
281 |
is still fresh, given the last modification time, or ``false`` otherwise.
|
282 |
|
|
|
|
|
|
|
|
|
|
|
283 |
.. tip::
|
284 |
|
285 |
As of Twig 1.11.0, you can also implement ``Twig_ExistsLoaderInterface``
|
115 |
``false`` to disable).
|
116 |
|
117 |
As of Twig 1.9, you can set the escaping strategy to use (``css``, ``url``,
|
118 |
+
``html_attr``, or a PHP callback that takes the template name and must
|
119 |
return the escaping strategy to use -- the callback cannot be a function name
|
120 |
to avoid collision with built-in escaping strategies).
|
121 |
|
122 |
+
As of Twig 1.17, the ``filename`` escaping strategy (renamed to ``name`` as
|
123 |
+
of Twig 1.27) determines the escaping strategy to use for a template based on
|
124 |
+
the template filename extension (this strategy does not incur any overhead at
|
125 |
+
runtime as auto-escaping is done at compilation time.)
|
126 |
|
127 |
* ``optimizations`` *integer*
|
128 |
|
156 |
.. versionadded:: 1.10
|
157 |
The ``prependPath()`` and support for namespaces were added in Twig 1.10.
|
158 |
|
159 |
+
.. versionadded:: 1.27
|
160 |
+
Relative paths support was added in Twig 1.27.
|
161 |
+
|
162 |
``Twig_Loader_Filesystem`` loads templates from the file system. This loader
|
163 |
can find templates in folders on the file system and is the preferred way to
|
164 |
load them::
|
193 |
|
194 |
$twig->render('@admin/index.html', array());
|
195 |
|
196 |
+
``Twig_Loader_Filesystem`` support absolute and relative paths. Using relative
|
197 |
+
paths is preferred as it makes the cache keys independent of the project root
|
198 |
+
directory (for instance, it allows warming the cache from a build server where
|
199 |
+
the directory might be different from the one used on production servers)::
|
200 |
+
|
201 |
+
$loader = new Twig_Loader_Filesystem('templates', getcwd().'/..');
|
202 |
+
|
203 |
+
.. note::
|
204 |
+
|
205 |
+
When not passing the root path as a second argument, Twig uses ``getcwd()``
|
206 |
+
for relative paths.
|
207 |
+
|
208 |
``Twig_Loader_Array``
|
209 |
.....................
|
210 |
|
271 |
* @param string $name string The name of the template to load
|
272 |
*
|
273 |
* @return string The template source code
|
274 |
+
*
|
275 |
+
* @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface
|
276 |
*/
|
277 |
function getSource($name);
|
278 |
|
297 |
The ``isFresh()`` method must return ``true`` if the current cached template
|
298 |
is still fresh, given the last modification time, or ``false`` otherwise.
|
299 |
|
300 |
+
.. note::
|
301 |
+
|
302 |
+
As of Twig 1.27, you should also implement
|
303 |
+
``Twig_SourceContextLoaderInterface`` to avoid deprecation notices.
|
304 |
+
|
305 |
.. tip::
|
306 |
|
307 |
As of Twig 1.11.0, you can also implement ``Twig_ExistsLoaderInterface``
|
vendor/twig/twig/doc/deprecated.rst
CHANGED
@@ -20,6 +20,11 @@ Token Parsers
|
|
20 |
* ``Twig_TokenParserBrokerInterface``
|
21 |
* ``Twig_TokenParserBroker``
|
22 |
|
|
|
|
|
|
|
|
|
|
|
23 |
Extensions
|
24 |
----------
|
25 |
|
@@ -37,6 +42,9 @@ Extensions
|
|
37 |
deprecated. Implement ``Twig_Extension_GlobalsInterface`` to avoid
|
38 |
deprecation notices.
|
39 |
|
|
|
|
|
|
|
40 |
PEAR
|
41 |
----
|
42 |
|
@@ -109,6 +117,17 @@ Nodes
|
|
109 |
* As of Twig 1.x, ``Node::toXml()`` is deprecated and will be removed in Twig
|
110 |
2.0.
|
111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
Interfaces
|
113 |
----------
|
114 |
|
@@ -120,16 +139,30 @@ Interfaces
|
|
120 |
* ``Twig_NodeInterface`` (use ``Twig_Node`` instead)
|
121 |
* ``Twig_ParserInterface`` (use ``Twig_Parser`` instead)
|
122 |
* ``Twig_ExistsLoaderInterface`` (merged with ``Twig_LoaderInterface``)
|
|
|
123 |
* ``Twig_TemplateInterface`` (use ``Twig_Template`` instead, and use
|
124 |
those constants Twig_Template::ANY_CALL, Twig_Template::ARRAY_CALL,
|
125 |
Twig_Template::METHOD_CALL)
|
126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
Loaders
|
128 |
-------
|
129 |
|
130 |
* As of Twig 1.x, ``Twig_Loader_String`` is deprecated and will be removed in
|
131 |
2.0. You can render a string via ``Twig_Environment::createTemplate()``.
|
132 |
|
|
|
|
|
|
|
|
|
133 |
Node Visitors
|
134 |
-------------
|
135 |
|
@@ -153,10 +186,25 @@ Globals
|
|
153 |
Miscellaneous
|
154 |
-------------
|
155 |
|
156 |
-
* As of Twig 1.x, ``Twig_Environment::clearTemplateCache()``,
|
157 |
-
``Twig_Environment::
|
158 |
-
``Twig_Environment::
|
|
|
|
|
|
|
|
|
159 |
|
160 |
* As of Twig 1.x, ``Twig_Template::getEnvironment()`` and
|
161 |
``Twig_TemplateInterface::getEnvironment()`` are deprecated and will be
|
162 |
removed in 2.0.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
* ``Twig_TokenParserBrokerInterface``
|
21 |
* ``Twig_TokenParserBroker``
|
22 |
|
23 |
+
* As of Twig 1.27, ``Twig_Parser::getFilename()`` is deprecated. From a token
|
24 |
+
parser, use ``$this->parser->getStream()->getSourceContext()->getPath()`` instead.
|
25 |
+
|
26 |
+
* As of Twig 1.27, ``Twig_Parser::getEnvironment()`` is deprecated.
|
27 |
+
|
28 |
Extensions
|
29 |
----------
|
30 |
|
42 |
deprecated. Implement ``Twig_Extension_GlobalsInterface`` to avoid
|
43 |
deprecation notices.
|
44 |
|
45 |
+
* As of Twig 1.26, the ``Twig_ExtensionInterface::getName()`` method is
|
46 |
+
deprecated and it is not used internally anymore.
|
47 |
+
|
48 |
PEAR
|
49 |
----
|
50 |
|
117 |
* As of Twig 1.x, ``Node::toXml()`` is deprecated and will be removed in Twig
|
118 |
2.0.
|
119 |
|
120 |
+
* As of Twig 1.26, ``Node::$nodes`` should only contains ``Twig_Node``
|
121 |
+
instances, storing a ``null`` value is deprecated and won't be possible in
|
122 |
+
Twig 2.x.
|
123 |
+
|
124 |
+
* As of Twig 1.27, the ``filename`` attribute on ``Twig_Node_Module`` is
|
125 |
+
deprecated. Use ``getName()`` instead.
|
126 |
+
|
127 |
+
* As of Twig 1.27, the ``Twig_Node::getFilename()/Twig_Node::getLine()``
|
128 |
+
methods are deprecated, use
|
129 |
+
``Twig_Node::getTemplateName()/Twig_Node::getTemplateLine()`` instead.
|
130 |
+
|
131 |
Interfaces
|
132 |
----------
|
133 |
|
139 |
* ``Twig_NodeInterface`` (use ``Twig_Node`` instead)
|
140 |
* ``Twig_ParserInterface`` (use ``Twig_Parser`` instead)
|
141 |
* ``Twig_ExistsLoaderInterface`` (merged with ``Twig_LoaderInterface``)
|
142 |
+
* ``Twig_SourceContextLoaderInterface`` (merged with ``Twig_LoaderInterface``)
|
143 |
* ``Twig_TemplateInterface`` (use ``Twig_Template`` instead, and use
|
144 |
those constants Twig_Template::ANY_CALL, Twig_Template::ARRAY_CALL,
|
145 |
Twig_Template::METHOD_CALL)
|
146 |
|
147 |
+
Compiler
|
148 |
+
--------
|
149 |
+
|
150 |
+
* As of Twig 1.26, the ``Twig_Compiler::getFilename()`` has been deprecated.
|
151 |
+
You should not use it anyway as its values is not reliable.
|
152 |
+
|
153 |
+
* As of Twig 1.27, the ``Twig_Compiler::addIndentation()`` has been deprecated.
|
154 |
+
Use ``Twig_Compiler::write('')`` instead.
|
155 |
+
|
156 |
Loaders
|
157 |
-------
|
158 |
|
159 |
* As of Twig 1.x, ``Twig_Loader_String`` is deprecated and will be removed in
|
160 |
2.0. You can render a string via ``Twig_Environment::createTemplate()``.
|
161 |
|
162 |
+
* As of Twig 1.27, ``Twig_LoaderInterface::getSource()`` is deprecated.
|
163 |
+
Implement ``Twig_SourceContextLoaderInterface`` instead and use
|
164 |
+
``getSourceContext()``.
|
165 |
+
|
166 |
Node Visitors
|
167 |
-------------
|
168 |
|
186 |
Miscellaneous
|
187 |
-------------
|
188 |
|
189 |
+
* As of Twig 1.x, ``Twig_Environment::clearTemplateCache()``,
|
190 |
+
``Twig_Environment::writeCacheFile()``,
|
191 |
+
``Twig_Environment::clearCacheFiles()``,
|
192 |
+
``Twig_Environment::getCacheFilename()``,
|
193 |
+
``Twig_Environment::getTemplateClassPrefix()``,
|
194 |
+
``Twig_Environment::getLexer()``, ``Twig_Environment::getParser()``, and
|
195 |
+
``Twig_Environment::getCompiler()`` are deprecated and will be removed in 2.0.
|
196 |
|
197 |
* As of Twig 1.x, ``Twig_Template::getEnvironment()`` and
|
198 |
``Twig_TemplateInterface::getEnvironment()`` are deprecated and will be
|
199 |
removed in 2.0.
|
200 |
+
|
201 |
+
* As of Twig 1.27, ``Twig_Error::getTemplateFile()`` and
|
202 |
+
``Twig_Error::setTemplateFile()`` are deprecated. Use
|
203 |
+
``Twig_Error::getTemplateName()`` and ``Twig_Error::setTemplateName()``
|
204 |
+
instead.
|
205 |
+
|
206 |
+
* As of Twig 1.27, ``Twig_Template::getSource()`` is deprecated. Use
|
207 |
+
``Twig_Template::getSourceContext()`` instead.
|
208 |
+
|
209 |
+
* As of Twig 1.27, ``Twig_Parser::addHandler()`` and
|
210 |
+
``Twig_Parser::addNodeVisitor()`` are deprecated and will be removed in 2.0.
|
vendor/twig/twig/doc/filters/date.rst
CHANGED
@@ -54,6 +54,9 @@ dates and the second one is the default format for date intervals:
|
|
54 |
.. code-block:: php
|
55 |
|
56 |
$twig = new Twig_Environment($loader);
|
|
|
|
|
|
|
57 |
$twig->getExtension('core')->setDateFormat('d/m/Y', '%d days');
|
58 |
|
59 |
Timezone
|
@@ -79,6 +82,9 @@ The default timezone can also be set globally by calling ``setTimezone()``:
|
|
79 |
.. code-block:: php
|
80 |
|
81 |
$twig = new Twig_Environment($loader);
|
|
|
|
|
|
|
82 |
$twig->getExtension('core')->setTimezone('Europe/Paris');
|
83 |
|
84 |
Arguments
|
54 |
.. code-block:: php
|
55 |
|
56 |
$twig = new Twig_Environment($loader);
|
57 |
+
$twig->getExtension('Twig_Extension_Core')->setDateFormat('d/m/Y', '%d days');
|
58 |
+
|
59 |
+
// before Twig 1.26
|
60 |
$twig->getExtension('core')->setDateFormat('d/m/Y', '%d days');
|
61 |
|
62 |
Timezone
|
82 |
.. code-block:: php
|
83 |
|
84 |
$twig = new Twig_Environment($loader);
|
85 |
+
$twig->getExtension('Twig_Extension_Core')->setTimezone('Europe/Paris');
|
86 |
+
|
87 |
+
// before Twig 1.26
|
88 |
$twig->getExtension('core')->setTimezone('Europe/Paris');
|
89 |
|
90 |
Arguments
|
vendor/twig/twig/doc/filters/escape.rst
CHANGED
@@ -97,6 +97,9 @@ used in the ``escape`` call) and the second one must be a valid PHP callable:
|
|
97 |
.. code-block:: php
|
98 |
|
99 |
$twig = new Twig_Environment($loader);
|
|
|
|
|
|
|
100 |
$twig->getExtension('core')->setEscaper('csv', 'csv_escaper');
|
101 |
|
102 |
When called by Twig, the callable receives the Twig environment instance, the
|
97 |
.. code-block:: php
|
98 |
|
99 |
$twig = new Twig_Environment($loader);
|
100 |
+
$twig->getExtension('Twig_Extension_Core')->setEscaper('csv', 'csv_escaper');
|
101 |
+
|
102 |
+
// before Twig 1.26
|
103 |
$twig->getExtension('core')->setEscaper('csv', 'csv_escaper');
|
104 |
|
105 |
When called by Twig, the callable receives the Twig environment instance, the
|
vendor/twig/twig/doc/filters/number_format.rst
CHANGED
@@ -30,6 +30,9 @@ These defaults can be easily changed through the core extension:
|
|
30 |
.. code-block:: php
|
31 |
|
32 |
$twig = new Twig_Environment($loader);
|
|
|
|
|
|
|
33 |
$twig->getExtension('core')->setNumberFormat(3, '.', ',');
|
34 |
|
35 |
The defaults set for ``number_format`` can be over-ridden upon each call using the
|
30 |
.. code-block:: php
|
31 |
|
32 |
$twig = new Twig_Environment($loader);
|
33 |
+
$twig->getExtension('Twig_Extension_Core')->setNumberFormat(3, '.', ',');
|
34 |
+
|
35 |
+
// before Twig 1.26
|
36 |
$twig->getExtension('core')->setNumberFormat(3, '.', ',');
|
37 |
|
38 |
The defaults set for ``number_format`` can be over-ridden upon each call using the
|
vendor/twig/twig/doc/functions/date.rst
CHANGED
@@ -41,6 +41,9 @@ If no argument is passed, the function returns the current date:
|
|
41 |
.. code-block:: php
|
42 |
|
43 |
$twig = new Twig_Environment($loader);
|
|
|
|
|
|
|
44 |
$twig->getExtension('core')->setTimezone('Europe/Paris');
|
45 |
|
46 |
Arguments
|
41 |
.. code-block:: php
|
42 |
|
43 |
$twig = new Twig_Environment($loader);
|
44 |
+
$twig->getExtension('Twig_Extension_Core')->setTimezone('Europe/Paris');
|
45 |
+
|
46 |
+
// before Twig 1.26
|
47 |
$twig->getExtension('core')->setTimezone('Europe/Paris');
|
48 |
|
49 |
Arguments
|
vendor/twig/twig/doc/internals.rst
CHANGED
@@ -44,7 +44,11 @@ an instance of ``Twig_Token``, and the stream is an instance of
|
|
44 |
You can manually convert a source code into a token stream by calling the
|
45 |
``tokenize()`` method of an environment::
|
46 |
|
47 |
-
$stream = $twig->tokenize($source, $identifier);
|
|
|
|
|
|
|
|
|
48 |
|
49 |
As the stream has a ``__toString()`` method, you can have a textual
|
50 |
representation of it by echoing the object::
|
44 |
You can manually convert a source code into a token stream by calling the
|
45 |
``tokenize()`` method of an environment::
|
46 |
|
47 |
+
$stream = $twig->tokenize(new Twig_Source($source, $identifier));
|
48 |
+
|
49 |
+
.. versionadded:: 1.27
|
50 |
+
``Twig_Source`` was introduced in version 1.27, pass the source and the
|
51 |
+
identifier directly on previous versions.
|
52 |
|
53 |
As the stream has a ``__toString()`` method, you can have a textual
|
54 |
representation of it by echoing the object::
|
vendor/twig/twig/doc/recipes.rst
CHANGED
@@ -306,7 +306,7 @@ saving it. If the template code is stored in a `$template` variable, here is
|
|
306 |
how you can do it::
|
307 |
|
308 |
try {
|
309 |
-
$twig->parse($twig->tokenize($template));
|
310 |
|
311 |
// the $template is valid
|
312 |
} catch (Twig_Error_Syntax $e) {
|
@@ -318,7 +318,7 @@ If you iterate over a set of files, you can pass the filename to the
|
|
318 |
|
319 |
foreach ($files as $file) {
|
320 |
try {
|
321 |
-
$twig->parse($twig->tokenize($template, $file));
|
322 |
|
323 |
// the $template is valid
|
324 |
} catch (Twig_Error_Syntax $e) {
|
@@ -326,6 +326,10 @@ If you iterate over a set of files, you can pass the filename to the
|
|
326 |
}
|
327 |
}
|
328 |
|
|
|
|
|
|
|
|
|
329 |
.. note::
|
330 |
|
331 |
This method won't catch any sandbox policy violations because the policy
|
@@ -413,7 +417,7 @@ We have created a simple ``templates`` table that hosts two templates:
|
|
413 |
|
414 |
Now, let's define a loader able to use this database::
|
415 |
|
416 |
-
class DatabaseTwigLoader implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
|
417 |
{
|
418 |
protected $dbh;
|
419 |
|
@@ -431,6 +435,16 @@ Now, let's define a loader able to use this database::
|
|
431 |
return $source;
|
432 |
}
|
433 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
434 |
// Twig_ExistsLoaderInterface as of Twig 1.11
|
435 |
public function exists($name)
|
436 |
{
|
@@ -515,4 +529,40 @@ From PHP, it's also possible to load a template stored in a string via
|
|
515 |
|
516 |
Never use the ``Twig_Loader_String`` loader, which has severe limitations.
|
517 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
518 |
.. _callback: http://www.php.net/manual/en/function.is-callable.php
|
306 |
how you can do it::
|
307 |
|
308 |
try {
|
309 |
+
$twig->parse($twig->tokenize(new Twig_Source($template)));
|
310 |
|
311 |
// the $template is valid
|
312 |
} catch (Twig_Error_Syntax $e) {
|
318 |
|
319 |
foreach ($files as $file) {
|
320 |
try {
|
321 |
+
$twig->parse($twig->tokenize(new Twig_Source($template, $file->getFilename(), $file)));
|
322 |
|
323 |
// the $template is valid
|
324 |
} catch (Twig_Error_Syntax $e) {
|
326 |
}
|
327 |
}
|
328 |
|
329 |
+
.. versionadded:: 1.27
|
330 |
+
``Twig_Source`` was introduced in version 1.27, pass the source and the
|
331 |
+
identifier directly on previous versions.
|
332 |
+
|
333 |
.. note::
|
334 |
|
335 |
This method won't catch any sandbox policy violations because the policy
|
417 |
|
418 |
Now, let's define a loader able to use this database::
|
419 |
|
420 |
+
class DatabaseTwigLoader implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
|
421 |
{
|
422 |
protected $dbh;
|
423 |
|
435 |
return $source;
|
436 |
}
|
437 |
|
438 |
+
// Twig_SourceContextLoaderInterface as of Twig 1.27
|
439 |
+
public function getSourceContext($name)
|
440 |
+
{
|
441 |
+
if (false === $source = $this->getValue('source', $name)) {
|
442 |
+
throw new Twig_Error_Loader(sprintf('Template "%s" does not exist.', $name));
|
443 |
+
}
|
444 |
+
|
445 |
+
return new Twig_Source($source, $name);
|
446 |
+
}
|
447 |
+
|
448 |
// Twig_ExistsLoaderInterface as of Twig 1.11
|
449 |
public function exists($name)
|
450 |
{
|
529 |
|
530 |
Never use the ``Twig_Loader_String`` loader, which has severe limitations.
|
531 |
|
532 |
+
Using Twig and AngularJS in the same Templates
|
533 |
+
----------------------------------------------
|
534 |
+
|
535 |
+
Mixing different template syntaxes in the same file is not a recommended
|
536 |
+
practice as both AngularJS and Twig use the same delimiters in their syntax:
|
537 |
+
``{{`` and ``}}``.
|
538 |
+
|
539 |
+
Still, if you want to use AngularJS and Twig in the same template, there are
|
540 |
+
two ways to make it work depending on the amount of AngularJS you need to
|
541 |
+
include in your templates:
|
542 |
+
|
543 |
+
* Escaping the AngularJS delimiters by wrapping AngularJS sections with the
|
544 |
+
``{% verbatim %}`` tag or by escaping each delimiter via ``{{ '{{' }}`` and
|
545 |
+
``{{ '}}' }}``;
|
546 |
+
|
547 |
+
* Changing the delimiters of one of the template engines (depending on which
|
548 |
+
engine you introduced last):
|
549 |
+
|
550 |
+
* For AngularJS, change the interpolation tags using the
|
551 |
+
``interpolateProvider`` service, for instance at the module initialization
|
552 |
+
time:
|
553 |
+
|
554 |
+
```js
|
555 |
+
angular.module('myApp', []).config(function($interpolateProvider) {
|
556 |
+
$interpolateProvider.startSymbol('{[').endSymbol(']}');
|
557 |
+
});
|
558 |
+
```
|
559 |
+
|
560 |
+
* For Twig, change the delimiters via the ``tag_variable`` Lexer option:
|
561 |
+
|
562 |
+
```php
|
563 |
+
$env->setLexer(new Twig_Lexer($env, array(
|
564 |
+
'tag_variable' => array('{[', ']}'),
|
565 |
+
)));
|
566 |
+
```
|
567 |
+
|
568 |
.. _callback: http://www.php.net/manual/en/function.is-callable.php
|
vendor/twig/twig/doc/tags/embed.rst
CHANGED
@@ -170,9 +170,9 @@ The ``embed`` tag takes the exact same arguments as the ``include`` tag:
|
|
170 |
.. warning::
|
171 |
|
172 |
As embedded templates do not have "names", auto-escaping strategies based
|
173 |
-
on the template
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
|
178 |
.. seealso:: :doc:`include<../tags/include>`
|
170 |
.. warning::
|
171 |
|
172 |
As embedded templates do not have "names", auto-escaping strategies based
|
173 |
+
on the template name won't work as expected if you change the context (for
|
174 |
+
instance, if you embed a CSS/JavaScript template into an HTML one). In that
|
175 |
+
case, explicitly set the default auto-escaping strategy with the
|
176 |
+
``autoescape`` tag.
|
177 |
|
178 |
.. seealso:: :doc:`include<../tags/include>`
|
vendor/twig/twig/doc/tests/empty.rst
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
``empty``
|
2 |
=========
|
3 |
|
4 |
-
``empty`` checks if a variable is empty
|
|
|
5 |
|
6 |
.. code-block:: jinja
|
7 |
|
8 |
-
{# evaluates to true if the foo variable is null, false, an empty array, or the empty string #}
|
9 |
{% if foo is empty %}
|
10 |
...
|
11 |
{% endif %}
|
1 |
``empty``
|
2 |
=========
|
3 |
|
4 |
+
``empty`` checks if a variable is an empty string, an empty array, an empty
|
5 |
+
hash, exactly ``false``, or exactly ``null``:
|
6 |
|
7 |
.. code-block:: jinja
|
8 |
|
|
|
9 |
{% if foo is empty %}
|
10 |
...
|
11 |
{% endif %}
|
vendor/twig/twig/ext/twig/php_twig.h
CHANGED
@@ -15,7 +15,7 @@
|
|
15 |
#ifndef PHP_TWIG_H
|
16 |
#define PHP_TWIG_H
|
17 |
|
18 |
-
#define PHP_TWIG_VERSION "1.
|
19 |
|
20 |
#include "php.h"
|
21 |
|
15 |
#ifndef PHP_TWIG_H
|
16 |
#define PHP_TWIG_H
|
17 |
|
18 |
+
#define PHP_TWIG_VERSION "1.27.0"
|
19 |
|
20 |
#include "php.h"
|
21 |
|
vendor/twig/twig/ext/twig/twig.c
CHANGED
@@ -144,7 +144,7 @@ static zval *TWIG_GET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
|
|
144 |
|
145 |
if (!retval) {
|
146 |
if (!EG(exception)) {
|
147 |
-
zend_error(E_ERROR, "Undefined offset for object of type %s used as array", ce->name);
|
148 |
}
|
149 |
return NULL;
|
150 |
}
|
@@ -167,7 +167,7 @@ static int TWIG_ISSET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
|
|
167 |
|
168 |
if (!retval) {
|
169 |
if (!EG(exception)) {
|
170 |
-
zend_error(E_ERROR, "Undefined offset for object of type %s used as array", ce->name);
|
171 |
}
|
172 |
return 0;
|
173 |
}
|
@@ -811,15 +811,15 @@ PHP_FUNCTION(twig_template_get_attributes)
|
|
811 |
}
|
812 |
*/
|
813 |
if (TWIG_INSTANCE_OF(object, zend_ce_arrayaccess TSRMLS_CC)) {
|
814 |
-
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" in object with ArrayAccess of class \"%s\" does not exist", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
|
815 |
} else if (Z_TYPE_P(object) == IS_OBJECT) {
|
816 |
-
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to access a key \"%s\" on an object of class \"%s\" that does not implement ArrayAccess interface", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
|
817 |
} else if (Z_TYPE_P(object) == IS_ARRAY) {
|
818 |
if (0 == zend_hash_num_elements(Z_ARRVAL_P(object))) {
|
819 |
-
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" does not exist as the array is empty", item);
|
820 |
} else {
|
821 |
char *array_keys = TWIG_IMPLODE_ARRAY_KEYS(", ", object TSRMLS_CC);
|
822 |
-
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" for array with keys \"%s\" does not exist", item, array_keys);
|
823 |
efree(array_keys);
|
824 |
}
|
825 |
} else {
|
@@ -829,15 +829,15 @@ PHP_FUNCTION(twig_template_get_attributes)
|
|
829 |
convert_to_string(object);
|
830 |
TWIG_RUNTIME_ERROR(template TSRMLS_CC,
|
831 |
(strcmp("array", type) == 0)
|
832 |
-
? "Impossible to access a key (\"%s\") on a %s variable"
|
833 |
-
: "Impossible to access an attribute (\"%s\") on a %s variable",
|
834 |
item, type_name);
|
835 |
} else {
|
836 |
convert_to_string(object);
|
837 |
TWIG_RUNTIME_ERROR(template TSRMLS_CC,
|
838 |
(strcmp("array", type) == 0)
|
839 |
-
? "Impossible to access a key (\"%s\") on a %s variable (\"%s\")"
|
840 |
-
: "Impossible to access an attribute (\"%s\") on a %s variable (\"%s\")",
|
841 |
item, type_name, Z_STRVAL_P(object));
|
842 |
}
|
843 |
zval_ptr_dtor(&object);
|
@@ -883,11 +883,11 @@ PHP_FUNCTION(twig_template_get_attributes)
|
|
883 |
if (Z_TYPE_P(object) == IS_NULL) {
|
884 |
convert_to_string_ex(&object);
|
885 |
|
886 |
-
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable", item, type_name);
|
887 |
} else {
|
888 |
convert_to_string_ex(&object);
|
889 |
|
890 |
-
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable (\"%s\")", item, type_name, Z_STRVAL_P(object));
|
891 |
}
|
892 |
|
893 |
zval_ptr_dtor(&object);
|
@@ -916,8 +916,8 @@ PHP_FUNCTION(twig_template_get_attributes)
|
|
916 |
return true;
|
917 |
}
|
918 |
|
919 |
-
if ($this->env->hasExtension('
|
920 |
-
$this->env->getExtension('
|
921 |
}
|
922 |
|
923 |
return $object->$item;
|
@@ -935,8 +935,8 @@ PHP_FUNCTION(twig_template_get_attributes)
|
|
935 |
efree(item);
|
936 |
RETURN_TRUE;
|
937 |
}
|
938 |
-
if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "
|
939 |
-
TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "
|
940 |
}
|
941 |
if (EG(exception)) {
|
942 |
efree(item);
|
@@ -1020,7 +1020,7 @@ PHP_FUNCTION(twig_template_get_attributes)
|
|
1020 |
return null;
|
1021 |
}
|
1022 |
|
1023 |
-
throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName());
|
1024 |
}
|
1025 |
|
1026 |
if ($isDefinedTest) {
|
@@ -1040,7 +1040,7 @@ PHP_FUNCTION(twig_template_get_attributes)
|
|
1040 |
efree(item);
|
1041 |
return;
|
1042 |
}
|
1043 |
-
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Neither the property \"%s\" nor one of the methods \"%s()\", \"get%s()\"/\"is%s()\" or \"__call()\" exist and have public access in class \"%s\"", item, item, item, item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
|
1044 |
efree(item);
|
1045 |
return;
|
1046 |
}
|
@@ -1052,14 +1052,14 @@ PHP_FUNCTION(twig_template_get_attributes)
|
|
1052 |
RETURN_TRUE;
|
1053 |
}
|
1054 |
/*
|
1055 |
-
if ($this->env->hasExtension('
|
1056 |
-
$this->env->getExtension('
|
1057 |
}
|
1058 |
*/
|
1059 |
MAKE_STD_ZVAL(zmethod);
|
1060 |
ZVAL_STRING(zmethod, method, 1);
|
1061 |
-
if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "
|
1062 |
-
TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "
|
1063 |
}
|
1064 |
zval_ptr_dtor(&zmethod);
|
1065 |
if (EG(exception)) {
|
144 |
|
145 |
if (!retval) {
|
146 |
if (!EG(exception)) {
|
147 |
+
zend_error(E_ERROR, "Undefined offset for object of type %s used as array.", ce->name);
|
148 |
}
|
149 |
return NULL;
|
150 |
}
|
167 |
|
168 |
if (!retval) {
|
169 |
if (!EG(exception)) {
|
170 |
+
zend_error(E_ERROR, "Undefined offset for object of type %s used as array.", ce->name);
|
171 |
}
|
172 |
return 0;
|
173 |
}
|
811 |
}
|
812 |
*/
|
813 |
if (TWIG_INSTANCE_OF(object, zend_ce_arrayaccess TSRMLS_CC)) {
|
814 |
+
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" in object with ArrayAccess of class \"%s\" does not exist.", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
|
815 |
} else if (Z_TYPE_P(object) == IS_OBJECT) {
|
816 |
+
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to access a key \"%s\" on an object of class \"%s\" that does not implement ArrayAccess interface.", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
|
817 |
} else if (Z_TYPE_P(object) == IS_ARRAY) {
|
818 |
if (0 == zend_hash_num_elements(Z_ARRVAL_P(object))) {
|
819 |
+
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" does not exist as the array is empty.", item);
|
820 |
} else {
|
821 |
char *array_keys = TWIG_IMPLODE_ARRAY_KEYS(", ", object TSRMLS_CC);
|
822 |
+
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" for array with keys \"%s\" does not exist.", item, array_keys);
|
823 |
efree(array_keys);
|
824 |
}
|
825 |
} else {
|
829 |
convert_to_string(object);
|
830 |
TWIG_RUNTIME_ERROR(template TSRMLS_CC,
|
831 |
(strcmp("array", type) == 0)
|
832 |
+
? "Impossible to access a key (\"%s\") on a %s variable."
|
833 |
+
: "Impossible to access an attribute (\"%s\") on a %s variable.",
|
834 |
item, type_name);
|
835 |
} else {
|
836 |
convert_to_string(object);
|
837 |
TWIG_RUNTIME_ERROR(template TSRMLS_CC,
|
838 |
(strcmp("array", type) == 0)
|
839 |
+
? "Impossible to access a key (\"%s\") on a %s variable (\"%s\")."
|
840 |
+
: "Impossible to access an attribute (\"%s\") on a %s variable (\"%s\").",
|
841 |
item, type_name, Z_STRVAL_P(object));
|
842 |
}
|
843 |
zval_ptr_dtor(&object);
|
883 |
if (Z_TYPE_P(object) == IS_NULL) {
|
884 |
convert_to_string_ex(&object);
|
885 |
|
886 |
+
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable.", item, type_name);
|
887 |
} else {
|
888 |
convert_to_string_ex(&object);
|
889 |
|
890 |
+
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable (\"%s\").", item, type_name, Z_STRVAL_P(object));
|
891 |
}
|
892 |
|
893 |
zval_ptr_dtor(&object);
|
916 |
return true;
|
917 |
}
|
918 |
|
919 |
+
if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
|
920 |
+
$this->env->getExtension('Twig_Extension_Sandbox')->checkPropertyAllowed($object, $item);
|
921 |
}
|
922 |
|
923 |
return $object->$item;
|
935 |
efree(item);
|
936 |
RETURN_TRUE;
|
937 |
}
|
938 |
+
if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "Twig_Extension_Sandbox" TSRMLS_CC)) {
|
939 |
+
TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "Twig_Extension_Sandbox" TSRMLS_CC), "checkPropertyAllowed", object, zitem TSRMLS_CC);
|
940 |
}
|
941 |
if (EG(exception)) {
|
942 |
efree(item);
|
1020 |
return null;
|
1021 |
}
|
1022 |
|
1023 |
+
throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist.', $item, get_class($object)), -1, $this->getTemplateName());
|
1024 |
}
|
1025 |
|
1026 |
if ($isDefinedTest) {
|
1040 |
efree(item);
|
1041 |
return;
|
1042 |
}
|
1043 |
+
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Neither the property \"%s\" nor one of the methods \"%s()\", \"get%s()\"/\"is%s()\" or \"__call()\" exist and have public access in class \"%s\".", item, item, item, item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
|
1044 |
efree(item);
|
1045 |
return;
|
1046 |
}
|
1052 |
RETURN_TRUE;
|
1053 |
}
|
1054 |
/*
|
1055 |
+
if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
|
1056 |
+
$this->env->getExtension('Twig_Extension_Sandbox')->checkMethodAllowed($object, $method);
|
1057 |
}
|
1058 |
*/
|
1059 |
MAKE_STD_ZVAL(zmethod);
|
1060 |
ZVAL_STRING(zmethod, method, 1);
|
1061 |
+
if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "Twig_Extension_Sandbox" TSRMLS_CC)) {
|
1062 |
+
TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "Twig_Extension_Sandbox" TSRMLS_CC), "checkMethodAllowed", object, zmethod TSRMLS_CC);
|
1063 |
}
|
1064 |
zval_ptr_dtor(&zmethod);
|
1065 |
if (EG(exception)) {
|
vendor/twig/twig/lib/Twig/Compiler.php
CHANGED
@@ -36,8 +36,13 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|
36 |
$this->env = $env;
|
37 |
}
|
38 |
|
|
|
|
|
|
|
39 |
public function getFilename()
|
40 |
{
|
|
|
|
|
41 |
return $this->filename;
|
42 |
}
|
43 |
|
@@ -80,7 +85,8 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|
80 |
$this->indentation = $indentation;
|
81 |
|
82 |
if ($node instanceof Twig_Node_Module) {
|
83 |
-
|
|
|
84 |
}
|
85 |
|
86 |
$node->compile($this);
|
@@ -91,7 +97,7 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|
91 |
public function subcompile(Twig_NodeInterface $node, $raw = true)
|
92 |
{
|
93 |
if (false === $raw) {
|
94 |
-
$this->
|
95 |
}
|
96 |
|
97 |
$node->compile($this);
|
@@ -122,8 +128,7 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|
122 |
{
|
123 |
$strings = func_get_args();
|
124 |
foreach ($strings as $string) {
|
125 |
-
$this->
|
126 |
-
$this->source .= $string;
|
127 |
}
|
128 |
|
129 |
return $this;
|
@@ -133,9 +138,13 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|
133 |
* Appends an indentation to the current PHP code after compilation.
|
134 |
*
|
135 |
* @return Twig_Compiler The current compiler instance
|
|
|
|
|
136 |
*/
|
137 |
public function addIndentation()
|
138 |
{
|
|
|
|
|
139 |
$this->source .= str_repeat(' ', $this->indentation * 4);
|
140 |
|
141 |
return $this;
|
@@ -207,8 +216,8 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|
207 |
*/
|
208 |
public function addDebugInfo(Twig_NodeInterface $node)
|
209 |
{
|
210 |
-
if ($node->
|
211 |
-
$this->write(sprintf("// line %d\n", $node->
|
212 |
|
213 |
// when mbstring.func_overload is set to 2
|
214 |
// mb_substr_count() replaces substr_count()
|
@@ -220,9 +229,9 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|
220 |
$this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
|
221 |
}
|
222 |
$this->sourceOffset = strlen($this->source);
|
223 |
-
$this->debugInfo[$this->sourceLine] = $node->
|
224 |
|
225 |
-
$this->lastLine = $node->
|
226 |
}
|
227 |
|
228 |
return $this;
|
@@ -262,7 +271,7 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|
262 |
{
|
263 |
// can't outdent by more steps than the current indentation level
|
264 |
if ($this->indentation < $step) {
|
265 |
-
throw new LogicException('Unable to call outdent() as the indentation would become negative');
|
266 |
}
|
267 |
|
268 |
$this->indentation -= $step;
|
36 |
$this->env = $env;
|
37 |
}
|
38 |
|
39 |
+
/**
|
40 |
+
* @deprecated since 1.25 (to be removed in 2.0)
|
41 |
+
*/
|
42 |
public function getFilename()
|
43 |
{
|
44 |
+
@trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
|
45 |
+
|
46 |
return $this->filename;
|
47 |
}
|
48 |
|
85 |
$this->indentation = $indentation;
|
86 |
|
87 |
if ($node instanceof Twig_Node_Module) {
|
88 |
+
// to be removed in 2.0
|
89 |
+
$this->filename = $node->getTemplateName();
|
90 |
}
|
91 |
|
92 |
$node->compile($this);
|
97 |
public function subcompile(Twig_NodeInterface $node, $raw = true)
|
98 |
{
|
99 |
if (false === $raw) {
|
100 |
+
$this->source .= str_repeat(' ', $this->indentation * 4);
|
101 |
}
|
102 |
|
103 |
$node->compile($this);
|
128 |
{
|
129 |
$strings = func_get_args();
|
130 |
foreach ($strings as $string) {
|
131 |
+
$this->source .= str_repeat(' ', $this->indentation * 4).$string;
|
|
|
132 |
}
|
133 |
|
134 |
return $this;
|
138 |
* Appends an indentation to the current PHP code after compilation.
|
139 |
*
|
140 |
* @return Twig_Compiler The current compiler instance
|
141 |
+
*
|
142 |
+
* @deprecated since 1.27 (to be removed in 2.0).
|
143 |
*/
|
144 |
public function addIndentation()
|
145 |
{
|
146 |
+
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use write(\'\') instead.', E_USER_DEPRECATED);
|
147 |
+
|
148 |
$this->source .= str_repeat(' ', $this->indentation * 4);
|
149 |
|
150 |
return $this;
|
216 |
*/
|
217 |
public function addDebugInfo(Twig_NodeInterface $node)
|
218 |
{
|
219 |
+
if ($node->getTemplateLine() != $this->lastLine) {
|
220 |
+
$this->write(sprintf("// line %d\n", $node->getTemplateLine()));
|
221 |
|
222 |
// when mbstring.func_overload is set to 2
|
223 |
// mb_substr_count() replaces substr_count()
|
229 |
$this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
|
230 |
}
|
231 |
$this->sourceOffset = strlen($this->source);
|
232 |
+
$this->debugInfo[$this->sourceLine] = $node->getTemplateLine();
|
233 |
|
234 |
+
$this->lastLine = $node->getTemplateLine();
|
235 |
}
|
236 |
|
237 |
return $this;
|
271 |
{
|
272 |
// can't outdent by more steps than the current indentation level
|
273 |
if ($this->indentation < $step) {
|
274 |
+
throw new LogicException('Unable to call outdent() as the indentation would become negative.');
|
275 |
}
|
276 |
|
277 |
$this->indentation -= $step;
|
vendor/twig/twig/lib/Twig/Environment.php
CHANGED
@@ -16,7 +16,7 @@
|
|
16 |
*/
|
17 |
class Twig_Environment
|
18 |
{
|
19 |
-
const VERSION = '1.
|
20 |
|
21 |
protected $charset;
|
22 |
protected $loader;
|
@@ -49,6 +49,10 @@ class Twig_Environment
|
|
49 |
private $bcWriteCacheFile = false;
|
50 |
private $bcGetCacheFilename = false;
|
51 |
private $lastModifiedExtension = 0;
|
|
|
|
|
|
|
|
|
52 |
|
53 |
/**
|
54 |
* Constructor.
|
@@ -78,8 +82,8 @@ class Twig_Environment
|
|
78 |
* * false: disable auto-escaping
|
79 |
* * true: equivalent to html
|
80 |
* * html, js: set the autoescaping to one of the supported strategies
|
81 |
-
* *
|
82 |
-
* * PHP callback: a PHP callback that returns an escaping strategy based on the template "
|
83 |
*
|
84 |
* * optimizations: A flag that indicates which optimizations to apply
|
85 |
* (default to -1 which means that all optimizations are enabled;
|
@@ -155,6 +159,7 @@ class Twig_Environment
|
|
155 |
public function setBaseTemplateClass($class)
|
156 |
{
|
157 |
$this->baseTemplateClass = $class;
|
|
|
158 |
}
|
159 |
|
160 |
/**
|
@@ -163,6 +168,7 @@ class Twig_Environment
|
|
163 |
public function enableDebug()
|
164 |
{
|
165 |
$this->debug = true;
|
|
|
166 |
}
|
167 |
|
168 |
/**
|
@@ -171,6 +177,7 @@ class Twig_Environment
|
|
171 |
public function disableDebug()
|
172 |
{
|
173 |
$this->debug = false;
|
|
|
174 |
}
|
175 |
|
176 |
/**
|
@@ -215,6 +222,7 @@ class Twig_Environment
|
|
215 |
public function enableStrictVariables()
|
216 |
{
|
217 |
$this->strictVariables = true;
|
|
|
218 |
}
|
219 |
|
220 |
/**
|
@@ -223,6 +231,7 @@ class Twig_Environment
|
|
223 |
public function disableStrictVariables()
|
224 |
{
|
225 |
$this->strictVariables = false;
|
|
|
226 |
}
|
227 |
|
228 |
/**
|
@@ -300,7 +309,10 @@ class Twig_Environment
|
|
300 |
*
|
301 |
* * The cache key for the given template;
|
302 |
* * The currently enabled extensions;
|
303 |
-
* * Whether the Twig C extension is available or not
|
|
|
|
|
|
|
304 |
*
|
305 |
* @param string $name The name for which to calculate the template class name
|
306 |
* @param int|null $index The index if it is an embedded template
|
@@ -309,9 +321,7 @@ class Twig_Environment
|
|
309 |
*/
|
310 |
public function getTemplateClass($name, $index = null)
|
311 |
{
|
312 |
-
$key = $this->getLoader()->getCacheKey($name);
|
313 |
-
$key .= json_encode(array_keys($this->extensions));
|
314 |
-
$key .= function_exists('twig_template_get_attributes');
|
315 |
|
316 |
return $this->templateClassPrefix.hash('sha256', $key).(null === $index ? '' : '_'.$index);
|
317 |
}
|
@@ -393,7 +403,15 @@ class Twig_Environment
|
|
393 |
}
|
394 |
|
395 |
if (!class_exists($cls, false)) {
|
396 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
397 |
if ($this->bcWriteCacheFile) {
|
398 |
$this->writeCacheFile($key, $content);
|
399 |
} else {
|
@@ -546,9 +564,13 @@ class Twig_Environment
|
|
546 |
* Gets the Lexer instance.
|
547 |
*
|
548 |
* @return Twig_LexerInterface A Twig_LexerInterface instance
|
|
|
|
|
549 |
*/
|
550 |
public function getLexer()
|
551 |
{
|
|
|
|
|
552 |
if (null === $this->lexer) {
|
553 |
$this->lexer = new Twig_Lexer($this);
|
554 |
}
|
@@ -569,8 +591,8 @@ class Twig_Environment
|
|
569 |
/**
|
570 |
* Tokenizes a source code.
|
571 |
*
|
572 |
-
* @param string $source The template source code
|
573 |
-
* @param string
|
574 |
*
|
575 |
* @return Twig_TokenStream A Twig_TokenStream instance
|
576 |
*
|
@@ -578,16 +600,29 @@ class Twig_Environment
|
|
578 |
*/
|
579 |
public function tokenize($source, $name = null)
|
580 |
{
|
581 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
582 |
}
|
583 |
|
584 |
/**
|
585 |
* Gets the Parser instance.
|
586 |
*
|
587 |
* @return Twig_ParserInterface A Twig_ParserInterface instance
|
|
|
|
|
588 |
*/
|
589 |
public function getParser()
|
590 |
{
|
|
|
|
|
591 |
if (null === $this->parser) {
|
592 |
$this->parser = new Twig_Parser($this);
|
593 |
}
|
@@ -616,16 +651,24 @@ class Twig_Environment
|
|
616 |
*/
|
617 |
public function parse(Twig_TokenStream $stream)
|
618 |
{
|
619 |
-
|
|
|
|
|
|
|
|
|
620 |
}
|
621 |
|
622 |
/**
|
623 |
* Gets the Compiler instance.
|
624 |
*
|
625 |
* @return Twig_CompilerInterface A Twig_CompilerInterface instance
|
|
|
|
|
626 |
*/
|
627 |
public function getCompiler()
|
628 |
{
|
|
|
|
|
629 |
if (null === $this->compiler) {
|
630 |
$this->compiler = new Twig_Compiler($this);
|
631 |
}
|
@@ -652,14 +695,18 @@ class Twig_Environment
|
|
652 |
*/
|
653 |
public function compile(Twig_NodeInterface $node)
|
654 |
{
|
655 |
-
|
|
|
|
|
|
|
|
|
656 |
}
|
657 |
|
658 |
/**
|
659 |
* Compiles a template source code.
|
660 |
*
|
661 |
-
* @param string $source The template source code
|
662 |
-
* @param string
|
663 |
*
|
664 |
* @return string The compiled PHP source code
|
665 |
*
|
@@ -667,19 +714,18 @@ class Twig_Environment
|
|
667 |
*/
|
668 |
public function compileSource($source, $name = null)
|
669 |
{
|
670 |
-
|
671 |
-
$
|
672 |
-
|
673 |
-
|
674 |
-
$compiled .= '/* '.str_replace(array('*/', "\r\n", "\r", "\n"), array('*//* ', "\n", "\n", "*/\n/* "), $source)."*/\n";
|
675 |
-
}
|
676 |
|
677 |
-
|
|
|
678 |
} catch (Twig_Error $e) {
|
679 |
-
$e->
|
680 |
throw $e;
|
681 |
} catch (Exception $e) {
|
682 |
-
throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $
|
683 |
}
|
684 |
}
|
685 |
|
@@ -690,6 +736,10 @@ class Twig_Environment
|
|
690 |
*/
|
691 |
public function setLoader(Twig_LoaderInterface $loader)
|
692 |
{
|
|
|
|
|
|
|
|
|
693 |
$this->loader = $loader;
|
694 |
}
|
695 |
|
@@ -752,29 +802,80 @@ class Twig_Environment
|
|
752 |
/**
|
753 |
* Returns true if the given extension is registered.
|
754 |
*
|
755 |
-
* @param string $
|
756 |
*
|
757 |
* @return bool Whether the extension is registered or not
|
758 |
*/
|
759 |
-
public function hasExtension($
|
760 |
{
|
761 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
762 |
}
|
763 |
|
764 |
/**
|
765 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
766 |
*
|
767 |
-
* @param string $
|
768 |
*
|
769 |
* @return Twig_ExtensionInterface A Twig_ExtensionInterface instance
|
770 |
*/
|
771 |
-
public function getExtension($
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
772 |
{
|
773 |
-
if (
|
774 |
-
|
775 |
}
|
776 |
|
777 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
778 |
}
|
779 |
|
780 |
/**
|
@@ -784,19 +885,22 @@ class Twig_Environment
|
|
784 |
*/
|
785 |
public function addExtension(Twig_ExtensionInterface $extension)
|
786 |
{
|
787 |
-
$name = $extension->getName();
|
788 |
-
|
789 |
if ($this->extensionInitialized) {
|
790 |
-
throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $
|
791 |
}
|
792 |
|
793 |
-
|
794 |
-
|
|
|
|
|
|
|
|
|
795 |
}
|
796 |
|
797 |
$this->lastModifiedExtension = 0;
|
798 |
-
|
799 |
-
$this->extensions[$
|
|
|
800 |
}
|
801 |
|
802 |
/**
|
@@ -816,7 +920,17 @@ class Twig_Environment
|
|
816 |
throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
|
817 |
}
|
818 |
|
819 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
820 |
}
|
821 |
|
822 |
/**
|
@@ -834,7 +948,7 @@ class Twig_Environment
|
|
834 |
/**
|
835 |
* Returns all registered extensions.
|
836 |
*
|
837 |
-
* @return
|
838 |
*/
|
839 |
public function getExtensions()
|
840 |
{
|
@@ -931,7 +1045,7 @@ class Twig_Environment
|
|
931 |
public function addFilter($name, $filter = null)
|
932 |
{
|
933 |
if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) {
|
934 |
-
throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter');
|
935 |
}
|
936 |
|
937 |
if ($name instanceof Twig_SimpleFilter) {
|
@@ -1026,7 +1140,7 @@ class Twig_Environment
|
|
1026 |
public function addTest($name, $test = null)
|
1027 |
{
|
1028 |
if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) {
|
1029 |
-
throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest');
|
1030 |
}
|
1031 |
|
1032 |
if ($name instanceof Twig_SimpleTest) {
|
@@ -1090,7 +1204,7 @@ class Twig_Environment
|
|
1090 |
public function addFunction($name, $function = null)
|
1091 |
{
|
1092 |
if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) {
|
1093 |
-
throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction');
|
1094 |
}
|
1095 |
|
1096 |
if ($name instanceof Twig_SimpleFunction) {
|
@@ -1388,7 +1502,7 @@ class Twig_Environment
|
|
1388 |
|
1389 |
$this->parsers->addTokenParserBroker($parser);
|
1390 |
} else {
|
1391 |
-
throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances');
|
1392 |
}
|
1393 |
}
|
1394 |
|
@@ -1415,4 +1529,21 @@ class Twig_Environment
|
|
1415 |
{
|
1416 |
$this->cache->write($file, $content);
|
1417 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1418 |
}
|
16 |
*/
|
17 |
class Twig_Environment
|
18 |
{
|
19 |
+
const VERSION = '1.27.0';
|
20 |
|
21 |
protected $charset;
|
22 |
protected $loader;
|
49 |
private $bcWriteCacheFile = false;
|
50 |
private $bcGetCacheFilename = false;
|
51 |
private $lastModifiedExtension = 0;
|
52 |
+
private $extensionsByClass = array();
|
53 |
+
private $runtimeLoaders = array();
|
54 |
+
private $runtimes = array();
|
55 |
+
private $optionsHash;
|
56 |
|
57 |
/**
|
58 |
* Constructor.
|
82 |
* * false: disable auto-escaping
|
83 |
* * true: equivalent to html
|
84 |
* * html, js: set the autoescaping to one of the supported strategies
|
85 |
+
* * name: set the autoescaping strategy based on the template name extension
|
86 |
+
* * PHP callback: a PHP callback that returns an escaping strategy based on the template "name"
|
87 |
*
|
88 |
* * optimizations: A flag that indicates which optimizations to apply
|
89 |
* (default to -1 which means that all optimizations are enabled;
|
159 |
public function setBaseTemplateClass($class)
|
160 |
{
|
161 |
$this->baseTemplateClass = $class;
|
162 |
+
$this->updateOptionsHash();
|
163 |
}
|
164 |
|
165 |
/**
|
168 |
public function enableDebug()
|
169 |
{
|
170 |
$this->debug = true;
|
171 |
+
$this->updateOptionsHash();
|
172 |
}
|
173 |
|
174 |
/**
|
177 |
public function disableDebug()
|
178 |
{
|
179 |
$this->debug = false;
|
180 |
+
$this->updateOptionsHash();
|
181 |
}
|
182 |
|
183 |
/**
|
222 |
public function enableStrictVariables()
|
223 |
{
|
224 |
$this->strictVariables = true;
|
225 |
+
$this->updateOptionsHash();
|
226 |
}
|
227 |
|
228 |
/**
|
231 |
public function disableStrictVariables()
|
232 |
{
|
233 |
$this->strictVariables = false;
|
234 |
+
$this->updateOptionsHash();
|
235 |
}
|
236 |
|
237 |
/**
|
309 |
*
|
310 |
* * The cache key for the given template;
|
311 |
* * The currently enabled extensions;
|
312 |
+
* * Whether the Twig C extension is available or not;
|
313 |
+
* * PHP version;
|
314 |
+
* * Twig version;
|
315 |
+
* * Options with what environment was created.
|
316 |
*
|
317 |
* @param string $name The name for which to calculate the template class name
|
318 |
* @param int|null $index The index if it is an embedded template
|
321 |
*/
|
322 |
public function getTemplateClass($name, $index = null)
|
323 |
{
|
324 |
+
$key = $this->getLoader()->getCacheKey($name).$this->optionsHash;
|
|
|
|
|
325 |
|
326 |
return $this->templateClassPrefix.hash('sha256', $key).(null === $index ? '' : '_'.$index);
|
327 |
}
|
403 |
}
|
404 |
|
405 |
if (!class_exists($cls, false)) {
|
406 |
+
$loader = $this->getLoader();
|
407 |
+
if (!$loader instanceof Twig_SourceContextLoaderInterface) {
|
408 |
+
$source = new Twig_Source($loader->getSource($name), $name);
|
409 |
+
} else {
|
410 |
+
$source = $loader->getSourceContext($name);
|
411 |
+
}
|
412 |
+
|
413 |
+
$content = $this->compileSource($source);
|
414 |
+
|
415 |
if ($this->bcWriteCacheFile) {
|
416 |
$this->writeCacheFile($key, $content);
|
417 |
} else {
|
564 |
* Gets the Lexer instance.
|
565 |
*
|
566 |
* @return Twig_LexerInterface A Twig_LexerInterface instance
|
567 |
+
*
|
568 |
+
* @deprecated since 1.25 (to be removed in 2.0)
|
569 |
*/
|
570 |
public function getLexer()
|
571 |
{
|
572 |
+
@trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
|
573 |
+
|
574 |
if (null === $this->lexer) {
|
575 |
$this->lexer = new Twig_Lexer($this);
|
576 |
}
|
591 |
/**
|
592 |
* Tokenizes a source code.
|
593 |
*
|
594 |
+
* @param string|Twig_Source $source The template source code
|
595 |
+
* @param string $name The template name (deprecated)
|
596 |
*
|
597 |
* @return Twig_TokenStream A Twig_TokenStream instance
|
598 |
*
|
600 |
*/
|
601 |
public function tokenize($source, $name = null)
|
602 |
{
|
603 |
+
if (!$source instanceof Twig_Source) {
|
604 |
+
@trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
|
605 |
+
$source = new Twig_Source($source, $name);
|
606 |
+
}
|
607 |
+
|
608 |
+
if (null === $this->lexer) {
|
609 |
+
$this->lexer = new Twig_Lexer($this);
|
610 |
+
}
|
611 |
+
|
612 |
+
return $this->lexer->tokenize($source);
|
613 |
}
|
614 |
|
615 |
/**
|
616 |
* Gets the Parser instance.
|
617 |
*
|
618 |
* @return Twig_ParserInterface A Twig_ParserInterface instance
|
619 |
+
*
|
620 |
+
* @deprecated since 1.25 (to be removed in 2.0)
|
621 |
*/
|
622 |
public function getParser()
|
623 |
{
|
624 |
+
@trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
|
625 |
+
|
626 |
if (null === $this->parser) {
|
627 |
$this->parser = new Twig_Parser($this);
|
628 |
}
|
651 |
*/
|
652 |
public function parse(Twig_TokenStream $stream)
|
653 |
{
|
654 |
+
if (null === $this->parser) {
|
655 |
+
$this->parser = new Twig_Parser($this);
|
656 |
+
}
|
657 |
+
|
658 |
+
return $this->parser->parse($stream);
|
659 |
}
|
660 |
|
661 |
/**
|
662 |
* Gets the Compiler instance.
|
663 |
*
|
664 |
* @return Twig_CompilerInterface A Twig_CompilerInterface instance
|
665 |
+
*
|
666 |
+
* @deprecated since 1.25 (to be removed in 2.0)
|
667 |
*/
|
668 |
public function getCompiler()
|
669 |
{
|
670 |
+
@trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
|
671 |
+
|
672 |
if (null === $this->compiler) {
|
673 |
$this->compiler = new Twig_Compiler($this);
|
674 |
}
|
695 |
*/
|
696 |
public function compile(Twig_NodeInterface $node)
|
697 |
{
|
698 |
+
if (null === $this->compiler) {
|
699 |
+
$this->compiler = new Twig_Compiler($this);
|
700 |
+
}
|
701 |
+
|
702 |
+
return $this->compiler->compile($node)->getSource();
|
703 |
}
|
704 |
|
705 |
/**
|
706 |
* Compiles a template source code.
|
707 |
*
|
708 |
+
* @param string|Twig_Source $source The template source code
|
709 |
+
* @param string $name The template name (deprecated)
|
710 |
*
|
711 |
* @return string The compiled PHP source code
|
712 |
*
|
714 |
*/
|
715 |
public function compileSource($source, $name = null)
|
716 |
{
|
717 |
+
if (!$source instanceof Twig_Source) {
|
718 |
+
@trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
|
719 |
+
$source = new Twig_Source($source, $name);
|
720 |
+
}
|
|
|
|
|
721 |
|
722 |
+
try {
|
723 |
+
return $this->compile($this->parse($this->tokenize($source)));
|
724 |
} catch (Twig_Error $e) {
|
725 |
+
$e->setTemplateName($source->getName());
|
726 |
throw $e;
|
727 |
} catch (Exception $e) {
|
728 |
+
throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source->getName(), $e);
|
729 |
}
|
730 |
}
|
731 |
|
736 |
*/
|
737 |
public function setLoader(Twig_LoaderInterface $loader)
|
738 |
{
|
739 |
+
if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader), 'Mock_Twig_LoaderInterface')) {
|
740 |
+
@trigger_error(sprintf('Twig loader "%s" should implement Twig_SourceContextLoaderInterface since version 1.27.', get_class($loader)), E_USER_DEPRECATED);
|
741 |
+
}
|
742 |
+
|
743 |
$this->loader = $loader;
|
744 |
}
|
745 |
|
802 |
/**
|
803 |
* Returns true if the given extension is registered.
|
804 |
*
|
805 |
+
* @param string $class The extension class name
|
806 |
*
|
807 |
* @return bool Whether the extension is registered or not
|
808 |
*/
|
809 |
+
public function hasExtension($class)
|
810 |
{
|
811 |
+
$class = ltrim($class, '\\');
|
812 |
+
if (isset($this->extensions[$class])) {
|
813 |
+
if ($class !== get_class($this->extensions[$class])) {
|
814 |
+
@trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
|
815 |
+
}
|
816 |
+
|
817 |
+
return true;
|
818 |
+
}
|
819 |
+
|
820 |
+
return isset($this->extensionsByClass[ltrim($class, '\\')]);
|
821 |
}
|
822 |
|
823 |
/**
|
824 |
+
* Adds a runtime loader.
|
825 |
+
*/
|
826 |
+
public function addRuntimeLoader(Twig_RuntimeLoaderInterface $loader)
|
827 |
+
{
|
828 |
+
$this->runtimeLoaders[] = $loader;
|
829 |
+
}
|
830 |
+
|
831 |
+
/**
|
832 |
+
* Gets an extension by class name.
|
833 |
*
|
834 |
+
* @param string $class The extension class name
|
835 |
*
|
836 |
* @return Twig_ExtensionInterface A Twig_ExtensionInterface instance
|
837 |
*/
|
838 |
+
public function getExtension($class)
|
839 |
+
{
|
840 |
+
$class = ltrim($class, '\\');
|
841 |
+
|
842 |
+
if (isset($this->extensions[$class])) {
|
843 |
+
if ($class !== get_class($this->extensions[$class])) {
|
844 |
+
@trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
|
845 |
+
}
|
846 |
+
|
847 |
+
return $this->extensions[$class];
|
848 |
+
}
|
849 |
+
|
850 |
+
if (!isset($this->extensionsByClass[$class])) {
|
851 |
+
throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $class));
|
852 |
+
}
|
853 |
+
|
854 |
+
return $this->extensionsByClass[$class];
|
855 |
+
}
|
856 |
+
|
857 |
+
/**
|
858 |
+
* Returns the runtime implementation of a Twig element (filter/function/test).
|
859 |
+
*
|
860 |
+
* @param string $class A runtime class name
|
861 |
+
*
|
862 |
+
* @return object The runtime implementation
|
863 |
+
*
|
864 |
+
* @throws Twig_Error_Runtime When the template cannot be found
|
865 |
+
*/
|
866 |
+
public function getRuntime($class)
|
867 |
{
|
868 |
+
if (isset($this->runtimes[$class])) {
|
869 |
+
return $this->runtimes[$class];
|
870 |
}
|
871 |
|
872 |
+
foreach ($this->runtimeLoaders as $loader) {
|
873 |
+
if (null !== $runtime = $loader->load($class)) {
|
874 |
+
return $this->runtimes[$class] = $runtime;
|
875 |
+
}
|
876 |
+
}
|
877 |
+
|
878 |
+
throw new Twig_Error_Runtime(sprintf('Unable to load the "%s" runtime.', $class));
|
879 |
}
|
880 |
|
881 |
/**
|
885 |
*/
|
886 |
public function addExtension(Twig_ExtensionInterface $extension)
|
887 |
{
|
|
|
|
|
888 |
if ($this->extensionInitialized) {
|
889 |
+
throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName()));
|
890 |
}
|
891 |
|
892 |
+
$class = get_class($extension);
|
893 |
+
if ($class !== $extension->getName()) {
|
894 |
+
if (isset($this->extensions[$extension->getName()])) {
|
895 |
+
unset($this->extensions[$extension->getName()], $this->extensionsByClass[$class]);
|
896 |
+
@trigger_error(sprintf('The possibility to register the same extension twice ("%s") is deprecated since version 1.23 and will be removed in Twig 2.0. Use proper PHP inheritance instead.', $extension->getName()), E_USER_DEPRECATED);
|
897 |
+
}
|
898 |
}
|
899 |
|
900 |
$this->lastModifiedExtension = 0;
|
901 |
+
$this->extensionsByClass[$class] = $extension;
|
902 |
+
$this->extensions[$extension->getName()] = $extension;
|
903 |
+
$this->updateOptionsHash();
|
904 |
}
|
905 |
|
906 |
/**
|
920 |
throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
|
921 |
}
|
922 |
|
923 |
+
$class = ltrim($name, '\\');
|
924 |
+
if (isset($this->extensions[$class])) {
|
925 |
+
if ($class !== get_class($this->extensions[$class])) {
|
926 |
+
@trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
|
927 |
+
}
|
928 |
+
|
929 |
+
unset($this->extensions[$class]);
|
930 |
+
}
|
931 |
+
|
932 |
+
unset($this->extensions[$class]);
|
933 |
+
$this->updateOptionsHash();
|
934 |
}
|
935 |
|
936 |
/**
|
948 |
/**
|
949 |
* Returns all registered extensions.
|
950 |
*
|
951 |
+
* @return Twig_ExtensionInterface[] An array of extensions (keys are for internal usage only and should not be relied on)
|
952 |
*/
|
953 |
public function getExtensions()
|
954 |
{
|
1045 |
public function addFilter($name, $filter = null)
|
1046 |
{
|
1047 |
if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) {
|
1048 |
+
throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter.');
|
1049 |
}
|
1050 |
|
1051 |
if ($name instanceof Twig_SimpleFilter) {
|
1140 |
public function addTest($name, $test = null)
|
1141 |
{
|
1142 |
if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) {
|
1143 |
+
throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest.');
|
1144 |
}
|
1145 |
|
1146 |
if ($name instanceof Twig_SimpleTest) {
|
1204 |
public function addFunction($name, $function = null)
|
1205 |
{
|
1206 |
if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) {
|
1207 |
+
throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction.');
|
1208 |
}
|
1209 |
|
1210 |
if ($name instanceof Twig_SimpleFunction) {
|
1502 |
|
1503 |
$this->parsers->addTokenParserBroker($parser);
|
1504 |
} else {
|
1505 |
+
throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances.');
|
1506 |
}
|
1507 |
}
|
1508 |
|
1529 |
{
|
1530 |
$this->cache->write($file, $content);
|
1531 |
}
|
1532 |
+
|
1533 |
+
private function updateOptionsHash()
|
1534 |
+
{
|
1535 |
+
$hashParts = array_merge(
|
1536 |
+
array_keys($this->extensions),
|
1537 |
+
array(
|
1538 |
+
(int) function_exists('twig_template_get_attributes'),
|
1539 |
+
PHP_MAJOR_VERSION,
|
1540 |
+
PHP_MINOR_VERSION,
|
1541 |
+
self::VERSION,
|
1542 |
+
(int) $this->debug,
|
1543 |
+
$this->baseTemplateClass,
|
1544 |
+
(int) $this->strictVariables,
|
1545 |
+
)
|
1546 |
+
);
|
1547 |
+
$this->optionsHash = implode(':', $hashParts);
|
1548 |
+
}
|
1549 |
}
|
vendor/twig/twig/lib/Twig/Error.php
CHANGED
@@ -25,8 +25,8 @@
|
|
25 |
* and line number) yourself by passing them to the constructor. If some or all
|
26 |
* these information are not available from where you throw the exception, then
|
27 |
* this class will guess them automatically (when the line number is set to -1
|
28 |
-
* and/or the
|
29 |
-
* can be disabled by passing false for both the
|
30 |
* when creating a new instance of this class.
|
31 |
*
|
32 |
* @author Fabien Potencier <fabien@symfony.com>
|
@@ -34,6 +34,7 @@
|
|
34 |
class Twig_Error extends Exception
|
35 |
{
|
36 |
protected $lineno;
|
|
|
37 |
protected $filename;
|
38 |
protected $rawMessage;
|
39 |
protected $previous;
|
@@ -41,21 +42,21 @@ class Twig_Error extends Exception
|
|
41 |
/**
|
42 |
* Constructor.
|
43 |
*
|
44 |
-
* Set both the line number and the
|
45 |
* disable automatic guessing of the original template name
|
46 |
* and line number.
|
47 |
*
|
48 |
* Set the line number to -1 to enable its automatic guessing.
|
49 |
-
* Set the
|
50 |
*
|
51 |
* By default, automatic guessing is enabled.
|
52 |
*
|
53 |
* @param string $message The error message
|
54 |
* @param int $lineno The template line where the error occurred
|
55 |
-
* @param string $
|
56 |
* @param Exception $previous The previous exception
|
57 |
*/
|
58 |
-
public function __construct($message, $lineno = -1, $
|
59 |
{
|
60 |
if (PHP_VERSION_ID < 50300) {
|
61 |
$this->previous = $previous;
|
@@ -65,9 +66,9 @@ class Twig_Error extends Exception
|
|
65 |
}
|
66 |
|
67 |
$this->lineno = $lineno;
|
68 |
-
$this->filename = $
|
69 |
|
70 |
-
if (-1 === $
|
71 |
$this->guessTemplateInfo();
|
72 |
}
|
73 |
|
@@ -87,23 +88,53 @@ class Twig_Error extends Exception
|
|
87 |
}
|
88 |
|
89 |
/**
|
90 |
-
* Gets the
|
91 |
*
|
92 |
-
* @return string The
|
|
|
|
|
93 |
*/
|
94 |
public function getTemplateFile()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
{
|
96 |
return $this->filename;
|
97 |
}
|
98 |
|
99 |
/**
|
100 |
-
* Sets the
|
101 |
*
|
102 |
-
* @param string $
|
103 |
*/
|
104 |
-
public function
|
105 |
{
|
106 |
-
$this->filename = $
|
107 |
|
108 |
$this->updateRepr();
|
109 |
}
|
@@ -182,11 +213,11 @@ class Twig_Error extends Exception
|
|
182 |
|
183 |
if ($this->filename) {
|
184 |
if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) {
|
185 |
-
$
|
186 |
} else {
|
187 |
-
$
|
188 |
}
|
189 |
-
$this->message .= sprintf(' in %s', $
|
190 |
}
|
191 |
|
192 |
if ($this->lineno && $this->lineno >= 0) {
|
@@ -227,7 +258,7 @@ class Twig_Error extends Exception
|
|
227 |
}
|
228 |
}
|
229 |
|
230 |
-
// update template
|
231 |
if (null !== $template && null === $this->filename) {
|
232 |
$this->filename = $template->getTemplateName();
|
233 |
}
|
25 |
* and line number) yourself by passing them to the constructor. If some or all
|
26 |
* these information are not available from where you throw the exception, then
|
27 |
* this class will guess them automatically (when the line number is set to -1
|
28 |
+
* and/or the name is set to null). As this is a costly operation, this
|
29 |
+
* can be disabled by passing false for both the name and the line number
|
30 |
* when creating a new instance of this class.
|
31 |
*
|
32 |
* @author Fabien Potencier <fabien@symfony.com>
|
34 |
class Twig_Error extends Exception
|
35 |
{
|
36 |
protected $lineno;
|
37 |
+
// to be renamed to name in 2.0
|
38 |
protected $filename;
|
39 |
protected $rawMessage;
|
40 |
protected $previous;
|
42 |
/**
|
43 |
* Constructor.
|
44 |
*
|
45 |
+
* Set both the line number and the name to false to
|
46 |
* disable automatic guessing of the original template name
|
47 |
* and line number.
|
48 |
*
|
49 |
* Set the line number to -1 to enable its automatic guessing.
|
50 |
+
* Set the name to null to enable its automatic guessing.
|
51 |
*
|
52 |
* By default, automatic guessing is enabled.
|
53 |
*
|
54 |
* @param string $message The error message
|
55 |
* @param int $lineno The template line where the error occurred
|
56 |
+
* @param string $name The template logical name where the error occurred
|
57 |
* @param Exception $previous The previous exception
|
58 |
*/
|
59 |
+
public function __construct($message, $lineno = -1, $name = null, Exception $previous = null)
|
60 |
{
|
61 |
if (PHP_VERSION_ID < 50300) {
|
62 |
$this->previous = $previous;
|
66 |
}
|
67 |
|
68 |
$this->lineno = $lineno;
|
69 |
+
$this->filename = $name;
|
70 |
|
71 |
+
if (-1 === $lineno || null === $name) {
|
72 |
$this->guessTemplateInfo();
|
73 |
}
|
74 |
|
88 |
}
|
89 |
|
90 |
/**
|
91 |
+
* Gets the logical name where the error occurred.
|
92 |
*
|
93 |
+
* @return string The name
|
94 |
+
*
|
95 |
+
* @deprecated since 1.27 (to be removed in 2.0). Use getTemplateName() instead.
|
96 |
*/
|
97 |
public function getTemplateFile()
|
98 |
+
{
|
99 |
+
@trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateName() instead.', __METHOD__), E_USER_DEPRECATED);
|
100 |
+
|
101 |
+
return $this->filename;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Sets the logical name where the error occurred.
|
106 |
+
*
|
107 |
+
* @param string $name The name
|
108 |
+
*
|
109 |
+
* @deprecated since 1.27 (to be removed in 2.0). Use setTemplateName() instead.
|
110 |
+
*/
|
111 |
+
public function setTemplateFile($name)
|
112 |
+
{
|
113 |
+
@trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use setTemplateName() instead.', __METHOD__), E_USER_DEPRECATED);
|
114 |
+
|
115 |
+
$this->filename = $name;
|
116 |
+
|
117 |
+
$this->updateRepr();
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Gets the logical name where the error occurred.
|
122 |
+
*
|
123 |
+
* @return string The name
|
124 |
+
*/
|
125 |
+
public function getTemplateName()
|
126 |
{
|
127 |
return $this->filename;
|
128 |
}
|
129 |
|
130 |
/**
|
131 |
+
* Sets the logical name where the error occurred.
|
132 |
*
|
133 |
+
* @param string $name The name
|
134 |
*/
|
135 |
+
public function setTemplateName($name)
|
136 |
{
|
137 |
+
$this->filename = $name;
|
138 |
|
139 |
$this->updateRepr();
|
140 |
}
|
213 |
|
214 |
if ($this->filename) {
|
215 |
if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) {
|
216 |
+
$name = sprintf('"%s"', $this->filename);
|
217 |
} else {
|
218 |
+
$name = json_encode($this->filename);
|
219 |
}
|
220 |
+
$this->message .= sprintf(' in %s', $name);
|
221 |
}
|
222 |
|
223 |
if ($this->lineno && $this->lineno >= 0) {
|
258 |
}
|
259 |
}
|
260 |
|
261 |
+
// update template name
|
262 |
if (null !== $template && null === $this->filename) {
|
263 |
$this->filename = $template->getTemplateName();
|
264 |
}
|
vendor/twig/twig/lib/Twig/ExpressionParser.php
CHANGED
@@ -19,6 +19,8 @@
|
|
19 |
* @see http://en.wikipedia.org/wiki/Operator-precedence_parser
|
20 |
*
|
21 |
* @author Fabien Potencier <fabien@symfony.com>
|
|
|
|
|
22 |
*/
|
23 |
class Twig_ExpressionParser
|
24 |
{
|
@@ -29,11 +31,23 @@ class Twig_ExpressionParser
|
|
29 |
protected $unaryOperators;
|
30 |
protected $binaryOperators;
|
31 |
|
32 |
-
|
|
|
|
|
33 |
{
|
34 |
$this->parser = $parser;
|
35 |
-
|
36 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
}
|
38 |
|
39 |
public function parseExpression($precedence = 0)
|
@@ -44,7 +58,11 @@ class Twig_ExpressionParser
|
|
44 |
$op = $this->binaryOperators[$token->getValue()];
|
45 |
$this->parser->getStream()->next();
|
46 |
|
47 |
-
if (
|
|
|
|
|
|
|
|
|
48 |
$expr = call_user_func($op['callable'], $this->parser, $expr);
|
49 |
} else {
|
50 |
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
|
@@ -171,7 +189,7 @@ class Twig_ExpressionParser
|
|
171 |
$negClass = 'Twig_Node_Expression_Unary_Neg';
|
172 |
$posClass = 'Twig_Node_Expression_Unary_Pos';
|
173 |
if (!(in_array($ref->getName(), array($negClass, $posClass)) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) {
|
174 |
-
throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->
|
175 |
}
|
176 |
|
177 |
$this->parser->getStream()->next();
|
@@ -187,7 +205,7 @@ class Twig_ExpressionParser
|
|
187 |
} elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
|
188 |
$node = $this->parseHashExpression();
|
189 |
} else {
|
190 |
-
throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->
|
191 |
}
|
192 |
}
|
193 |
|
@@ -216,7 +234,7 @@ class Twig_ExpressionParser
|
|
216 |
|
217 |
$expr = array_shift($nodes);
|
218 |
foreach ($nodes as $node) {
|
219 |
-
$expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->
|
220 |
}
|
221 |
|
222 |
return $expr;
|
@@ -278,7 +296,7 @@ class Twig_ExpressionParser
|
|
278 |
} else {
|
279 |
$current = $stream->getCurrent();
|
280 |
|
281 |
-
throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $
|
282 |
}
|
283 |
|
284 |
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
|
@@ -317,11 +335,11 @@ class Twig_ExpressionParser
|
|
317 |
case 'parent':
|
318 |
$this->parseArguments();
|
319 |
if (!count($this->parser->getBlockStack())) {
|
320 |
-
throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden.', $line, $this->parser->
|
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->
|
325 |
}
|
326 |
|
327 |
return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
|
@@ -330,7 +348,7 @@ class Twig_ExpressionParser
|
|
330 |
case 'attribute':
|
331 |
$args = $this->parseArguments();
|
332 |
if (count($args) < 2) {
|
333 |
-
throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->
|
334 |
}
|
335 |
|
336 |
return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line);
|
@@ -379,18 +397,18 @@ class Twig_ExpressionParser
|
|
379 |
}
|
380 |
}
|
381 |
} else {
|
382 |
-
throw new Twig_Error_Syntax('Expected name or number', $lineno, $
|
383 |
}
|
384 |
|
385 |
if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
|
386 |
if (!$arg instanceof Twig_Node_Expression_Constant) {
|
387 |
-
throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $
|
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(), $
|
394 |
}
|
395 |
|
396 |
$node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno);
|
@@ -500,7 +518,7 @@ class Twig_ExpressionParser
|
|
500 |
$name = null;
|
501 |
if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
|
502 |
if (!$value instanceof Twig_Node_Expression_Name) {
|
503 |
-
throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given.', get_class($value)), $token->getLine(), $
|
504 |
}
|
505 |
$name = $value->getAttribute('name');
|
506 |
|
@@ -508,7 +526,7 @@ class Twig_ExpressionParser
|
|
508 |
$value = $this->parsePrimaryExpression();
|
509 |
|
510 |
if (!$this->checkConstantExpression($value)) {
|
511 |
-
throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $
|
512 |
}
|
513 |
} else {
|
514 |
$value = $this->parseExpression();
|
@@ -536,16 +554,17 @@ class Twig_ExpressionParser
|
|
536 |
|
537 |
public function parseAssignmentExpression()
|
538 |
{
|
|
|
539 |
$targets = array();
|
540 |
while (true) {
|
541 |
-
$token = $
|
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(), $
|
545 |
}
|
546 |
$targets[] = new Twig_Node_Expression_AssignName($value, $token->getLine());
|
547 |
|
548 |
-
if (!$
|
549 |
break;
|
550 |
}
|
551 |
}
|
@@ -566,13 +585,79 @@ class Twig_ExpressionParser
|
|
566 |
return new Twig_Node($targets);
|
567 |
}
|
568 |
|
569 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
570 |
{
|
571 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
572 |
|
573 |
-
if (
|
574 |
-
|
575 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
576 |
|
577 |
throw $e;
|
578 |
}
|
@@ -585,7 +670,7 @@ class Twig_ExpressionParser
|
|
585 |
if ($function->getAlternative()) {
|
586 |
$message .= sprintf('. Use "%s" instead', $function->getAlternative());
|
587 |
}
|
588 |
-
$message .= sprintf(' in %s at line %d.', $this->parser->
|
589 |
|
590 |
@trigger_error($message, E_USER_DEPRECATED);
|
591 |
}
|
@@ -599,11 +684,9 @@ class Twig_ExpressionParser
|
|
599 |
|
600 |
protected function getFilterNodeClass($name, $line)
|
601 |
{
|
602 |
-
$
|
603 |
-
|
604 |
-
|
605 |
-
$e = new Twig_Error_Syntax(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getFilename());
|
606 |
-
$e->addSuggestions($name, array_keys($env->getFilters()));
|
607 |
|
608 |
throw $e;
|
609 |
}
|
@@ -616,7 +699,7 @@ class Twig_ExpressionParser
|
|
616 |
if ($filter->getAlternative()) {
|
617 |
$message .= sprintf('. Use "%s" instead', $filter->getAlternative());
|
618 |
}
|
619 |
-
$message .= sprintf(' in %s at line %d.', $this->parser->
|
620 |
|
621 |
@trigger_error($message, E_USER_DEPRECATED);
|
622 |
}
|
19 |
* @see http://en.wikipedia.org/wiki/Operator-precedence_parser
|
20 |
*
|
21 |
* @author Fabien Potencier <fabien@symfony.com>
|
22 |
+
*
|
23 |
+
* @internal
|
24 |
*/
|
25 |
class Twig_ExpressionParser
|
26 |
{
|
31 |
protected $unaryOperators;
|
32 |
protected $binaryOperators;
|
33 |
|
34 |
+
private $env;
|
35 |
+
|
36 |
+
public function __construct(Twig_Parser $parser, Twig_Environment $env = null)
|
37 |
{
|
38 |
$this->parser = $parser;
|
39 |
+
|
40 |
+
if ($env instanceof Twig_Environment) {
|
41 |
+
$this->env = $env;
|
42 |
+
$this->unaryOperators = $env->getUnaryOperators();
|
43 |
+
$this->binaryOperators = $env->getBinaryOperators();
|
44 |
+
} else {
|
45 |
+
@trigger_error('Passing the operators as constructor arguments to '.__METHOD__.' is deprecated since version 1.27. Pass the environment instead.', E_USER_DEPRECATED);
|
46 |
+
|
47 |
+
$this->env = $parser->getEnvironment();
|
48 |
+
$this->unaryOperators = func_get_arg(1);
|
49 |
+
$this->binaryOperators = func_get_arg(2);
|
50 |
+
}
|
51 |
}
|
52 |
|
53 |
public function parseExpression($precedence = 0)
|
58 |
$op = $this->binaryOperators[$token->getValue()];
|
59 |
$this->parser->getStream()->next();
|
60 |
|
61 |
+
if ('is not' === $token->getValue()) {
|
62 |
+
$expr = $this->parseNotTestExpression($expr);
|
63 |
+
} elseif ('is' === $token->getValue()) {
|
64 |
+
$expr = $this->parseTestExpression($expr);
|
65 |
+
} elseif (isset($op['callable'])) {
|
66 |
$expr = call_user_func($op['callable'], $this->parser, $expr);
|
67 |
} else {
|
68 |
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
|
189 |
$negClass = 'Twig_Node_Expression_Unary_Neg';
|
190 |
$posClass = 'Twig_Node_Expression_Unary_Pos';
|
191 |
if (!(in_array($ref->getName(), array($negClass, $posClass)) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) {
|
192 |
+
throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext()->getName());
|
193 |
}
|
194 |
|
195 |
$this->parser->getStream()->next();
|
205 |
} elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
|
206 |
$node = $this->parseHashExpression();
|
207 |
} else {
|
208 |
+
throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext()->getName());
|
209 |
}
|
210 |
}
|
211 |
|
234 |
|
235 |
$expr = array_shift($nodes);
|
236 |
foreach ($nodes as $node) {
|
237 |
+
$expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getTemplateLine());
|
238 |
}
|
239 |
|
240 |
return $expr;
|
296 |
} else {
|
297 |
$current = $stream->getCurrent();
|
298 |
|
299 |
+
throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext()->getName());
|
300 |
}
|
301 |
|
302 |
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
|
335 |
case 'parent':
|
336 |
$this->parseArguments();
|
337 |
if (!count($this->parser->getBlockStack())) {
|
338 |
+
throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext()->getName());
|
339 |
}
|
340 |
|
341 |
if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
|
342 |
+
throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext()->getName());
|
343 |
}
|
344 |
|
345 |
return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
|
348 |
case 'attribute':
|
349 |
$args = $this->parseArguments();
|
350 |
if (count($args) < 2) {
|
351 |
+
throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext()->getName());
|
352 |
}
|
353 |
|
354 |
return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line);
|
397 |
}
|
398 |
}
|
399 |
} else {
|
400 |
+
throw new Twig_Error_Syntax('Expected name or number.', $lineno, $stream->getSourceContext()->getName());
|
401 |
}
|
402 |
|
403 |
if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
|
404 |
if (!$arg instanceof Twig_Node_Expression_Constant) {
|
405 |
+
throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $stream->getSourceContext()->getName());
|
406 |
}
|
407 |
|
408 |
$name = $arg->getAttribute('value');
|
409 |
|
410 |
if ($this->parser->isReservedMacroName($name)) {
|
411 |
+
throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext()->getName());
|
412 |
}
|
413 |
|
414 |
$node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno);
|
518 |
$name = null;
|
519 |
if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
|
520 |
if (!$value instanceof Twig_Node_Expression_Name) {
|
521 |
+
throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given.', get_class($value)), $token->getLine(), $stream->getSourceContext()->getName());
|
522 |
}
|
523 |
$name = $value->getAttribute('name');
|
524 |
|
526 |
$value = $this->parsePrimaryExpression();
|
527 |
|
528 |
if (!$this->checkConstantExpression($value)) {
|
529 |
+
throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $stream->getSourceContext()->getName());
|
530 |
}
|
531 |
} else {
|
532 |
$value = $this->parseExpression();
|
554 |
|
555 |
public function parseAssignmentExpression()
|
556 |
{
|
557 |
+
$stream = $this->parser->getStream();
|
558 |
$targets = array();
|
559 |
while (true) {
|
560 |
+
$token = $stream->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
|
561 |
$value = $token->getValue();
|
562 |
if (in_array(strtolower($value), array('true', 'false', 'none', 'null'))) {
|
563 |
+
throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext()->getName());
|
564 |
}
|
565 |
$targets[] = new Twig_Node_Expression_AssignName($value, $token->getLine());
|
566 |
|
567 |
+
if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
|
568 |
break;
|
569 |
}
|
570 |
}
|
585 |
return new Twig_Node($targets);
|
586 |
}
|
587 |
|
588 |
+
private function parseNotTestExpression(Twig_NodeInterface $node)
|
589 |
+
{
|
590 |
+
return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
|
591 |
+
}
|
592 |
+
|
593 |
+
private function parseTestExpression(Twig_NodeInterface $node)
|
594 |
+
{
|
595 |
+
$stream = $this->parser->getStream();
|
596 |
+
list($name, $test) = $this->getTest($node->getTemplateLine());
|
597 |
+
|
598 |
+
$class = $this->getTestNodeClass($test);
|
599 |
+
$arguments = null;
|
600 |
+
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
|
601 |
+
$arguments = $this->parser->getExpressionParser()->parseArguments(true);
|
602 |
+
}
|
603 |
+
|
604 |
+
return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
|
605 |
+
}
|
606 |
+
|
607 |
+
private function getTest($line)
|
608 |
+
{
|
609 |
+
$stream = $this->parser->getStream();
|
610 |
+
$name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
|
611 |
+
|
612 |
+
if ($test = $this->env->getTest($name)) {
|
613 |
+
return array($name, $test);
|
614 |
+
}
|
615 |
+
|
616 |
+
if ($stream->test(Twig_Token::NAME_TYPE)) {
|
617 |
+
// try 2-words tests
|
618 |
+
$name = $name.' '.$this->parser->getCurrentToken()->getValue();
|
619 |
+
|
620 |
+
if ($test = $this->env->getTest($name)) {
|
621 |
+
$stream->next();
|
622 |
+
|
623 |
+
return array($name, $test);
|
624 |
+
}
|
625 |
+
}
|
626 |
+
|
627 |
+
$e = new Twig_Error_Syntax(sprintf('Unknown "%s" test.', $name), $line, $stream->getSourceContext()->getName());
|
628 |
+
$e->addSuggestions($name, array_keys($this->env->getTests()));
|
629 |
+
|
630 |
+
throw $e;
|
631 |
+
}
|
632 |
+
|
633 |
+
private function getTestNodeClass($test)
|
634 |
{
|
635 |
+
if ($test instanceof Twig_SimpleTest && $test->isDeprecated()) {
|
636 |
+
$stream = $this->parser->getStream();
|
637 |
+
$message = sprintf('Twig Test "%s" is deprecated', $test->getName());
|
638 |
+
if (!is_bool($test->getDeprecatedVersion())) {
|
639 |
+
$message .= sprintf(' since version %s', $test->getDeprecatedVersion());
|
640 |
+
}
|
641 |
+
if ($test->getAlternative()) {
|
642 |
+
$message .= sprintf('. Use "%s" instead', $test->getAlternative());
|
643 |
+
}
|
644 |
+
$message .= sprintf(' in %s at line %d.', $stream->getSourceContext()->getName(), $stream->getCurrent()->getLine());
|
645 |
+
|
646 |
+
@trigger_error($message, E_USER_DEPRECATED);
|
647 |
+
}
|
648 |
|
649 |
+
if ($test instanceof Twig_SimpleTest) {
|
650 |
+
return $test->getNodeClass();
|
651 |
+
}
|
652 |
+
|
653 |
+
return $test instanceof Twig_Test_Node ? $test->getClass() : 'Twig_Node_Expression_Test';
|
654 |
+
}
|
655 |
+
|
656 |
+
protected function getFunctionNodeClass($name, $line)
|
657 |
+
{
|
658 |
+
if (false === $function = $this->env->getFunction($name)) {
|
659 |
+
$e = new Twig_Error_Syntax(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext()->getName());
|
660 |
+
$e->addSuggestions($name, array_keys($this->env->getFunctions()));
|
661 |
|
662 |
throw $e;
|
663 |
}
|
670 |
if ($function->getAlternative()) {
|
671 |
$message .= sprintf('. Use "%s" instead', $function->getAlternative());
|
672 |
}
|
673 |
+
$message .= sprintf(' in %s at line %d.', $this->parser->getStream()->getSourceContext()->getName(), $line);
|
674 |
|
675 |
@trigger_error($message, E_USER_DEPRECATED);
|
676 |
}
|
684 |
|
685 |
protected function getFilterNodeClass($name, $line)
|
686 |
{
|
687 |
+
if (false === $filter = $this->env->getFilter($name)) {
|
688 |
+
$e = new Twig_Error_Syntax(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext()->getName());
|
689 |
+
$e->addSuggestions($name, array_keys($this->env->getFilters()));
|
|
|
|
|
690 |
|
691 |
throw $e;
|
692 |
}
|
699 |
if ($filter->getAlternative()) {
|
700 |
$message .= sprintf('. Use "%s" instead', $filter->getAlternative());
|
701 |
}
|
702 |
+
$message .= sprintf(' in %s at line %d.', $this->parser->getStream()->getSourceContext()->getName(), $line);
|
703 |
|
704 |
@trigger_error($message, E_USER_DEPRECATED);
|
705 |
}
|
vendor/twig/twig/lib/Twig/Extension.php
CHANGED
@@ -76,4 +76,14 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
|
|
76 |
{
|
77 |
return array();
|
78 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
76 |
{
|
77 |
return array();
|
78 |
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* {@inheritdoc}
|
82 |
+
*
|
83 |
+
* @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
|
84 |
+
*/
|
85 |
+
public function getName()
|
86 |
+
{
|
87 |
+
return get_class($this);
|
88 |
+
}
|
89 |
}
|
vendor/twig/twig/lib/Twig/Extension/Core.php
CHANGED
@@ -258,82 +258,14 @@ class Twig_Extension_Core extends Twig_Extension
|
|
258 |
'/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
259 |
'//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
260 |
'%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
261 |
-
'is' => array('precedence' => 100, '
|
262 |
-
'is not' => array('precedence' => 100, '
|
263 |
'**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
|
264 |
'??' => array('precedence' => 300, 'class' => 'Twig_Node_Expression_NullCoalesce', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
|
265 |
),
|
266 |
);
|
267 |
}
|
268 |
|
269 |
-
public function parseNotTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
|
270 |
-
{
|
271 |
-
return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine());
|
272 |
-
}
|
273 |
-
|
274 |
-
public function parseTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
|
275 |
-
{
|
276 |
-
$stream = $parser->getStream();
|
277 |
-
list($name, $test) = $this->getTest($parser, $node->getLine());
|
278 |
-
|
279 |
-
if ($test instanceof Twig_SimpleTest && $test->isDeprecated()) {
|
280 |
-
$message = sprintf('Twig Test "%s" is deprecated', $name);
|
281 |
-
if (!is_bool($test->getDeprecatedVersion())) {
|
282 |
-
$message .= sprintf(' since version %s', $test->getDeprecatedVersion());
|
283 |
-
}
|
284 |
-
if ($test->getAlternative()) {
|
285 |
-
$message .= sprintf('. Use "%s" instead', $test->getAlternative());
|
286 |
-
}
|
287 |
-
$message .= sprintf(' in %s at line %d.', $stream->getFilename(), $stream->getCurrent()->getLine());
|
288 |
-
|
289 |
-
@trigger_error($message, E_USER_DEPRECATED);
|
290 |
-
}
|
291 |
-
|
292 |
-
$class = $this->getTestNodeClass($parser, $test);
|
293 |
-
$arguments = null;
|
294 |
-
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
|
295 |
-
$arguments = $parser->getExpressionParser()->parseArguments(true);
|
296 |
-
}
|
297 |
-
|
298 |
-
return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine());
|
299 |
-
}
|
300 |
-
|
301 |
-
protected function getTest(Twig_Parser $parser, $line)
|
302 |
-
{
|
303 |
-
$stream = $parser->getStream();
|
304 |
-
$name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
|
305 |
-
$env = $parser->getEnvironment();
|
306 |
-
|
307 |
-
if ($test = $env->getTest($name)) {
|
308 |
-
return array($name, $test);
|
309 |
-
}
|
310 |
-
|
311 |
-
if ($stream->test(Twig_Token::NAME_TYPE)) {
|
312 |
-
// try 2-words tests
|
313 |
-
$name = $name.' '.$parser->getCurrentToken()->getValue();
|
314 |
-
|
315 |
-
if ($test = $env->getTest($name)) {
|
316 |
-
$parser->getStream()->next();
|
317 |
-
|
318 |
-
return array($name, $test);
|
319 |
-
}
|
320 |
-
}
|
321 |
-
|
322 |
-
$e = new Twig_Error_Syntax(sprintf('Unknown "%s" test.', $name), $line, $parser->getFilename());
|
323 |
-
$e->addSuggestions($name, array_keys($env->getTests()));
|
324 |
-
|
325 |
-
throw $e;
|
326 |
-
}
|
327 |
-
|
328 |
-
protected function getTestNodeClass(Twig_Parser $parser, $test)
|
329 |
-
{
|
330 |
-
if ($test instanceof Twig_SimpleTest) {
|
331 |
-
return $test->getNodeClass();
|
332 |
-
}
|
333 |
-
|
334 |
-
return $test instanceof Twig_Test_Node ? $test->getClass() : 'Twig_Node_Expression_Test';
|
335 |
-
}
|
336 |
-
|
337 |
public function getName()
|
338 |
{
|
339 |
return 'core';
|
@@ -433,7 +365,7 @@ function twig_random(Twig_Environment $env, $values = null)
|
|
433 |
function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null)
|
434 |
{
|
435 |
if (null === $format) {
|
436 |
-
$formats = $env->getExtension('
|
437 |
$format = $date instanceof DateInterval ? $formats[1] : $formats[0];
|
438 |
}
|
439 |
|
@@ -488,7 +420,7 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
|
|
488 |
// determine the timezone
|
489 |
if (false !== $timezone) {
|
490 |
if (null === $timezone) {
|
491 |
-
$timezone = $env->getExtension('
|
492 |
} elseif (!$timezone instanceof DateTimeZone) {
|
493 |
$timezone = new DateTimeZone($timezone);
|
494 |
}
|
@@ -509,14 +441,14 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
|
|
509 |
}
|
510 |
|
511 |
if (null === $date || 'now' === $date) {
|
512 |
-
return new DateTime($date, false !== $timezone ? $timezone : $env->getExtension('
|
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('
|
520 |
}
|
521 |
|
522 |
if (false !== $timezone) {
|
@@ -544,7 +476,7 @@ function twig_replace_filter($str, $from, $to = null)
|
|
544 |
|
545 |
return strtr($str, $from, $to);
|
546 |
} elseif (!is_array($from)) {
|
547 |
-
throw new Twig_Error_Runtime(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".',is_object($from) ? get_class($from) : gettype($from)));
|
548 |
}
|
549 |
|
550 |
return strtr($str, $from);
|
@@ -589,7 +521,7 @@ function twig_round($value, $precision = 0, $method = 'common')
|
|
589 |
*/
|
590 |
function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
|
591 |
{
|
592 |
-
$defaults = $env->getExtension('
|
593 |
if (null === $decimal) {
|
594 |
$decimal = $defaults[0];
|
595 |
}
|
@@ -978,7 +910,7 @@ function twig_in_filter($value, $compare)
|
|
978 |
* Escapes a string.
|
979 |
*
|
980 |
* @param Twig_Environment $env A Twig_Environment instance
|
981 |
-
* @param
|
982 |
* @param string $strategy The escaping strategy
|
983 |
* @param string $charset The charset
|
984 |
* @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
|
@@ -1115,7 +1047,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
|
|
1115 |
static $escapers;
|
1116 |
|
1117 |
if (null === $escapers) {
|
1118 |
-
$escapers = $env->getExtension('
|
1119 |
}
|
1120 |
|
1121 |
if (isset($escapers[$strategy])) {
|
@@ -1451,8 +1383,8 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
|
|
1451 |
$variables = array_merge($context, $variables);
|
1452 |
}
|
1453 |
|
1454 |
-
if ($isSandboxed = $sandboxed && $env->hasExtension('
|
1455 |
-
$sandbox = $env->getExtension('
|
1456 |
if (!$alreadySandboxed = $sandbox->isSandboxed()) {
|
1457 |
$sandbox->enableSandbox();
|
1458 |
}
|
@@ -1489,8 +1421,13 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
|
|
1489 |
*/
|
1490 |
function twig_source(Twig_Environment $env, $name, $ignoreMissing = false)
|
1491 |
{
|
|
|
1492 |
try {
|
1493 |
-
|
|
|
|
|
|
|
|
|
1494 |
} catch (Twig_Error_Loader $e) {
|
1495 |
if (!$ignoreMissing) {
|
1496 |
throw $e;
|
258 |
'/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
259 |
'//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
260 |
'%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
261 |
+
'is' => array('precedence' => 100, 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
262 |
+
'is not' => array('precedence' => 100, 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
263 |
'**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
|
264 |
'??' => array('precedence' => 300, 'class' => 'Twig_Node_Expression_NullCoalesce', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
|
265 |
),
|
266 |
);
|
267 |
}
|
268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
public function getName()
|
270 |
{
|
271 |
return 'core';
|
365 |
function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null)
|
366 |
{
|
367 |
if (null === $format) {
|
368 |
+
$formats = $env->getExtension('Twig_Extension_Core')->getDateFormat();
|
369 |
$format = $date instanceof DateInterval ? $formats[1] : $formats[0];
|
370 |
}
|
371 |
|
420 |
// determine the timezone
|
421 |
if (false !== $timezone) {
|
422 |
if (null === $timezone) {
|
423 |
+
$timezone = $env->getExtension('Twig_Extension_Core')->getTimezone();
|
424 |
} elseif (!$timezone instanceof DateTimeZone) {
|
425 |
$timezone = new DateTimeZone($timezone);
|
426 |
}
|
441 |
}
|
442 |
|
443 |
if (null === $date || 'now' === $date) {
|
444 |
+
return new DateTime($date, false !== $timezone ? $timezone : $env->getExtension('Twig_Extension_Core')->getTimezone());
|
445 |
}
|
446 |
|
447 |
$asString = (string) $date;
|
448 |
if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
|
449 |
$date = new DateTime('@'.$date);
|
450 |
} else {
|
451 |
+
$date = new DateTime($date, $env->getExtension('Twig_Extension_Core')->getTimezone());
|
452 |
}
|
453 |
|
454 |
if (false !== $timezone) {
|
476 |
|
477 |
return strtr($str, $from, $to);
|
478 |
} elseif (!is_array($from)) {
|
479 |
+
throw new Twig_Error_Runtime(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', is_object($from) ? get_class($from) : gettype($from)));
|
480 |
}
|
481 |
|
482 |
return strtr($str, $from);
|
521 |
*/
|
522 |
function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
|
523 |
{
|
524 |
+
$defaults = $env->getExtension('Twig_Extension_Core')->getNumberFormat();
|
525 |
if (null === $decimal) {
|
526 |
$decimal = $defaults[0];
|
527 |
}
|
910 |
* Escapes a string.
|
911 |
*
|
912 |
* @param Twig_Environment $env A Twig_Environment instance
|
913 |
+
* @param mixed $string The value to be escaped
|
914 |
* @param string $strategy The escaping strategy
|
915 |
* @param string $charset The charset
|
916 |
* @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
|
1047 |
static $escapers;
|
1048 |
|
1049 |
if (null === $escapers) {
|
1050 |
+
$escapers = $env->getExtension('Twig_Extension_Core')->getEscapers();
|
1051 |
}
|
1052 |
|
1053 |
if (isset($escapers[$strategy])) {
|
1383 |
$variables = array_merge($context, $variables);
|
1384 |
}
|
1385 |
|
1386 |
+
if ($isSandboxed = $sandboxed && $env->hasExtension('Twig_Extension_Sandbox')) {
|
1387 |
+
$sandbox = $env->getExtension('Twig_Extension_Sandbox');
|
1388 |
if (!$alreadySandboxed = $sandbox->isSandboxed()) {
|
1389 |
$sandbox->enableSandbox();
|
1390 |
}
|
1421 |
*/
|
1422 |
function twig_source(Twig_Environment $env, $name, $ignoreMissing = false)
|
1423 |
{
|
1424 |
+
$loader = $env->getLoader();
|
1425 |
try {
|
1426 |
+
if (!$loader instanceof Twig_SourceContextLoaderInterface) {
|
1427 |
+
return $loader->getSource($name);
|
1428 |
+
} else {
|
1429 |
+
return $loader->getSourceContext($name)->getCode();
|
1430 |
+
}
|
1431 |
} catch (Twig_Error_Loader $e) {
|
1432 |
if (!$ignoreMissing) {
|
1433 |
throw $e;
|
vendor/twig/twig/lib/Twig/Extension/Escaper.php
CHANGED
@@ -45,7 +45,7 @@ class Twig_Extension_Escaper extends Twig_Extension
|
|
45 |
* Sets the default strategy to use when not defined by the user.
|
46 |
*
|
47 |
* The strategy can be a valid PHP callback that takes the template
|
48 |
-
*
|
49 |
*
|
50 |
* @param string|false|callable $defaultStrategy An escaping strategy
|
51 |
*/
|
@@ -59,6 +59,12 @@ class Twig_Extension_Escaper extends Twig_Extension
|
|
59 |
}
|
60 |
|
61 |
if ('filename' === $defaultStrategy) {
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
$defaultStrategy = array('Twig_FileExtensionEscapingStrategy', 'guess');
|
63 |
}
|
64 |
|
@@ -68,16 +74,16 @@ class Twig_Extension_Escaper extends Twig_Extension
|
|
68 |
/**
|
69 |
* Gets the default strategy to use when not defined by the user.
|
70 |
*
|
71 |
-
* @param string $
|
72 |
*
|
73 |
* @return string|false The default strategy to use for the template
|
74 |
*/
|
75 |
-
public function getDefaultStrategy($
|
76 |
{
|
77 |
// disable string callables to avoid calling a function named html or js,
|
78 |
// or any other upcoming escaping strategy
|
79 |
if (!is_string($this->defaultStrategy) && false !== $this->defaultStrategy) {
|
80 |
-
return call_user_func($this->defaultStrategy, $
|
81 |
}
|
82 |
|
83 |
return $this->defaultStrategy;
|
45 |
* Sets the default strategy to use when not defined by the user.
|
46 |
*
|
47 |
* The strategy can be a valid PHP callback that takes the template
|
48 |
+
* name as an argument and returns the strategy to use.
|
49 |
*
|
50 |
* @param string|false|callable $defaultStrategy An escaping strategy
|
51 |
*/
|
59 |
}
|
60 |
|
61 |
if ('filename' === $defaultStrategy) {
|
62 |
+
@trigger_error('Using "filename" as the default strategy is deprecated since version 1.27. Use "name" instead.', E_USER_DEPRECATED);
|
63 |
+
|
64 |
+
$defaultStrategy = 'name';
|
65 |
+
}
|
66 |
+
|
67 |
+
if ('name' === $defaultStrategy) {
|
68 |
$defaultStrategy = array('Twig_FileExtensionEscapingStrategy', 'guess');
|
69 |
}
|
70 |
|
74 |
/**
|
75 |
* Gets the default strategy to use when not defined by the user.
|
76 |
*
|
77 |
+
* @param string $name The template name
|
78 |
*
|
79 |
* @return string|false The default strategy to use for the template
|
80 |
*/
|
81 |
+
public function getDefaultStrategy($name)
|
82 |
{
|
83 |
// disable string callables to avoid calling a function named html or js,
|
84 |
// or any other upcoming escaping strategy
|
85 |
if (!is_string($this->defaultStrategy) && false !== $this->defaultStrategy) {
|
86 |
+
return call_user_func($this->defaultStrategy, $name);
|
87 |
}
|
88 |
|
89 |
return $this->defaultStrategy;
|
vendor/twig/twig/lib/Twig/Extension/Profiler.php
CHANGED
@@ -36,7 +36,7 @@ class Twig_Extension_Profiler extends Twig_Extension
|
|
36 |
|
37 |
public function getNodeVisitors()
|
38 |
{
|
39 |
-
return array(new Twig_Profiler_NodeVisitor_Profiler($this
|
40 |
}
|
41 |
|
42 |
public function getName()
|
36 |
|
37 |
public function getNodeVisitors()
|
38 |
{
|
39 |
+
return array(new Twig_Profiler_NodeVisitor_Profiler(get_class($this)));
|
40 |
}
|
41 |
|
42 |
public function getName()
|
vendor/twig/twig/lib/Twig/ExtensionInterface.php
CHANGED
@@ -82,6 +82,8 @@ interface Twig_ExtensionInterface
|
|
82 |
* Returns the name of the extension.
|
83 |
*
|
84 |
* @return string The extension name
|
|
|
|
|
85 |
*/
|
86 |
public function getName();
|
87 |
}
|
82 |
* Returns the name of the extension.
|
83 |
*
|
84 |
* @return string The extension name
|
85 |
+
*
|
86 |
+
* @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
|
87 |
*/
|
88 |
public function getName();
|
89 |
}
|
vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php
CHANGED
@@ -13,7 +13,7 @@
|
|
13 |
* Default autoescaping strategy based on file names.
|
14 |
*
|
15 |
* This strategy sets the HTML as the default autoescaping strategy,
|
16 |
-
* but changes it based on the
|
17 |
*
|
18 |
* Note that there is no runtime performance impact as the
|
19 |
* default autoescaping strategy is set at compilation time.
|
@@ -25,21 +25,21 @@ class Twig_FileExtensionEscapingStrategy
|
|
25 |
/**
|
26 |
* Guesses the best autoescaping strategy based on the file name.
|
27 |
*
|
28 |
-
* @param string $
|
29 |
*
|
30 |
* @return string|false The escaping strategy name to use or false to disable
|
31 |
*/
|
32 |
-
public static function guess($
|
33 |
{
|
34 |
-
if (in_array(substr($
|
35 |
return 'html'; // return html for directories
|
36 |
}
|
37 |
|
38 |
-
if ('.twig' === substr($
|
39 |
-
$
|
40 |
}
|
41 |
|
42 |
-
$extension = pathinfo($
|
43 |
|
44 |
switch ($extension) {
|
45 |
case 'js':
|
13 |
* Default autoescaping strategy based on file names.
|
14 |
*
|
15 |
* This strategy sets the HTML as the default autoescaping strategy,
|
16 |
+
* but changes it based on the template name.
|
17 |
*
|
18 |
* Note that there is no runtime performance impact as the
|
19 |
* default autoescaping strategy is set at compilation time.
|
25 |
/**
|
26 |
* Guesses the best autoescaping strategy based on the file name.
|
27 |
*
|
28 |
+
* @param string $name The template name
|
29 |
*
|
30 |
* @return string|false The escaping strategy name to use or false to disable
|
31 |
*/
|
32 |
+
public static function guess($name)
|
33 |
{
|
34 |
+
if (in_array(substr($name, -1), array('/', '\\'))) {
|
35 |
return 'html'; // return html for directories
|
36 |
}
|
37 |
|
38 |
+
if ('.twig' === substr($name, -5)) {
|
39 |
+
$name = substr($name, 0, -5);
|
40 |
}
|
41 |
|
42 |
+
$extension = pathinfo($name, PATHINFO_EXTENSION);
|
43 |
|
44 |
switch ($extension) {
|
45 |
case 'js':
|
vendor/twig/twig/lib/Twig/Filter/Method.php
CHANGED
@@ -37,6 +37,6 @@ class Twig_Filter_Method extends Twig_Filter
|
|
37 |
|
38 |
public function compile()
|
39 |
{
|
40 |
-
return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension
|
41 |
}
|
42 |
}
|
37 |
|
38 |
public function compile()
|
39 |
{
|
40 |
+
return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method);
|
41 |
}
|
42 |
}
|
vendor/twig/twig/lib/Twig/Function/Method.php
CHANGED
@@ -38,6 +38,6 @@ class Twig_Function_Method extends Twig_Function
|
|
38 |
|
39 |
public function compile()
|
40 |
{
|
41 |
-
return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension
|
42 |
}
|
43 |
}
|
38 |
|
39 |
public function compile()
|
40 |
{
|
41 |
+
return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method);
|
42 |
}
|
43 |
}
|
vendor/twig/twig/lib/Twig/Lexer.php
CHANGED
@@ -26,6 +26,7 @@ class Twig_Lexer implements Twig_LexerInterface
|
|
26 |
protected $states;
|
27 |
protected $brackets;
|
28 |
protected $env;
|
|
|
29 |
protected $filename;
|
30 |
protected $options;
|
31 |
protected $regexes;
|
@@ -75,8 +76,15 @@ class Twig_Lexer implements Twig_LexerInterface
|
|
75 |
/**
|
76 |
* {@inheritdoc}
|
77 |
*/
|
78 |
-
public function tokenize($code, $
|
79 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
|
81 |
$mbEncoding = mb_internal_encoding();
|
82 |
mb_internal_encoding('ASCII');
|
@@ -84,8 +92,8 @@ class Twig_Lexer implements Twig_LexerInterface
|
|
84 |
$mbEncoding = null;
|
85 |
}
|
86 |
|
87 |
-
$this->code = str_replace(array("\r\n", "\r"), "\n", $
|
88 |
-
$this->filename = $
|
89 |
$this->cursor = 0;
|
90 |
$this->lineno = 1;
|
91 |
$this->end = strlen($this->code);
|
@@ -136,7 +144,7 @@ class Twig_Lexer implements Twig_LexerInterface
|
|
136 |
mb_internal_encoding($mbEncoding);
|
137 |
}
|
138 |
|
139 |
-
return new Twig_TokenStream($this->tokens, $
|
140 |
}
|
141 |
|
142 |
protected function lexData()
|
@@ -403,7 +411,7 @@ class Twig_Lexer implements Twig_LexerInterface
|
|
403 |
protected function popState()
|
404 |
{
|
405 |
if (0 === count($this->states)) {
|
406 |
-
throw new Exception('Cannot pop state without a previous state');
|
407 |
}
|
408 |
|
409 |
$this->state = array_pop($this->states);
|
26 |
protected $states;
|
27 |
protected $brackets;
|
28 |
protected $env;
|
29 |
+
// to be renamed to $name in 2.0 (where it is private)
|
30 |
protected $filename;
|
31 |
protected $options;
|
32 |
protected $regexes;
|
76 |
/**
|
77 |
* {@inheritdoc}
|
78 |
*/
|
79 |
+
public function tokenize($code, $name = null)
|
80 |
{
|
81 |
+
if (!$code instanceof Twig_Source) {
|
82 |
+
@trigger_error(sprintf('Passing a string as the $code argument of %s() is deprecated since version 1.27 and will be removed in 2.0. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
|
83 |
+
$source = new Twig_Source($code, $name);
|
84 |
+
} else {
|
85 |
+
$source = $code;
|
86 |
+
}
|
87 |
+
|
88 |
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
|
89 |
$mbEncoding = mb_internal_encoding();
|
90 |
mb_internal_encoding('ASCII');
|
92 |
$mbEncoding = null;
|
93 |
}
|
94 |
|
95 |
+
$this->code = str_replace(array("\r\n", "\r"), "\n", $source->getCode());
|
96 |
+
$this->filename = $source->getName();
|
97 |
$this->cursor = 0;
|
98 |
$this->lineno = 1;
|
99 |
$this->end = strlen($this->code);
|
144 |
mb_internal_encoding($mbEncoding);
|
145 |
}
|
146 |
|
147 |
+
return new Twig_TokenStream($this->tokens, $source);
|
148 |
}
|
149 |
|
150 |
protected function lexData()
|
411 |
protected function popState()
|
412 |
{
|
413 |
if (0 === count($this->states)) {
|
414 |
+
throw new Exception('Cannot pop state without a previous state.');
|
415 |
}
|
416 |
|
417 |
$this->state = array_pop($this->states);
|
vendor/twig/twig/lib/Twig/LexerInterface.php
CHANGED
@@ -21,12 +21,12 @@ interface Twig_LexerInterface
|
|
21 |
/**
|
22 |
* Tokenizes a source code.
|
23 |
*
|
24 |
-
* @param string $code
|
25 |
-
* @param string
|
26 |
*
|
27 |
* @return Twig_TokenStream A token stream instance
|
28 |
*
|
29 |
* @throws Twig_Error_Syntax When the code is syntactically wrong
|
30 |
*/
|
31 |
-
public function tokenize($code, $
|
32 |
}
|
21 |
/**
|
22 |
* Tokenizes a source code.
|
23 |
*
|
24 |
+
* @param string|Twig_Source $code The source code
|
25 |
+
* @param string $name A unique identifier for the source code
|
26 |
*
|
27 |
* @return Twig_TokenStream A token stream instance
|
28 |
*
|
29 |
* @throws Twig_Error_Syntax When the code is syntactically wrong
|
30 |
*/
|
31 |
+
public function tokenize($code, $name = null);
|
32 |
}
|
vendor/twig/twig/lib/Twig/Loader/Array.php
CHANGED
@@ -21,7 +21,7 @@
|
|
21 |
*
|
22 |
* @author Fabien Potencier <fabien@symfony.com>
|
23 |
*/
|
24 |
-
class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
|
25 |
{
|
26 |
protected $templates = array();
|
27 |
|
@@ -51,6 +51,8 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
|
|
51 |
*/
|
52 |
public function getSource($name)
|
53 |
{
|
|
|
|
|
54 |
$name = (string) $name;
|
55 |
if (!isset($this->templates[$name])) {
|
56 |
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
|
@@ -59,6 +61,19 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
|
|
59 |
return $this->templates[$name];
|
60 |
}
|
61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
/**
|
63 |
* {@inheritdoc}
|
64 |
*/
|
21 |
*
|
22 |
* @author Fabien Potencier <fabien@symfony.com>
|
23 |
*/
|
24 |
+
class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
|
25 |
{
|
26 |
protected $templates = array();
|
27 |
|
51 |
*/
|
52 |
public function getSource($name)
|
53 |
{
|
54 |
+
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
|
55 |
+
|
56 |
$name = (string) $name;
|
57 |
if (!isset($this->templates[$name])) {
|
58 |
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
|
61 |
return $this->templates[$name];
|
62 |
}
|
63 |
|
64 |
+
/**
|
65 |
+
* {@inheritdoc}
|
66 |
+
*/
|
67 |
+
public function getSourceContext($name)
|
68 |
+
{
|
69 |
+
$name = (string) $name;
|
70 |
+
if (!isset($this->templates[$name])) {
|
71 |
+
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
|
72 |
+
}
|
73 |
+
|
74 |
+
return new Twig_Source($this->templates[$name], $name);
|
75 |
+
}
|
76 |
+
|
77 |
/**
|
78 |
* {@inheritdoc}
|
79 |
*/
|
vendor/twig/twig/lib/Twig/Loader/Chain.php
CHANGED
@@ -14,7 +14,7 @@
|
|
14 |
*
|
15 |
* @author Fabien Potencier <fabien@symfony.com>
|
16 |
*/
|
17 |
-
class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
|
18 |
{
|
19 |
private $hasSourceCache = array();
|
20 |
protected $loaders = array();
|
@@ -47,6 +47,8 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
|
|
47 |
*/
|
48 |
public function getSource($name)
|
49 |
{
|
|
|
|
|
50 |
$exceptions = array();
|
51 |
foreach ($this->loaders as $loader) {
|
52 |
if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
|
@@ -63,6 +65,31 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
|
|
63 |
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
|
64 |
}
|
65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
/**
|
67 |
* {@inheritdoc}
|
68 |
*/
|
@@ -84,7 +111,11 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
|
|
84 |
}
|
85 |
|
86 |
try {
|
87 |
-
$loader
|
|
|
|
|
|
|
|
|
88 |
|
89 |
return $this->hasSourceCache[$name] = true;
|
90 |
} catch (Twig_Error_Loader $e) {
|
14 |
*
|
15 |
* @author Fabien Potencier <fabien@symfony.com>
|
16 |
*/
|
17 |
+
class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
|
18 |
{
|
19 |
private $hasSourceCache = array();
|
20 |
protected $loaders = array();
|
47 |
*/
|
48 |
public function getSource($name)
|
49 |
{
|
50 |
+
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
|
51 |
+
|
52 |
$exceptions = array();
|
53 |
foreach ($this->loaders as $loader) {
|
54 |
if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
|
65 |
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
|
66 |
}
|
67 |
|
68 |
+
/**
|
69 |
+
* {@inheritdoc}
|
70 |
+
*/
|
71 |
+
public function getSourceContext($name)
|
72 |
+
{
|
73 |
+
$exceptions = array();
|
74 |
+
foreach ($this->loaders as $loader) {
|
75 |
+
if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
|
76 |
+
continue;
|
77 |
+
}
|
78 |
+
|
79 |
+
try {
|
80 |
+
if ($loader instanceof Twig_SourceContextLoaderInterface) {
|
81 |
+
return $loader->getSourceContext($name);
|
82 |
+
}
|
83 |
+
|
84 |
+
return new Twig_Source($loader->getSource($name), $name);
|
85 |
+
} catch (Twig_Error_Loader $e) {
|
86 |
+
$exceptions[] = $e->getMessage();
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
|
91 |
+
}
|
92 |
+
|
93 |
/**
|
94 |
* {@inheritdoc}
|
95 |
*/
|
111 |
}
|
112 |
|
113 |
try {
|
114 |
+
if ($loader instanceof Twig_SourceContextLoaderInterface) {
|
115 |
+
$loader->getSourceContext($name);
|
116 |
+
} else {
|
117 |
+
$loader->getSource($name);
|
118 |
+
}
|
119 |
|
120 |
return $this->hasSourceCache[$name] = true;
|
121 |
} catch (Twig_Error_Loader $e) {
|
vendor/twig/twig/lib/Twig/Loader/Filesystem.php
CHANGED
@@ -14,7 +14,7 @@
|
|
14 |
*
|
15 |
* @author Fabien Potencier <fabien@symfony.com>
|
16 |
*/
|
17 |
-
class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
|
18 |
{
|
19 |
/** Identifier of the main namespace. */
|
20 |
const MAIN_NAMESPACE = '__main__';
|
@@ -23,13 +23,21 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
|
|
23 |
protected $cache = array();
|
24 |
protected $errorCache = array();
|
25 |
|
|
|
|
|
26 |
/**
|
27 |
* Constructor.
|
28 |
*
|
29 |
-
* @param string|array $paths
|
|
|
30 |
*/
|
31 |
-
public function __construct($paths = array())
|
32 |
{
|
|
|
|
|
|
|
|
|
|
|
33 |
if ($paths) {
|
34 |
$this->setPaths($paths);
|
35 |
}
|
@@ -81,7 +89,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
|
|
81 |
* Adds a path where templates are stored.
|
82 |
*
|
83 |
* @param string $path A path where to look for templates
|
84 |
-
* @param string $namespace A path
|
85 |
*
|
86 |
* @throws Twig_Error_Loader
|
87 |
*/
|
@@ -90,8 +98,9 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
|
|
90 |
// invalidate the cache
|
91 |
$this->cache = $this->errorCache = array();
|
92 |
|
93 |
-
|
94 |
-
|
|
|
95 |
}
|
96 |
|
97 |
$this->paths[$namespace][] = rtrim($path, '/\\');
|
@@ -101,7 +110,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
|
|
101 |
* Prepends a path where templates are stored.
|
102 |
*
|
103 |
* @param string $path A path where to look for templates
|
104 |
-
* @param string $namespace A path
|
105 |
*
|
106 |
* @throws Twig_Error_Loader
|
107 |
*/
|
@@ -110,8 +119,9 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
|
|
110 |
// invalidate the cache
|
111 |
$this->cache = $this->errorCache = array();
|
112 |
|
113 |
-
|
114 |
-
|
|
|
115 |
}
|
116 |
|
117 |
$path = rtrim($path, '/\\');
|
@@ -128,15 +138,33 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
|
|
128 |
*/
|
129 |
public function getSource($name)
|
130 |
{
|
|
|
|
|
131 |
return file_get_contents($this->findTemplate($name));
|
132 |
}
|
133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
/**
|
135 |
* {@inheritdoc}
|
136 |
*/
|
137 |
public function getCacheKey($name)
|
138 |
{
|
139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
}
|
141 |
|
142 |
/**
|
@@ -153,6 +181,8 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
|
|
153 |
try {
|
154 |
return false !== $this->findTemplate($name, false);
|
155 |
} catch (Twig_Error_Loader $exception) {
|
|
|
|
|
156 |
return false;
|
157 |
}
|
158 |
}
|
@@ -197,6 +227,10 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
|
|
197 |
}
|
198 |
|
199 |
foreach ($this->paths[$namespace] as $path) {
|
|
|
|
|
|
|
|
|
200 |
if (is_file($path.'/'.$shortname)) {
|
201 |
if (false !== $realpath = realpath($path.'/'.$shortname)) {
|
202 |
return $this->cache[$name] = $realpath;
|
@@ -257,4 +291,15 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
|
|
257 |
}
|
258 |
}
|
259 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
}
|
14 |
*
|
15 |
* @author Fabien Potencier <fabien@symfony.com>
|
16 |
*/
|
17 |
+
class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
|
18 |
{
|
19 |
/** Identifier of the main namespace. */
|
20 |
const MAIN_NAMESPACE = '__main__';
|
23 |
protected $cache = array();
|
24 |
protected $errorCache = array();
|
25 |
|
26 |
+
private $rootPath;
|
27 |
+
|
28 |
/**
|
29 |
* Constructor.
|
30 |
*
|
31 |
+
* @param string|array $paths A path or an array of paths where to look for templates
|
32 |
+
* @param string|null $rootPath The root path common to all relative paths (null for getcwd())
|
33 |
*/
|
34 |
+
public function __construct($paths = array(), $rootPath = null)
|
35 |
{
|
36 |
+
$this->rootPath = (null === $rootPath ? getcwd() : $rootPath).DIRECTORY_SEPARATOR;
|
37 |
+
if (false !== $realPath = realpath($rootPath)) {
|
38 |
+
$this->rootPath = $realPath.DIRECTORY_SEPARATOR;
|
39 |
+
}
|
40 |
+
|
41 |
if ($paths) {
|
42 |
$this->setPaths($paths);
|
43 |
}
|
89 |
* Adds a path where templates are stored.
|
90 |
*
|
91 |
* @param string $path A path where to look for templates
|
92 |
+
* @param string $namespace A path namespace
|
93 |
*
|
94 |
* @throws Twig_Error_Loader
|
95 |
*/
|
98 |
// invalidate the cache
|
99 |
$this->cache = $this->errorCache = array();
|
100 |
|
101 |
+
$checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
|
102 |
+
if (!is_dir($checkPath)) {
|
103 |
+
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
|
104 |
}
|
105 |
|
106 |
$this->paths[$namespace][] = rtrim($path, '/\\');
|
110 |
* Prepends a path where templates are stored.
|
111 |
*
|
112 |
* @param string $path A path where to look for templates
|
113 |
+
* @param string $namespace A path namespace
|
114 |
*
|
115 |
* @throws Twig_Error_Loader
|
116 |
*/
|
119 |
// invalidate the cache
|
120 |
$this->cache = $this->errorCache = array();
|
121 |
|
122 |
+
$checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
|
123 |
+
if (!is_dir($checkPath)) {
|
124 |
+
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
|
125 |
}
|
126 |
|
127 |
$path = rtrim($path, '/\\');
|
138 |
*/
|
139 |
public function getSource($name)
|
140 |
{
|
141 |
+
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
|
142 |
+
|
143 |
return file_get_contents($this->findTemplate($name));
|
144 |
}
|
145 |
|
146 |
+
/**
|
147 |
+
* {@inheritdoc}
|
148 |
+
*/
|
149 |
+
public function getSourceContext($name)
|
150 |
+
{
|
151 |
+
$path = $this->findTemplate($name);
|
152 |
+
|
153 |
+
return new Twig_Source(file_get_contents($path), $name, $path);
|
154 |
+
}
|
155 |
+
|
156 |
/**
|
157 |
* {@inheritdoc}
|
158 |
*/
|
159 |
public function getCacheKey($name)
|
160 |
{
|
161 |
+
$path = $this->findTemplate($name);
|
162 |
+
$len = strlen($this->rootPath);
|
163 |
+
if (0 === strncmp($this->rootPath, $path, $len)) {
|
164 |
+
return substr($path, $len);
|
165 |
+
}
|
166 |
+
|
167 |
+
return $path;
|
168 |
}
|
169 |
|
170 |
/**
|
181 |
try {
|
182 |
return false !== $this->findTemplate($name, false);
|
183 |
} catch (Twig_Error_Loader $exception) {
|
184 |
+
@trigger_error(sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', get_class($this)), E_USER_DEPRECATED);
|
185 |
+
|
186 |
return false;
|
187 |
}
|
188 |
}
|
227 |
}
|
228 |
|
229 |
foreach ($this->paths[$namespace] as $path) {
|
230 |
+
if (!$this->isAbsolutePath($path)) {
|
231 |
+
$path = $this->rootPath.'/'.$path;
|
232 |
+
}
|
233 |
+
|
234 |
if (is_file($path.'/'.$shortname)) {
|
235 |
if (false !== $realpath = realpath($path.'/'.$shortname)) {
|
236 |
return $this->cache[$name] = $realpath;
|
291 |
}
|
292 |
}
|
293 |
}
|
294 |
+
|
295 |
+
private function isAbsolutePath($file)
|
296 |
+
{
|
297 |
+
return strspn($file, '/\\', 0, 1)
|
298 |
+
|| (strlen($file) > 3 && ctype_alpha($file[0])
|
299 |
+
&& substr($file, 1, 1) === ':'
|
300 |
+
&& strspn($file, '/\\', 2, 1)
|
301 |
+
)
|
302 |
+
|| null !== parse_url($file, PHP_URL_SCHEME)
|
303 |
+
;
|
304 |
+
}
|
305 |
}
|
vendor/twig/twig/lib/Twig/Loader/String.php
CHANGED
@@ -27,16 +27,26 @@
|
|
27 |
*
|
28 |
* @author Fabien Potencier <fabien@symfony.com>
|
29 |
*/
|
30 |
-
class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
|
31 |
{
|
32 |
/**
|
33 |
* {@inheritdoc}
|
34 |
*/
|
35 |
public function getSource($name)
|
36 |
{
|
|
|
|
|
37 |
return $name;
|
38 |
}
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
/**
|
41 |
* {@inheritdoc}
|
42 |
*/
|
27 |
*
|
28 |
* @author Fabien Potencier <fabien@symfony.com>
|
29 |
*/
|
30 |
+
class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
|
31 |
{
|
32 |
/**
|
33 |
* {@inheritdoc}
|
34 |
*/
|
35 |
public function getSource($name)
|
36 |
{
|
37 |
+
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
|
38 |
+
|
39 |
return $name;
|
40 |
}
|
41 |
|
42 |
+
/**
|
43 |
+
* {@inheritdoc}
|
44 |
+
*/
|
45 |
+
public function getSourceContext($name)
|
46 |
+
{
|
47 |
+
return new Twig_Source($name, $name);
|
48 |
+
}
|
49 |
+
|
50 |
/**
|
51 |
* {@inheritdoc}
|
52 |
*/
|
vendor/twig/twig/lib/Twig/LoaderInterface.php
CHANGED
@@ -24,6 +24,8 @@ interface Twig_LoaderInterface
|
|
24 |
* @return string The template source code
|
25 |
*
|
26 |
* @throws Twig_Error_Loader When $name is not found
|
|
|
|
|
27 |
*/
|
28 |
public function getSource($name);
|
29 |
|
24 |
* @return string The template source code
|
25 |
*
|
26 |
* @throws Twig_Error_Loader When $name is not found
|
27 |
+
*
|
28 |
+
* @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface
|
29 |
*/
|
30 |
public function getSource($name);
|
31 |
|
vendor/twig/twig/lib/Twig/Node.php
CHANGED
@@ -22,6 +22,8 @@ class Twig_Node implements Twig_NodeInterface
|
|
22 |
protected $lineno;
|
23 |
protected $tag;
|
24 |
|
|
|
|
|
25 |
/**
|
26 |
* Constructor.
|
27 |
*
|
@@ -35,6 +37,11 @@ class Twig_Node implements Twig_NodeInterface
|
|
35 |
*/
|
36 |
public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null)
|
37 |
{
|
|
|
|
|
|
|
|
|
|
|
38 |
$this->nodes = $nodes;
|
39 |
$this->attributes = $attributes;
|
40 |
$this->lineno = $lineno;
|
@@ -111,8 +118,18 @@ class Twig_Node implements Twig_NodeInterface
|
|
111 |
}
|
112 |
}
|
113 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
public function getLine()
|
115 |
{
|
|
|
|
|
116 |
return $this->lineno;
|
117 |
}
|
118 |
|
@@ -206,6 +223,10 @@ class Twig_Node implements Twig_NodeInterface
|
|
206 |
*/
|
207 |
public function setNode($name, $node = null)
|
208 |
{
|
|
|
|
|
|
|
|
|
209 |
$this->nodes[$name] = $node;
|
210 |
}
|
211 |
|
@@ -228,4 +249,39 @@ class Twig_Node implements Twig_NodeInterface
|
|
228 |
{
|
229 |
return new ArrayIterator($this->nodes);
|
230 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
}
|
22 |
protected $lineno;
|
23 |
protected $tag;
|
24 |
|
25 |
+
private $name;
|
26 |
+
|
27 |
/**
|
28 |
* Constructor.
|
29 |
*
|
37 |
*/
|
38 |
public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null)
|
39 |
{
|
40 |
+
foreach ($nodes as $name => $node) {
|
41 |
+
if (!$node instanceof Twig_NodeInterface) {
|
42 |
+
@trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', is_object($node) ? get_class($node) : null === $node ? 'null' : gettype($node), $name, get_class($this)), E_USER_DEPRECATED);
|
43 |
+
}
|
44 |
+
}
|
45 |
$this->nodes = $nodes;
|
46 |
$this->attributes = $attributes;
|
47 |
$this->lineno = $lineno;
|
118 |
}
|
119 |
}
|
120 |
|
121 |
+
public function getTemplateLine()
|
122 |
+
{
|
123 |
+
return $this->lineno;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* @deprecated since 1.27 (to be removed in 2.0)
|
128 |
+
*/
|
129 |
public function getLine()
|
130 |
{
|
131 |
+
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateName() instead.', E_USER_DEPRECATED);
|
132 |
+
|
133 |
return $this->lineno;
|
134 |
}
|
135 |
|
223 |
*/
|
224 |
public function setNode($name, $node = null)
|
225 |
{
|
226 |
+
if (!$node instanceof Twig_NodeInterface) {
|
227 |
+
@trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', is_object($node) ? get_class($node) : null === $node ? 'null' : gettype($node), $name, get_class($this)), E_USER_DEPRECATED);
|
228 |
+
}
|
229 |
+
|
230 |
$this->nodes[$name] = $node;
|
231 |
}
|
232 |
|
249 |
{
|
250 |
return new ArrayIterator($this->nodes);
|
251 |
}
|
252 |
+
|
253 |
+
public function setTemplateName($name)
|
254 |
+
{
|
255 |
+
$this->name = $name;
|
256 |
+
foreach ($this->nodes as $node) {
|
257 |
+
if (null !== $node) {
|
258 |
+
$node->setTemplateName($name);
|
259 |
+
}
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
public function getTemplateName()
|
264 |
+
{
|
265 |
+
return $this->name;
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* @deprecated since 1.27 (to be removed in 2.0)
|
270 |
+
*/
|
271 |
+
public function setFilename($name)
|
272 |
+
{
|
273 |
+
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use setTemplateName() instead.', E_USER_DEPRECATED);
|
274 |
+
|
275 |
+
$this->setTemplateName($name);
|
276 |
+
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* @deprecated since 1.27 (to be removed in 2.0)
|
280 |
+
*/
|
281 |
+
public function getFilename()
|
282 |
+
{
|
283 |
+
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateName() instead.', E_USER_DEPRECATED);
|
284 |
+
|
285 |
+
return $this->name;
|
286 |
+
}
|
287 |
}
|
vendor/twig/twig/lib/Twig/Node/CheckSecurity.php
CHANGED
@@ -33,7 +33,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
|
|
33 |
foreach (array('tags', 'filters', 'functions') as $type) {
|
34 |
foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
|
35 |
if ($node instanceof Twig_Node) {
|
36 |
-
${$type}[$name] = $node->
|
37 |
} else {
|
38 |
${$type}[$node] = null;
|
39 |
}
|
@@ -46,7 +46,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
|
|
46 |
->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
|
47 |
->write("try {\n")
|
48 |
->indent()
|
49 |
-
->write("\$this->env->getExtension('
|
50 |
->indent()
|
51 |
->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n")
|
52 |
->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n")
|
@@ -56,7 +56,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
|
|
56 |
->outdent()
|
57 |
->write("} catch (Twig_Sandbox_SecurityError \$e) {\n")
|
58 |
->indent()
|
59 |
-
->write("\$e->
|
60 |
->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
|
61 |
->indent()
|
62 |
->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
|
33 |
foreach (array('tags', 'filters', 'functions') as $type) {
|
34 |
foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
|
35 |
if ($node instanceof Twig_Node) {
|
36 |
+
${$type}[$name] = $node->getTemplateLine();
|
37 |
} else {
|
38 |
${$type}[$node] = null;
|
39 |
}
|
46 |
->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
|
47 |
->write("try {\n")
|
48 |
->indent()
|
49 |
+
->write("\$this->env->getExtension('Twig_Extension_Sandbox')->checkSecurity(\n")
|
50 |
->indent()
|
51 |
->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n")
|
52 |
->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n")
|
56 |
->outdent()
|
57 |
->write("} catch (Twig_Sandbox_SecurityError \$e) {\n")
|
58 |
->indent()
|
59 |
+
->write("\$e->setTemplateName(\$this->getTemplateName());\n\n")
|
60 |
->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
|
61 |
->indent()
|
62 |
->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
|
vendor/twig/twig/lib/Twig/Node/Embed.php
CHANGED
@@ -17,11 +17,13 @@
|
|
17 |
class Twig_Node_Embed extends Twig_Node_Include
|
18 |
{
|
19 |
// we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
|
20 |
-
public function __construct($
|
21 |
{
|
22 |
parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
|
23 |
|
24 |
-
$this->setAttribute('
|
|
|
|
|
25 |
$this->setAttribute('index', $index);
|
26 |
}
|
27 |
|
@@ -29,11 +31,11 @@ class Twig_Node_Embed extends Twig_Node_Include
|
|
29 |
{
|
30 |
$compiler
|
31 |
->write('$this->loadTemplate(')
|
32 |
-
->string($this->getAttribute('
|
33 |
->raw(', ')
|
34 |
-
->repr($
|
35 |
->raw(', ')
|
36 |
-
->repr($this->
|
37 |
->raw(', ')
|
38 |
->string($this->getAttribute('index'))
|
39 |
->raw(')')
|
17 |
class Twig_Node_Embed extends Twig_Node_Include
|
18 |
{
|
19 |
// we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
|
20 |
+
public function __construct($name, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
|
21 |
{
|
22 |
parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
|
23 |
|
24 |
+
$this->setAttribute('name', $name);
|
25 |
+
// to be removed in 2.0, used name instead
|
26 |
+
$this->setAttribute('filename', $name);
|
27 |
$this->setAttribute('index', $index);
|
28 |
}
|
29 |
|
31 |
{
|
32 |
$compiler
|
33 |
->write('$this->loadTemplate(')
|
34 |
+
->string($this->getAttribute('name'))
|
35 |
->raw(', ')
|
36 |
+
->repr($this->getTemplateName())
|
37 |
->raw(', ')
|
38 |
+
->repr($this->getTemplateLine())
|
39 |
->raw(', ')
|
40 |
->string($this->getAttribute('index'))
|
41 |
->raw(')')
|
vendor/twig/twig/lib/Twig/Node/Expression/Array.php
CHANGED
@@ -54,7 +54,7 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
|
|
54 |
public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null)
|
55 |
{
|
56 |
if (null === $key) {
|
57 |
-
$key = new Twig_Node_Expression_Constant(++$this->index, $value->
|
58 |
}
|
59 |
|
60 |
array_push($this->nodes, $key, $value);
|
54 |
public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null)
|
55 |
{
|
56 |
if (null === $key) {
|
57 |
+
$key = new Twig_Node_Expression_Constant(++$this->index, $value->getTemplateLine());
|
58 |
}
|
59 |
|
60 |
array_push($this->nodes, $key, $value);
|
vendor/twig/twig/lib/Twig/Node/Expression/Call.php
CHANGED
@@ -10,18 +10,29 @@
|
|
10 |
*/
|
11 |
abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
12 |
{
|
|
|
|
|
13 |
protected function compileCallable(Twig_Compiler $compiler)
|
14 |
{
|
15 |
$closingParenthesis = false;
|
16 |
if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
|
17 |
-
if (is_string($callable)) {
|
18 |
$compiler->raw($callable);
|
19 |
-
} elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) {
|
20 |
-
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', $callable[0]->getName(), $callable[1]));
|
21 |
} else {
|
22 |
-
$
|
23 |
-
|
24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
26 |
} else {
|
27 |
$compiler->raw($this->getAttribute('thing')->compile());
|
@@ -71,7 +82,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
|
71 |
$first = false;
|
72 |
}
|
73 |
|
74 |
-
if ($this->hasNode('arguments')
|
75 |
$callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
|
76 |
|
77 |
$arguments = $this->getArguments($callable, $this->getNode('arguments'));
|
@@ -121,7 +132,6 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
|
121 |
throw new LogicException($message);
|
122 |
}
|
123 |
|
124 |
-
// manage named arguments
|
125 |
$callableParameters = $this->getCallableParameters($callable, $isVariadic);
|
126 |
$arguments = array();
|
127 |
$names = array();
|
@@ -195,7 +205,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
|
195 |
throw new Twig_Error_Syntax(sprintf(
|
196 |
'Unknown argument%s "%s" for %s "%s(%s)".',
|
197 |
count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)
|
198 |
-
), $unknownParameter ? $unknownParameter->
|
199 |
}
|
200 |
|
201 |
return $arguments;
|
@@ -208,15 +218,9 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
|
208 |
|
209 |
private function getCallableParameters($callable, $isVariadic)
|
210 |
{
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
$r = new ReflectionObject($callable);
|
215 |
-
$r = $r->getMethod('__invoke');
|
216 |
-
} elseif (is_string($callable) && false !== strpos($callable, '::')) {
|
217 |
-
$r = new ReflectionMethod($callable);
|
218 |
-
} else {
|
219 |
-
$r = new ReflectionFunction($callable);
|
220 |
}
|
221 |
|
222 |
$parameters = $r->getParameters();
|
@@ -250,4 +254,36 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
|
250 |
|
251 |
return $parameters;
|
252 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
}
|
10 |
*/
|
11 |
abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
12 |
{
|
13 |
+
private $reflector;
|
14 |
+
|
15 |
protected function compileCallable(Twig_Compiler $compiler)
|
16 |
{
|
17 |
$closingParenthesis = false;
|
18 |
if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
|
19 |
+
if (is_string($callable) && false === strpos($callable, '::')) {
|
20 |
$compiler->raw($callable);
|
|
|
|
|
21 |
} else {
|
22 |
+
list($r, $callable) = $this->reflectCallable($callable);
|
23 |
+
if ($r instanceof ReflectionMethod && is_string($callable[0])) {
|
24 |
+
if ($r->isStatic()) {
|
25 |
+
$compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
|
26 |
+
} else {
|
27 |
+
$compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
|
28 |
+
}
|
29 |
+
} elseif ($r instanceof ReflectionMethod && $callable[0] instanceof Twig_ExtensionInterface) {
|
30 |
+
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', get_class($callable[0]), $callable[1]));
|
31 |
+
} else {
|
32 |
+
$type = ucfirst($this->getAttribute('type'));
|
33 |
+
$compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name')));
|
34 |
+
$closingParenthesis = true;
|
35 |
+
}
|
36 |
}
|
37 |
} else {
|
38 |
$compiler->raw($this->getAttribute('thing')->compile());
|
82 |
$first = false;
|
83 |
}
|
84 |
|
85 |
+
if ($this->hasNode('arguments')) {
|
86 |
$callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
|
87 |
|
88 |
$arguments = $this->getArguments($callable, $this->getNode('arguments'));
|
132 |
throw new LogicException($message);
|
133 |
}
|
134 |
|
|
|
135 |
$callableParameters = $this->getCallableParameters($callable, $isVariadic);
|
136 |
$arguments = array();
|
137 |
$names = array();
|
205 |
throw new Twig_Error_Syntax(sprintf(
|
206 |
'Unknown argument%s "%s" for %s "%s(%s)".',
|
207 |
count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)
|
208 |
+
), $unknownParameter ? $unknownParameter->getTemplateLine() : -1);
|
209 |
}
|
210 |
|
211 |
return $arguments;
|
218 |
|
219 |
private function getCallableParameters($callable, $isVariadic)
|
220 |
{
|
221 |
+
list($r, $_) = $this->reflectCallable($callable);
|
222 |
+
if (null === $r) {
|
223 |
+
return array();
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
}
|
225 |
|
226 |
$parameters = $r->getParameters();
|
254 |
|
255 |
return $parameters;
|
256 |
}
|
257 |
+
|
258 |
+
private function reflectCallable($callable)
|
259 |
+
{
|
260 |
+
if (null !== $this->reflector) {
|
261 |
+
return $this->reflector;
|
262 |
+
}
|
263 |
+
|
264 |
+
if (is_array($callable)) {
|
265 |
+
if (!method_exists($callable[0], $callable[1])) {
|
266 |
+
// __call()
|
267 |
+
return array(null, array());
|
268 |
+
}
|
269 |
+
$r = new ReflectionMethod($callable[0], $callable[1]);
|
270 |
+
} elseif (is_object($callable) && !$callable instanceof Closure) {
|
271 |
+
$r = new ReflectionObject($callable);
|
272 |
+
$r = $r->getMethod('__invoke');
|
273 |
+
$callable = array($callable, '__invoke');
|
274 |
+
} elseif (is_string($callable) && false !== $pos = strpos($callable, '::')) {
|
275 |
+
$class = substr($callable, 0, $pos);
|
276 |
+
$method = substr($callable, $pos + 2);
|
277 |
+
if (!method_exists($class, $method)) {
|
278 |
+
// __staticCall()
|
279 |
+
return array(null, array());
|
280 |
+
}
|
281 |
+
$r = new ReflectionMethod($callable);
|
282 |
+
$callable = array($class, $method);
|
283 |
+
} else {
|
284 |
+
$r = new ReflectionFunction($callable);
|
285 |
+
}
|
286 |
+
|
287 |
+
return $this->reflector = array($r, $callable);
|
288 |
+
}
|
289 |
}
|
vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php
CHANGED
@@ -22,13 +22,13 @@ class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter
|
|
22 |
{
|
23 |
public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
|
24 |
{
|
25 |
-
$default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->
|
26 |
|
27 |
if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) {
|
28 |
-
$test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->
|
29 |
-
$false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->
|
30 |
|
31 |
-
$node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->
|
32 |
} else {
|
33 |
$node = $default;
|
34 |
}
|
22 |
{
|
23 |
public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
|
24 |
{
|
25 |
+
$default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine());
|
26 |
|
27 |
if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) {
|
28 |
+
$test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getTemplateLine());
|
29 |
+
$false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getTemplateLine());
|
30 |
|
31 |
+
$node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getTemplateLine());
|
32 |
} else {
|
33 |
$node = $default;
|
34 |
}
|
vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php
CHANGED
@@ -13,7 +13,12 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
|
|
13 |
{
|
14 |
public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression $arguments = null, $type, $lineno)
|
15 |
{
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
17 |
}
|
18 |
|
19 |
public function compile(Twig_Compiler $compiler)
|
@@ -36,10 +41,10 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
|
|
36 |
$needFourth = $this->getAttribute('ignore_strict_check');
|
37 |
$needThird = $needFourth || $this->getAttribute('is_defined_test');
|
38 |
$needSecond = $needThird || Twig_Template::ANY_CALL !== $this->getAttribute('type');
|
39 |
-
$needFirst = $needSecond ||
|
40 |
|
41 |
if ($needFirst) {
|
42 |
-
if (
|
43 |
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
|
44 |
} else {
|
45 |
$compiler->raw(', array()');
|
13 |
{
|
14 |
public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression $arguments = null, $type, $lineno)
|
15 |
{
|
16 |
+
$nodes = array('node' => $node, 'attribute' => $attribute);
|
17 |
+
if (null !== $arguments) {
|
18 |
+
$nodes['arguments'] = $arguments;
|
19 |
+
}
|
20 |
+
|
21 |
+
parent::__construct($nodes, array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno);
|
22 |
}
|
23 |
|
24 |
public function compile(Twig_Compiler $compiler)
|
41 |
$needFourth = $this->getAttribute('ignore_strict_check');
|
42 |
$needThird = $needFourth || $this->getAttribute('is_defined_test');
|
43 |
$needSecond = $needThird || Twig_Template::ANY_CALL !== $this->getAttribute('type');
|
44 |
+
$needFirst = $needSecond || $this->hasNode('arguments');
|
45 |
|
46 |
if ($needFirst) {
|
47 |
+
if ($this->hasNode('arguments')) {
|
48 |
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
|
49 |
} else {
|
50 |
$compiler->raw(', array()');
|
vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php
CHANGED
@@ -13,9 +13,9 @@ class Twig_Node_Expression_NullCoalesce extends Twig_Node_Expression_Conditional
|
|
13 |
public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
|
14 |
{
|
15 |
$test = new Twig_Node_Expression_Binary_And(
|
16 |
-
new Twig_Node_Expression_Test_Defined(clone $left, 'defined', new Twig_Node(), $left->
|
17 |
-
new Twig_Node_Expression_Unary_Not(new Twig_Node_Expression_Test_Null($left, 'null', new Twig_Node(), $left->
|
18 |
-
$left->
|
19 |
);
|
20 |
|
21 |
parent::__construct($test, $left, $right, $lineno);
|
13 |
public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
|
14 |
{
|
15 |
$test = new Twig_Node_Expression_Binary_And(
|
16 |
+
new Twig_Node_Expression_Test_Defined(clone $left, 'defined', new Twig_Node(), $left->getTemplateLine()),
|
17 |
+
new Twig_Node_Expression_Unary_Not(new Twig_Node_Expression_Test_Null($left, 'null', new Twig_Node(), $left->getTemplateLine()), $left->getTemplateLine()),
|
18 |
+
$left->getTemplateLine()
|
19 |
);
|
20 |
|
21 |
parent::__construct($test, $left, $right, $lineno);
|
vendor/twig/twig/lib/Twig/Node/Expression/Test.php
CHANGED
@@ -12,7 +12,12 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression_Call
|
|
12 |
{
|
13 |
public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
|
14 |
{
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
16 |
}
|
17 |
|
18 |
public function compile(Twig_Compiler $compiler)
|
12 |
{
|
13 |
public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
|
14 |
{
|
15 |
+
$nodes = array('node' => $node);
|
16 |
+
if (null !== $arguments) {
|
17 |
+
$nodes['arguments'] = $arguments;
|
18 |
+
}
|
19 |
+
|
20 |
+
parent::__construct($nodes, array('name' => $name), $lineno);
|
21 |
}
|
22 |
|
23 |
public function compile(Twig_Compiler $compiler)
|
vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php
CHANGED
@@ -32,9 +32,9 @@ class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test
|
|
32 |
|
33 |
$this->changeIgnoreStrictCheck($node);
|
34 |
} elseif ($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array) {
|
35 |
-
$node = new Twig_Node_Expression_Constant(true, $node->
|
36 |
} else {
|
37 |
-
throw new Twig_Error_Syntax('The "defined" test only works with simple variables.', $this->
|
38 |
}
|
39 |
|
40 |
parent::__construct($node, $name, $arguments, $lineno);
|
32 |
|
33 |
$this->changeIgnoreStrictCheck($node);
|
34 |
} elseif ($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array) {
|
35 |
+
$node = new Twig_Node_Expression_Constant(true, $node->getTemplateLine());
|
36 |
} else {
|
37 |
+
throw new Twig_Error_Syntax('The "defined" test only works with simple variables.', $this->getTemplateLine());
|
38 |
}
|
39 |
|
40 |
parent::__construct($node, $name, $arguments, $lineno);
|
vendor/twig/twig/lib/Twig/Node/For.php
CHANGED
@@ -27,7 +27,12 @@ class Twig_Node_For extends Twig_Node
|
|
27 |
$body = new Twig_Node_If(new Twig_Node(array($ifexpr, $body)), null, $lineno, $tag);
|
28 |
}
|
29 |
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
31 |
}
|
32 |
|
33 |
public function compile(Twig_Compiler $compiler)
|
@@ -40,7 +45,7 @@ class Twig_Node_For extends Twig_Node
|
|
40 |
->raw(");\n")
|
41 |
;
|
42 |
|
43 |
-
if (
|
44 |
$compiler->write("\$context['_iterated'] = false;\n");
|
45 |
}
|
46 |
|
@@ -69,7 +74,7 @@ class Twig_Node_For extends Twig_Node
|
|
69 |
}
|
70 |
}
|
71 |
|
72 |
-
$this->loop->setAttribute('else',
|
73 |
$this->loop->setAttribute('with_loop', $this->getAttribute('with_loop'));
|
74 |
$this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr'));
|
75 |
|
@@ -85,7 +90,7 @@ class Twig_Node_For extends Twig_Node
|
|
85 |
->write("}\n")
|
86 |
;
|
87 |
|
88 |
-
if (
|
89 |
$compiler
|
90 |
->write("if (!\$context['_iterated']) {\n")
|
91 |
->indent()
|
27 |
$body = new Twig_Node_If(new Twig_Node(array($ifexpr, $body)), null, $lineno, $tag);
|
28 |
}
|
29 |
|
30 |
+
$nodes = array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body);
|
31 |
+
if (null !== $else) {
|
32 |
+
$nodes['else'] = $else;
|
33 |
+
}
|
34 |
+
|
35 |
+
parent::__construct($nodes, array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag);
|
36 |
}
|
37 |
|
38 |
public function compile(Twig_Compiler $compiler)
|
45 |
->raw(");\n")
|
46 |
;
|
47 |
|
48 |
+
if ($this->hasNode('else')) {
|
49 |
$compiler->write("\$context['_iterated'] = false;\n");
|
50 |
}
|
51 |
|
74 |
}
|
75 |
}
|
76 |
|
77 |
+
$this->loop->setAttribute('else', $this->hasNode('else'));
|
78 |
$this->loop->setAttribute('with_loop', $this->getAttribute('with_loop'));
|
79 |
$this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr'));
|
80 |
|
90 |
->write("}\n")
|
91 |
;
|
92 |
|
93 |
+
if ($this->hasNode('else')) {
|
94 |
$compiler
|
95 |
->write("if (!\$context['_iterated']) {\n")
|
96 |
->indent()
|
vendor/twig/twig/lib/Twig/Node/If.php
CHANGED
@@ -19,7 +19,12 @@ class Twig_Node_If extends Twig_Node
|
|
19 |
{
|
20 |
public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null)
|
21 |
{
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
24 |
|
25 |
public function compile(Twig_Compiler $compiler)
|
@@ -45,7 +50,7 @@ class Twig_Node_If extends Twig_Node
|
|
45 |
;
|
46 |
}
|
47 |
|
48 |
-
if ($this->hasNode('else')
|
49 |
$compiler
|
50 |
->outdent()
|
51 |
->write("} else {\n")
|
19 |
{
|
20 |
public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null)
|
21 |
{
|
22 |
+
$nodes = array('tests' => $tests);
|
23 |
+
if (null !== $else) {
|
24 |
+
$nodes['else'] = $else;
|
25 |
+
}
|
26 |
+
|
27 |
+
parent::__construct($nodes, array(), $lineno, $tag);
|
28 |
}
|
29 |
|
30 |
public function compile(Twig_Compiler $compiler)
|
50 |
;
|
51 |
}
|
52 |
|
53 |
+
if ($this->hasNode('else')) {
|
54 |
$compiler
|
55 |
->outdent()
|
56 |
->write("} else {\n")
|
vendor/twig/twig/lib/Twig/Node/Import.php
CHANGED
@@ -37,9 +37,9 @@ class Twig_Node_Import extends Twig_Node
|
|
37 |
->raw('$this->loadTemplate(')
|
38 |
->subcompile($this->getNode('expr'))
|
39 |
->raw(', ')
|
40 |
-
->repr($
|
41 |
->raw(', ')
|
42 |
-
->repr($this->
|
43 |
->raw(')')
|
44 |
;
|
45 |
}
|
37 |
->raw('$this->loadTemplate(')
|
38 |
->subcompile($this->getNode('expr'))
|
39 |
->raw(', ')
|
40 |
+
->repr($this->getTemplateName())
|
41 |
->raw(', ')
|
42 |
+
->repr($this->getTemplateLine())
|
43 |
->raw(')')
|
44 |
;
|
45 |
}
|
vendor/twig/twig/lib/Twig/Node/Include.php
CHANGED
@@ -19,7 +19,12 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
|
|
19 |
{
|
20 |
public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
|
21 |
{
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
24 |
|
25 |
public function compile(Twig_Compiler $compiler)
|
@@ -59,16 +64,16 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
|
|
59 |
->write('$this->loadTemplate(')
|
60 |
->subcompile($this->getNode('expr'))
|
61 |
->raw(', ')
|
62 |
-
->repr($
|
63 |
->raw(', ')
|
64 |
-
->repr($this->
|
65 |
->raw(')')
|
66 |
;
|
67 |
}
|
68 |
|
69 |
protected function addTemplateArguments(Twig_Compiler $compiler)
|
70 |
{
|
71 |
-
if (
|
72 |
$compiler->raw(false === $this->getAttribute('only') ? '$context' : 'array()');
|
73 |
} elseif (false === $this->getAttribute('only')) {
|
74 |
$compiler
|
19 |
{
|
20 |
public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
|
21 |
{
|
22 |
+
$nodes = array('expr' => $expr);
|
23 |
+
if (null !== $variables) {
|
24 |
+
$nodes['variables'] = $variables;
|
25 |
+
}
|
26 |
+
|
27 |
+
parent::__construct($nodes, array('only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag);
|
28 |
}
|
29 |
|
30 |
public function compile(Twig_Compiler $compiler)
|
64 |
->write('$this->loadTemplate(')
|
65 |
->subcompile($this->getNode('expr'))
|
66 |
->raw(', ')
|
67 |
+
->repr($this->getTemplateName())
|
68 |
->raw(', ')
|
69 |
+
->repr($this->getTemplateLine())
|
70 |
->raw(')')
|
71 |
;
|
72 |
}
|
73 |
|
74 |
protected function addTemplateArguments(Twig_Compiler $compiler)
|
75 |
{
|
76 |
+
if (!$this->hasNode('variables')) {
|
77 |
$compiler->raw(false === $this->getAttribute('only') ? '$context' : 'array()');
|
78 |
} elseif (false === $this->getAttribute('only')) {
|
79 |
$compiler
|
vendor/twig/twig/lib/Twig/Node/Macro.php
CHANGED
@@ -22,7 +22,7 @@ class Twig_Node_Macro extends Twig_Node
|
|
22 |
{
|
23 |
foreach ($arguments as $argumentName => $argument) {
|
24 |
if (self::VARARGS_NAME === $argumentName) {
|
25 |
-
throw new Twig_Error_Syntax(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->
|
26 |
}
|
27 |
}
|
28 |
|
@@ -70,7 +70,7 @@ class Twig_Node_Macro extends Twig_Node
|
|
70 |
|
71 |
foreach ($this->getNode('arguments') as $name => $default) {
|
72 |
$compiler
|
73 |
-
->
|
74 |
->string($name)
|
75 |
->raw(' => $__'.$name.'__')
|
76 |
->raw(",\n")
|
@@ -78,7 +78,7 @@ class Twig_Node_Macro extends Twig_Node
|
|
78 |
}
|
79 |
|
80 |
$compiler
|
81 |
-
->
|
82 |
->string(self::VARARGS_NAME)
|
83 |
->raw(' => ')
|
84 |
;
|
22 |
{
|
23 |
foreach ($arguments as $argumentName => $argument) {
|
24 |
if (self::VARARGS_NAME === $argumentName) {
|
25 |
+
throw new Twig_Error_Syntax(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getTemplateLine());
|
26 |
}
|
27 |
}
|
28 |
|
70 |
|
71 |
foreach ($this->getNode('arguments') as $name => $default) {
|
72 |
$compiler
|
73 |
+
->write('')
|
74 |
->string($name)
|
75 |
->raw(' => $__'.$name.'__')
|
76 |
->raw(",\n")
|
78 |
}
|
79 |
|
80 |
$compiler
|
81 |
+
->write('')
|
82 |
->string(self::VARARGS_NAME)
|
83 |
->raw(' => ')
|
84 |
;
|
vendor/twig/twig/lib/Twig/Node/Module.php
CHANGED
@@ -21,11 +21,18 @@
|
|
21 |
*/
|
22 |
class Twig_Node_Module extends Twig_Node
|
23 |
{
|
24 |
-
|
|
|
|
|
25 |
{
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
29 |
'body' => $body,
|
30 |
'blocks' => $blocks,
|
31 |
'macros' => $macros,
|
@@ -35,11 +42,23 @@ class Twig_Node_Module extends Twig_Node
|
|
35 |
'constructor_start' => new Twig_Node(),
|
36 |
'constructor_end' => new Twig_Node(),
|
37 |
'class_end' => new Twig_Node(),
|
38 |
-
)
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
'index' => null,
|
41 |
'embedded_templates' => $embeddedTemplates,
|
42 |
), 1);
|
|
|
|
|
|
|
43 |
}
|
44 |
|
45 |
public function setIndex($index)
|
@@ -67,7 +86,7 @@ class Twig_Node_Module extends Twig_Node
|
|
67 |
if (
|
68 |
count($this->getNode('blocks'))
|
69 |
|| count($this->getNode('traits'))
|
70 |
-
||
|
71 |
|| $this->getNode('parent') instanceof Twig_Node_Expression_Constant
|
72 |
|| count($this->getNode('constructor_start'))
|
73 |
|| count($this->getNode('constructor_end'))
|
@@ -89,14 +108,19 @@ class Twig_Node_Module extends Twig_Node
|
|
89 |
|
90 |
$this->compileDebugInfo($compiler);
|
91 |
|
|
|
|
|
|
|
|
|
92 |
$this->compileClassFooter($compiler);
|
93 |
}
|
94 |
|
95 |
protected function compileGetParent(Twig_Compiler $compiler)
|
96 |
{
|
97 |
-
if (
|
98 |
return;
|
99 |
}
|
|
|
100 |
|
101 |
$compiler
|
102 |
->write("protected function doGetParent(array \$context)\n", "{\n")
|
@@ -112,9 +136,9 @@ class Twig_Node_Module extends Twig_Node
|
|
112 |
->raw('$this->loadTemplate(')
|
113 |
->subcompile($parent)
|
114 |
->raw(', ')
|
115 |
-
->repr($
|
116 |
->raw(', ')
|
117 |
-
->repr($
|
118 |
->raw(')')
|
119 |
;
|
120 |
}
|
@@ -130,9 +154,9 @@ class Twig_Node_Module extends Twig_Node
|
|
130 |
{
|
131 |
$compiler
|
132 |
->write("\n\n")
|
133 |
-
// if the
|
134 |
-
->write('/* '.str_replace('*/', '* /', $this->
|
135 |
-
->write('class '.$compiler->getEnvironment()->getTemplateClass($this->
|
136 |
->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
|
137 |
->write("{\n")
|
138 |
->indent()
|
@@ -149,17 +173,17 @@ class Twig_Node_Module extends Twig_Node
|
|
149 |
;
|
150 |
|
151 |
// parent
|
152 |
-
if (
|
153 |
$compiler->write("\$this->parent = false;\n\n");
|
154 |
-
} elseif ($parent instanceof Twig_Node_Expression_Constant) {
|
155 |
$compiler
|
156 |
->addDebugInfo($parent)
|
157 |
->write('$this->parent = $this->loadTemplate(')
|
158 |
->subcompile($parent)
|
159 |
->raw(', ')
|
160 |
-
->repr($
|
161 |
->raw(', ')
|
162 |
-
->repr($
|
163 |
->raw(");\n")
|
164 |
;
|
165 |
}
|
@@ -277,7 +301,8 @@ class Twig_Node_Module extends Twig_Node
|
|
277 |
->subcompile($this->getNode('body'))
|
278 |
;
|
279 |
|
280 |
-
if (
|
|
|
281 |
$compiler->addDebugInfo($parent);
|
282 |
if ($parent instanceof Twig_Node_Expression_Constant) {
|
283 |
$compiler->write('$this->parent');
|
@@ -314,7 +339,7 @@ class Twig_Node_Module extends Twig_Node
|
|
314 |
->write("public function getTemplateName()\n", "{\n")
|
315 |
->indent()
|
316 |
->write('return ')
|
317 |
-
->repr($this->
|
318 |
->raw(";\n")
|
319 |
->outdent()
|
320 |
->write("}\n\n")
|
@@ -330,7 +355,7 @@ class Twig_Node_Module extends Twig_Node
|
|
330 |
//
|
331 |
// Put another way, a template can be used as a trait if it
|
332 |
// only contains blocks and use statements.
|
333 |
-
$traitable =
|
334 |
if ($traitable) {
|
335 |
if ($this->getNode('body') instanceof Twig_Node_Body) {
|
336 |
$nodes = $this->getNode('body')->getNode(0);
|
@@ -380,6 +405,37 @@ class Twig_Node_Module extends Twig_Node
|
|
380 |
->indent()
|
381 |
->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true))))
|
382 |
->outdent()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
383 |
->write("}\n")
|
384 |
;
|
385 |
}
|
@@ -391,13 +447,13 @@ class Twig_Node_Module extends Twig_Node
|
|
391 |
->write(sprintf('%s = $this->loadTemplate(', $var))
|
392 |
->subcompile($node)
|
393 |
->raw(', ')
|
394 |
-
->repr($
|
395 |
->raw(', ')
|
396 |
-
->repr($node->
|
397 |
->raw(");\n")
|
398 |
;
|
399 |
} else {
|
400 |
-
throw new LogicException('Trait templates can only be constant nodes');
|
401 |
}
|
402 |
}
|
403 |
}
|
21 |
*/
|
22 |
class Twig_Node_Module extends Twig_Node
|
23 |
{
|
24 |
+
private $source;
|
25 |
+
|
26 |
+
public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $name, $source = '')
|
27 |
{
|
28 |
+
if (!$name instanceof Twig_Source) {
|
29 |
+
@trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
|
30 |
+
$this->source = new Twig_Source($source, $name);
|
31 |
+
} else {
|
32 |
+
$this->source = $name;
|
33 |
+
}
|
34 |
+
|
35 |
+
$nodes = array(
|
36 |
'body' => $body,
|
37 |
'blocks' => $blocks,
|
38 |
'macros' => $macros,
|
42 |
'constructor_start' => new Twig_Node(),
|
43 |
'constructor_end' => new Twig_Node(),
|
44 |
'class_end' => new Twig_Node(),
|
45 |
+
);
|
46 |
+
if (null !== $parent) {
|
47 |
+
$nodes['parent'] = $parent;
|
48 |
+
}
|
49 |
+
|
50 |
+
// embedded templates are set as attributes so that they are only visited once by the visitors
|
51 |
+
parent::__construct($nodes, array(
|
52 |
+
// source to be remove in 2.0
|
53 |
+
'source' => $this->source->getCode(),
|
54 |
+
// filename to be remove in 2.0 (use getTemplateName() instead)
|
55 |
+
'filename' => $this->source->getName(),
|
56 |
'index' => null,
|
57 |
'embedded_templates' => $embeddedTemplates,
|
58 |
), 1);
|
59 |
+
|
60 |
+
// populate the template name of all node children
|
61 |
+
$this->setTemplateName($this->source->getName());
|
62 |
}
|
63 |
|
64 |
public function setIndex($index)
|
86 |
if (
|
87 |
count($this->getNode('blocks'))
|
88 |
|| count($this->getNode('traits'))
|
89 |
+
|| !$this->hasNode('parent')
|
90 |
|| $this->getNode('parent') instanceof Twig_Node_Expression_Constant
|
91 |
|| count($this->getNode('constructor_start'))
|
92 |
|| count($this->getNode('constructor_end'))
|
108 |
|
109 |
$this->compileDebugInfo($compiler);
|
110 |
|
111 |
+
$this->compileGetSource($compiler);
|
112 |
+
|
113 |
+
$this->compileGetSourceContext($compiler);
|
114 |
+
|
115 |
$this->compileClassFooter($compiler);
|
116 |
}
|
117 |
|
118 |
protected function compileGetParent(Twig_Compiler $compiler)
|
119 |
{
|
120 |
+
if (!$this->hasNode('parent')) {
|
121 |
return;
|
122 |
}
|
123 |
+
$parent = $this->getNode('parent');
|
124 |
|
125 |
$compiler
|
126 |
->write("protected function doGetParent(array \$context)\n", "{\n")
|
136 |
->raw('$this->loadTemplate(')
|
137 |
->subcompile($parent)
|
138 |
->raw(', ')
|
139 |
+
->repr($this->source->getName())
|
140 |
->raw(', ')
|
141 |
+
->repr($parent->getTemplateLine())
|
142 |
->raw(')')
|
143 |
;
|
144 |
}
|
154 |
{
|
155 |
$compiler
|
156 |
->write("\n\n")
|
157 |
+
// if the template name contains */, add a blank to avoid a PHP parse error
|
158 |
+
->write('/* '.str_replace('*/', '* /', $this->source->getName())." */\n")
|
159 |
+
->write('class '.$compiler->getEnvironment()->getTemplateClass($this->source->getName(), $this->getAttribute('index')))
|
160 |
->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
|
161 |
->write("{\n")
|
162 |
->indent()
|
173 |
;
|
174 |
|
175 |
// parent
|
176 |
+
if (!$this->hasNode('parent')) {
|
177 |
$compiler->write("\$this->parent = false;\n\n");
|
178 |
+
} elseif (($parent = $this->getNode('parent')) && $parent instanceof Twig_Node_Expression_Constant) {
|
179 |
$compiler
|
180 |
->addDebugInfo($parent)
|
181 |
->write('$this->parent = $this->loadTemplate(')
|
182 |
->subcompile($parent)
|
183 |
->raw(', ')
|
184 |
+
->repr($this->source->getName())
|
185 |
->raw(', ')
|
186 |
+
->repr($parent->getTemplateLine())
|
187 |
->raw(");\n")
|
188 |
;
|
189 |
}
|
301 |
->subcompile($this->getNode('body'))
|
302 |
;
|
303 |
|
304 |
+
if ($this->hasNode('parent')) {
|
305 |
+
$parent = $this->getNode('parent');
|
306 |
$compiler->addDebugInfo($parent);
|
307 |
if ($parent instanceof Twig_Node_Expression_Constant) {
|
308 |
$compiler->write('$this->parent');
|
339 |
->write("public function getTemplateName()\n", "{\n")
|
340 |
->indent()
|
341 |
->write('return ')
|
342 |
+
->repr($this->source->getName())
|
343 |
->raw(";\n")
|
344 |
->outdent()
|
345 |
->write("}\n\n")
|
355 |
//
|
356 |
// Put another way, a template can be used as a trait if it
|
357 |
// only contains blocks and use statements.
|
358 |
+
$traitable = !$this->hasNode('parent') && 0 === count($this->getNode('macros'));
|
359 |
if ($traitable) {
|
360 |
if ($this->getNode('body') instanceof Twig_Node_Body) {
|
361 |
$nodes = $this->getNode('body')->getNode(0);
|
405 |
->indent()
|
406 |
->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true))))
|
407 |
->outdent()
|
408 |
+
->write("}\n\n")
|
409 |
+
;
|
410 |
+
}
|
411 |
+
|
412 |
+
protected function compileGetSource(Twig_Compiler $compiler)
|
413 |
+
{
|
414 |
+
$compiler
|
415 |
+
->write("/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */\n")
|
416 |
+
->write("public function getSource()\n", "{\n")
|
417 |
+
->indent()
|
418 |
+
->write("@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);\n\n")
|
419 |
+
->write('return $this->getSourceContext()->getCode();')
|
420 |
+
->raw("\n")
|
421 |
+
->outdent()
|
422 |
+
->write("}\n\n")
|
423 |
+
;
|
424 |
+
}
|
425 |
+
|
426 |
+
protected function compileGetSourceContext(Twig_Compiler $compiler)
|
427 |
+
{
|
428 |
+
$compiler
|
429 |
+
->write("public function getSourceContext()\n", "{\n")
|
430 |
+
->indent()
|
431 |
+
->write('return new Twig_Source(')
|
432 |
+
->string($compiler->getEnvironment()->isDebug() ? $this->source->getCode() : '')
|
433 |
+
->raw(', ')
|
434 |
+
->string($this->source->getName())
|
435 |
+
->raw(', ')
|
436 |
+
->string($this->source->getPath())
|
437 |
+
->raw(");\n")
|
438 |
+
->outdent()
|
439 |
->write("}\n")
|
440 |
;
|
441 |
}
|
447 |
->write(sprintf('%s = $this->loadTemplate(', $var))
|
448 |
->subcompile($node)
|
449 |
->raw(', ')
|
450 |
+
->repr($node->getTemplateName())
|
451 |
->raw(', ')
|
452 |
+
->repr($node->getTemplateLine())
|
453 |
->raw(");\n")
|
454 |
;
|
455 |
} else {
|
456 |
+
throw new LogicException('Trait templates can only be constant nodes.');
|
457 |
}
|
458 |
}
|
459 |
}
|
vendor/twig/twig/lib/Twig/Node/Sandbox.php
CHANGED
@@ -25,7 +25,7 @@ class Twig_Node_Sandbox extends Twig_Node
|
|
25 |
{
|
26 |
$compiler
|
27 |
->addDebugInfo($this)
|
28 |
-
->write("\$sandbox = \$this->env->getExtension('
|
29 |
->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n")
|
30 |
->indent()
|
31 |
->write("\$sandbox->enableSandbox();\n")
|
25 |
{
|
26 |
$compiler
|
27 |
->addDebugInfo($this)
|
28 |
+
->write("\$sandbox = \$this->env->getExtension('Twig_Extension_Sandbox');\n")
|
29 |
->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n")
|
30 |
->indent()
|
31 |
->write("\$sandbox->enableSandbox();\n")
|
vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php
CHANGED
@@ -25,7 +25,7 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
|
|
25 |
{
|
26 |
$compiler
|
27 |
->addDebugInfo($this)
|
28 |
-
->write('echo $this->env->getExtension(\'
|
29 |
->subcompile($this->getNode('expr'))
|
30 |
->raw(");\n")
|
31 |
;
|
25 |
{
|
26 |
$compiler
|
27 |
->addDebugInfo($this)
|
28 |
+
->write('echo $this->env->getExtension(\'Twig_Extension_Sandbox\')->ensureToStringAllowed(')
|
29 |
->subcompile($this->getNode('expr'))
|
30 |
->raw(");\n")
|
31 |
;
|
vendor/twig/twig/lib/Twig/Node/Set.php
CHANGED
@@ -30,7 +30,7 @@ class Twig_Node_Set extends Twig_Node
|
|
30 |
|
31 |
$values = $this->getNode('values');
|
32 |
if ($values instanceof Twig_Node_Text) {
|
33 |
-
$this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->
|
34 |
$this->setAttribute('capture', false);
|
35 |
}
|
36 |
}
|
30 |
|
31 |
$values = $this->getNode('values');
|
32 |
if ($values instanceof Twig_Node_Text) {
|
33 |
+
$this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getTemplateLine()));
|
34 |
$this->setAttribute('capture', false);
|
35 |
}
|
36 |
}
|
vendor/twig/twig/lib/Twig/NodeInterface.php
CHANGED
@@ -25,6 +25,9 @@ interface Twig_NodeInterface extends Countable, IteratorAggregate
|
|
25 |
*/
|
26 |
public function compile(Twig_Compiler $compiler);
|
27 |
|
|
|
|
|
|
|
28 |
public function getLine();
|
29 |
|
30 |
public function getNodeTag();
|
25 |
*/
|
26 |
public function compile(Twig_Compiler $compiler);
|
27 |
|
28 |
+
/**
|
29 |
+
* @deprecated since 1.27 (to be removed in 2.0)
|
30 |
+
*/
|
31 |
public function getLine();
|
32 |
|
33 |
public function getNodeTag();
|
vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php
CHANGED
@@ -34,7 +34,7 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
|
|
34 |
protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
|
35 |
{
|
36 |
if ($node instanceof Twig_Node_Module) {
|
37 |
-
if ($env->hasExtension('
|
38 |
$this->defaultStrategy = $defaultStrategy;
|
39 |
}
|
40 |
$this->safeVars = array();
|
@@ -90,7 +90,7 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
|
|
90 |
|
91 |
return new $class(
|
92 |
$this->getEscaperFilter($type, $expression),
|
93 |
-
$node->
|
94 |
);
|
95 |
}
|
96 |
|
@@ -142,7 +142,7 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
|
|
142 |
|
143 |
protected function getEscaperFilter($type, Twig_NodeInterface $node)
|
144 |
{
|
145 |
-
$line = $node->
|
146 |
$name = new Twig_Node_Expression_Constant('escape', $line);
|
147 |
$args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line), new Twig_Node_Expression_Constant(null, $line), new Twig_Node_Expression_Constant(true, $line)));
|
148 |
|
34 |
protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
|
35 |
{
|
36 |
if ($node instanceof Twig_Node_Module) {
|
37 |
+
if ($env->hasExtension('Twig_Extension_Escaper') && $defaultStrategy = $env->getExtension('Twig_Extension_Escaper')->getDefaultStrategy($node->getTemplateName())) {
|
38 |
$this->defaultStrategy = $defaultStrategy;
|
39 |
}
|
40 |
$this->safeVars = array();
|
90 |
|
91 |
return new $class(
|
92 |
$this->getEscaperFilter($type, $expression),
|
93 |
+
$node->getTemplateLine()
|
94 |
);
|
95 |
}
|
96 |
|
142 |
|
143 |
protected function getEscaperFilter($type, Twig_NodeInterface $node)
|
144 |
{
|
145 |
+
$line = $node->getTemplateLine();
|
146 |
$name = new Twig_Node_Expression_Constant('escape', $line);
|
147 |
$args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line), new Twig_Node_Expression_Constant(null, $line), new Twig_Node_Expression_Constant(true, $line)));
|
148 |
|
vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php
CHANGED
@@ -56,7 +56,7 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
|
|
56 |
$this->enterOptimizeFor($node, $env);
|
57 |
}
|
58 |
|
59 |
-
if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('
|
60 |
if ($this->inABody) {
|
61 |
if (!$node instanceof Twig_Node_Expression) {
|
62 |
if (get_class($node) !== 'Twig_Node') {
|
@@ -90,14 +90,14 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
|
|
90 |
|
91 |
$node = $this->optimizePrintNode($node, $env);
|
92 |
|
93 |
-
if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('
|
94 |
if ($node instanceof Twig_Node_Body) {
|
95 |
$this->inABody = false;
|
96 |
} elseif ($this->inABody) {
|
97 |
if (!$expression && get_class($node) !== 'Twig_Node' && $prependedNodes = array_shift($this->prependedNodes)) {
|
98 |
$nodes = array();
|
99 |
foreach (array_unique($prependedNodes) as $name) {
|
100 |
-
$nodes[] = new Twig_Node_SetTemp($name, $node->
|
101 |
}
|
102 |
|
103 |
$nodes[] = $node;
|
@@ -114,7 +114,7 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
|
|
114 |
if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) {
|
115 |
$this->prependedNodes[0][] = $node->getAttribute('name');
|
116 |
|
117 |
-
return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->
|
118 |
}
|
119 |
|
120 |
return $node;
|
56 |
$this->enterOptimizeFor($node, $env);
|
57 |
}
|
58 |
|
59 |
+
if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('Twig_Extension_Sandbox')) {
|
60 |
if ($this->inABody) {
|
61 |
if (!$node instanceof Twig_Node_Expression) {
|
62 |
if (get_class($node) !== 'Twig_Node') {
|
90 |
|
91 |
$node = $this->optimizePrintNode($node, $env);
|
92 |
|
93 |
+
if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('Twig_Extension_Sandbox')) {
|
94 |
if ($node instanceof Twig_Node_Body) {
|
95 |
$this->inABody = false;
|
96 |
} elseif ($this->inABody) {
|
97 |
if (!$expression && get_class($node) !== 'Twig_Node' && $prependedNodes = array_shift($this->prependedNodes)) {
|
98 |
$nodes = array();
|
99 |
foreach (array_unique($prependedNodes) as $name) {
|
100 |
+
$nodes[] = new Twig_Node_SetTemp($name, $node->getTemplateLine());
|
101 |
}
|
102 |
|
103 |
$nodes[] = $node;
|
114 |
if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) {
|
115 |
$this->prependedNodes[0][] = $node->getAttribute('name');
|
116 |
|
117 |
+
return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getTemplateLine());
|
118 |
}
|
119 |
|
120 |
return $node;
|
vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php
CHANGED
@@ -51,7 +51,7 @@ class Twig_NodeVisitor_Sandbox extends Twig_BaseNodeVisitor
|
|
51 |
|
52 |
// wrap print to check __toString() calls
|
53 |
if ($node instanceof Twig_Node_Print) {
|
54 |
-
return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->
|
55 |
}
|
56 |
}
|
57 |
|
51 |
|
52 |
// wrap print to check __toString() calls
|
53 |
if ($node instanceof Twig_Node_Print) {
|
54 |
+
return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getTemplateLine(), $node->getNodeTag());
|
55 |
}
|
56 |
}
|
57 |
|
vendor/twig/twig/lib/Twig/Parser.php
CHANGED
@@ -42,8 +42,13 @@ class Twig_Parser implements Twig_ParserInterface
|
|
42 |
$this->env = $env;
|
43 |
}
|
44 |
|
|
|
|
|
|
|
45 |
public function getEnvironment()
|
46 |
{
|
|
|
|
|
47 |
return $this->env;
|
48 |
}
|
49 |
|
@@ -52,9 +57,14 @@ class Twig_Parser implements Twig_ParserInterface
|
|
52 |
return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
|
53 |
}
|
54 |
|
|
|
|
|
|
|
55 |
public function getFilename()
|
56 |
{
|
57 |
-
|
|
|
|
|
58 |
}
|
59 |
|
60 |
/**
|
@@ -64,6 +74,7 @@ class Twig_Parser implements Twig_ParserInterface
|
|
64 |
{
|
65 |
// push all variables into the stack to keep the current state of the parser
|
66 |
// using get_object_vars() instead of foreach would lead to https://bugs.php.net/71336
|
|
|
67 |
$vars = array();
|
68 |
foreach ($this as $k => $v) {
|
69 |
$vars[$k] = $v;
|
@@ -84,7 +95,7 @@ class Twig_Parser implements Twig_ParserInterface
|
|
84 |
}
|
85 |
|
86 |
if (null === $this->expressionParser) {
|
87 |
-
$this->expressionParser = new Twig_ExpressionParser($this, $this->env
|
88 |
}
|
89 |
|
90 |
$this->stream = $stream;
|
@@ -103,8 +114,8 @@ class Twig_Parser implements Twig_ParserInterface
|
|
103 |
$body = new Twig_Node();
|
104 |
}
|
105 |
} catch (Twig_Error_Syntax $e) {
|
106 |
-
if (!$e->
|
107 |
-
$e->
|
108 |
}
|
109 |
|
110 |
if (!$e->getTemplateLine()) {
|
@@ -114,7 +125,7 @@ class Twig_Parser implements Twig_ParserInterface
|
|
114 |
throw $e;
|
115 |
}
|
116 |
|
117 |
-
$node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $
|
118 |
|
119 |
$traverser = new Twig_NodeTraverser($this->env, $this->visitors);
|
120 |
|
@@ -151,7 +162,7 @@ class Twig_Parser implements Twig_ParserInterface
|
|
151 |
$token = $this->getCurrentToken();
|
152 |
|
153 |
if ($token->getType() !== Twig_Token::NAME_TYPE) {
|
154 |
-
throw new Twig_Error_Syntax('A block must start with a tag name.', $token->getLine(), $this->
|
155 |
}
|
156 |
|
157 |
if (null !== $test && call_user_func($test, $token)) {
|
@@ -169,13 +180,13 @@ class Twig_Parser implements Twig_ParserInterface
|
|
169 |
$subparser = $this->handlers->getTokenParser($token->getValue());
|
170 |
if (null === $subparser) {
|
171 |
if (null !== $test) {
|
172 |
-
$e = new Twig_Error_Syntax(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->
|
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->
|
179 |
$e->addSuggestions($token->getValue(), array_keys($this->env->getTags()));
|
180 |
}
|
181 |
|
@@ -191,7 +202,7 @@ class Twig_Parser implements Twig_ParserInterface
|
|
191 |
break;
|
192 |
|
193 |
default:
|
194 |
-
throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', 0, $this->
|
195 |
}
|
196 |
}
|
197 |
|
@@ -202,13 +213,23 @@ class Twig_Parser implements Twig_ParserInterface
|
|
202 |
return new Twig_Node($rv, array(), $lineno);
|
203 |
}
|
204 |
|
|
|
|
|
|
|
205 |
public function addHandler($name, $class)
|
206 |
{
|
|
|
|
|
207 |
$this->handlers[$name] = $class;
|
208 |
}
|
209 |
|
|
|
|
|
|
|
210 |
public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
|
211 |
{
|
|
|
|
|
212 |
$this->visitors[] = $visitor;
|
213 |
}
|
214 |
|
@@ -244,7 +265,7 @@ class Twig_Parser implements Twig_ParserInterface
|
|
244 |
|
245 |
public function setBlock($name, Twig_Node_Block $value)
|
246 |
{
|
247 |
-
$this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->
|
248 |
}
|
249 |
|
250 |
public function hasMacro($name)
|
@@ -255,7 +276,7 @@ class Twig_Parser implements Twig_ParserInterface
|
|
255 |
public function setMacro($name, Twig_Node_Macro $node)
|
256 |
{
|
257 |
if ($this->isReservedMacroName($name)) {
|
258 |
-
throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->
|
259 |
}
|
260 |
|
261 |
$this->macros[$name] = $node;
|
@@ -373,10 +394,10 @@ class Twig_Parser implements Twig_ParserInterface
|
|
373 |
(!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface)
|
374 |
) {
|
375 |
if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) {
|
376 |
-
throw new Twig_Error_Syntax('A template that extends another one cannot
|
377 |
}
|
378 |
|
379 |
-
throw new Twig_Error_Syntax('A template that extends another one cannot
|
380 |
}
|
381 |
|
382 |
// bypass "set" nodes as they "capture" the output
|
42 |
$this->env = $env;
|
43 |
}
|
44 |
|
45 |
+
/**
|
46 |
+
* @deprecated since 1.27 (to be removed in 2.0)
|
47 |
+
*/
|
48 |
public function getEnvironment()
|
49 |
{
|
50 |
+
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED);
|
51 |
+
|
52 |
return $this->env;
|
53 |
}
|
54 |
|
57 |
return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
|
58 |
}
|
59 |
|
60 |
+
/**
|
61 |
+
* @deprecated since 1.27 (to be removed in 2.0). Use $parser->getStream()->getSourceContext()->getPath() instead.
|
62 |
+
*/
|
63 |
public function getFilename()
|
64 |
{
|
65 |
+
@trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use $parser->getStream()->getSourceContext()->getPath() instead.', __METHOD__), E_USER_DEPRECATED);
|
66 |
+
|
67 |
+
return $this->stream->getSourceContext()->getName();
|
68 |
}
|
69 |
|
70 |
/**
|
74 |
{
|
75 |
// push all variables into the stack to keep the current state of the parser
|
76 |
// using get_object_vars() instead of foreach would lead to https://bugs.php.net/71336
|
77 |
+
// This hack can be removed when min version if PHP 7.0
|
78 |
$vars = array();
|
79 |
foreach ($this as $k => $v) {
|
80 |
$vars[$k] = $v;
|
95 |
}
|
96 |
|
97 |
if (null === $this->expressionParser) {
|
98 |
+
$this->expressionParser = new Twig_ExpressionParser($this, $this->env);
|
99 |
}
|
100 |
|
101 |
$this->stream = $stream;
|
114 |
$body = new Twig_Node();
|
115 |
}
|
116 |
} catch (Twig_Error_Syntax $e) {
|
117 |
+
if (!$e->getTemplateName()) {
|
118 |
+
$e->setTemplateName($this->stream->getSourceContext()->getName());
|
119 |
}
|
120 |
|
121 |
if (!$e->getTemplateLine()) {
|
125 |
throw $e;
|
126 |
}
|
127 |
|
128 |
+
$node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $stream->getSourceContext());
|
129 |
|
130 |
$traverser = new Twig_NodeTraverser($this->env, $this->visitors);
|
131 |
|
162 |
$token = $this->getCurrentToken();
|
163 |
|
164 |
if ($token->getType() !== Twig_Token::NAME_TYPE) {
|
165 |
+
throw new Twig_Error_Syntax('A block must start with a tag name.', $token->getLine(), $this->stream->getSourceContext()->getName());
|
166 |
}
|
167 |
|
168 |
if (null !== $test && call_user_func($test, $token)) {
|
180 |
$subparser = $this->handlers->getTokenParser($token->getValue());
|
181 |
if (null === $subparser) {
|
182 |
if (null !== $test) {
|
183 |
+
$e = new Twig_Error_Syntax(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->stream->getSourceContext()->getName());
|
184 |
|
185 |
if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) {
|
186 |
$e->appendMessage(sprintf(' (expecting closing tag for the "%s" tag defined near line %s).', $test[0]->getTag(), $lineno));
|
187 |
}
|
188 |
} else {
|
189 |
+
$e = new Twig_Error_Syntax(sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->stream->getSourceContext()->getName());
|
190 |
$e->addSuggestions($token->getValue(), array_keys($this->env->getTags()));
|
191 |
}
|
192 |
|
202 |
break;
|
203 |
|
204 |
default:
|
205 |
+
throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', 0, $this->stream->getSourceContext()->getName());
|
206 |
}
|
207 |
}
|
208 |
|
213 |
return new Twig_Node($rv, array(), $lineno);
|
214 |
}
|
215 |
|
216 |
+
/**
|
217 |
+
* @deprecated since 1.27 (to be removed in 2.0)
|
218 |
+
*/
|
219 |
public function addHandler($name, $class)
|
220 |
{
|
221 |
+
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED);
|
222 |
+
|
223 |
$this->handlers[$name] = $class;
|
224 |
}
|
225 |
|
226 |
+
/**
|
227 |
+
* @deprecated since 1.27 (to be removed in 2.0)
|
228 |
+
*/
|
229 |
public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
|
230 |
{
|
231 |
+
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED);
|
232 |
+
|
233 |
$this->visitors[] = $visitor;
|
234 |
}
|
235 |
|
265 |
|
266 |
public function setBlock($name, Twig_Node_Block $value)
|
267 |
{
|
268 |
+
$this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getTemplateLine());
|
269 |
}
|
270 |
|
271 |
public function hasMacro($name)
|
276 |
public function setMacro($name, Twig_Node_Macro $node)
|
277 |
{
|
278 |
if ($this->isReservedMacroName($name)) {
|
279 |
+
throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->getTemplateLine(), $this->stream->getSourceContext()->getName());
|
280 |
}
|
281 |
|
282 |
$this->macros[$name] = $node;
|
394 |
(!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface)
|
395 |
) {
|
396 |
if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) {
|
397 |
+
throw new Twig_Error_Syntax('A template that extends another one cannot start with a byte order mark (BOM); it must be removed.', $node->getTemplateLine(), $this->stream->getSourceContext()->getName());
|
398 |
}
|
399 |
|
400 |
+
throw new Twig_Error_Syntax('A template that extends another one cannot include contents outside Twig blocks. Did you forget to put the contents inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext()->getName());
|
401 |
}
|
402 |
|
403 |
// bypass "set" nodes as they "capture" the output
|
vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php
CHANGED
@@ -36,19 +36,19 @@ class Twig_Profiler_NodeVisitor_Profiler extends Twig_BaseNodeVisitor
|
|
36 |
{
|
37 |
if ($node instanceof Twig_Node_Module) {
|
38 |
$varName = $this->getVarName();
|
39 |
-
$node->setNode('display_start', new Twig_Node(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::TEMPLATE, $node->
|
40 |
$node->setNode('display_end', new Twig_Node(array(new Twig_Profiler_Node_LeaveProfile($varName), $node->getNode('display_end'))));
|
41 |
} elseif ($node instanceof Twig_Node_Block) {
|
42 |
$varName = $this->getVarName();
|
43 |
$node->setNode('body', new Twig_Node_Body(array(
|
44 |
-
new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::BLOCK, $node->
|
45 |
$node->getNode('body'),
|
46 |
new Twig_Profiler_Node_LeaveProfile($varName),
|
47 |
)));
|
48 |
} elseif ($node instanceof Twig_Node_Macro) {
|
49 |
$varName = $this->getVarName();
|
50 |
$node->setNode('body', new Twig_Node_Body(array(
|
51 |
-
new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::MACRO, $node->
|
52 |
$node->getNode('body'),
|
53 |
new Twig_Profiler_Node_LeaveProfile($varName),
|
54 |
)));
|
36 |
{
|
37 |
if ($node instanceof Twig_Node_Module) {
|
38 |
$varName = $this->getVarName();
|
39 |
+
$node->setNode('display_start', new Twig_Node(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::TEMPLATE, $node->getTemplateName(), $varName), $node->getNode('display_start'))));
|
40 |
$node->setNode('display_end', new Twig_Node(array(new Twig_Profiler_Node_LeaveProfile($varName), $node->getNode('display_end'))));
|
41 |
} elseif ($node instanceof Twig_Node_Block) {
|
42 |
$varName = $this->getVarName();
|
43 |
$node->setNode('body', new Twig_Node_Body(array(
|
44 |
+
new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::BLOCK, $node->getTemplateName(), $varName),
|
45 |
$node->getNode('body'),
|
46 |
new Twig_Profiler_Node_LeaveProfile($varName),
|
47 |
)));
|
48 |
} elseif ($node instanceof Twig_Node_Macro) {
|
49 |
$varName = $this->getVarName();
|
50 |
$node->setNode('body', new Twig_Node_Body(array(
|
51 |
+
new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::MACRO, $node->getTemplateName(), $varName),
|
52 |
$node->getNode('body'),
|
53 |
new Twig_Profiler_Node_LeaveProfile($varName),
|
54 |
)));
|
vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Twig.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Creates runtime implementations for Twig elements (filters/functions/tests).
|
14 |
+
*
|
15 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
16 |
+
*/
|
17 |
+
interface Twig_RuntimeLoaderInterface
|
18 |
+
{
|
19 |
+
/**
|
20 |
+
* Creates the runtime implementation of a Twig element (filter/function/test).
|
21 |
+
*
|
22 |
+
* @param string $class A runtime class
|
23 |
+
*
|
24 |
+
* @return object|null The runtime instance or null if the loader does not know how to create the runtime for this class
|
25 |
+
*/
|
26 |
+
public function load($class);
|
27 |
+
}
|
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Twig.
|
5 |
+
*
|
6 |
+
* (c) 2009 Fabien Potencier
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Exception thrown when a not allowed class method is used in a template.
|
14 |
+
*
|
15 |
+
* @author Kit Burton-Senior <mail@kitbs.com>
|
16 |
+
*/
|
17 |
+
class Twig_Sandbox_SecurityNotAllowedMethodError extends Twig_Sandbox_SecurityError
|
18 |
+
{
|
19 |
+
private $className;
|
20 |
+
private $methodName;
|
21 |
+
|
22 |
+
public function __construct($message, $className, $methodName, $lineno = -1, $filename = null, Exception $previous = null)
|
23 |
+
{
|
24 |
+
parent::__construct($message, $lineno, $filename, $previous);
|
25 |
+
$this->className = $className;
|
26 |
+
$this->methodName = $methodName;
|
27 |
+
}
|
28 |
+
|
29 |
+
public function getClassName()
|
30 |
+
{
|
31 |
+
return $this->className;
|
32 |
+
}
|
33 |
+
|
34 |
+
public function getMethodName()
|
35 |
+
{
|
36 |
+
return $this->methodName;
|
37 |
+
}
|
38 |
+
}
|
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Twig.
|
5 |
+
*
|
6 |
+
* (c) 2009 Fabien Potencier
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Exception thrown when a not allowed class property is used in a template.
|
14 |
+
*
|
15 |
+
* @author Kit Burton-Senior <mail@kitbs.com>
|
16 |
+
*/
|
17 |
+
class Twig_Sandbox_SecurityNotAllowedPropertyError extends Twig_Sandbox_SecurityError
|
18 |
+
{
|
19 |
+
private $className;
|
20 |
+
private $propertyName;
|
21 |
+
|
22 |
+
public function __construct($message, $className, $propertyName, $lineno = -1, $filename = null, Exception $previous = null)
|
23 |
+
{
|
24 |
+
parent::__construct($message, $lineno, $filename, $previous);
|
25 |
+
$this->className = $className;
|
26 |
+
$this->propertyName = $propertyName;
|
27 |
+
}
|
28 |
+
|
29 |
+
public function getClassName()
|
30 |
+
{
|
31 |
+
return $this->className;
|
32 |
+
}
|
33 |
+
|
34 |
+
public function getPropertyName()
|
35 |
+
{
|
36 |
+
return $this->propertyName;
|
37 |
+
}
|
38 |
+
}
|
vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php
CHANGED
@@ -97,7 +97,8 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac
|
|
97 |
}
|
98 |
|
99 |
if (!$allowed) {
|
100 |
-
|
|
|
101 |
}
|
102 |
}
|
103 |
|
@@ -113,7 +114,8 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac
|
|
113 |
}
|
114 |
|
115 |
if (!$allowed) {
|
116 |
-
|
|
|
117 |
}
|
118 |
}
|
119 |
}
|
97 |
}
|
98 |
|
99 |
if (!$allowed) {
|
100 |
+
$class = get_class($obj);
|
101 |
+
throw new Twig_Sandbox_SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method);
|
102 |
}
|
103 |
}
|
104 |
|
114 |
}
|
115 |
|
116 |
if (!$allowed) {
|
117 |
+
$class = get_class($obj);
|
118 |
+
throw new Twig_Sandbox_SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property);
|
119 |
}
|
120 |
}
|
121 |
}
|
vendor/twig/twig/lib/Twig/Source.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Twig.
|
5 |
+
*
|
6 |
+
* (c) 2016 Fabien Potencier
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Holds information about a non-compiled Twig template.
|
14 |
+
*
|
15 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
16 |
+
*/
|
17 |
+
class Twig_Source
|
18 |
+
{
|
19 |
+
private $code;
|
20 |
+
private $name;
|
21 |
+
private $path;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @param string $code The template source code
|
25 |
+
* @param string $name The template logical name
|
26 |
+
* @param string $path The filesystem path of the template if any
|
27 |
+
*/
|
28 |
+
public function __construct($code, $name, $path = '')
|
29 |
+
{
|
30 |
+
$this->code = $code;
|
31 |
+
$this->name = $name;
|
32 |
+
$this->path = $path;
|
33 |
+
}
|
34 |
+
|
35 |
+
public function getCode()
|
36 |
+
{
|
37 |
+
return $this->code;
|
38 |
+
}
|
39 |
+
|
40 |
+
public function getName()
|
41 |
+
{
|
42 |
+
return $this->name;
|
43 |
+
}
|
44 |
+
|
45 |
+
public function getPath()
|
46 |
+
{
|
47 |
+
return $this->path;
|
48 |
+
}
|
49 |
+
}
|
vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Twig.
|
5 |
+
*
|
6 |
+
* (c) 2016 Fabien Potencier
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Adds a getSourceContext() method for loaders.
|
14 |
+
*
|
15 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
16 |
+
*
|
17 |
+
* @deprecated since 1.27 (to be removed in 3.0)
|
18 |
+
*/
|
19 |
+
interface Twig_SourceContextLoaderInterface
|
20 |
+
{
|
21 |
+
/**
|
22 |
+
* Returns the source context for a given template logical name.
|
23 |
+
*
|
24 |
+
* @param string $name The template logical name
|
25 |
+
*
|
26 |
+
* @return Twig_Source
|
27 |
+
*
|
28 |
+
* @throws Twig_Error_Loader When $name is not found
|
29 |
+
*/
|
30 |
+
public function getSourceContext($name);
|
31 |
+
}
|
vendor/twig/twig/lib/Twig/Template.php
CHANGED
@@ -42,6 +42,42 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
42 |
*/
|
43 |
abstract public function getTemplateName();
|
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
/**
|
46 |
* @deprecated since 1.20 (to be removed in 2.0)
|
47 |
*/
|
@@ -85,7 +121,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
85 |
$this->parents[$parent] = $this->loadTemplate($parent);
|
86 |
}
|
87 |
} catch (Twig_Error_Loader $e) {
|
88 |
-
$e->
|
89 |
$e->guess();
|
90 |
|
91 |
throw $e;
|
@@ -125,7 +161,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
125 |
} elseif (false !== $parent = $this->getParent($context)) {
|
126 |
$parent->displayBlock($name, $context, $blocks, false);
|
127 |
} else {
|
128 |
-
throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName());
|
129 |
}
|
130 |
}
|
131 |
|
@@ -166,8 +202,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
166 |
try {
|
167 |
$template->$block($context, $blocks);
|
168 |
} catch (Twig_Error $e) {
|
169 |
-
if (!$e->
|
170 |
-
$e->
|
171 |
}
|
172 |
|
173 |
// this is mostly useful for Twig_Error_Loader exceptions
|
@@ -285,8 +321,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
285 |
|
286 |
return $this->env->loadTemplate($template, $index);
|
287 |
} catch (Twig_Error $e) {
|
288 |
-
if (!$e->
|
289 |
-
$e->
|
290 |
}
|
291 |
|
292 |
if ($e->getTemplateLine()) {
|
@@ -320,33 +356,6 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
320 |
return $this->blocks;
|
321 |
}
|
322 |
|
323 |
-
/**
|
324 |
-
* Returns the template source code.
|
325 |
-
*
|
326 |
-
* @return string|null The template source code or null if it is not available
|
327 |
-
*/
|
328 |
-
public function getSource()
|
329 |
-
{
|
330 |
-
$reflector = new ReflectionClass($this);
|
331 |
-
$file = $reflector->getFileName();
|
332 |
-
|
333 |
-
if (!file_exists($file)) {
|
334 |
-
return;
|
335 |
-
}
|
336 |
-
|
337 |
-
$source = file($file, FILE_IGNORE_NEW_LINES);
|
338 |
-
array_splice($source, 0, $reflector->getEndLine());
|
339 |
-
|
340 |
-
$i = 0;
|
341 |
-
while (isset($source[$i]) && '/* */' === substr_replace($source[$i], '', 3, -2)) {
|
342 |
-
$source[$i] = str_replace('*//* ', '*/', substr($source[$i], 3, -2));
|
343 |
-
++$i;
|
344 |
-
}
|
345 |
-
array_splice($source, $i);
|
346 |
-
|
347 |
-
return implode("\n", $source);
|
348 |
-
}
|
349 |
-
|
350 |
/**
|
351 |
* {@inheritdoc}
|
352 |
*/
|
@@ -386,8 +395,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
386 |
try {
|
387 |
$this->doDisplay($context, $blocks);
|
388 |
} catch (Twig_Error $e) {
|
389 |
-
if (!$e->
|
390 |
-
$e->
|
391 |
}
|
392 |
|
393 |
// this is mostly useful for Twig_Error_Loader exceptions
|
@@ -439,7 +448,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
439 |
return;
|
440 |
}
|
441 |
|
442 |
-
throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item), -1, $this->getTemplateName());
|
443 |
}
|
444 |
|
445 |
return $context[$item];
|
@@ -485,25 +494,25 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
485 |
}
|
486 |
|
487 |
if ($object instanceof ArrayAccess) {
|
488 |
-
$message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist', $arrayItem, get_class($object));
|
489 |
} elseif (is_object($object)) {
|
490 |
-
$message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface', $item, get_class($object));
|
491 |
} elseif (is_array($object)) {
|
492 |
if (empty($object)) {
|
493 |
-
$message = sprintf('Key "%s" does not exist as the array is empty', $arrayItem);
|
494 |
} else {
|
495 |
-
$message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object)));
|
496 |
}
|
497 |
} elseif (self::ARRAY_CALL === $type) {
|
498 |
if (null === $object) {
|
499 |
-
$message = sprintf('Impossible to access a key ("%s") on a null variable', $item);
|
500 |
} else {
|
501 |
-
$message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
|
502 |
}
|
503 |
} elseif (null === $object) {
|
504 |
-
$message = sprintf('Impossible to access an attribute ("%s") on a null variable', $item);
|
505 |
} else {
|
506 |
-
$message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
|
507 |
}
|
508 |
|
509 |
throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
|
@@ -520,9 +529,9 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
520 |
}
|
521 |
|
522 |
if (null === $object) {
|
523 |
-
$message = sprintf('Impossible to invoke a method ("%s") on a null variable', $item);
|
524 |
} else {
|
525 |
-
$message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
|
526 |
}
|
527 |
|
528 |
throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
|
@@ -535,8 +544,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
535 |
return true;
|
536 |
}
|
537 |
|
538 |
-
if ($this->env->hasExtension('
|
539 |
-
$this->env->getExtension('
|
540 |
}
|
541 |
|
542 |
return $object->$item;
|
@@ -587,15 +596,15 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|
587 |
return;
|
588 |
}
|
589 |
|
590 |
-
throw new Twig_Error_Runtime(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s"', $item, get_class($object)), -1, $this->getTemplateName());
|
591 |
}
|
592 |
|
593 |
if ($isDefinedTest) {
|
594 |
return true;
|
595 |
}
|
596 |
|
597 |
-
if ($this->env->hasExtension('
|
598 |
-
$this->env->getExtension('
|
599 |
}
|
600 |
|
601 |
// Some objects throw exceptions when they have __call, and the method we try
|
42 |
*/
|
43 |
abstract public function getTemplateName();
|
44 |
|
45 |
+
/**
|
46 |
+
* Returns debug information about the template.
|
47 |
+
*
|
48 |
+
* @return array Debug information
|
49 |
+
*
|
50 |
+
* @internal
|
51 |
+
*/
|
52 |
+
public function getDebugInfo()
|
53 |
+
{
|
54 |
+
return array();
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Returns the template source code.
|
59 |
+
*
|
60 |
+
* @return string The template source code
|
61 |
+
*
|
62 |
+
* @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead
|
63 |
+
*/
|
64 |
+
public function getSource()
|
65 |
+
{
|
66 |
+
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);
|
67 |
+
|
68 |
+
return '';
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Returns information about the original template source code.
|
73 |
+
*
|
74 |
+
* @return Twig_Source
|
75 |
+
*/
|
76 |
+
public function getSourceContext()
|
77 |
+
{
|
78 |
+
return new Twig_Source('', $this->getTemplateName());
|
79 |
+
}
|
80 |
+
|
81 |
/**
|
82 |
* @deprecated since 1.20 (to be removed in 2.0)
|
83 |
*/
|
121 |
$this->parents[$parent] = $this->loadTemplate($parent);
|
122 |
}
|
123 |
} catch (Twig_Error_Loader $e) {
|
124 |
+
$e->setTemplateName(null);
|
125 |
$e->guess();
|
126 |
|
127 |
throw $e;
|
161 |
} elseif (false !== $parent = $this->getParent($context)) {
|
162 |
$parent->displayBlock($name, $context, $blocks, false);
|
163 |
} else {
|
164 |
+
throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getTemplateName());
|
165 |
}
|
166 |
}
|
167 |
|
202 |
try {
|
203 |
$template->$block($context, $blocks);
|
204 |
} catch (Twig_Error $e) {
|
205 |
+
if (!$e->getTemplateName()) {
|
206 |
+
$e->setTemplateName($template->getTemplateName());
|
207 |
}
|
208 |
|
209 |
// this is mostly useful for Twig_Error_Loader exceptions
|
321 |
|
322 |
return $this->env->loadTemplate($template, $index);
|
323 |
} catch (Twig_Error $e) {
|
324 |
+
if (!$e->getTemplateName()) {
|
325 |
+
$e->setTemplateName($templateName ? $templateName : $this->getTemplateName());
|
326 |
}
|
327 |
|
328 |
if ($e->getTemplateLine()) {
|
356 |
return $this->blocks;
|
357 |
}
|
358 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
359 |
/**
|
360 |
* {@inheritdoc}
|
361 |
*/
|
395 |
try {
|
396 |
$this->doDisplay($context, $blocks);
|
397 |
} catch (Twig_Error $e) {
|
398 |
+
if (!$e->getTemplateName()) {
|
399 |
+
$e->setTemplateName($this->getTemplateName());
|
400 |
}
|
401 |
|
402 |
// this is mostly useful for Twig_Error_Loader exceptions
|
448 |
return;
|
449 |
}
|
450 |
|
451 |
+
throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist.', $item), -1, $this->getTemplateName());
|
452 |
}
|
453 |
|
454 |
return $context[$item];
|
494 |
}
|
495 |
|
496 |
if ($object instanceof ArrayAccess) {
|
497 |
+
$message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist.', $arrayItem, get_class($object));
|
498 |
} elseif (is_object($object)) {
|
499 |
+
$message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface.', $item, get_class($object));
|
500 |
} elseif (is_array($object)) {
|
501 |
if (empty($object)) {
|
502 |
+
$message = sprintf('Key "%s" does not exist as the array is empty.', $arrayItem);
|
503 |
} else {
|
504 |
+
$message = sprintf('Key "%s" for array with keys "%s" does not exist.', $arrayItem, implode(', ', array_keys($object)));
|
505 |
}
|
506 |
} elseif (self::ARRAY_CALL === $type) {
|
507 |
if (null === $object) {
|
508 |
+
$message = sprintf('Impossible to access a key ("%s") on a null variable.', $item);
|
509 |
} else {
|
510 |
+
$message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s").', $item, gettype($object), $object);
|
511 |
}
|
512 |
} elseif (null === $object) {
|
513 |
+
$message = sprintf('Impossible to access an attribute ("%s") on a null variable.', $item);
|
514 |
} else {
|
515 |
+
$message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s").', $item, gettype($object), $object);
|
516 |
}
|
517 |
|
518 |
throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
|
529 |
}
|
530 |
|
531 |
if (null === $object) {
|
532 |
+
$message = sprintf('Impossible to invoke a method ("%s") on a null variable.', $item);
|
533 |
} else {
|
534 |
+
$message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s").', $item, gettype($object), $object);
|
535 |
}
|
536 |
|
537 |
throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
|
544 |
return true;
|
545 |
}
|
546 |
|
547 |
+
if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
|
548 |
+
$this->env->getExtension('Twig_Extension_Sandbox')->checkPropertyAllowed($object, $item);
|
549 |
}
|
550 |
|
551 |
return $object->$item;
|
596 |
return;
|
597 |
}
|
598 |
|
599 |
+
throw new Twig_Error_Runtime(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s".', $item, get_class($object)), -1, $this->getTemplateName());
|
600 |
}
|
601 |
|
602 |
if ($isDefinedTest) {
|
603 |
return true;
|
604 |
}
|
605 |
|
606 |
+
if ($this->env->hasExtension('Twig_Extension_Sandbox')) {
|
607 |
+
$this->env->getExtension('Twig_Extension_Sandbox')->checkMethodAllowed($object, $method);
|
608 |
}
|
609 |
|
610 |
// Some objects throw exceptions when they have __call, and the method we try
|
vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php
CHANGED
@@ -167,13 +167,14 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
|
|
167 |
if (false !== $exception) {
|
168 |
$message = $e->getMessage();
|
169 |
$this->assertSame(trim($exception), trim(sprintf('%s: %s', get_class($e), $message)));
|
170 |
-
$
|
|
|
171 |
|
172 |
return;
|
173 |
}
|
174 |
|
175 |
if ($e instanceof Twig_Error_Syntax) {
|
176 |
-
$e->
|
177 |
|
178 |
throw $e;
|
179 |
}
|
@@ -191,7 +192,7 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
|
|
191 |
}
|
192 |
|
193 |
if ($e instanceof Twig_Error_Syntax) {
|
194 |
-
$e->
|
195 |
} else {
|
196 |
$e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
|
197 |
}
|
@@ -211,8 +212,13 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
|
|
211 |
|
212 |
foreach (array_keys($templates) as $name) {
|
213 |
echo "Template: $name\n";
|
214 |
-
$
|
215 |
-
|
|
|
|
|
|
|
|
|
|
|
216 |
}
|
217 |
}
|
218 |
$this->assertEquals($expected, $output, $message.' (in '.$file.')');
|
167 |
if (false !== $exception) {
|
168 |
$message = $e->getMessage();
|
169 |
$this->assertSame(trim($exception), trim(sprintf('%s: %s', get_class($e), $message)));
|
170 |
+
$last = substr($message, strlen($message) - 1);
|
171 |
+
$this->assertTrue('.' === $last || '?' === $last, $message, 'Exception message must end with a dot or a question mark.');
|
172 |
|
173 |
return;
|
174 |
}
|
175 |
|
176 |
if ($e instanceof Twig_Error_Syntax) {
|
177 |
+
$e->setTemplateName($file);
|
178 |
|
179 |
throw $e;
|
180 |
}
|
192 |
}
|
193 |
|
194 |
if ($e instanceof Twig_Error_Syntax) {
|
195 |
+
$e->setTemplateName($file);
|
196 |
} else {
|
197 |
$e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
|
198 |
}
|
212 |
|
213 |
foreach (array_keys($templates) as $name) {
|
214 |
echo "Template: $name\n";
|
215 |
+
$loader = $twig->getLoader();
|
216 |
+
if (!$loader instanceof Twig_SourceContextLoaderInterface) {
|
217 |
+
$source = new Twig_Source($loader->getSource($name), $name);
|
218 |
+
} else {
|
219 |
+
$source = $loader->getSourceContext($name);
|
220 |
+
}
|
221 |
+
echo $twig->compile($twig->parse($twig->tokenize($source)));
|
222 |
}
|
223 |
}
|
224 |
$this->assertEquals($expected, $output, $message.' (in '.$file.')');
|
vendor/twig/twig/lib/Twig/Test/Method.php
CHANGED
@@ -35,6 +35,6 @@ class Twig_Test_Method extends Twig_Test
|
|
35 |
|
36 |
public function compile()
|
37 |
{
|
38 |
-
return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension
|
39 |
}
|
40 |
}
|
35 |
|
36 |
public function compile()
|
37 |
{
|
38 |
+
return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method);
|
39 |
}
|
40 |
}
|
vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php
CHANGED
@@ -39,7 +39,7 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser
|
|
39 |
} else {
|
40 |
$expr = $this->parser->getExpressionParser()->parseExpression();
|
41 |
if (!$expr instanceof Twig_Node_Expression_Constant) {
|
42 |
-
throw new Twig_Error_Syntax('An escaping strategy must be a string or a bool.', $stream->getCurrent()->getLine(), $stream->
|
43 |
}
|
44 |
$value = $expr->getAttribute('value');
|
45 |
|
@@ -53,7 +53,7 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser
|
|
53 |
@trigger_error('Using the autoescape tag with "true" or "false" before the strategy name is deprecated since version 1.21.', E_USER_DEPRECATED);
|
54 |
|
55 |
if (false === $value) {
|
56 |
-
throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->
|
57 |
}
|
58 |
|
59 |
$value = $stream->next()->getValue();
|
39 |
} else {
|
40 |
$expr = $this->parser->getExpressionParser()->parseExpression();
|
41 |
if (!$expr instanceof Twig_Node_Expression_Constant) {
|
42 |
+
throw new Twig_Error_Syntax('An escaping strategy must be a string or a bool.', $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
|
43 |
}
|
44 |
$value = $expr->getAttribute('value');
|
45 |
|
53 |
@trigger_error('Using the autoescape tag with "true" or "false" before the strategy name is deprecated since version 1.21.', E_USER_DEPRECATED);
|
54 |
|
55 |
if (false === $value) {
|
56 |
+
throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
|
57 |
}
|
58 |
|
59 |
$value = $stream->next()->getValue();
|
vendor/twig/twig/lib/Twig/TokenParser/Block.php
CHANGED
@@ -28,7 +28,7 @@ class Twig_TokenParser_Block extends Twig_TokenParser
|
|
28 |
$stream = $this->parser->getStream();
|
29 |
$name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
|
30 |
if ($this->parser->hasBlock($name)) {
|
31 |
-
throw new Twig_Error_Syntax(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->
|
32 |
}
|
33 |
$this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno));
|
34 |
$this->parser->pushLocalScope();
|
@@ -40,7 +40,7 @@ class Twig_TokenParser_Block extends Twig_TokenParser
|
|
40 |
$value = $token->getValue();
|
41 |
|
42 |
if ($value != $name) {
|
43 |
-
throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->
|
44 |
}
|
45 |
}
|
46 |
} else {
|
28 |
$stream = $this->parser->getStream();
|
29 |
$name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
|
30 |
if ($this->parser->hasBlock($name)) {
|
31 |
+
throw new Twig_Error_Syntax(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
|
32 |
}
|
33 |
$this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno));
|
34 |
$this->parser->pushLocalScope();
|
40 |
$value = $token->getValue();
|
41 |
|
42 |
if ($value != $name) {
|
43 |
+
throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
|
44 |
}
|
45 |
}
|
46 |
} else {
|
vendor/twig/twig/lib/Twig/TokenParser/Embed.php
CHANGED
@@ -22,24 +22,33 @@ class Twig_TokenParser_Embed extends Twig_TokenParser_Include
|
|
22 |
|
23 |
list($variables, $only, $ignoreMissing) = $this->parseArguments();
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
// inject a fake parent to make the parent() function work
|
26 |
$stream->injectTokens(array(
|
27 |
new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()),
|
28 |
new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()),
|
29 |
-
|
30 |
new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()),
|
31 |
));
|
32 |
|
33 |
$module = $this->parser->parse($stream, array($this, 'decideBlockEnd'), true);
|
34 |
|
35 |
// override the parent with the correct one
|
36 |
-
$
|
|
|
|
|
37 |
|
38 |
$this->parser->embedTemplate($module);
|
39 |
|
40 |
$stream->expect(Twig_Token::BLOCK_END_TYPE);
|
41 |
|
42 |
-
return new Twig_Node_Embed($module->
|
43 |
}
|
44 |
|
45 |
public function decideBlockEnd(Twig_Token $token)
|
22 |
|
23 |
list($variables, $only, $ignoreMissing) = $this->parseArguments();
|
24 |
|
25 |
+
$parentToken = $fakeParentToken = new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine());
|
26 |
+
if ($parent instanceof Twig_Node_Expression_Constant) {
|
27 |
+
$parentToken = new Twig_Token(Twig_Token::STRING_TYPE, $parent->getAttribute('value'), $token->getLine());
|
28 |
+
} elseif ($parent instanceof Twig_Node_Expression_Name) {
|
29 |
+
$parentToken = new Twig_Token(Twig_Token::NAME_TYPE, $parent->getAttribute('name'), $token->getLine());
|
30 |
+
}
|
31 |
+
|
32 |
// inject a fake parent to make the parent() function work
|
33 |
$stream->injectTokens(array(
|
34 |
new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()),
|
35 |
new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()),
|
36 |
+
$parentToken,
|
37 |
new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()),
|
38 |
));
|
39 |
|
40 |
$module = $this->parser->parse($stream, array($this, 'decideBlockEnd'), true);
|
41 |
|
42 |
// override the parent with the correct one
|
43 |
+
if ($fakeParentToken === $parentToken) {
|
44 |
+
$module->setNode('parent', $parent);
|
45 |
+
}
|
46 |
|
47 |
$this->parser->embedTemplate($module);
|
48 |
|
49 |
$stream->expect(Twig_Token::BLOCK_END_TYPE);
|
50 |
|
51 |
+
return new Twig_Node_Embed($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
|
52 |
}
|
53 |
|
54 |
public function decideBlockEnd(Twig_Token $token)
|
vendor/twig/twig/lib/Twig/TokenParser/Extends.php
CHANGED
@@ -21,16 +21,18 @@ class Twig_TokenParser_Extends extends Twig_TokenParser
|
|
21 |
{
|
22 |
public function parse(Twig_Token $token)
|
23 |
{
|
|
|
|
|
24 |
if (!$this->parser->isMainScope()) {
|
25 |
-
throw new Twig_Error_Syntax('Cannot extend from a block.', $token->getLine(), $
|
26 |
}
|
27 |
|
28 |
if (null !== $this->parser->getParent()) {
|
29 |
-
throw new Twig_Error_Syntax('Multiple extends tags are forbidden.', $token->getLine(), $
|
30 |
}
|
31 |
$this->parser->setParent($this->parser->getExpressionParser()->parseExpression());
|
32 |
|
33 |
-
$
|
34 |
}
|
35 |
|
36 |
public function getTag()
|
21 |
{
|
22 |
public function parse(Twig_Token $token)
|
23 |
{
|
24 |
+
$stream = $this->parser->getStream();
|
25 |
+
|
26 |
if (!$this->parser->isMainScope()) {
|
27 |
+
throw new Twig_Error_Syntax('Cannot extend from a block.', $token->getLine(), $stream->getSourceContext()->getName());
|
28 |
}
|
29 |
|
30 |
if (null !== $this->parser->getParent()) {
|
31 |
+
throw new Twig_Error_Syntax('Multiple extends tags are forbidden.', $token->getLine(), $stream->getSourceContext()->getName());
|
32 |
}
|
33 |
$this->parser->setParent($this->parser->getExpressionParser()->parseExpression());
|
34 |
|
35 |
+
$stream->expect(Twig_Token::BLOCK_END_TYPE);
|
36 |
}
|
37 |
|
38 |
public function getTag()
|
vendor/twig/twig/lib/Twig/TokenParser/For.php
CHANGED
@@ -48,13 +48,13 @@ class Twig_TokenParser_For extends Twig_TokenParser
|
|
48 |
|
49 |
if (count($targets) > 1) {
|
50 |
$keyTarget = $targets->getNode(0);
|
51 |
-
$keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->
|
52 |
$valueTarget = $targets->getNode(1);
|
53 |
-
$valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->
|
54 |
} else {
|
55 |
$keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno);
|
56 |
$valueTarget = $targets->getNode(0);
|
57 |
-
$valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->
|
58 |
}
|
59 |
|
60 |
if ($ifexpr) {
|
@@ -79,7 +79,7 @@ class Twig_TokenParser_For extends Twig_TokenParser
|
|
79 |
protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node)
|
80 |
{
|
81 |
if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
|
82 |
-
throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition.', $node->
|
83 |
}
|
84 |
|
85 |
foreach ($node as $n) {
|
@@ -98,7 +98,7 @@ class Twig_TokenParser_For extends Twig_TokenParser
|
|
98 |
if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
|
99 |
$attribute = $node->getNode('attribute');
|
100 |
if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) {
|
101 |
-
throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition.', $attribute->getAttribute('value')), $node->
|
102 |
}
|
103 |
}
|
104 |
|
48 |
|
49 |
if (count($targets) > 1) {
|
50 |
$keyTarget = $targets->getNode(0);
|
51 |
+
$keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->getTemplateLine());
|
52 |
$valueTarget = $targets->getNode(1);
|
53 |
+
$valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
|
54 |
} else {
|
55 |
$keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno);
|
56 |
$valueTarget = $targets->getNode(0);
|
57 |
+
$valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
|
58 |
}
|
59 |
|
60 |
if ($ifexpr) {
|
79 |
protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node)
|
80 |
{
|
81 |
if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
|
82 |
+
throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition.', $node->getTemplateLine(), $stream->getSourceContext()->getName());
|
83 |
}
|
84 |
|
85 |
foreach ($node as $n) {
|
98 |
if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
|
99 |
$attribute = $node->getNode('attribute');
|
100 |
if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) {
|
101 |
+
throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition.', $attribute->getAttribute('value')), $node->getTemplateLine(), $stream->getSourceContext()->getName());
|
102 |
}
|
103 |
}
|
104 |
|
vendor/twig/twig/lib/Twig/TokenParser/From.php
CHANGED
@@ -46,7 +46,7 @@ class Twig_TokenParser_From extends Twig_TokenParser
|
|
46 |
|
47 |
foreach ($targets as $name => $alias) {
|
48 |
if ($this->parser->isReservedMacroName($name)) {
|
49 |
-
throw new Twig_Error_Syntax(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->
|
50 |
}
|
51 |
|
52 |
$this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var'));
|
46 |
|
47 |
foreach ($targets as $name => $alias) {
|
48 |
if ($this->parser->isReservedMacroName($name)) {
|
49 |
+
throw new Twig_Error_Syntax(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext()->getName());
|
50 |
}
|
51 |
|
52 |
$this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var'));
|
vendor/twig/twig/lib/Twig/TokenParser/If.php
CHANGED
@@ -56,7 +56,7 @@ class Twig_TokenParser_If extends Twig_TokenParser
|
|
56 |
break;
|
57 |
|
58 |
default:
|
59 |
-
throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->
|
60 |
}
|
61 |
}
|
62 |
|
56 |
break;
|
57 |
|
58 |
default:
|
59 |
+
throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
|
60 |
}
|
61 |
}
|
62 |
|
vendor/twig/twig/lib/Twig/TokenParser/Macro.php
CHANGED
@@ -35,7 +35,7 @@ class Twig_TokenParser_Macro extends Twig_TokenParser
|
|
35 |
$value = $token->getValue();
|
36 |
|
37 |
if ($value != $name) {
|
38 |
-
throw new Twig_Error_Syntax(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->
|
39 |
}
|
40 |
}
|
41 |
$this->parser->popLocalScope();
|
35 |
$value = $token->getValue();
|
36 |
|
37 |
if ($value != $name) {
|
38 |
+
throw new Twig_Error_Syntax(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
|
39 |
}
|
40 |
}
|
41 |
$this->parser->popLocalScope();
|
vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php
CHANGED
@@ -24,9 +24,10 @@ class Twig_TokenParser_Sandbox extends Twig_TokenParser
|
|
24 |
{
|
25 |
public function parse(Twig_Token $token)
|
26 |
{
|
27 |
-
$this->parser->getStream()
|
|
|
28 |
$body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
|
29 |
-
$
|
30 |
|
31 |
// in a sandbox tag, only include tags are allowed
|
32 |
if (!$body instanceof Twig_Node_Include) {
|
@@ -36,7 +37,7 @@ class Twig_TokenParser_Sandbox extends Twig_TokenParser
|
|
36 |
}
|
37 |
|
38 |
if (!$node instanceof Twig_Node_Include) {
|
39 |
-
throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section.', $node->
|
40 |
}
|
41 |
}
|
42 |
}
|
24 |
{
|
25 |
public function parse(Twig_Token $token)
|
26 |
{
|
27 |
+
$stream = $this->parser->getStream();
|
28 |
+
$stream->expect(Twig_Token::BLOCK_END_TYPE);
|
29 |
$body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
|
30 |
+
$stream->expect(Twig_Token::BLOCK_END_TYPE);
|
31 |
|
32 |
// in a sandbox tag, only include tags are allowed
|
33 |
if (!$body instanceof Twig_Node_Include) {
|
37 |
}
|
38 |
|
39 |
if (!$node instanceof Twig_Node_Include) {
|
40 |
+
throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section.', $node->getTemplateLine(), $stream->getSourceContext()->getName());
|
41 |
}
|
42 |
}
|
43 |
}
|
vendor/twig/twig/lib/Twig/TokenParser/Set.php
CHANGED
@@ -41,13 +41,13 @@ class Twig_TokenParser_Set extends Twig_TokenParser
|
|
41 |
$stream->expect(Twig_Token::BLOCK_END_TYPE);
|
42 |
|
43 |
if (count($names) !== count($values)) {
|
44 |
-
throw new Twig_Error_Syntax('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->
|
45 |
}
|
46 |
} else {
|
47 |
$capture = true;
|
48 |
|
49 |
if (count($names) > 1) {
|
50 |
-
throw new Twig_Error_Syntax('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->
|
51 |
}
|
52 |
|
53 |
$stream->expect(Twig_Token::BLOCK_END_TYPE);
|
41 |
$stream->expect(Twig_Token::BLOCK_END_TYPE);
|
42 |
|
43 |
if (count($names) !== count($values)) {
|
44 |
+
throw new Twig_Error_Syntax('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
|
45 |
}
|
46 |
} else {
|
47 |
$capture = true;
|
48 |
|
49 |
if (count($names) > 1) {
|
50 |
+
throw new Twig_Error_Syntax('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
|
51 |
}
|
52 |
|
53 |
$stream->expect(Twig_Token::BLOCK_END_TYPE);
|
vendor/twig/twig/lib/Twig/TokenParser/Use.php
CHANGED
@@ -31,7 +31,7 @@ class Twig_TokenParser_Use extends Twig_TokenParser
|
|
31 |
$stream = $this->parser->getStream();
|
32 |
|
33 |
if (!$template instanceof Twig_Node_Expression_Constant) {
|
34 |
-
throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->
|
35 |
}
|
36 |
|
37 |
$targets = array();
|
31 |
$stream = $this->parser->getStream();
|
32 |
|
33 |
if (!$template instanceof Twig_Node_Expression_Constant) {
|
34 |
+
throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getSourceContext()->getName());
|
35 |
}
|
36 |
|
37 |
$targets = array();
|
vendor/twig/twig/lib/Twig/TokenStream.php
CHANGED
@@ -21,16 +21,30 @@ class Twig_TokenStream
|
|
21 |
protected $current = 0;
|
22 |
protected $filename;
|
23 |
|
|
|
|
|
24 |
/**
|
25 |
* Constructor.
|
26 |
*
|
27 |
-
* @param array
|
28 |
-
* @param string $
|
|
|
29 |
*/
|
30 |
-
public function __construct(array $tokens, $
|
31 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
$this->tokens = $tokens;
|
33 |
-
|
|
|
|
|
34 |
}
|
35 |
|
36 |
/**
|
@@ -56,7 +70,7 @@ class Twig_TokenStream
|
|
56 |
public function next()
|
57 |
{
|
58 |
if (!isset($this->tokens[++$this->current])) {
|
59 |
-
throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->
|
60 |
}
|
61 |
|
62 |
return $this->tokens[$this->current - 1];
|
@@ -89,7 +103,7 @@ class Twig_TokenStream
|
|
89 |
Twig_Token::typeToEnglish($token->getType()), $token->getValue(),
|
90 |
Twig_Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
|
91 |
$line,
|
92 |
-
$this->
|
93 |
);
|
94 |
}
|
95 |
$this->next();
|
@@ -107,7 +121,7 @@ class Twig_TokenStream
|
|
107 |
public function look($number = 1)
|
108 |
{
|
109 |
if (!isset($this->tokens[$this->current + $number])) {
|
110 |
-
throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->
|
111 |
}
|
112 |
|
113 |
return $this->tokens[$this->current + $number];
|
@@ -144,12 +158,44 @@ class Twig_TokenStream
|
|
144 |
}
|
145 |
|
146 |
/**
|
147 |
-
* Gets the
|
148 |
*
|
149 |
-
* @return string
|
|
|
|
|
150 |
*/
|
151 |
public function getFilename()
|
152 |
{
|
153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
}
|
155 |
}
|
21 |
protected $current = 0;
|
22 |
protected $filename;
|
23 |
|
24 |
+
private $source;
|
25 |
+
|
26 |
/**
|
27 |
* Constructor.
|
28 |
*
|
29 |
+
* @param array $tokens An array of tokens
|
30 |
+
* @param string|null $name The name of the template which tokens are associated with
|
31 |
+
* @param string|null $source The source code associated with the tokens
|
32 |
*/
|
33 |
+
public function __construct(array $tokens, $name = null, $source = null)
|
34 |
{
|
35 |
+
if (!$name instanceof Twig_Source) {
|
36 |
+
if (null !== $name || null !== $source) {
|
37 |
+
@trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
|
38 |
+
}
|
39 |
+
$this->source = new Twig_Source($source, $name);
|
40 |
+
} else {
|
41 |
+
$this->source = $name;
|
42 |
+
}
|
43 |
+
|
44 |
$this->tokens = $tokens;
|
45 |
+
|
46 |
+
// deprecated, not used anymore, to be removed in 2.0
|
47 |
+
$this->filename = $this->source->getName();
|
48 |
}
|
49 |
|
50 |
/**
|
70 |
public function next()
|
71 |
{
|
72 |
if (!isset($this->tokens[++$this->current])) {
|
73 |
+
throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->source->getName());
|
74 |
}
|
75 |
|
76 |
return $this->tokens[$this->current - 1];
|
103 |
Twig_Token::typeToEnglish($token->getType()), $token->getValue(),
|
104 |
Twig_Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
|
105 |
$line,
|
106 |
+
$this->source->getName()
|
107 |
);
|
108 |
}
|
109 |
$this->next();
|
121 |
public function look($number = 1)
|
122 |
{
|
123 |
if (!isset($this->tokens[$this->current + $number])) {
|
124 |
+
throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->source->getName());
|
125 |
}
|
126 |
|
127 |
return $this->tokens[$this->current + $number];
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
+
* Gets the name associated with this stream (null if not defined).
|
162 |
*
|
163 |
+
* @return string|null
|
164 |
+
*
|
165 |
+
* @deprecated since 1.27 (to be removed in 2.0)
|
166 |
*/
|
167 |
public function getFilename()
|
168 |
{
|
169 |
+
@trigger_error(sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED);
|
170 |
+
|
171 |
+
return $this->source->getName();
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Gets the source code associated with this stream.
|
176 |
+
*
|
177 |
+
* @return string
|
178 |
+
*
|
179 |
+
* @internal Don't use this as it might be empty depending on the environment configuration
|
180 |
+
*
|
181 |
+
* @deprecated since 1.27 (to be removed in 2.0)
|
182 |
+
*/
|
183 |
+
public function getSource()
|
184 |
+
{
|
185 |
+
@trigger_error(sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED);
|
186 |
+
|
187 |
+
return $this->source->getCode();
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Gets the source associated with this stream.
|
192 |
+
*
|
193 |
+
* @return Twig_Source
|
194 |
+
*
|
195 |
+
* @internal
|
196 |
+
*/
|
197 |
+
public function getSourceContext()
|
198 |
+
{
|
199 |
+
return $this->source;
|
200 |
}
|
201 |
}
|
vendor/twig/twig/test/Twig/Tests/Cache/FilesystemTest.php
CHANGED
@@ -115,7 +115,7 @@ class Twig_Tests_Cache_FilesystemTest extends PHPUnit_Framework_TestCase
|
|
115 |
// Create root directory.
|
116 |
@mkdir($this->directory, 0777, true);
|
117 |
// Create read-only subdirectory.
|
118 |
-
@mkdir($this->directory.'/cache'
|
119 |
$this->assertTrue(is_dir($this->directory.'/cache'));
|
120 |
|
121 |
$this->cache->write($key, $content);
|
115 |
// Create root directory.
|
116 |
@mkdir($this->directory, 0777, true);
|
117 |
// Create read-only subdirectory.
|
118 |
+
@mkdir($this->directory.'/cache', 0555);
|
119 |
$this->assertTrue(is_dir($this->directory.'/cache'));
|
120 |
|
121 |
$this->cache->write($key, $content);
|
vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php
CHANGED
@@ -15,6 +15,27 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
15 |
{
|
16 |
private $deprecations = array();
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
/**
|
19 |
* @expectedException LogicException
|
20 |
* @expectedExceptionMessage You must set a loader first.
|
@@ -43,16 +64,21 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
43 |
$this->assertEquals('foo\x3Cbr\x2F\x20\x3E foo\x3Cbr\x2F\x20\x3E', $twig->render('js', array('bar' => 'foo<br/ >')));
|
44 |
}
|
45 |
|
46 |
-
public function escapingStrategyCallback($
|
47 |
{
|
48 |
-
return $
|
49 |
}
|
50 |
|
51 |
public function testGlobals()
|
52 |
{
|
|
|
|
|
|
|
|
|
|
|
53 |
// globals can be added after calling getGlobals
|
54 |
|
55 |
-
$twig = new Twig_Environment($
|
56 |
$twig->addGlobal('foo', 'foo');
|
57 |
$twig->getGlobals();
|
58 |
$twig->addGlobal('foo', 'bar');
|
@@ -60,7 +86,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
60 |
$this->assertEquals('bar', $globals['foo']);
|
61 |
|
62 |
// globals can be modified after a template has been loaded
|
63 |
-
$twig = new Twig_Environment($
|
64 |
$twig->addGlobal('foo', 'foo');
|
65 |
$twig->getGlobals();
|
66 |
$twig->loadTemplate('index');
|
@@ -69,7 +95,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
69 |
$this->assertEquals('bar', $globals['foo']);
|
70 |
|
71 |
// globals can be modified after extensions init
|
72 |
-
$twig = new Twig_Environment($
|
73 |
$twig->addGlobal('foo', 'foo');
|
74 |
$twig->getGlobals();
|
75 |
$twig->getFunctions();
|
@@ -78,7 +104,8 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
78 |
$this->assertEquals('bar', $globals['foo']);
|
79 |
|
80 |
// globals can be modified after extensions and a template has been loaded
|
81 |
-
$
|
|
|
82 |
$twig->addGlobal('foo', 'foo');
|
83 |
$twig->getGlobals();
|
84 |
$twig->getFunctions();
|
@@ -87,7 +114,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
87 |
$globals = $twig->getGlobals();
|
88 |
$this->assertEquals('bar', $globals['foo']);
|
89 |
|
90 |
-
$twig = new Twig_Environment($
|
91 |
$twig->getGlobals();
|
92 |
$twig->addGlobal('foo', 'bar');
|
93 |
$template = $twig->loadTemplate('index');
|
@@ -95,7 +122,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
95 |
|
96 |
/* to be uncomment in Twig 2.0
|
97 |
// globals cannot be added after a template has been loaded
|
98 |
-
$twig = new Twig_Environment($
|
99 |
$twig->addGlobal('foo', 'foo');
|
100 |
$twig->getGlobals();
|
101 |
$twig->loadTemplate('index');
|
@@ -107,7 +134,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
107 |
}
|
108 |
|
109 |
// globals cannot be added after extensions init
|
110 |
-
$twig = new Twig_Environment($
|
111 |
$twig->addGlobal('foo', 'foo');
|
112 |
$twig->getGlobals();
|
113 |
$twig->getFunctions();
|
@@ -119,7 +146,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
119 |
}
|
120 |
|
121 |
// globals cannot be added after extensions and a template has been loaded
|
122 |
-
$twig = new Twig_Environment($
|
123 |
$twig->addGlobal('foo', 'foo');
|
124 |
$twig->getGlobals();
|
125 |
$twig->getFunctions();
|
@@ -132,7 +159,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
132 |
}
|
133 |
|
134 |
// test adding globals after a template has been loaded without call to getGlobals
|
135 |
-
$twig = new Twig_Environment($
|
136 |
$twig->loadTemplate('index');
|
137 |
try {
|
138 |
$twig->addGlobal('bar', 'bar');
|
@@ -143,18 +170,6 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
143 |
*/
|
144 |
}
|
145 |
|
146 |
-
public function testCompileSourceInlinesSource()
|
147 |
-
{
|
148 |
-
$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
|
149 |
-
|
150 |
-
$source = "<? */*foo*/ ?>\r\nbar\n";
|
151 |
-
$expected = "/* <? *//* *foo*//* ?>*/\n/* bar*/\n/* */\n";
|
152 |
-
$compiled = $twig->compileSource($source, 'index');
|
153 |
-
|
154 |
-
$this->assertContains($expected, $compiled);
|
155 |
-
$this->assertNotContains('/**', $compiled);
|
156 |
-
}
|
157 |
-
|
158 |
public function testExtensionsAreNotInitializedWhenRenderingACompiledTemplate()
|
159 |
{
|
160 |
$cache = new Twig_Cache_Filesystem($dir = sys_get_temp_dir().'/twig');
|
@@ -164,7 +179,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
164 |
$twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{ foo }}')), $options);
|
165 |
|
166 |
$key = $cache->generateKey('index', $twig->getTemplateClass('index'));
|
167 |
-
$cache->write($key, $twig->compileSource('{{ foo }}', 'index'));
|
168 |
|
169 |
// check that extensions won't be initialized when rendering a template that is already in the cache
|
170 |
$twig = $this
|
@@ -262,6 +277,38 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
262 |
$twig->loadTemplate($templateName);
|
263 |
}
|
264 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
public function testAddExtension()
|
266 |
{
|
267 |
$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
|
@@ -275,7 +322,13 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
275 |
$this->assertArrayHasKey('foo_binary', $twig->getBinaryOperators());
|
276 |
$this->assertArrayHasKey('foo_global', $twig->getGlobals());
|
277 |
$visitors = $twig->getNodeVisitors();
|
278 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
}
|
280 |
|
281 |
/**
|
@@ -292,7 +345,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
292 |
$this->assertArrayHasKey('foo_global', $twig->getGlobals());
|
293 |
|
294 |
$this->assertCount(1, $this->deprecations);
|
295 |
-
$this->assertContains('Defining the getGlobals() method in the "
|
296 |
|
297 |
restore_error_handler();
|
298 |
}
|
@@ -303,7 +356,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
303 |
public function testRemoveExtension()
|
304 |
{
|
305 |
$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
|
306 |
-
$twig->addExtension(new
|
307 |
$twig->removeExtension('environment_test');
|
308 |
|
309 |
$this->assertFalse(array_key_exists('test', $twig->getTags()));
|
@@ -318,17 +371,22 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
318 |
|
319 |
public function testAddMockExtension()
|
320 |
{
|
321 |
-
|
322 |
-
$extension
|
323 |
-
|
324 |
-
|
|
|
|
|
|
|
|
|
|
|
325 |
|
326 |
$loader = new Twig_Loader_Array(array('page' => 'hey'));
|
327 |
|
328 |
$twig = new Twig_Environment($loader);
|
329 |
$twig->addExtension($extension);
|
330 |
|
331 |
-
$this->assertInstanceOf('Twig_ExtensionInterface', $twig->getExtension(
|
332 |
$this->assertTrue($twig->isTemplateFresh('page', time()));
|
333 |
}
|
334 |
|
@@ -354,7 +412,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
354 |
$twig->initRuntime();
|
355 |
|
356 |
$this->assertCount(1, $this->deprecations);
|
357 |
-
$this->assertContains('Defining the initRuntime() method in the "
|
358 |
|
359 |
restore_error_handler();
|
360 |
}
|
@@ -377,8 +435,8 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
377 |
$this->deprecations = array();
|
378 |
set_error_handler(array($this, 'handleError'));
|
379 |
|
380 |
-
$twig->addExtension(new
|
381 |
-
$twig->addExtension(new
|
382 |
|
383 |
$this->assertCount(1, $this->deprecations);
|
384 |
$this->assertContains('The possibility to register the same extension twice', $this->deprecations[0]);
|
@@ -386,13 +444,41 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
|
386 |
restore_error_handler();
|
387 |
}
|
388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
389 |
protected function getMockLoader($templateName, $templateContent)
|
390 |
{
|
391 |
-
|
|
|
|
|
392 |
$loader->expects($this->any())
|
393 |
-
->method('
|
394 |
->with($templateName)
|
395 |
-
->will($this->returnValue($templateContent));
|
396 |
$loader->expects($this->any())
|
397 |
->method('getCacheKey')
|
398 |
->with($templateName)
|
@@ -410,11 +496,6 @@ class Twig_Tests_EnvironmentTest_Extension_WithGlobals extends Twig_Extension
|
|
410 |
'foo_global' => 'foo_global',
|
411 |
);
|
412 |
}
|
413 |
-
|
414 |
-
public function getName()
|
415 |
-
{
|
416 |
-
return 'environment_test';
|
417 |
-
}
|
418 |
}
|
419 |
|
420 |
class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension implements Twig_Extension_GlobalsInterface
|
@@ -468,13 +549,31 @@ class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension implements Twi
|
|
468 |
'foo_global' => 'foo_global',
|
469 |
);
|
470 |
}
|
|
|
471 |
|
|
|
|
|
472 |
public function getName()
|
473 |
{
|
474 |
return 'environment_test';
|
475 |
}
|
476 |
}
|
477 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
478 |
class Twig_Tests_EnvironmentTest_TokenParser extends Twig_TokenParser
|
479 |
{
|
480 |
public function parse(Twig_Token $token)
|
@@ -510,21 +609,39 @@ class Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime extends Twi
|
|
510 |
public function initRuntime(Twig_Environment $env)
|
511 |
{
|
512 |
}
|
|
|
513 |
|
514 |
-
|
|
|
|
|
515 |
{
|
516 |
-
return 'with_deprecation';
|
517 |
}
|
518 |
}
|
519 |
|
520 |
-
class
|
521 |
{
|
522 |
-
public function
|
523 |
{
|
|
|
|
|
|
|
|
|
524 |
}
|
525 |
|
526 |
public function getName()
|
527 |
{
|
528 |
-
return '
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
529 |
}
|
530 |
}
|
|
|
|
|
|
|
|
15 |
{
|
16 |
private $deprecations = array();
|
17 |
|
18 |
+
/**
|
19 |
+
* @group legacy
|
20 |
+
*/
|
21 |
+
public function testLegacyTokenizeSignature()
|
22 |
+
{
|
23 |
+
$env = new Twig_Environment();
|
24 |
+
$stream = $env->tokenize('{{ foo }}', 'foo');
|
25 |
+
$this->assertEquals('{{ foo }}', $stream->getSource());
|
26 |
+
$this->assertEquals('foo', $stream->getFilename());
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @group legacy
|
31 |
+
*/
|
32 |
+
public function testLegacyCompileSourceSignature()
|
33 |
+
{
|
34 |
+
$loader = new Twig_Loader_Array(array('foo' => '{{ foo }}'));
|
35 |
+
$env = new Twig_Environment($loader);
|
36 |
+
$this->assertContains('getTemplateName', $env->compileSource('{{ foo }}', 'foo'));
|
37 |
+
}
|
38 |
+
|
39 |
/**
|
40 |
* @expectedException LogicException
|
41 |
* @expectedExceptionMessage You must set a loader first.
|
64 |
$this->assertEquals('foo\x3Cbr\x2F\x20\x3E foo\x3Cbr\x2F\x20\x3E', $twig->render('js', array('bar' => 'foo<br/ >')));
|
65 |
}
|
66 |
|
67 |
+
public function escapingStrategyCallback($name)
|
68 |
{
|
69 |
+
return $name;
|
70 |
}
|
71 |
|
72 |
public function testGlobals()
|
73 |
{
|
74 |
+
// to be removed in 2.0
|
75 |
+
$loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
|
76 |
+
//$loader = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock();
|
77 |
+
$loader->expects($this->any())->method('getSourceContext')->will($this->returnValue(new Twig_Source('', '')));
|
78 |
+
|
79 |
// globals can be added after calling getGlobals
|
80 |
|
81 |
+
$twig = new Twig_Environment($loader);
|
82 |
$twig->addGlobal('foo', 'foo');
|
83 |
$twig->getGlobals();
|
84 |
$twig->addGlobal('foo', 'bar');
|
86 |
$this->assertEquals('bar', $globals['foo']);
|
87 |
|
88 |
// globals can be modified after a template has been loaded
|
89 |
+
$twig = new Twig_Environment($loader);
|
90 |
$twig->addGlobal('foo', 'foo');
|
91 |
$twig->getGlobals();
|
92 |
$twig->loadTemplate('index');
|
95 |
$this->assertEquals('bar', $globals['foo']);
|
96 |
|
97 |
// globals can be modified after extensions init
|
98 |
+
$twig = new Twig_Environment($loader);
|
99 |
$twig->addGlobal('foo', 'foo');
|
100 |
$twig->getGlobals();
|
101 |
$twig->getFunctions();
|
104 |
$this->assertEquals('bar', $globals['foo']);
|
105 |
|
106 |
// globals can be modified after extensions and a template has been loaded
|
107 |
+
$arrayLoader = new Twig_Loader_Array(array('index' => '{{foo}}'));
|
108 |
+
$twig = new Twig_Environment($arrayLoader);
|
109 |
$twig->addGlobal('foo', 'foo');
|
110 |
$twig->getGlobals();
|
111 |
$twig->getFunctions();
|
114 |
$globals = $twig->getGlobals();
|
115 |
$this->assertEquals('bar', $globals['foo']);
|
116 |
|
117 |
+
$twig = new Twig_Environment($arrayLoader);
|
118 |
$twig->getGlobals();
|
119 |
$twig->addGlobal('foo', 'bar');
|
120 |
$template = $twig->loadTemplate('index');
|
122 |
|
123 |
/* to be uncomment in Twig 2.0
|
124 |
// globals cannot be added after a template has been loaded
|
125 |
+
$twig = new Twig_Environment($loader);
|
126 |
$twig->addGlobal('foo', 'foo');
|
127 |
$twig->getGlobals();
|
128 |
$twig->loadTemplate('index');
|
134 |
}
|
135 |
|
136 |
// globals cannot be added after extensions init
|
137 |
+
$twig = new Twig_Environment($loader);
|
138 |
$twig->addGlobal('foo', 'foo');
|
139 |
$twig->getGlobals();
|
140 |
$twig->getFunctions();
|
146 |
}
|
147 |
|
148 |
// globals cannot be added after extensions and a template has been loaded
|
149 |
+
$twig = new Twig_Environment($loader);
|
150 |
$twig->addGlobal('foo', 'foo');
|
151 |
$twig->getGlobals();
|
152 |
$twig->getFunctions();
|
159 |
}
|
160 |
|
161 |
// test adding globals after a template has been loaded without call to getGlobals
|
162 |
+
$twig = new Twig_Environment($loader);
|
163 |
$twig->loadTemplate('index');
|
164 |
try {
|
165 |
$twig->addGlobal('bar', 'bar');
|
170 |
*/
|
171 |
}
|
172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
public function testExtensionsAreNotInitializedWhenRenderingACompiledTemplate()
|
174 |
{
|
175 |
$cache = new Twig_Cache_Filesystem($dir = sys_get_temp_dir().'/twig');
|
179 |
$twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{ foo }}')), $options);
|
180 |
|
181 |
$key = $cache->generateKey('index', $twig->getTemplateClass('index'));
|
182 |
+
$cache->write($key, $twig->compileSource(new Twig_Source('{{ foo }}', 'index')));
|
183 |
|
184 |
// check that extensions won't be initialized when rendering a template that is already in the cache
|
185 |
$twig = $this
|
277 |
$twig->loadTemplate($templateName);
|
278 |
}
|
279 |
|
280 |
+
/**
|
281 |
+
* @group legacy
|
282 |
+
*/
|
283 |
+
public function testHasGetExtensionWithDynamicName()
|
284 |
+
{
|
285 |
+
$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
|
286 |
+
|
287 |
+
$ext1 = new Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName('ext1');
|
288 |
+
$ext2 = new Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName('ext2');
|
289 |
+
$twig->addExtension($ext1);
|
290 |
+
$twig->addExtension($ext2);
|
291 |
+
|
292 |
+
$this->assertTrue($twig->hasExtension('ext1'));
|
293 |
+
$this->assertTrue($twig->hasExtension('ext2'));
|
294 |
+
|
295 |
+
$this->assertTrue($twig->hasExtension('Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName'));
|
296 |
+
|
297 |
+
$this->assertSame($ext1, $twig->getExtension('ext1'));
|
298 |
+
$this->assertSame($ext2, $twig->getExtension('ext2'));
|
299 |
+
}
|
300 |
+
|
301 |
+
public function testHasGetExtensionByClassName()
|
302 |
+
{
|
303 |
+
$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
|
304 |
+
$twig->addExtension($ext = new Twig_Tests_EnvironmentTest_Extension());
|
305 |
+
$this->assertTrue($twig->hasExtension('Twig_Tests_EnvironmentTest_Extension'));
|
306 |
+
$this->assertTrue($twig->hasExtension('\Twig_Tests_EnvironmentTest_Extension'));
|
307 |
+
|
308 |
+
$this->assertSame($ext, $twig->getExtension('Twig_Tests_EnvironmentTest_Extension'));
|
309 |
+
$this->assertSame($ext, $twig->getExtension('\Twig_Tests_EnvironmentTest_Extension'));
|
310 |
+
}
|
311 |
+
|
312 |
public function testAddExtension()
|
313 |
{
|
314 |
$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
|
322 |
$this->assertArrayHasKey('foo_binary', $twig->getBinaryOperators());
|
323 |
$this->assertArrayHasKey('foo_global', $twig->getGlobals());
|
324 |
$visitors = $twig->getNodeVisitors();
|
325 |
+
$found = false;
|
326 |
+
foreach ($visitors as $visitor) {
|
327 |
+
if ($visitor instanceof Twig_Tests_EnvironmentTest_NodeVisitor) {
|
328 |
+
$found = true;
|
329 |
+
}
|
330 |
+
}
|
331 |
+
$this->assertTrue($found);
|
332 |
}
|
333 |
|
334 |
/**
|
345 |
$this->assertArrayHasKey('foo_global', $twig->getGlobals());
|
346 |
|
347 |
$this->assertCount(1, $this->deprecations);
|
348 |
+
$this->assertContains('Defining the getGlobals() method in the "Twig_Tests_EnvironmentTest_Extension_WithGlobals" extension ', $this->deprecations[0]);
|
349 |
|
350 |
restore_error_handler();
|
351 |
}
|
356 |
public function testRemoveExtension()
|
357 |
{
|
358 |
$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
|
359 |
+
$twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName());
|
360 |
$twig->removeExtension('environment_test');
|
361 |
|
362 |
$this->assertFalse(array_key_exists('test', $twig->getTags()));
|
371 |
|
372 |
public function testAddMockExtension()
|
373 |
{
|
374 |
+
// should be replaced by the following in 2.0 (this current code is just to avoid a dep notice)
|
375 |
+
// $extension = $this->getMockBuilder('Twig_Extension')->getMock();
|
376 |
+
$extension = eval(<<<EOF
|
377 |
+
class Twig_Tests_EnvironmentTest_ExtensionInEval extends Twig_Extension
|
378 |
+
{
|
379 |
+
}
|
380 |
+
EOF
|
381 |
+
);
|
382 |
+
$extension = new Twig_Tests_EnvironmentTest_ExtensionInEval();
|
383 |
|
384 |
$loader = new Twig_Loader_Array(array('page' => 'hey'));
|
385 |
|
386 |
$twig = new Twig_Environment($loader);
|
387 |
$twig->addExtension($extension);
|
388 |
|
389 |
+
$this->assertInstanceOf('Twig_ExtensionInterface', $twig->getExtension(get_class($extension)));
|
390 |
$this->assertTrue($twig->isTemplateFresh('page', time()));
|
391 |
}
|
392 |
|
412 |
$twig->initRuntime();
|
413 |
|
414 |
$this->assertCount(1, $this->deprecations);
|
415 |
+
$this->assertContains('Defining the initRuntime() method in the "Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime" extension is deprecated since version 1.23.', $this->deprecations[0]);
|
416 |
|
417 |
restore_error_handler();
|
418 |
}
|
435 |
$this->deprecations = array();
|
436 |
set_error_handler(array($this, 'handleError'));
|
437 |
|
438 |
+
$twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName());
|
439 |
+
$twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName());
|
440 |
|
441 |
$this->assertCount(1, $this->deprecations);
|
442 |
$this->assertContains('The possibility to register the same extension twice', $this->deprecations[0]);
|
444 |
restore_error_handler();
|
445 |
}
|
446 |
|
447 |
+
public function testAddRuntimeLoader()
|
448 |
+
{
|
449 |
+
$runtimeLoader = $this->getMockBuilder('Twig_RuntimeLoaderInterface')->getMock();
|
450 |
+
$runtimeLoader->expects($this->any())->method('load')->will($this->returnValue(new Twig_Tests_EnvironmentTest_Runtime()));
|
451 |
+
|
452 |
+
$loader = new Twig_Loader_Array(array(
|
453 |
+
'func_array' => '{{ from_runtime_array("foo") }}',
|
454 |
+
'func_array_default' => '{{ from_runtime_array() }}',
|
455 |
+
'func_array_named_args' => '{{ from_runtime_array(name="foo") }}',
|
456 |
+
'func_string' => '{{ from_runtime_string("foo") }}',
|
457 |
+
'func_string_default' => '{{ from_runtime_string() }}',
|
458 |
+
'func_string_named_args' => '{{ from_runtime_string(name="foo") }}',
|
459 |
+
));
|
460 |
+
|
461 |
+
$twig = new Twig_Environment($loader);
|
462 |
+
$twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithoutRuntime());
|
463 |
+
$twig->addRuntimeLoader($runtimeLoader);
|
464 |
+
|
465 |
+
$this->assertEquals('foo', $twig->render('func_array'));
|
466 |
+
$this->assertEquals('bar', $twig->render('func_array_default'));
|
467 |
+
$this->assertEquals('foo', $twig->render('func_array_named_args'));
|
468 |
+
$this->assertEquals('foo', $twig->render('func_string'));
|
469 |
+
$this->assertEquals('bar', $twig->render('func_string_default'));
|
470 |
+
$this->assertEquals('foo', $twig->render('func_string_named_args'));
|
471 |
+
}
|
472 |
+
|
473 |
protected function getMockLoader($templateName, $templateContent)
|
474 |
{
|
475 |
+
// to be removed in 2.0
|
476 |
+
$loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
|
477 |
+
//$loader = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock();
|
478 |
$loader->expects($this->any())
|
479 |
+
->method('getSourceContext')
|
480 |
->with($templateName)
|
481 |
+
->will($this->returnValue(new Twig_Source($templateContent, $templateName)));
|
482 |
$loader->expects($this->any())
|
483 |
->method('getCacheKey')
|
484 |
->with($templateName)
|
496 |
'foo_global' => 'foo_global',
|
497 |
);
|
498 |
}
|
|
|
|
|
|
|
|
|
|
|
499 |
}
|
500 |
|
501 |
class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension implements Twig_Extension_GlobalsInterface
|
549 |
'foo_global' => 'foo_global',
|
550 |
);
|
551 |
}
|
552 |
+
}
|
553 |
|
554 |
+
class Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName extends Twig_Extension
|
555 |
+
{
|
556 |
public function getName()
|
557 |
{
|
558 |
return 'environment_test';
|
559 |
}
|
560 |
}
|
561 |
|
562 |
+
class Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName extends Twig_Extension
|
563 |
+
{
|
564 |
+
private $name;
|
565 |
+
|
566 |
+
public function __construct($name)
|
567 |
+
{
|
568 |
+
$this->name = $name;
|
569 |
+
}
|
570 |
+
|
571 |
+
public function getName()
|
572 |
+
{
|
573 |
+
return $this->name;
|
574 |
+
}
|
575 |
+
}
|
576 |
+
|
577 |
class Twig_Tests_EnvironmentTest_TokenParser extends Twig_TokenParser
|
578 |
{
|
579 |
public function parse(Twig_Token $token)
|
609 |
public function initRuntime(Twig_Environment $env)
|
610 |
{
|
611 |
}
|
612 |
+
}
|
613 |
|
614 |
+
class Twig_Tests_EnvironmentTest_ExtensionWithoutDeprecationInitRuntime extends Twig_Extension implements Twig_Extension_InitRuntimeInterface
|
615 |
+
{
|
616 |
+
public function initRuntime(Twig_Environment $env)
|
617 |
{
|
|
|
618 |
}
|
619 |
}
|
620 |
|
621 |
+
class Twig_Tests_EnvironmentTest_ExtensionWithoutRuntime extends Twig_Extension
|
622 |
{
|
623 |
+
public function getFunctions()
|
624 |
{
|
625 |
+
return array(
|
626 |
+
new Twig_SimpleFunction('from_runtime_array', array('Twig_Tests_EnvironmentTest_Runtime', 'fromRuntime')),
|
627 |
+
new Twig_SimpleFunction('from_runtime_string', 'Twig_Tests_EnvironmentTest_Runtime::fromRuntime'),
|
628 |
+
);
|
629 |
}
|
630 |
|
631 |
public function getName()
|
632 |
{
|
633 |
+
return 'from_runtime';
|
634 |
+
}
|
635 |
+
}
|
636 |
+
|
637 |
+
class Twig_Tests_EnvironmentTest_Runtime
|
638 |
+
{
|
639 |
+
public function fromRuntime($name = 'bar')
|
640 |
+
{
|
641 |
+
return $name;
|
642 |
}
|
643 |
}
|
644 |
+
|
645 |
+
interface Twig_EnvironmentTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface
|
646 |
+
{
|
647 |
+
}
|
vendor/twig/twig/test/Twig/Tests/ErrorTest.php
CHANGED
@@ -14,7 +14,7 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
|
|
14 |
public function testErrorWithObjectFilename()
|
15 |
{
|
16 |
$error = new Twig_Error('foo');
|
17 |
-
$error->
|
18 |
|
19 |
$this->assertContains('test'.DIRECTORY_SEPARATOR.'Twig'.DIRECTORY_SEPARATOR.'Tests'.DIRECTORY_SEPARATOR.'ErrorTest.php', $error->getMessage());
|
20 |
}
|
@@ -22,7 +22,7 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
|
|
22 |
public function testErrorWithArrayFilename()
|
23 |
{
|
24 |
$error = new Twig_Error('foo');
|
25 |
-
$error->
|
26 |
|
27 |
$this->assertEquals('foo in {"foo":"bar"}', $error->getMessage());
|
28 |
}
|
@@ -38,9 +38,9 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
|
|
38 |
|
39 |
$this->fail();
|
40 |
} catch (Twig_Error_Runtime $e) {
|
41 |
-
$this->assertEquals('Variable "foo" does not exist in "index.html" at line 3', $e->getMessage());
|
42 |
$this->assertEquals(3, $e->getTemplateLine());
|
43 |
-
$this->assertEquals('index.html', $e->
|
44 |
}
|
45 |
|
46 |
try {
|
@@ -50,7 +50,7 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
|
|
50 |
} catch (Twig_Error_Runtime $e) {
|
51 |
$this->assertEquals('An exception has been thrown during the rendering of a template ("Runtime error...") in "index.html" at line 3.', $e->getMessage());
|
52 |
$this->assertEquals(3, $e->getTemplateLine());
|
53 |
-
$this->assertEquals('index.html', $e->
|
54 |
}
|
55 |
}
|
56 |
|
@@ -69,9 +69,9 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
|
|
69 |
|
70 |
$this->fail();
|
71 |
} catch (Twig_Error_Runtime $e) {
|
72 |
-
$this->assertEquals(sprintf('Variable "foo" does not exist in "%s" at line %d', $name, $line), $e->getMessage());
|
73 |
$this->assertEquals($line, $e->getTemplateLine());
|
74 |
-
$this->assertEquals($name, $e->
|
75 |
}
|
76 |
|
77 |
try {
|
@@ -81,7 +81,7 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase
|
|
81 |
} catch (Twig_Error_Runtime $e) {
|
82 |
$this->assertEquals(sprintf('An exception has been thrown during the rendering of a template ("Runtime error...") in "%s" at line %d.', $name, $line), $e->getMessage());
|
83 |
$this->assertEquals($line, $e->getTemplateLine());
|
84 |
-
$this->assertEquals($name, $e->
|
85 |
}
|
86 |
}
|
87 |
|
14 |
public function testErrorWithObjectFilename()
|
15 |
{
|
16 |
$error = new Twig_Error('foo');
|
17 |
+
$error->setTemplateName(new SplFileInfo(__FILE__));
|
18 |
|
19 |
$this->assertContains('test'.DIRECTORY_SEPARATOR.'Twig'.DIRECTORY_SEPARATOR.'Tests'.DIRECTORY_SEPARATOR.'ErrorTest.php', $error->getMessage());
|
20 |
}
|
22 |
public function testErrorWithArrayFilename()
|
23 |
{
|
24 |
$error = new Twig_Error('foo');
|
25 |
+
$error->setTemplateName(array('foo' => 'bar'));
|
26 |
|
27 |
$this->assertEquals('foo in {"foo":"bar"}', $error->getMessage());
|
28 |
}
|
38 |
|
39 |
$this->fail();
|
40 |
} catch (Twig_Error_Runtime $e) {
|
41 |
+
$this->assertEquals('Variable "foo" does not exist in "index.html" at line 3.', $e->getMessage());
|
42 |
$this->assertEquals(3, $e->getTemplateLine());
|
43 |
+
$this->assertEquals('index.html', $e->getTemplateName());
|
44 |
}
|
45 |
|
46 |
try {
|
50 |
} catch (Twig_Error_Runtime $e) {
|
51 |
$this->assertEquals('An exception has been thrown during the rendering of a template ("Runtime error...") in "index.html" at line 3.', $e->getMessage());
|
52 |
$this->assertEquals(3, $e->getTemplateLine());
|
53 |
+
$this->assertEquals('index.html', $e->getTemplateName());
|
54 |
}
|
55 |
}
|
56 |
|
69 |
|
70 |
$this->fail();
|
71 |
} catch (Twig_Error_Runtime $e) {
|
72 |
+
$this->assertEquals(sprintf('Variable "foo" does not exist in "%s" at line %d.', $name, $line), $e->getMessage());
|
73 |
$this->assertEquals($line, $e->getTemplateLine());
|
74 |
+
$this->assertEquals($name, $e->getTemplateName());
|
75 |
}
|
76 |
|
77 |
try {
|
81 |
} catch (Twig_Error_Runtime $e) {
|
82 |
$this->assertEquals(sprintf('An exception has been thrown during the rendering of a template ("Runtime error...") in "%s" at line %d.', $name, $line), $e->getMessage());
|
83 |
$this->assertEquals($line, $e->getTemplateLine());
|
84 |
+
$this->assertEquals($name, $e->getTemplateName());
|
85 |
}
|
86 |
}
|
87 |
|
vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php
CHANGED
@@ -20,7 +20,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
20 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
21 |
$parser = new Twig_Parser($env);
|
22 |
|
23 |
-
$parser->parse($env->tokenize($template, 'index'));
|
24 |
}
|
25 |
|
26 |
public function getFailingTestsForAssignment()
|
@@ -47,7 +47,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
47 |
public function testArrayExpression($template, $expected)
|
48 |
{
|
49 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
50 |
-
$stream = $env->tokenize($template, '
|
51 |
$parser = new Twig_Parser($env);
|
52 |
|
53 |
$this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
|
@@ -62,7 +62,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
62 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
63 |
$parser = new Twig_Parser($env);
|
64 |
|
65 |
-
$parser->parse($env->tokenize($template, 'index'));
|
66 |
}
|
67 |
|
68 |
public function getFailingTestsForArray()
|
@@ -155,7 +155,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
155 |
public function testStringExpressionDoesNotConcatenateTwoConsecutiveStrings()
|
156 |
{
|
157 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
|
158 |
-
$stream = $env->tokenize('{{ "a" "b" }}', 'index');
|
159 |
$parser = new Twig_Parser($env);
|
160 |
|
161 |
$parser->parse($stream);
|
@@ -167,7 +167,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
167 |
public function testStringExpression($template, $expected)
|
168 |
{
|
169 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
|
170 |
-
$stream = $env->tokenize($template, '
|
171 |
$parser = new Twig_Parser($env);
|
172 |
|
173 |
$this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
|
@@ -228,7 +228,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
228 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
229 |
$parser = new Twig_Parser($env);
|
230 |
|
231 |
-
$parser->parse($env->tokenize('{{ foo.bar(name="Foo") }}', 'index'));
|
232 |
}
|
233 |
|
234 |
/**
|
@@ -239,7 +239,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
239 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
240 |
$parser = new Twig_Parser($env);
|
241 |
|
242 |
-
$parser->parse($env->tokenize('{% from _self import foo %}{% macro foo() %}{% endmacro %}{{ foo(name="Foo") }}', 'index'));
|
243 |
}
|
244 |
|
245 |
/**
|
@@ -251,7 +251,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
251 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
252 |
$parser = new Twig_Parser($env);
|
253 |
|
254 |
-
$parser->parse($env->tokenize('{% macro foo("a") %}{% endmacro %}', 'index'));
|
255 |
}
|
256 |
|
257 |
/**
|
@@ -264,7 +264,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
264 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
265 |
$parser = new Twig_Parser($env);
|
266 |
|
267 |
-
$parser->parse($env->tokenize($template, 'index'));
|
268 |
}
|
269 |
|
270 |
public function getMacroDefinitionDoesNotSupportNonConstantDefaultValues()
|
@@ -283,7 +283,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
283 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
284 |
$parser = new Twig_Parser($env);
|
285 |
|
286 |
-
$parser->parse($env->tokenize($template, 'index'));
|
287 |
}
|
288 |
|
289 |
public function getMacroDefinitionSupportsConstantDefaultValues()
|
@@ -308,7 +308,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
308 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
309 |
$parser = new Twig_Parser($env);
|
310 |
|
311 |
-
$parser->parse($env->tokenize('{{ cycl() }}', 'index'));
|
312 |
}
|
313 |
|
314 |
/**
|
@@ -320,7 +320,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
320 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
321 |
$parser = new Twig_Parser($env);
|
322 |
|
323 |
-
$parser->parse($env->tokenize('{{ foobar() }}', 'index'));
|
324 |
}
|
325 |
|
326 |
/**
|
@@ -332,7 +332,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
332 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
333 |
$parser = new Twig_Parser($env);
|
334 |
|
335 |
-
$parser->parse($env->tokenize('{{ 1|lowe }}', 'index'));
|
336 |
}
|
337 |
|
338 |
/**
|
@@ -344,7 +344,7 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
344 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
345 |
$parser = new Twig_Parser($env);
|
346 |
|
347 |
-
$parser->parse($env->tokenize('{{ 1|foobar }}', 'index'));
|
348 |
}
|
349 |
|
350 |
/**
|
@@ -355,8 +355,8 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
355 |
{
|
356 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
357 |
$parser = new Twig_Parser($env);
|
358 |
-
|
359 |
-
$parser->parse($
|
360 |
}
|
361 |
|
362 |
/**
|
@@ -368,6 +368,6 @@ class Twig_Tests_ExpressionParserTest extends PHPUnit_Framework_TestCase
|
|
368 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
369 |
$parser = new Twig_Parser($env);
|
370 |
|
371 |
-
$parser->parse($env->tokenize('{{ 1 is foobar }}', 'index'));
|
372 |
}
|
373 |
}
|
20 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
21 |
$parser = new Twig_Parser($env);
|
22 |
|
23 |
+
$parser->parse($env->tokenize(new Twig_Source($template, 'index')));
|
24 |
}
|
25 |
|
26 |
public function getFailingTestsForAssignment()
|
47 |
public function testArrayExpression($template, $expected)
|
48 |
{
|
49 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
50 |
+
$stream = $env->tokenize(new Twig_Source($template, ''));
|
51 |
$parser = new Twig_Parser($env);
|
52 |
|
53 |
$this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
|
62 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
63 |
$parser = new Twig_Parser($env);
|
64 |
|
65 |
+
$parser->parse($env->tokenize(new Twig_Source($template, 'index')));
|
66 |
}
|
67 |
|
68 |
public function getFailingTestsForArray()
|
155 |
public function testStringExpressionDoesNotConcatenateTwoConsecutiveStrings()
|
156 |
{
|
157 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
|
158 |
+
$stream = $env->tokenize(new Twig_Source('{{ "a" "b" }}', 'index'));
|
159 |
$parser = new Twig_Parser($env);
|
160 |
|
161 |
$parser->parse($stream);
|
167 |
public function testStringExpression($template, $expected)
|
168 |
{
|
169 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
|
170 |
+
$stream = $env->tokenize(new Twig_Source($template, ''));
|
171 |
$parser = new Twig_Parser($env);
|
172 |
|
173 |
$this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr'));
|
228 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
229 |
$parser = new Twig_Parser($env);
|
230 |
|
231 |
+
$parser->parse($env->tokenize(new Twig_Source('{{ foo.bar(name="Foo") }}', 'index')));
|
232 |
}
|
233 |
|
234 |
/**
|
239 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
240 |
$parser = new Twig_Parser($env);
|
241 |
|
242 |
+
$parser->parse($env->tokenize(new Twig_Source('{% from _self import foo %}{% macro foo() %}{% endmacro %}{{ foo(name="Foo") }}', 'index')));
|
243 |
}
|
244 |
|
245 |
/**
|
251 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
252 |
$parser = new Twig_Parser($env);
|
253 |
|
254 |
+
$parser->parse($env->tokenize(new Twig_Source('{% macro foo("a") %}{% endmacro %}', 'index')));
|
255 |
}
|
256 |
|
257 |
/**
|
264 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
265 |
$parser = new Twig_Parser($env);
|
266 |
|
267 |
+
$parser->parse($env->tokenize(new Twig_Source($template, 'index')));
|
268 |
}
|
269 |
|
270 |
public function getMacroDefinitionDoesNotSupportNonConstantDefaultValues()
|
283 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
284 |
$parser = new Twig_Parser($env);
|
285 |
|
286 |
+
$parser->parse($env->tokenize(new Twig_Source($template, 'index')));
|
287 |
}
|
288 |
|
289 |
public function getMacroDefinitionSupportsConstantDefaultValues()
|
308 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
309 |
$parser = new Twig_Parser($env);
|
310 |
|
311 |
+
$parser->parse($env->tokenize(new Twig_Source('{{ cycl() }}', 'index')));
|
312 |
}
|
313 |
|
314 |
/**
|
320 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
321 |
$parser = new Twig_Parser($env);
|
322 |
|
323 |
+
$parser->parse($env->tokenize(new Twig_Source('{{ foobar() }}', 'index')));
|
324 |
}
|
325 |
|
326 |
/**
|
332 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
333 |
$parser = new Twig_Parser($env);
|
334 |
|
335 |
+
$parser->parse($env->tokenize(new Twig_Source('{{ 1|lowe }}', 'index')));
|
336 |
}
|
337 |
|
338 |
/**
|
344 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
345 |
$parser = new Twig_Parser($env);
|
346 |
|
347 |
+
$parser->parse($env->tokenize(new Twig_Source('{{ 1|foobar }}', 'index')));
|
348 |
}
|
349 |
|
350 |
/**
|
355 |
{
|
356 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
357 |
$parser = new Twig_Parser($env);
|
358 |
+
$stream = $env->tokenize(new Twig_Source('{{ 1 is nul }}', 'index'));
|
359 |
+
$parser->parse($stream);
|
360 |
}
|
361 |
|
362 |
/**
|
368 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
369 |
$parser = new Twig_Parser($env);
|
370 |
|
371 |
+
$parser->parse($env->tokenize(new Twig_Source('{{ 1 is foobar }}', 'index')));
|
372 |
}
|
373 |
}
|
vendor/twig/twig/test/Twig/Tests/Extension/CoreTest.php
CHANGED
@@ -118,7 +118,7 @@ class Twig_Tests_Extension_CoreTest extends PHPUnit_Framework_TestCase
|
|
118 |
public function testCustomEscaper()
|
119 |
{
|
120 |
$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
|
121 |
-
$twig->getExtension('
|
122 |
|
123 |
$this->assertEquals('fooUTF-8', twig_escape_filter($twig, 'foo', 'foo'));
|
124 |
$this->assertEquals('UTF-8', twig_escape_filter($twig, null, 'foo'));
|
118 |
public function testCustomEscaper()
|
119 |
{
|
120 |
$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
|
121 |
+
$twig->getExtension('Twig_Extension_Core')->setEscaper('foo', 'foo_escaper_for_test');
|
122 |
|
123 |
$this->assertEquals('fooUTF-8', twig_escape_filter($twig, 'foo', 'foo'));
|
124 |
$this->assertEquals('UTF-8', twig_escape_filter($twig, null, 'foo'));
|
vendor/twig/twig/test/Twig/Tests/Extension/SandboxTest.php
CHANGED
@@ -51,83 +51,146 @@ class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase
|
|
51 |
{
|
52 |
$twig = $this->getEnvironment(false, array(), self::$templates);
|
53 |
$this->assertEquals('FOO', $twig->loadTemplate('1_basic')->render(self::$params), 'Sandbox does nothing if it is disabled globally');
|
|
|
54 |
|
|
|
|
|
55 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
56 |
try {
|
57 |
$twig->loadTemplate('1_basic1')->render(self::$params);
|
58 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed method is called');
|
59 |
} catch (Twig_Sandbox_SecurityError $e) {
|
|
|
|
|
|
|
60 |
}
|
|
|
61 |
|
|
|
|
|
62 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
63 |
try {
|
64 |
$twig->loadTemplate('1_basic2')->render(self::$params);
|
65 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called');
|
66 |
} catch (Twig_Sandbox_SecurityError $e) {
|
|
|
|
|
67 |
}
|
|
|
68 |
|
|
|
|
|
69 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
70 |
try {
|
71 |
$twig->loadTemplate('1_basic3')->render(self::$params);
|
72 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed tag is used in the template');
|
73 |
} catch (Twig_Sandbox_SecurityError $e) {
|
|
|
|
|
74 |
}
|
|
|
75 |
|
|
|
|
|
76 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
77 |
try {
|
78 |
$twig->loadTemplate('1_basic4')->render(self::$params);
|
79 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed property is called in the template');
|
80 |
} catch (Twig_Sandbox_SecurityError $e) {
|
|
|
|
|
|
|
81 |
}
|
|
|
82 |
|
|
|
|
|
83 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
84 |
try {
|
85 |
$twig->loadTemplate('1_basic5')->render(self::$params);
|
86 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template');
|
87 |
} catch (Twig_Sandbox_SecurityError $e) {
|
|
|
|
|
|
|
88 |
}
|
|
|
89 |
|
|
|
|
|
90 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
91 |
try {
|
92 |
$twig->loadTemplate('1_basic6')->render(self::$params);
|
93 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template');
|
94 |
} catch (Twig_Sandbox_SecurityError $e) {
|
|
|
|
|
|
|
95 |
}
|
|
|
96 |
|
|
|
|
|
97 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
98 |
try {
|
99 |
$twig->loadTemplate('1_basic7')->render(self::$params);
|
100 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed function is called in the template');
|
101 |
} catch (Twig_Sandbox_SecurityError $e) {
|
|
|
|
|
102 |
}
|
|
|
103 |
|
|
|
|
|
104 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => 'foo'));
|
105 |
FooObject::reset();
|
106 |
$this->assertEquals('foo', $twig->loadTemplate('1_basic1')->render(self::$params), 'Sandbox allow some methods');
|
107 |
$this->assertEquals(1, FooObject::$called['foo'], 'Sandbox only calls method once');
|
|
|
108 |
|
|
|
|
|
109 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => '__toString'));
|
110 |
FooObject::reset();
|
111 |
$this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allow some methods');
|
112 |
$this->assertEquals(1, FooObject::$called['__toString'], 'Sandbox only calls method once');
|
|
|
113 |
|
|
|
|
|
114 |
$twig = $this->getEnvironment(false, array(), self::$templates);
|
115 |
FooObject::reset();
|
116 |
$this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allows __toString when sandbox disabled');
|
117 |
$this->assertEquals(1, FooObject::$called['__toString'], 'Sandbox only calls method once');
|
|
|
118 |
|
|
|
|
|
119 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array('upper'));
|
120 |
$this->assertEquals('FABIEN', $twig->loadTemplate('1_basic2')->render(self::$params), 'Sandbox allow some filters');
|
|
|
121 |
|
|
|
|
|
122 |
$twig = $this->getEnvironment(true, array(), self::$templates, array('if'));
|
123 |
$this->assertEquals('foo', $twig->loadTemplate('1_basic3')->render(self::$params), 'Sandbox allow some tags');
|
|
|
124 |
|
|
|
|
|
125 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array('FooObject' => 'bar'));
|
126 |
$this->assertEquals('bar', $twig->loadTemplate('1_basic4')->render(self::$params), 'Sandbox allow some properties');
|
|
|
127 |
|
|
|
|
|
128 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array(), array('cycle'));
|
129 |
$this->assertEquals('bar', $twig->loadTemplate('1_basic7')->render(self::$params), 'Sandbox allow some functions');
|
|
|
130 |
|
|
|
|
|
131 |
foreach (array('getfoobar', 'getFoobar', 'getFooBar') as $name) {
|
132 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => $name));
|
133 |
FooObject::reset();
|
@@ -158,6 +221,8 @@ class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase
|
|
158 |
$twig->loadTemplate('3_basic')->render(self::$params);
|
159 |
$this->fail('Sandbox throws a SecurityError exception when the included file is sandboxed');
|
160 |
} catch (Twig_Sandbox_SecurityError $e) {
|
|
|
|
|
161 |
}
|
162 |
}
|
163 |
|
51 |
{
|
52 |
$twig = $this->getEnvironment(false, array(), self::$templates);
|
53 |
$this->assertEquals('FOO', $twig->loadTemplate('1_basic')->render(self::$params), 'Sandbox does nothing if it is disabled globally');
|
54 |
+
}
|
55 |
|
56 |
+
public function testSandboxUnallowedMethodAccessor()
|
57 |
+
{
|
58 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
59 |
try {
|
60 |
$twig->loadTemplate('1_basic1')->render(self::$params);
|
61 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed method is called');
|
62 |
} catch (Twig_Sandbox_SecurityError $e) {
|
63 |
+
$this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedMethodError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedMethodError');
|
64 |
+
$this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class');
|
65 |
+
$this->assertEquals('foo', $e->getMethodName(), 'Exception should be raised on the "foo" method');
|
66 |
}
|
67 |
+
}
|
68 |
|
69 |
+
public function testSandboxUnallowedFilter()
|
70 |
+
{
|
71 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
72 |
try {
|
73 |
$twig->loadTemplate('1_basic2')->render(self::$params);
|
74 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called');
|
75 |
} catch (Twig_Sandbox_SecurityError $e) {
|
76 |
+
$this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedFilterError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedFilterError');
|
77 |
+
$this->assertEquals('upper', $e->getFilterName(), 'Exception should be raised on the "upper" filter');
|
78 |
}
|
79 |
+
}
|
80 |
|
81 |
+
public function testSandboxUnallowedTag()
|
82 |
+
{
|
83 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
84 |
try {
|
85 |
$twig->loadTemplate('1_basic3')->render(self::$params);
|
86 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed tag is used in the template');
|
87 |
} catch (Twig_Sandbox_SecurityError $e) {
|
88 |
+
$this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedTagError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedTagError');
|
89 |
+
$this->assertEquals('if', $e->getTagName(), 'Exception should be raised on the "if" tag');
|
90 |
}
|
91 |
+
}
|
92 |
|
93 |
+
public function testSandboxUnallowedProperty()
|
94 |
+
{
|
95 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
96 |
try {
|
97 |
$twig->loadTemplate('1_basic4')->render(self::$params);
|
98 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed property is called in the template');
|
99 |
} catch (Twig_Sandbox_SecurityError $e) {
|
100 |
+
$this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedPropertyError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedPropertyError');
|
101 |
+
$this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class');
|
102 |
+
$this->assertEquals('bar', $e->getPropertyName(), 'Exception should be raised on the "bar" property');
|
103 |
}
|
104 |
+
}
|
105 |
|
106 |
+
public function testSandboxUnallowedToString()
|
107 |
+
{
|
108 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
109 |
try {
|
110 |
$twig->loadTemplate('1_basic5')->render(self::$params);
|
111 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template');
|
112 |
} catch (Twig_Sandbox_SecurityError $e) {
|
113 |
+
$this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedMethodError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedMethodError');
|
114 |
+
$this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class');
|
115 |
+
$this->assertEquals('__tostring', $e->getMethodName(), 'Exception should be raised on the "__toString" method');
|
116 |
}
|
117 |
+
}
|
118 |
|
119 |
+
public function testSandboxUnallowedToStringArray()
|
120 |
+
{
|
121 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
122 |
try {
|
123 |
$twig->loadTemplate('1_basic6')->render(self::$params);
|
124 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template');
|
125 |
} catch (Twig_Sandbox_SecurityError $e) {
|
126 |
+
$this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedMethodError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedMethodError');
|
127 |
+
$this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class');
|
128 |
+
$this->assertEquals('__tostring', $e->getMethodName(), 'Exception should be raised on the "__toString" method');
|
129 |
}
|
130 |
+
}
|
131 |
|
132 |
+
public function testSandboxUnallowedFunction()
|
133 |
+
{
|
134 |
$twig = $this->getEnvironment(true, array(), self::$templates);
|
135 |
try {
|
136 |
$twig->loadTemplate('1_basic7')->render(self::$params);
|
137 |
$this->fail('Sandbox throws a SecurityError exception if an unallowed function is called in the template');
|
138 |
} catch (Twig_Sandbox_SecurityError $e) {
|
139 |
+
$this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedFunctionError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedFunctionError');
|
140 |
+
$this->assertEquals('cycle', $e->getFunctionName(), 'Exception should be raised on the "cycle" function');
|
141 |
}
|
142 |
+
}
|
143 |
|
144 |
+
public function testSandboxAllowMethodFoo()
|
145 |
+
{
|
146 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => 'foo'));
|
147 |
FooObject::reset();
|
148 |
$this->assertEquals('foo', $twig->loadTemplate('1_basic1')->render(self::$params), 'Sandbox allow some methods');
|
149 |
$this->assertEquals(1, FooObject::$called['foo'], 'Sandbox only calls method once');
|
150 |
+
}
|
151 |
|
152 |
+
public function testSandboxAllowMethodToString()
|
153 |
+
{
|
154 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => '__toString'));
|
155 |
FooObject::reset();
|
156 |
$this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allow some methods');
|
157 |
$this->assertEquals(1, FooObject::$called['__toString'], 'Sandbox only calls method once');
|
158 |
+
}
|
159 |
|
160 |
+
public function testSandboxAllowMethodToStringDisabled()
|
161 |
+
{
|
162 |
$twig = $this->getEnvironment(false, array(), self::$templates);
|
163 |
FooObject::reset();
|
164 |
$this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allows __toString when sandbox disabled');
|
165 |
$this->assertEquals(1, FooObject::$called['__toString'], 'Sandbox only calls method once');
|
166 |
+
}
|
167 |
|
168 |
+
public function testSandboxAllowFilter()
|
169 |
+
{
|
170 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array('upper'));
|
171 |
$this->assertEquals('FABIEN', $twig->loadTemplate('1_basic2')->render(self::$params), 'Sandbox allow some filters');
|
172 |
+
}
|
173 |
|
174 |
+
public function testSandboxAllowTag()
|
175 |
+
{
|
176 |
$twig = $this->getEnvironment(true, array(), self::$templates, array('if'));
|
177 |
$this->assertEquals('foo', $twig->loadTemplate('1_basic3')->render(self::$params), 'Sandbox allow some tags');
|
178 |
+
}
|
179 |
|
180 |
+
public function testSandboxAllowProperty()
|
181 |
+
{
|
182 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array('FooObject' => 'bar'));
|
183 |
$this->assertEquals('bar', $twig->loadTemplate('1_basic4')->render(self::$params), 'Sandbox allow some properties');
|
184 |
+
}
|
185 |
|
186 |
+
public function testSandboxAllowFunction()
|
187 |
+
{
|
188 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array(), array('cycle'));
|
189 |
$this->assertEquals('bar', $twig->loadTemplate('1_basic7')->render(self::$params), 'Sandbox allow some functions');
|
190 |
+
}
|
191 |
|
192 |
+
public function testSandboxAllowFunctionsCaseInsensitive()
|
193 |
+
{
|
194 |
foreach (array('getfoobar', 'getFoobar', 'getFooBar') as $name) {
|
195 |
$twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => $name));
|
196 |
FooObject::reset();
|
221 |
$twig->loadTemplate('3_basic')->render(self::$params);
|
222 |
$this->fail('Sandbox throws a SecurityError exception when the included file is sandboxed');
|
223 |
} catch (Twig_Sandbox_SecurityError $e) {
|
224 |
+
$this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedTagError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedTagError');
|
225 |
+
$this->assertEquals('sandbox', $e->getTagName());
|
226 |
}
|
227 |
}
|
228 |
|
vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/block.test
CHANGED
@@ -16,6 +16,6 @@ blocks and autoescape
|
|
16 |
--DATA--
|
17 |
return array('br' => '<br />')
|
18 |
--CONFIG--
|
19 |
-
return array('autoescape' => '
|
20 |
--EXPECT--
|
21 |
<br />
|
16 |
--DATA--
|
17 |
return array('br' => '<br />')
|
18 |
--CONFIG--
|
19 |
+
return array('autoescape' => 'name')
|
20 |
--EXPECT--
|
21 |
<br />
|
vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/name.test
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
--TEST--
|
2 |
+
"name" autoescape strategy
|
3 |
+
--TEMPLATE--
|
4 |
+
{{ br -}}
|
5 |
+
{{ include('index.html.twig') -}}
|
6 |
+
{{ include('index.txt.twig') -}}
|
7 |
+
--TEMPLATE(index.html.twig)--
|
8 |
+
{{ br -}}
|
9 |
+
--TEMPLATE(index.txt.twig)--
|
10 |
+
{{ br -}}
|
11 |
+
--DATA--
|
12 |
+
return array('br' => '<br />')
|
13 |
+
--CONFIG--
|
14 |
+
return array('autoescape' => 'name')
|
15 |
+
--EXPECT--
|
16 |
+
<br />
|
17 |
+
<br />
|
18 |
+
<br />
|
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/child_contents_outside_blocks.test
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
--TEST--
|
2 |
+
Exception for child templates defining contents outside blocks defined by parent
|
3 |
+
--TEMPLATE--
|
4 |
+
{% extends 'base.twig' %}
|
5 |
+
|
6 |
+
Content outside a block.
|
7 |
+
|
8 |
+
{% block sidebar %}
|
9 |
+
Content inside a block.
|
10 |
+
{% endblock %}
|
11 |
+
--TEMPLATE(base.twig)--
|
12 |
+
{% block sidebar %}
|
13 |
+
{% endblock %}
|
14 |
+
--EXCEPTION--
|
15 |
+
Twig_Error_Syntax: A template that extends another one cannot include contents outside Twig blocks. Did you forget to put the contents inside a {% block %} tag in "index.twig" at line 3?
|
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable.test
CHANGED
@@ -15,4 +15,4 @@ Exception for multiline array with undefined variable
|
|
15 |
--DATA--
|
16 |
return array('foobar' => 'foobar')
|
17 |
--EXCEPTION--
|
18 |
-
Twig_Error_Runtime: Variable "foo2" does not exist in "index.twig" at line 11
|
15 |
--DATA--
|
16 |
return array('foobar' => 'foobar')
|
17 |
--EXCEPTION--
|
18 |
+
Twig_Error_Runtime: Variable "foo2" does not exist in "index.twig" at line 11.
|
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable_again.test
CHANGED
@@ -15,4 +15,4 @@ Exception for multiline array with undefined variable
|
|
15 |
--DATA--
|
16 |
return array()
|
17 |
--EXCEPTION--
|
18 |
-
Twig_Error_Runtime: Variable "foobar" does not exist in "index.twig" at line 7
|
15 |
--DATA--
|
16 |
return array()
|
17 |
--EXCEPTION--
|
18 |
+
Twig_Error_Runtime: Variable "foobar" does not exist in "index.twig" at line 7.
|
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_undefined_variable.test
CHANGED
@@ -9,4 +9,4 @@ Foo
|
|
9 |
--DATA--
|
10 |
return array()
|
11 |
--EXCEPTION--
|
12 |
-
Twig_Error_Runtime: Variable "with_context" does not exist in "index.twig" at line 3
|
9 |
--DATA--
|
10 |
return array()
|
11 |
--EXCEPTION--
|
12 |
+
Twig_Error_Runtime: Variable "with_context" does not exist in "index.twig" at line 3.
|
vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_tag_with_undefined_variable.test
CHANGED
@@ -9,4 +9,4 @@ Foo
|
|
9 |
--DATA--
|
10 |
return array()
|
11 |
--EXCEPTION--
|
12 |
-
Twig_Error_Runtime: Variable "vars" does not exist in "index.twig" at line 3
|
9 |
--DATA--
|
10 |
return array()
|
11 |
--EXCEPTION--
|
12 |
+
Twig_Error_Runtime: Variable "vars" does not exist in "index.twig" at line 3.
|
vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/magic_call.test
CHANGED
@@ -6,21 +6,21 @@ Twig supports __call() for attributes
|
|
6 |
--DATA--
|
7 |
class TestClassForMagicCallAttributes
|
8 |
{
|
9 |
-
|
10 |
-
{
|
11 |
-
return 'bar_from_getbar';
|
12 |
-
}
|
13 |
-
|
14 |
-
public function __call($method, $arguments)
|
15 |
-
{
|
16 |
-
if ('foo' === $method)
|
17 |
{
|
18 |
-
|
19 |
}
|
20 |
|
21 |
-
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
|
|
24 |
return array('foo' => new TestClassForMagicCallAttributes())
|
25 |
--EXPECT--
|
26 |
foo_from_call
|
6 |
--DATA--
|
7 |
class TestClassForMagicCallAttributes
|
8 |
{
|
9 |
+
public function getBar()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
{
|
11 |
+
return 'bar_from_getbar';
|
12 |
}
|
13 |
|
14 |
+
public function __call($method, $arguments)
|
15 |
+
{
|
16 |
+
if ('foo' === $method) {
|
17 |
+
return 'foo_from_call';
|
18 |
+
}
|
19 |
+
|
20 |
+
return false;
|
21 |
+
}
|
22 |
}
|
23 |
+
|
24 |
return array('foo' => new TestClassForMagicCallAttributes())
|
25 |
--EXPECT--
|
26 |
foo_from_call
|
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format.test
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
{{ date1|date('d/m/Y') }}
|
6 |
--DATA--
|
7 |
date_default_timezone_set('UTC');
|
8 |
-
$twig->getExtension('
|
9 |
return array(
|
10 |
'date1' => mktime(13, 45, 0, 10, 4, 2010),
|
11 |
)
|
5 |
{{ date1|date('d/m/Y') }}
|
6 |
--DATA--
|
7 |
date_default_timezone_set('UTC');
|
8 |
+
$twig->getExtension('Twig_Extension_Core')->setDateFormat('Y-m-d', '%d days %h hours');
|
9 |
return array(
|
10 |
'date1' => mktime(13, 45, 0, 10, 4, 2010),
|
11 |
)
|
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format_interval.test
CHANGED
@@ -7,7 +7,7 @@ version_compare(phpversion(), '5.3.0', '>=')
|
|
7 |
{{ date2|date('%d days') }}
|
8 |
--DATA--
|
9 |
date_default_timezone_set('UTC');
|
10 |
-
$twig->getExtension('
|
11 |
return array(
|
12 |
'date2' => new DateInterval('P2D'),
|
13 |
)
|
7 |
{{ date2|date('%d days') }}
|
8 |
--DATA--
|
9 |
date_default_timezone_set('UTC');
|
10 |
+
$twig->getExtension('Twig_Extension_Core')->setDateFormat('Y-m-d', '%d days %h hours');
|
11 |
return array(
|
12 |
'date2' => new DateInterval('P2D'),
|
13 |
)
|
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format_default.test
CHANGED
@@ -9,7 +9,7 @@
|
|
9 |
{{ 1020.25|number_format(2, ',') }}
|
10 |
{{ 1020.25|number_format(2, ',', '.') }}
|
11 |
--DATA--
|
12 |
-
$twig->getExtension('
|
13 |
return array();
|
14 |
--EXPECT--
|
15 |
20!00
|
9 |
{{ 1020.25|number_format(2, ',') }}
|
10 |
{{ 1020.25|number_format(2, ',', '.') }}
|
11 |
--DATA--
|
12 |
+
$twig->getExtension('Twig_Extension_Core')->setNumberFormat(2, '!', '=');
|
13 |
return array();
|
14 |
--EXPECT--
|
15 |
20!00
|
vendor/twig/twig/test/Twig/Tests/Fixtures/filters/static_calls.test
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
--TEST--
|
2 |
+
Filters as static method calls
|
3 |
+
--TEMPLATE--
|
4 |
+
{{ 'foo'|static_call_string }}
|
5 |
+
{{ 'foo'|static_call_array }}
|
6 |
+
--DATA--
|
7 |
+
return array('foo' => 'foo')
|
8 |
+
--EXPECT--
|
9 |
+
*foo*
|
10 |
+
*foo*
|
vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call.test
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
--TEST--
|
2 |
+
__call calls
|
3 |
+
--TEMPLATE--
|
4 |
+
{{ 'foo'|magic_call }}
|
5 |
+
--DATA--
|
6 |
+
return array()
|
7 |
+
--EXPECT--
|
8 |
+
magic_foo
|
vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call53.test
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
--TEST--
|
2 |
+
__staticCall calls
|
3 |
+
--CONDITION--
|
4 |
+
version_compare(phpversion(), '5.3.0', '>=')
|
5 |
+
--TEMPLATE--
|
6 |
+
{{ 'foo'|magic_call_string }}
|
7 |
+
{{ 'foo'|magic_call_array }}
|
8 |
+
--DATA--
|
9 |
+
return array()
|
10 |
+
--EXPECT--
|
11 |
+
static_magic_foo
|
12 |
+
static_magic_foo
|
vendor/twig/twig/test/Twig/Tests/Fixtures/functions/static_calls.test
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
--TEST--
|
2 |
+
Functions as static method calls
|
3 |
+
--TEMPLATE--
|
4 |
+
{{ static_call_string('foo') }}
|
5 |
+
{{ static_call_array('foo') }}
|
6 |
+
--DATA--
|
7 |
+
return array('foo' => 'foo')
|
8 |
+
--EXPECT--
|
9 |
+
*foo*
|
10 |
+
*foo*
|
vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs_argument.test
CHANGED
@@ -5,4 +5,3 @@ macro with varargs argument
|
|
5 |
{% endmacro %}
|
6 |
--EXCEPTION--
|
7 |
Twig_Error_Syntax: The argument "varargs" in macro "test" cannot be defined because the variable "varargs" is reserved for arbitrary arguments in "index.twig" at line 2.
|
8 |
-
|
5 |
{% endmacro %}
|
6 |
--EXCEPTION--
|
7 |
Twig_Error_Syntax: The argument "varargs" in macro "test" cannot be defined because the variable "varargs" is reserved for arbitrary arguments in "index.twig" at line 2.
|
|
vendor/twig/twig/test/Twig/Tests/Fixtures/regression/combined_debug_info.test
CHANGED
@@ -12,4 +12,4 @@ foo
|
|
12 |
--DATA--
|
13 |
return array('foo' => 'foo');
|
14 |
--EXCEPTION--
|
15 |
-
Twig_Error_Runtime: Impossible to access an attribute ("bar") on a string variable ("foo") in "foo" at line 3
|
12 |
--DATA--
|
13 |
return array('foo' => 'foo');
|
14 |
--EXCEPTION--
|
15 |
+
Twig_Error_Runtime: Impossible to access an attribute ("bar") on a string variable ("foo") in "foo" at line 3.
|
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/complex_dynamic_parent.test
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
--TEST--
|
2 |
+
"embed" tag
|
3 |
+
--TEMPLATE--
|
4 |
+
FOO
|
5 |
+
{% embed foo ~ ".twig" %}
|
6 |
+
{% block c1 %}
|
7 |
+
{{ parent() }}
|
8 |
+
block1extended
|
9 |
+
{% endblock %}
|
10 |
+
{% endembed %}
|
11 |
+
|
12 |
+
BAR
|
13 |
+
--TEMPLATE(foo.twig)--
|
14 |
+
A
|
15 |
+
{% block c1 %}
|
16 |
+
block1
|
17 |
+
{% endblock %}
|
18 |
+
B
|
19 |
+
{% block c2 %}
|
20 |
+
block2
|
21 |
+
{% endblock %}
|
22 |
+
C
|
23 |
+
--DATA--
|
24 |
+
return array('foo' => 'foo')
|
25 |
+
--EXPECT--
|
26 |
+
FOO
|
27 |
+
|
28 |
+
A
|
29 |
+
block1
|
30 |
+
|
31 |
+
block1extended
|
32 |
+
B
|
33 |
+
block2
|
34 |
+
C
|
35 |
+
BAR
|
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/dynamic_parent.test
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
--TEST--
|
2 |
+
"embed" tag
|
3 |
+
--TEMPLATE--
|
4 |
+
FOO
|
5 |
+
{% embed foo %}
|
6 |
+
{% block c1 %}
|
7 |
+
{{ parent() }}
|
8 |
+
block1extended
|
9 |
+
{% endblock %}
|
10 |
+
{% endembed %}
|
11 |
+
|
12 |
+
BAR
|
13 |
+
--TEMPLATE(foo.twig)--
|
14 |
+
A
|
15 |
+
{% block c1 %}
|
16 |
+
block1
|
17 |
+
{% endblock %}
|
18 |
+
B
|
19 |
+
{% block c2 %}
|
20 |
+
block2
|
21 |
+
{% endblock %}
|
22 |
+
C
|
23 |
+
--DATA--
|
24 |
+
return array('foo' => 'foo.twig')
|
25 |
+
--EXPECT--
|
26 |
+
FOO
|
27 |
+
|
28 |
+
A
|
29 |
+
block1
|
30 |
+
|
31 |
+
block1extended
|
32 |
+
B
|
33 |
+
block2
|
34 |
+
C
|
35 |
+
BAR
|
vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/error_line.test
CHANGED
@@ -13,4 +13,4 @@ BAR
|
|
13 |
--DATA--
|
14 |
return array()
|
15 |
--EXCEPTION--
|
16 |
-
Twig_Error_Runtime: Variable "nothing" does not exist in "index.twig" at line 5
|
13 |
--DATA--
|
14 |
return array()
|
15 |
--EXCEPTION--
|
16 |
+
Twig_Error_Runtime: Variable "nothing" does not exist in "index.twig" at line 5.
|
vendor/twig/twig/test/Twig/Tests/IntegrationTest.php
CHANGED
@@ -141,6 +141,11 @@ class TwigTestExtension extends Twig_Extension
|
|
141 |
new Twig_SimpleFilter('nl2br', array($this, 'nl2br'), array('pre_escape' => 'html', 'is_safe' => array('html'))),
|
142 |
new Twig_SimpleFilter('escape_something', array($this, 'escape_something'), array('is_safe' => array('something'))),
|
143 |
new Twig_SimpleFilter('preserves_safety', array($this, 'preserves_safety'), array('preserves_safety' => array('html'))),
|
|
|
|
|
|
|
|
|
|
|
144 |
new Twig_SimpleFilter('*_path', array($this, 'dynamic_path')),
|
145 |
new Twig_SimpleFilter('*_foo_*_bar', array($this, 'dynamic_foo')),
|
146 |
);
|
@@ -152,6 +157,8 @@ class TwigTestExtension extends Twig_Extension
|
|
152 |
new Twig_SimpleFunction('§', array($this, '§Function')),
|
153 |
new Twig_SimpleFunction('safe_br', array($this, 'br'), array('is_safe' => array('html'))),
|
154 |
new Twig_SimpleFunction('unsafe_br', array($this, 'br')),
|
|
|
|
|
155 |
new Twig_SimpleFunction('*_path', array($this, 'dynamic_path')),
|
156 |
new Twig_SimpleFunction('*_foo_*_bar', array($this, 'dynamic_foo')),
|
157 |
);
|
@@ -212,6 +219,11 @@ class TwigTestExtension extends Twig_Extension
|
|
212 |
return strtoupper($value);
|
213 |
}
|
214 |
|
|
|
|
|
|
|
|
|
|
|
215 |
public function br()
|
216 |
{
|
217 |
return '<br />';
|
@@ -222,8 +234,21 @@ class TwigTestExtension extends Twig_Extension
|
|
222 |
return false !== strpos($value, ' ');
|
223 |
}
|
224 |
|
225 |
-
public function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
{
|
227 |
-
|
|
|
|
|
|
|
|
|
228 |
}
|
229 |
}
|
141 |
new Twig_SimpleFilter('nl2br', array($this, 'nl2br'), array('pre_escape' => 'html', 'is_safe' => array('html'))),
|
142 |
new Twig_SimpleFilter('escape_something', array($this, 'escape_something'), array('is_safe' => array('something'))),
|
143 |
new Twig_SimpleFilter('preserves_safety', array($this, 'preserves_safety'), array('preserves_safety' => array('html'))),
|
144 |
+
new Twig_SimpleFilter('static_call_string', 'TwigTestExtension::staticCall'),
|
145 |
+
new Twig_SimpleFilter('static_call_array', array('TwigTestExtension', 'staticCall')),
|
146 |
+
new Twig_SimpleFilter('magic_call', array($this, 'magicCall')),
|
147 |
+
new Twig_SimpleFilter('magic_call_string', 'TwigTestExtension::magicStaticCall'),
|
148 |
+
new Twig_SimpleFilter('magic_call_array', array('TwigTestExtension', 'magicStaticCall')),
|
149 |
new Twig_SimpleFilter('*_path', array($this, 'dynamic_path')),
|
150 |
new Twig_SimpleFilter('*_foo_*_bar', array($this, 'dynamic_foo')),
|
151 |
);
|
157 |
new Twig_SimpleFunction('§', array($this, '§Function')),
|
158 |
new Twig_SimpleFunction('safe_br', array($this, 'br'), array('is_safe' => array('html'))),
|
159 |
new Twig_SimpleFunction('unsafe_br', array($this, 'br')),
|
160 |
+
new Twig_SimpleFunction('static_call_string', 'TwigTestExtension::staticCall'),
|
161 |
+
new Twig_SimpleFunction('static_call_array', array('TwigTestExtension', 'staticCall')),
|
162 |
new Twig_SimpleFunction('*_path', array($this, 'dynamic_path')),
|
163 |
new Twig_SimpleFunction('*_foo_*_bar', array($this, 'dynamic_foo')),
|
164 |
);
|
219 |
return strtoupper($value);
|
220 |
}
|
221 |
|
222 |
+
public static function staticCall($value)
|
223 |
+
{
|
224 |
+
return "*$value*";
|
225 |
+
}
|
226 |
+
|
227 |
public function br()
|
228 |
{
|
229 |
return '<br />';
|
234 |
return false !== strpos($value, ' ');
|
235 |
}
|
236 |
|
237 |
+
public function __call($method, $arguments)
|
238 |
+
{
|
239 |
+
if ('magicCall' !== $method) {
|
240 |
+
throw new BadMethodCallException('Unexpected call to __call');
|
241 |
+
}
|
242 |
+
|
243 |
+
return 'magic_'.$arguments[0];
|
244 |
+
}
|
245 |
+
|
246 |
+
public static function __callStatic($method, $arguments)
|
247 |
{
|
248 |
+
if ('magicStaticCall' !== $method) {
|
249 |
+
throw new BadMethodCallException('Unexpected call to __callStatic');
|
250 |
+
}
|
251 |
+
|
252 |
+
return 'static_magic_'.$arguments[0];
|
253 |
}
|
254 |
}
|
vendor/twig/twig/test/Twig/Tests/{Fixtures/autoescape/filename.test → LegacyFixtures/autoescape/filename.legacy.test}
RENAMED
File without changes
|
vendor/twig/twig/test/Twig/Tests/LexerTest.php
CHANGED
@@ -10,12 +10,23 @@
|
|
10 |
*/
|
11 |
class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
12 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
public function testNameLabelForTag()
|
14 |
{
|
15 |
$template = '{% § %}';
|
16 |
|
17 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
18 |
-
$stream = $lexer->tokenize($template);
|
19 |
|
20 |
$stream->expect(Twig_Token::BLOCK_START_TYPE);
|
21 |
$this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
|
@@ -26,7 +37,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
26 |
$template = '{{ §() }}';
|
27 |
|
28 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
29 |
-
$stream = $lexer->tokenize($template);
|
30 |
|
31 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
32 |
$this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
|
@@ -43,7 +54,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
43 |
protected function countToken($template, $type, $value = null)
|
44 |
{
|
45 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
46 |
-
$stream = $lexer->tokenize($template);
|
47 |
|
48 |
$count = 0;
|
49 |
while (!$stream->isEOF()) {
|
@@ -68,7 +79,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
68 |
."}}\n";
|
69 |
|
70 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
71 |
-
$stream = $lexer->tokenize($template);
|
72 |
|
73 |
// foo\nbar\n
|
74 |
$this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
|
@@ -88,7 +99,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
88 |
."}}\n";
|
89 |
|
90 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
91 |
-
$stream = $lexer->tokenize($template);
|
92 |
|
93 |
// foo\nbar
|
94 |
$this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
|
@@ -103,7 +114,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
103 |
$template = '{# '.str_repeat('*', 100000).' #}';
|
104 |
|
105 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
106 |
-
$lexer->tokenize($template);
|
107 |
|
108 |
// should not throw an exception
|
109 |
}
|
@@ -113,7 +124,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
113 |
$template = '{% verbatim %}'.str_repeat('*', 100000).'{% endverbatim %}';
|
114 |
|
115 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
116 |
-
$lexer->tokenize($template);
|
117 |
|
118 |
// should not throw an exception
|
119 |
}
|
@@ -123,7 +134,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
123 |
$template = '{{ '.str_repeat('x', 100000).' }}';
|
124 |
|
125 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
126 |
-
$lexer->tokenize($template);
|
127 |
|
128 |
// should not throw an exception
|
129 |
}
|
@@ -133,7 +144,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
133 |
$template = '{% '.str_repeat('x', 100000).' %}';
|
134 |
|
135 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
136 |
-
$lexer->tokenize($template);
|
137 |
|
138 |
// should not throw an exception
|
139 |
}
|
@@ -143,7 +154,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
143 |
$template = '{{ 922337203685477580700 }}';
|
144 |
|
145 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
146 |
-
$stream = $lexer->tokenize($template);
|
147 |
$stream->next();
|
148 |
$node = $stream->next();
|
149 |
$this->assertEquals('922337203685477580700', $node->getValue());
|
@@ -157,7 +168,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
157 |
);
|
158 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
159 |
foreach ($tests as $template => $expected) {
|
160 |
-
$stream = $lexer->tokenize($template);
|
161 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
162 |
$stream->expect(Twig_Token::STRING_TYPE, $expected);
|
163 |
}
|
@@ -168,7 +179,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
168 |
$template = 'foo {{ "bar #{ baz + 1 }" }}';
|
169 |
|
170 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
171 |
-
$stream = $lexer->tokenize($template);
|
172 |
$stream->expect(Twig_Token::TEXT_TYPE, 'foo ');
|
173 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
174 |
$stream->expect(Twig_Token::STRING_TYPE, 'bar ');
|
@@ -185,7 +196,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
185 |
$template = '{{ "bar \#{baz+1}" }}';
|
186 |
|
187 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
188 |
-
$stream = $lexer->tokenize($template);
|
189 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
190 |
$stream->expect(Twig_Token::STRING_TYPE, 'bar #{baz+1}');
|
191 |
$stream->expect(Twig_Token::VAR_END_TYPE);
|
@@ -196,7 +207,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
196 |
$template = '{{ "bar # baz" }}';
|
197 |
|
198 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
199 |
-
$stream = $lexer->tokenize($template);
|
200 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
201 |
$stream->expect(Twig_Token::STRING_TYPE, 'bar # baz');
|
202 |
$stream->expect(Twig_Token::VAR_END_TYPE);
|
@@ -211,7 +222,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
211 |
$template = '{{ "bar #{x" }}';
|
212 |
|
213 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
214 |
-
$lexer->tokenize($template);
|
215 |
}
|
216 |
|
217 |
public function testStringWithNestedInterpolations()
|
@@ -219,7 +230,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
219 |
$template = '{{ "bar #{ "foo#{bar}" }" }}';
|
220 |
|
221 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
222 |
-
$stream = $lexer->tokenize($template);
|
223 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
224 |
$stream->expect(Twig_Token::STRING_TYPE, 'bar ');
|
225 |
$stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
|
@@ -236,7 +247,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
236 |
$template = '{% foo "bar #{ "foo#{bar}" }" %}';
|
237 |
|
238 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
239 |
-
$stream = $lexer->tokenize($template);
|
240 |
$stream->expect(Twig_Token::BLOCK_START_TYPE);
|
241 |
$stream->expect(Twig_Token::NAME_TYPE, 'foo');
|
242 |
$stream->expect(Twig_Token::STRING_TYPE, 'bar ');
|
@@ -254,7 +265,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
254 |
$template = "{{ 1 and\n0}}";
|
255 |
|
256 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
257 |
-
$stream = $lexer->tokenize($template);
|
258 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
259 |
$stream->expect(Twig_Token::NUMBER_TYPE, 1);
|
260 |
$stream->expect(Twig_Token::OPERATOR_TYPE, 'and');
|
@@ -262,7 +273,7 @@ class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
|
262 |
|
263 |
/**
|
264 |
* @expectedException Twig_Error_Syntax
|
265 |
-
* @expectedExceptionMessage Unclosed "variable" at line 3
|
266 |
*/
|
267 |
public function testUnterminatedVariable()
|
268 |
{
|
@@ -276,12 +287,12 @@ bar
|
|
276 |
';
|
277 |
|
278 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
279 |
-
$lexer->tokenize($template);
|
280 |
}
|
281 |
|
282 |
/**
|
283 |
* @expectedException Twig_Error_Syntax
|
284 |
-
* @expectedExceptionMessage Unclosed "block" at line 3
|
285 |
*/
|
286 |
public function testUnterminatedBlock()
|
287 |
{
|
@@ -295,6 +306,6 @@ bar
|
|
295 |
';
|
296 |
|
297 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
298 |
-
$lexer->tokenize($template);
|
299 |
}
|
300 |
}
|
10 |
*/
|
11 |
class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
|
12 |
{
|
13 |
+
/**
|
14 |
+
* @group legacy
|
15 |
+
*/
|
16 |
+
public function testLegacyConstructorSignature()
|
17 |
+
{
|
18 |
+
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
19 |
+
$stream = $lexer->tokenize('{{ foo }}', 'foo');
|
20 |
+
$this->assertEquals('foo', $stream->getFilename());
|
21 |
+
$this->assertEquals('{{ foo }}', $stream->getSource());
|
22 |
+
}
|
23 |
+
|
24 |
public function testNameLabelForTag()
|
25 |
{
|
26 |
$template = '{% § %}';
|
27 |
|
28 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
29 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
30 |
|
31 |
$stream->expect(Twig_Token::BLOCK_START_TYPE);
|
32 |
$this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
|
37 |
$template = '{{ §() }}';
|
38 |
|
39 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
40 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
41 |
|
42 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
43 |
$this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
|
54 |
protected function countToken($template, $type, $value = null)
|
55 |
{
|
56 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
57 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
58 |
|
59 |
$count = 0;
|
60 |
while (!$stream->isEOF()) {
|
79 |
."}}\n";
|
80 |
|
81 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
82 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
83 |
|
84 |
// foo\nbar\n
|
85 |
$this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
|
99 |
."}}\n";
|
100 |
|
101 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
102 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
103 |
|
104 |
// foo\nbar
|
105 |
$this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
|
114 |
$template = '{# '.str_repeat('*', 100000).' #}';
|
115 |
|
116 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
117 |
+
$lexer->tokenize(new Twig_Source($template, 'index'));
|
118 |
|
119 |
// should not throw an exception
|
120 |
}
|
124 |
$template = '{% verbatim %}'.str_repeat('*', 100000).'{% endverbatim %}';
|
125 |
|
126 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
127 |
+
$lexer->tokenize(new Twig_Source($template, 'index'));
|
128 |
|
129 |
// should not throw an exception
|
130 |
}
|
134 |
$template = '{{ '.str_repeat('x', 100000).' }}';
|
135 |
|
136 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
137 |
+
$lexer->tokenize(new Twig_Source($template, 'index'));
|
138 |
|
139 |
// should not throw an exception
|
140 |
}
|
144 |
$template = '{% '.str_repeat('x', 100000).' %}';
|
145 |
|
146 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
147 |
+
$lexer->tokenize(new Twig_Source($template, 'index'));
|
148 |
|
149 |
// should not throw an exception
|
150 |
}
|
154 |
$template = '{{ 922337203685477580700 }}';
|
155 |
|
156 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
157 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
158 |
$stream->next();
|
159 |
$node = $stream->next();
|
160 |
$this->assertEquals('922337203685477580700', $node->getValue());
|
168 |
);
|
169 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
170 |
foreach ($tests as $template => $expected) {
|
171 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
172 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
173 |
$stream->expect(Twig_Token::STRING_TYPE, $expected);
|
174 |
}
|
179 |
$template = 'foo {{ "bar #{ baz + 1 }" }}';
|
180 |
|
181 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
182 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
183 |
$stream->expect(Twig_Token::TEXT_TYPE, 'foo ');
|
184 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
185 |
$stream->expect(Twig_Token::STRING_TYPE, 'bar ');
|
196 |
$template = '{{ "bar \#{baz+1}" }}';
|
197 |
|
198 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
199 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
200 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
201 |
$stream->expect(Twig_Token::STRING_TYPE, 'bar #{baz+1}');
|
202 |
$stream->expect(Twig_Token::VAR_END_TYPE);
|
207 |
$template = '{{ "bar # baz" }}';
|
208 |
|
209 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
210 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
211 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
212 |
$stream->expect(Twig_Token::STRING_TYPE, 'bar # baz');
|
213 |
$stream->expect(Twig_Token::VAR_END_TYPE);
|
222 |
$template = '{{ "bar #{x" }}';
|
223 |
|
224 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
225 |
+
$lexer->tokenize(new Twig_Source($template, 'index'));
|
226 |
}
|
227 |
|
228 |
public function testStringWithNestedInterpolations()
|
230 |
$template = '{{ "bar #{ "foo#{bar}" }" }}';
|
231 |
|
232 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
233 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
234 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
235 |
$stream->expect(Twig_Token::STRING_TYPE, 'bar ');
|
236 |
$stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
|
247 |
$template = '{% foo "bar #{ "foo#{bar}" }" %}';
|
248 |
|
249 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
250 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
251 |
$stream->expect(Twig_Token::BLOCK_START_TYPE);
|
252 |
$stream->expect(Twig_Token::NAME_TYPE, 'foo');
|
253 |
$stream->expect(Twig_Token::STRING_TYPE, 'bar ');
|
265 |
$template = "{{ 1 and\n0}}";
|
266 |
|
267 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
268 |
+
$stream = $lexer->tokenize(new Twig_Source($template, 'index'));
|
269 |
$stream->expect(Twig_Token::VAR_START_TYPE);
|
270 |
$stream->expect(Twig_Token::NUMBER_TYPE, 1);
|
271 |
$stream->expect(Twig_Token::OPERATOR_TYPE, 'and');
|
273 |
|
274 |
/**
|
275 |
* @expectedException Twig_Error_Syntax
|
276 |
+
* @expectedExceptionMessage Unclosed "variable" in "index" at line 3
|
277 |
*/
|
278 |
public function testUnterminatedVariable()
|
279 |
{
|
287 |
';
|
288 |
|
289 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
290 |
+
$lexer->tokenize(new Twig_Source($template, 'index'));
|
291 |
}
|
292 |
|
293 |
/**
|
294 |
* @expectedException Twig_Error_Syntax
|
295 |
+
* @expectedExceptionMessage Unclosed "block" in "index" at line 3
|
296 |
*/
|
297 |
public function testUnterminatedBlock()
|
298 |
{
|
306 |
';
|
307 |
|
308 |
$lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
309 |
+
$lexer->tokenize(new Twig_Source($template, 'index'));
|
310 |
}
|
311 |
}
|
vendor/twig/twig/test/Twig/Tests/Loader/ArrayTest.php
CHANGED
@@ -11,6 +11,9 @@
|
|
11 |
|
12 |
class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
|
13 |
{
|
|
|
|
|
|
|
14 |
public function testGetSource()
|
15 |
{
|
16 |
$loader = new Twig_Loader_Array(array('foo' => 'bar'));
|
@@ -19,6 +22,7 @@ class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
|
|
19 |
}
|
20 |
|
21 |
/**
|
|
|
22 |
* @expectedException Twig_Error_Loader
|
23 |
*/
|
24 |
public function testGetSourceWhenTemplateDoesNotExist()
|
@@ -28,6 +32,16 @@ class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
|
|
28 |
$loader->getSource('foo');
|
29 |
}
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
public function testGetCacheKey()
|
32 |
{
|
33 |
$loader = new Twig_Loader_Array(array('foo' => 'bar'));
|
@@ -50,7 +64,7 @@ class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
|
|
50 |
$loader = new Twig_Loader_Array(array());
|
51 |
$loader->setTemplate('foo', 'bar');
|
52 |
|
53 |
-
$this->assertEquals('bar', $loader->
|
54 |
}
|
55 |
|
56 |
public function testIsFresh()
|
@@ -75,7 +89,7 @@ class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
|
|
75 |
$loader = new Twig_Loader_Array(array('foo' => 'bar'));
|
76 |
|
77 |
$loader->getCacheKey($name);
|
78 |
-
$loader->
|
79 |
$loader->isFresh($name, time());
|
80 |
$loader->setTemplate($name, 'foobar');
|
81 |
}
|
11 |
|
12 |
class Twig_Tests_Loader_ArrayTest extends PHPUnit_Framework_TestCase
|
13 |
{
|
14 |
+
/**
|
15 |
+
* @group legacy
|
16 |
+
*/
|
17 |
public function testGetSource()
|
18 |
{
|
19 |
$loader = new Twig_Loader_Array(array('foo' => 'bar'));
|
22 |
}
|
23 |
|
24 |
/**
|
25 |
+
* @group legacy
|
26 |
* @expectedException Twig_Error_Loader
|
27 |
*/
|
28 |
public function testGetSourceWhenTemplateDoesNotExist()
|
32 |
$loader->getSource('foo');
|
33 |
}
|
34 |
|
35 |
+
/**
|
36 |
+
* @expectedException Twig_Error_Loader
|
37 |
+
*/
|
38 |
+
public function testGetSourceContextWhenTemplateDoesNotExist()
|
39 |
+
{
|
40 |
+
$loader = new Twig_Loader_Array(array());
|
41 |
+
|
42 |
+
$loader->getSourceContext('foo');
|
43 |
+
}
|
44 |
+
|
45 |
public function testGetCacheKey()
|
46 |
{
|
47 |
$loader = new Twig_Loader_Array(array('foo' => 'bar'));
|
64 |
$loader = new Twig_Loader_Array(array());
|
65 |
$loader->setTemplate('foo', 'bar');
|
66 |
|
67 |
+
$this->assertEquals('bar', $loader->getSourceContext('foo')->getCode());
|
68 |
}
|
69 |
|
70 |
public function testIsFresh()
|
89 |
$loader = new Twig_Loader_Array(array('foo' => 'bar'));
|
90 |
|
91 |
$loader->getCacheKey($name);
|
92 |
+
$loader->getSourceContext($name);
|
93 |
$loader->isFresh($name, time());
|
94 |
$loader->setTemplate($name, 'foobar');
|
95 |
}
|
vendor/twig/twig/test/Twig/Tests/Loader/ChainTest.php
CHANGED
@@ -11,6 +11,9 @@
|
|
11 |
|
12 |
class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
|
13 |
{
|
|
|
|
|
|
|
14 |
public function testGetSource()
|
15 |
{
|
16 |
$loader = new Twig_Loader_Chain(array(
|
@@ -22,9 +25,41 @@ class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
|
|
22 |
$this->assertEquals('foo', $loader->getSource('bar'));
|
23 |
}
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
/**
|
26 |
* @expectedException Twig_Error_Loader
|
27 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
public function testGetSourceWhenTemplateDoesNotExist()
|
29 |
{
|
30 |
$loader = new Twig_Loader_Chain(array());
|
@@ -58,17 +93,19 @@ class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
|
|
58 |
$loader = new Twig_Loader_Chain();
|
59 |
$loader->addLoader(new Twig_Loader_Array(array('foo' => 'bar')));
|
60 |
|
61 |
-
$this->assertEquals('bar', $loader->
|
62 |
}
|
63 |
|
64 |
public function testExists()
|
65 |
{
|
66 |
-
$loader1 = $this->getMockBuilder('Twig_Loader_Array')->setMethods(array('exists', '
|
67 |
$loader1->expects($this->once())->method('exists')->will($this->returnValue(false));
|
68 |
-
$loader1->expects($this->never())->method('
|
69 |
|
70 |
-
|
71 |
-
$loader2
|
|
|
|
|
72 |
|
73 |
$loader = new Twig_Loader_Chain();
|
74 |
$loader->addLoader($loader1);
|
@@ -77,3 +114,7 @@ class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
|
|
77 |
$this->assertTrue($loader->exists('foo'));
|
78 |
}
|
79 |
}
|
|
|
|
|
|
|
|
11 |
|
12 |
class Twig_Tests_Loader_ChainTest extends PHPUnit_Framework_TestCase
|
13 |
{
|
14 |
+
/**
|
15 |
+
* @group legacy
|
16 |
+
*/
|
17 |
public function testGetSource()
|
18 |
{
|
19 |
$loader = new Twig_Loader_Chain(array(
|
25 |
$this->assertEquals('foo', $loader->getSource('bar'));
|
26 |
}
|
27 |
|
28 |
+
public function testGetSourceContext()
|
29 |
+
{
|
30 |
+
$path = dirname(__FILE__).'/../Fixtures';
|
31 |
+
$loader = new Twig_Loader_Chain(array(
|
32 |
+
new Twig_Loader_Array(array('foo' => 'bar')),
|
33 |
+
new Twig_Loader_Array(array('errors/index.html' => 'baz')),
|
34 |
+
new Twig_Loader_Filesystem(array($path)),
|
35 |
+
));
|
36 |
+
|
37 |
+
$this->assertEquals('foo', $loader->getSourceContext('foo')->getName());
|
38 |
+
$this->assertSame('', $loader->getSourceContext('foo')->getPath());
|
39 |
+
|
40 |
+
$this->assertEquals('errors/index.html', $loader->getSourceContext('errors/index.html')->getName());
|
41 |
+
$this->assertSame('', $loader->getSourceContext('errors/index.html')->getPath());
|
42 |
+
$this->assertEquals('baz', $loader->getSourceContext('errors/index.html')->getCode());
|
43 |
+
|
44 |
+
$this->assertEquals('errors/base.html', $loader->getSourceContext('errors/base.html')->getName());
|
45 |
+
$this->assertEquals(realpath($path.'/errors/base.html'), realpath($loader->getSourceContext('errors/base.html')->getPath()));
|
46 |
+
$this->assertNotEquals('baz', $loader->getSourceContext('errors/base.html')->getCode());
|
47 |
+
}
|
48 |
+
|
49 |
/**
|
50 |
* @expectedException Twig_Error_Loader
|
51 |
*/
|
52 |
+
public function testGetSourceContextWhenTemplateDoesNotExist()
|
53 |
+
{
|
54 |
+
$loader = new Twig_Loader_Chain(array());
|
55 |
+
|
56 |
+
$loader->getSourceContext('foo');
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @group legacy
|
61 |
+
* @expectedException Twig_Error_Loader
|
62 |
+
*/
|
63 |
public function testGetSourceWhenTemplateDoesNotExist()
|
64 |
{
|
65 |
$loader = new Twig_Loader_Chain(array());
|
93 |
$loader = new Twig_Loader_Chain();
|
94 |
$loader->addLoader(new Twig_Loader_Array(array('foo' => 'bar')));
|
95 |
|
96 |
+
$this->assertEquals('bar', $loader->getSourceContext('foo')->getCode());
|
97 |
}
|
98 |
|
99 |
public function testExists()
|
100 |
{
|
101 |
+
$loader1 = $this->getMockBuilder('Twig_Loader_Array')->setMethods(array('exists', 'getSourceContext'))->disableOriginalConstructor()->getMock();
|
102 |
$loader1->expects($this->once())->method('exists')->will($this->returnValue(false));
|
103 |
+
$loader1->expects($this->never())->method('getSourceContext');
|
104 |
|
105 |
+
// can be removed in 2.0
|
106 |
+
$loader2 = $this->getMockBuilder('Twig_ChainTestLoaderInterface')->getMock();
|
107 |
+
//$loader2 = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock();
|
108 |
+
$loader2->expects($this->once())->method('getSourceContext')->will($this->returnValue(new Twig_Source('content', 'index')));
|
109 |
|
110 |
$loader = new Twig_Loader_Chain();
|
111 |
$loader->addLoader($loader1);
|
114 |
$this->assertTrue($loader->exists('foo'));
|
115 |
}
|
116 |
}
|
117 |
+
|
118 |
+
interface Twig_ChainTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface
|
119 |
+
{
|
120 |
+
}
|
vendor/twig/twig/test/Twig/Tests/Loader/FilesystemTest.php
CHANGED
@@ -11,6 +11,14 @@
|
|
11 |
|
12 |
class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
|
13 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
/**
|
15 |
* @dataProvider getSecurityTests
|
16 |
*/
|
@@ -51,11 +59,12 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
|
|
51 |
);
|
52 |
}
|
53 |
|
54 |
-
|
|
|
|
|
|
|
55 |
{
|
56 |
-
$
|
57 |
-
|
58 |
-
$loader = new Twig_Loader_Filesystem(array($basePath.'/normal', $basePath.'/normal_bis'));
|
59 |
$loader->setPaths(array($basePath.'/named', $basePath.'/named_bis'), 'named');
|
60 |
$loader->addPath($basePath.'/named_ter', 'named');
|
61 |
$loader->addPath($basePath.'/normal_ter');
|
@@ -77,13 +86,42 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
|
|
77 |
$basePath.'/named_ter',
|
78 |
), $loader->getPaths('named'));
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
);
|
84 |
-
$this->assertEquals("path (final)\n", $loader->getSource('index.html'));
|
85 |
-
$this->assertEquals("path (final)\n", $loader->getSource('@__main__/index.html'));
|
86 |
-
$this->assertEquals("named path (final)\n", $loader->getSource('@named/index.html'));
|
87 |
}
|
88 |
|
89 |
public function testEmptyConstructor()
|
@@ -109,7 +147,7 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
|
|
109 |
$loader->addPath($basePath.'/named', 'named');
|
110 |
|
111 |
try {
|
112 |
-
$loader->
|
113 |
} catch (Exception $e) {
|
114 |
$this->assertInstanceof('Twig_Error_Loader', $e);
|
115 |
$this->assertContains('Unable to find template "@named/nowhere.html"', $e->getMessage());
|
@@ -124,11 +162,11 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
|
|
124 |
$loader->addPath($basePath.'/named', 'named');
|
125 |
|
126 |
// prime the cache for index.html in the named namespace
|
127 |
-
$namedSource = $loader->
|
128 |
$this->assertEquals("named path\n", $namedSource);
|
129 |
|
130 |
// get index.html from the main namespace
|
131 |
-
$this->assertEquals("path\n", $loader->
|
132 |
}
|
133 |
|
134 |
public function testLoadTemplateAndRenderBlockWithCache()
|
@@ -172,4 +210,17 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
|
|
172 |
$template = $twig->loadTemplate($templateName);
|
173 |
$this->assertSame('VALID Child', $template->renderBlock('body', array()));
|
174 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
}
|
11 |
|
12 |
class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
|
13 |
{
|
14 |
+
public function testGetSourceContext()
|
15 |
+
{
|
16 |
+
$path = dirname(__FILE__).'/../Fixtures';
|
17 |
+
$loader = new Twig_Loader_Filesystem(array($path));
|
18 |
+
$this->assertEquals('errors/index.html', $loader->getSourceContext('errors/index.html')->getName());
|
19 |
+
$this->assertEquals(realpath($path.'/errors/index.html'), realpath($loader->getSourceContext('errors/index.html')->getPath()));
|
20 |
+
}
|
21 |
+
|
22 |
/**
|
23 |
* @dataProvider getSecurityTests
|
24 |
*/
|
59 |
);
|
60 |
}
|
61 |
|
62 |
+
/**
|
63 |
+
* @dataProvider getBasePaths
|
64 |
+
*/
|
65 |
+
public function testPaths($basePath, $cacheKey, $rootPath)
|
66 |
{
|
67 |
+
$loader = new Twig_Loader_Filesystem(array($basePath.'/normal', $basePath.'/normal_bis'), $rootPath);
|
|
|
|
|
68 |
$loader->setPaths(array($basePath.'/named', $basePath.'/named_bis'), 'named');
|
69 |
$loader->addPath($basePath.'/named_ter', 'named');
|
70 |
$loader->addPath($basePath.'/normal_ter');
|
86 |
$basePath.'/named_ter',
|
87 |
), $loader->getPaths('named'));
|
88 |
|
89 |
+
// do not use realpath here as it would make the test unuseful
|
90 |
+
$this->assertEquals($cacheKey, str_replace('\\', '/', $loader->getCacheKey('@named/named_absolute.html')));
|
91 |
+
$this->assertEquals("path (final)\n", $loader->getSourceContext('index.html')->getCode());
|
92 |
+
$this->assertEquals("path (final)\n", $loader->getSourceContext('@__main__/index.html')->getCode());
|
93 |
+
$this->assertEquals("named path (final)\n", $loader->getSourceContext('@named/index.html')->getCode());
|
94 |
+
}
|
95 |
+
|
96 |
+
public function getBasePaths()
|
97 |
+
{
|
98 |
+
return array(
|
99 |
+
array(
|
100 |
+
dirname(__FILE__).'/Fixtures',
|
101 |
+
'test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html',
|
102 |
+
null,
|
103 |
+
),
|
104 |
+
array(
|
105 |
+
dirname(__FILE__).'/Fixtures/../Fixtures',
|
106 |
+
'test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html',
|
107 |
+
null,
|
108 |
+
),
|
109 |
+
array(
|
110 |
+
'test/Twig/Tests/Loader/Fixtures',
|
111 |
+
'test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html',
|
112 |
+
getcwd(),
|
113 |
+
),
|
114 |
+
array(
|
115 |
+
'Fixtures',
|
116 |
+
'Fixtures/named_quater/named_absolute.html',
|
117 |
+
getcwd().'/test/Twig/Tests/Loader',
|
118 |
+
),
|
119 |
+
array(
|
120 |
+
'Fixtures',
|
121 |
+
'Fixtures/named_quater/named_absolute.html',
|
122 |
+
getcwd().'/test/../test/Twig/Tests/Loader',
|
123 |
+
),
|
124 |
);
|
|
|
|
|
|
|
125 |
}
|
126 |
|
127 |
public function testEmptyConstructor()
|
147 |
$loader->addPath($basePath.'/named', 'named');
|
148 |
|
149 |
try {
|
150 |
+
$loader->getSourceContext('@named/nowhere.html');
|
151 |
} catch (Exception $e) {
|
152 |
$this->assertInstanceof('Twig_Error_Loader', $e);
|
153 |
$this->assertContains('Unable to find template "@named/nowhere.html"', $e->getMessage());
|
162 |
$loader->addPath($basePath.'/named', 'named');
|
163 |
|
164 |
// prime the cache for index.html in the named namespace
|
165 |
+
$namedSource = $loader->getSourceContext('@named/index.html')->getCode();
|
166 |
$this->assertEquals("named path\n", $namedSource);
|
167 |
|
168 |
// get index.html from the main namespace
|
169 |
+
$this->assertEquals("path\n", $loader->getSourceContext('index.html')->getCode());
|
170 |
}
|
171 |
|
172 |
public function testLoadTemplateAndRenderBlockWithCache()
|
210 |
$template = $twig->loadTemplate($templateName);
|
211 |
$this->assertSame('VALID Child', $template->renderBlock('body', array()));
|
212 |
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* @requires PHP 5.3
|
216 |
+
*/
|
217 |
+
public function testLoadTemplateFromPhar()
|
218 |
+
{
|
219 |
+
$loader = new Twig_Loader_Filesystem(array());
|
220 |
+
// phar-sample.phar was created with the following script:
|
221 |
+
// $f = new Phar('phar-test.phar');
|
222 |
+
// $f->addFromString('hello.twig', 'hello from phar');
|
223 |
+
$loader->addPath('phar://'.dirname(__FILE__).'/Fixtures/phar/phar-sample.phar');
|
224 |
+
$this->assertSame('hello from phar', $loader->getSourceContext('hello.twig')->getCode());
|
225 |
+
}
|
226 |
}
|
vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/phar/phar-sample.phar
ADDED
Binary file
|
vendor/twig/twig/test/Twig/Tests/Node/ForTest.php
CHANGED
@@ -28,7 +28,7 @@ class Twig_Tests_Node_ForTest extends Twig_Test_NodeTestCase
|
|
28 |
$this->assertTrue($node->getAttribute('ifexpr'));
|
29 |
$this->assertEquals('Twig_Node_If', get_class($node->getNode('body')));
|
30 |
$this->assertEquals($body, $node->getNode('body')->getNode('tests')->getNode(1)->getNode(0));
|
31 |
-
$this->
|
32 |
|
33 |
$else = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1);
|
34 |
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1);
|
28 |
$this->assertTrue($node->getAttribute('ifexpr'));
|
29 |
$this->assertEquals('Twig_Node_If', get_class($node->getNode('body')));
|
30 |
$this->assertEquals($body, $node->getNode('body')->getNode('tests')->getNode(1)->getNode(0));
|
31 |
+
$this->assertFalse($node->hasNode('else'));
|
32 |
|
33 |
$else = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1);
|
34 |
$node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1);
|
vendor/twig/twig/test/Twig/Tests/Node/IfTest.php
CHANGED
@@ -21,7 +21,7 @@ class Twig_Tests_Node_IfTest extends Twig_Test_NodeTestCase
|
|
21 |
$node = new Twig_Node_If($t, $else, 1);
|
22 |
|
23 |
$this->assertEquals($t, $node->getNode('tests'));
|
24 |
-
$this->
|
25 |
|
26 |
$else = new Twig_Node_Print(new Twig_Node_Expression_Name('bar', 1), 1);
|
27 |
$node = new Twig_Node_If($t, $else, 1);
|
21 |
$node = new Twig_Node_If($t, $else, 1);
|
22 |
|
23 |
$this->assertEquals($t, $node->getNode('tests'));
|
24 |
+
$this->assertFalse($node->hasNode('else'));
|
25 |
|
26 |
$else = new Twig_Node_Print(new Twig_Node_Expression_Name('bar', 1), 1);
|
27 |
$node = new Twig_Node_If($t, $else, 1);
|
vendor/twig/twig/test/Twig/Tests/Node/IncludeTest.php
CHANGED
@@ -16,7 +16,7 @@ class Twig_Tests_Node_IncludeTest extends Twig_Test_NodeTestCase
|
|
16 |
$expr = new Twig_Node_Expression_Constant('foo.twig', 1);
|
17 |
$node = new Twig_Node_Include($expr, null, false, false, 1);
|
18 |
|
19 |
-
$this->
|
20 |
$this->assertEquals($expr, $node->getNode('expr'));
|
21 |
$this->assertFalse($node->getAttribute('only'));
|
22 |
|
16 |
$expr = new Twig_Node_Expression_Constant('foo.twig', 1);
|
17 |
$node = new Twig_Node_Include($expr, null, false, false, 1);
|
18 |
|
19 |
+
$this->assertFalse($node->hasNode('variables'));
|
20 |
$this->assertEquals($expr, $node->getNode('expr'));
|
21 |
$this->assertFalse($node->getAttribute('only'));
|
22 |
|
vendor/twig/twig/test/Twig/Tests/Node/ModuleTest.php
CHANGED
@@ -18,14 +18,14 @@ class Twig_Tests_Node_ModuleTest extends Twig_Test_NodeTestCase
|
|
18 |
$blocks = new Twig_Node();
|
19 |
$macros = new Twig_Node();
|
20 |
$traits = new Twig_Node();
|
21 |
-
$
|
22 |
-
$node = new Twig_Node_Module($body, $parent, $blocks, $macros, $traits, new Twig_Node(array()), $
|
23 |
|
24 |
$this->assertEquals($body, $node->getNode('body'));
|
25 |
$this->assertEquals($blocks, $node->getNode('blocks'));
|
26 |
$this->assertEquals($macros, $node->getNode('macros'));
|
27 |
$this->assertEquals($parent, $node->getNode('parent'));
|
28 |
-
$this->assertEquals($
|
29 |
}
|
30 |
|
31 |
public function getTests()
|
@@ -39,9 +39,9 @@ class Twig_Tests_Node_ModuleTest extends Twig_Test_NodeTestCase
|
|
39 |
$blocks = new Twig_Node();
|
40 |
$macros = new Twig_Node();
|
41 |
$traits = new Twig_Node();
|
42 |
-
$
|
43 |
|
44 |
-
$node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $
|
45 |
$tests[] = array($node, <<<EOF
|
46 |
<?php
|
47 |
|
@@ -73,6 +73,19 @@ class __TwigTemplate_%x extends Twig_Template
|
|
73 |
{
|
74 |
return array ( 19 => 1,);
|
75 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
}
|
77 |
EOF
|
78 |
, $twig, true);
|
@@ -82,7 +95,7 @@ EOF
|
|
82 |
$body = new Twig_Node(array($import));
|
83 |
$extends = new Twig_Node_Expression_Constant('layout.twig', 1);
|
84 |
|
85 |
-
$node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $
|
86 |
$tests[] = array($node, <<<EOF
|
87 |
<?php
|
88 |
|
@@ -126,6 +139,19 @@ class __TwigTemplate_%x extends Twig_Template
|
|
126 |
{
|
127 |
return array ( 26 => 1, 24 => 2, 11 => 1,);
|
128 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
}
|
130 |
EOF
|
131 |
, $twig, true);
|
@@ -139,7 +165,8 @@ EOF
|
|
139 |
2
|
140 |
);
|
141 |
|
142 |
-
$
|
|
|
143 |
$tests[] = array($node, <<<EOF
|
144 |
<?php
|
145 |
|
@@ -174,6 +201,19 @@ class __TwigTemplate_%x extends Twig_Template
|
|
174 |
{
|
175 |
return array ( 17 => 2, 15 => 4, 9 => 2,);
|
176 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
}
|
178 |
EOF
|
179 |
, $twig, true);
|
18 |
$blocks = new Twig_Node();
|
19 |
$macros = new Twig_Node();
|
20 |
$traits = new Twig_Node();
|
21 |
+
$source = new Twig_Source('{{ foo }}', 'foo.twig');
|
22 |
+
$node = new Twig_Node_Module($body, $parent, $blocks, $macros, $traits, new Twig_Node(array()), $source);
|
23 |
|
24 |
$this->assertEquals($body, $node->getNode('body'));
|
25 |
$this->assertEquals($blocks, $node->getNode('blocks'));
|
26 |
$this->assertEquals($macros, $node->getNode('macros'));
|
27 |
$this->assertEquals($parent, $node->getNode('parent'));
|
28 |
+
$this->assertEquals($source->getName(), $node->getTemplateName());
|
29 |
}
|
30 |
|
31 |
public function getTests()
|
39 |
$blocks = new Twig_Node();
|
40 |
$macros = new Twig_Node();
|
41 |
$traits = new Twig_Node();
|
42 |
+
$source = new Twig_Source('{{ foo }}', 'foo.twig');
|
43 |
|
44 |
+
$node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $source);
|
45 |
$tests[] = array($node, <<<EOF
|
46 |
<?php
|
47 |
|
73 |
{
|
74 |
return array ( 19 => 1,);
|
75 |
}
|
76 |
+
|
77 |
+
/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */
|
78 |
+
public function getSource()
|
79 |
+
{
|
80 |
+
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);
|
81 |
+
|
82 |
+
return \$this->getSourceContext()->getCode();
|
83 |
+
}
|
84 |
+
|
85 |
+
public function getSourceContext()
|
86 |
+
{
|
87 |
+
return new Twig_Source("", "foo.twig", "");
|
88 |
+
}
|
89 |
}
|
90 |
EOF
|
91 |
, $twig, true);
|
95 |
$body = new Twig_Node(array($import));
|
96 |
$extends = new Twig_Node_Expression_Constant('layout.twig', 1);
|
97 |
|
98 |
+
$node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $source);
|
99 |
$tests[] = array($node, <<<EOF
|
100 |
<?php
|
101 |
|
139 |
{
|
140 |
return array ( 26 => 1, 24 => 2, 11 => 1,);
|
141 |
}
|
142 |
+
|
143 |
+
/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */
|
144 |
+
public function getSource()
|
145 |
+
{
|
146 |
+
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);
|
147 |
+
|
148 |
+
return \$this->getSourceContext()->getCode();
|
149 |
+
}
|
150 |
+
|
151 |
+
public function getSourceContext()
|
152 |
+
{
|
153 |
+
return new Twig_Source("", "foo.twig", "");
|
154 |
+
}
|
155 |
}
|
156 |
EOF
|
157 |
, $twig, true);
|
165 |
2
|
166 |
);
|
167 |
|
168 |
+
$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('debug' => true));
|
169 |
+
$node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $source);
|
170 |
$tests[] = array($node, <<<EOF
|
171 |
<?php
|
172 |
|
201 |
{
|
202 |
return array ( 17 => 2, 15 => 4, 9 => 2,);
|
203 |
}
|
204 |
+
|
205 |
+
/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */
|
206 |
+
public function getSource()
|
207 |
+
{
|
208 |
+
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);
|
209 |
+
|
210 |
+
return \$this->getSourceContext()->getCode();
|
211 |
+
}
|
212 |
+
|
213 |
+
public function getSourceContext()
|
214 |
+
{
|
215 |
+
return new Twig_Source("{{ foo }}", "foo.twig", "");
|
216 |
+
}
|
217 |
}
|
218 |
EOF
|
219 |
, $twig, true);
|
vendor/twig/twig/test/Twig/Tests/Node/SandboxTest.php
CHANGED
@@ -28,7 +28,7 @@ class Twig_Tests_Node_SandboxTest extends Twig_Test_NodeTestCase
|
|
28 |
|
29 |
$tests[] = array($node, <<<EOF
|
30 |
// line 1
|
31 |
-
\$sandbox = \$this->env->getExtension('
|
32 |
if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {
|
33 |
\$sandbox->enableSandbox();
|
34 |
}
|
28 |
|
29 |
$tests[] = array($node, <<<EOF
|
30 |
// line 1
|
31 |
+
\$sandbox = \$this->env->getExtension('Twig_Extension_Sandbox');
|
32 |
if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {
|
33 |
\$sandbox->enableSandbox();
|
34 |
}
|
vendor/twig/twig/test/Twig/Tests/Node/SandboxedPrintTest.php
CHANGED
@@ -24,7 +24,7 @@ class Twig_Tests_Node_SandboxedPrintTest extends Twig_Test_NodeTestCase
|
|
24 |
|
25 |
$tests[] = array(new Twig_Node_SandboxedPrint(new Twig_Node_Expression_Constant('foo', 1), 1), <<<EOF
|
26 |
// line 1
|
27 |
-
echo \$this->env->getExtension('
|
28 |
EOF
|
29 |
);
|
30 |
|
24 |
|
25 |
$tests[] = array(new Twig_Node_SandboxedPrint(new Twig_Node_Expression_Constant('foo', 1), 1), <<<EOF
|
26 |
// line 1
|
27 |
+
echo \$this->env->getExtension('Twig_Extension_Sandbox')->ensureToStringAllowed("foo");
|
28 |
EOF
|
29 |
);
|
30 |
|
vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php
CHANGED
@@ -14,7 +14,7 @@ class Twig_Tests_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase
|
|
14 |
{
|
15 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
16 |
|
17 |
-
$stream = $env->parse($env->tokenize('{{ block("foo") }}', 'index'));
|
18 |
|
19 |
$node = $stream->getNode('body')->getNode(0);
|
20 |
|
@@ -26,7 +26,7 @@ class Twig_Tests_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase
|
|
26 |
{
|
27 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
28 |
|
29 |
-
$stream = $env->parse($env->tokenize('{% extends "foo" %}{% block content %}{{ parent() }}{% endblock %}', 'index'));
|
30 |
|
31 |
$node = $stream->getNode('blocks')->getNode('content')->getNode(0)->getNode('body');
|
32 |
|
@@ -41,7 +41,7 @@ class Twig_Tests_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase
|
|
41 |
}
|
42 |
|
43 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
44 |
-
$stream = $env->parse($env->tokenize('{{ block(name|lower) }}', 'index'));
|
45 |
|
46 |
$node = $stream->getNode('body')->getNode(0)->getNode(1);
|
47 |
|
@@ -56,7 +56,7 @@ class Twig_Tests_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase
|
|
56 |
{
|
57 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false));
|
58 |
|
59 |
-
$stream = $env->parse($env->tokenize($template, 'index'));
|
60 |
|
61 |
foreach ($expected as $target => $withLoop) {
|
62 |
$this->assertTrue($this->checkForConfiguration($stream, $target, $withLoop), sprintf('variable %s is %soptimized', $target, $withLoop ? 'not ' : ''));
|
14 |
{
|
15 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
16 |
|
17 |
+
$stream = $env->parse($env->tokenize(new Twig_Source('{{ block("foo") }}', 'index')));
|
18 |
|
19 |
$node = $stream->getNode('body')->getNode(0);
|
20 |
|
26 |
{
|
27 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
28 |
|
29 |
+
$stream = $env->parse($env->tokenize(new Twig_Source('{% extends "foo" %}{% block content %}{{ parent() }}{% endblock %}', 'index')));
|
30 |
|
31 |
$node = $stream->getNode('blocks')->getNode('content')->getNode(0)->getNode('body');
|
32 |
|
41 |
}
|
42 |
|
43 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false));
|
44 |
+
$stream = $env->parse($env->tokenize(new Twig_Source('{{ block(name|lower) }}', 'index')));
|
45 |
|
46 |
$node = $stream->getNode('body')->getNode(0)->getNode(1);
|
47 |
|
56 |
{
|
57 |
$env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false));
|
58 |
|
59 |
+
$stream = $env->parse($env->tokenize(new Twig_Source($template, 'index')));
|
60 |
|
61 |
foreach ($expected as $target => $withLoop) {
|
62 |
$this->assertTrue($this->checkForConfiguration($stream, $target, $withLoop), sprintf('variable %s is %soptimized', $target, $withLoop ? 'not ' : ''));
|
vendor/twig/twig/test/Twig/Tests/ParserTest.php
CHANGED
@@ -100,7 +100,7 @@ class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase
|
|
100 |
|
101 |
/**
|
102 |
* @expectedException Twig_Error_Syntax
|
103 |
-
* @expectedExceptionMessage A template that extends another one cannot
|
104 |
*/
|
105 |
public function testFilterBodyNodesWithBOM()
|
106 |
{
|
@@ -141,14 +141,14 @@ class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase
|
|
141 |
'optimizations' => 0,
|
142 |
));
|
143 |
|
144 |
-
$twig->parse($twig->tokenize(<<<EOF
|
145 |
{% from _self import foo %}
|
146 |
|
147 |
{% macro foo() %}
|
148 |
{{ foo }}
|
149 |
{% endmacro %}
|
150 |
EOF
|
151 |
-
));
|
152 |
}
|
153 |
|
154 |
protected function getParser()
|
@@ -156,6 +156,7 @@ EOF
|
|
156 |
$parser = new TestParser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
157 |
$parser->setParent(new Twig_Node());
|
158 |
$parser->stream = $this->getMockBuilder('Twig_TokenStream')->disableOriginalConstructor()->getMock();
|
|
|
159 |
|
160 |
return $parser;
|
161 |
}
|
100 |
|
101 |
/**
|
102 |
* @expectedException Twig_Error_Syntax
|
103 |
+
* @expectedExceptionMessage A template that extends another one cannot start with a byte order mark (BOM); it must be removed at line 1
|
104 |
*/
|
105 |
public function testFilterBodyNodesWithBOM()
|
106 |
{
|
141 |
'optimizations' => 0,
|
142 |
));
|
143 |
|
144 |
+
$twig->parse($twig->tokenize(new Twig_Source(<<<EOF
|
145 |
{% from _self import foo %}
|
146 |
|
147 |
{% macro foo() %}
|
148 |
{{ foo }}
|
149 |
{% endmacro %}
|
150 |
EOF
|
151 |
+
, 'index')));
|
152 |
}
|
153 |
|
154 |
protected function getParser()
|
156 |
$parser = new TestParser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
|
157 |
$parser->setParent(new Twig_Node());
|
158 |
$parser->stream = $this->getMockBuilder('Twig_TokenStream')->disableOriginalConstructor()->getMock();
|
159 |
+
$parser->stream->expects($this->any())->method('getSourceContext')->will($this->returnValue(new Twig_Source('', '')));
|
160 |
|
161 |
return $parser;
|
162 |
}
|
vendor/twig/twig/test/Twig/Tests/TemplateTest.php
CHANGED
@@ -56,22 +56,22 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
|
|
56 |
public function getAttributeExceptions()
|
57 |
{
|
58 |
$tests = array(
|
59 |
-
array('{{ string["a"] }}', 'Impossible to access a key ("a") on a string variable ("foo") in "%s" at line 1', false),
|
60 |
-
array('{{ null["a"] }}', 'Impossible to access a key ("a") on a null variable in "%s" at line 1', false),
|
61 |
-
array('{{ empty_array["a"] }}', 'Key "a" does not exist as the array is empty in "%s" at line 1', false),
|
62 |
-
array('{{ array["a"] }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1', false),
|
63 |
-
array('{{ array_access["a"] }}', 'Key "a" in object with ArrayAccess of class "Twig_TemplateArrayAccessObject" does not exist in "%s" at line 1', false),
|
64 |
-
array('{{ string.a }}', 'Impossible to access an attribute ("a") on a string variable ("foo") in "%s" at line 1', false),
|
65 |
-
array('{{ string.a() }}', 'Impossible to invoke a method ("a") on a string variable ("foo") in "%s" at line 1', false),
|
66 |
-
array('{{ null.a }}', 'Impossible to access an attribute ("a") on a null variable in "%s" at line 1', false),
|
67 |
-
array('{{ null.a() }}', 'Impossible to invoke a method ("a") on a null variable in "%s" at line 1', false),
|
68 |
-
array('{{ empty_array.a }}', 'Key "a" does not exist as the array is empty in "%s" at line 1', false),
|
69 |
-
array('{{ array.a }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1', false),
|
70 |
-
array('{{ attribute(array, -10) }}', 'Key "-10" for array with keys "foo" does not exist in "%s" at line 1', false),
|
71 |
-
array('{{ array_access.a }}', 'Neither the property "a" nor one of the methods "a()", "geta()"/"isa()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1', false),
|
72 |
-
array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', 'Neither the property "missing_method" nor one of the methods "missing_method()", "getmissing_method()"/"ismissing_method()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1', false),
|
73 |
array('{{ magic_exception.test }}', 'An exception has been thrown during the rendering of a template ("Hey! Don\'t try to isset me!") in "%s" at line 1.', false),
|
74 |
-
array('{{ object["a"] }}', 'Impossible to access a key "a" on an object of class "stdClass" that does not implement ArrayAccess interface in "%s" at line 1', false),
|
75 |
);
|
76 |
|
77 |
if (function_exists('twig_template_get_attributes')) {
|
@@ -84,13 +84,6 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
|
|
84 |
return $tests;
|
85 |
}
|
86 |
|
87 |
-
public function testGetSource()
|
88 |
-
{
|
89 |
-
$template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()), false);
|
90 |
-
|
91 |
-
$this->assertSame("<? */*bar*/ ?>\n", $template->getSource());
|
92 |
-
}
|
93 |
-
|
94 |
/**
|
95 |
* @dataProvider getGetAttributeWithSandbox
|
96 |
*/
|
@@ -394,9 +387,9 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
|
|
394 |
|
395 |
// tests when input is not an array or object
|
396 |
$tests = array_merge($tests, array(
|
397 |
-
array(false, null, 42, 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a integer variable ("42")'),
|
398 |
-
array(false, null, 'string', 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a string variable ("string")'),
|
399 |
-
array(false, null, array(), 'a', array(), $anyType, false, 'Key "a" does not exist as the array is empty'),
|
400 |
));
|
401 |
|
402 |
// add twig_template_get_attributes tests
|
@@ -453,6 +446,11 @@ class Twig_TemplateTest extends Twig_Template
|
|
453 |
return array();
|
454 |
}
|
455 |
|
|
|
|
|
|
|
|
|
|
|
456 |
protected function doGetParent(array $context)
|
457 |
{
|
458 |
}
|
@@ -470,8 +468,6 @@ class Twig_TemplateTest extends Twig_Template
|
|
470 |
}
|
471 |
}
|
472 |
}
|
473 |
-
/* <? *//* *bar*//* ?>*/
|
474 |
-
/* */
|
475 |
|
476 |
class Twig_TemplateArrayAccessObject implements ArrayAccess
|
477 |
{
|
56 |
public function getAttributeExceptions()
|
57 |
{
|
58 |
$tests = array(
|
59 |
+
array('{{ string["a"] }}', 'Impossible to access a key ("a") on a string variable ("foo") in "%s" at line 1.', false),
|
60 |
+
array('{{ null["a"] }}', 'Impossible to access a key ("a") on a null variable in "%s" at line 1.', false),
|
61 |
+
array('{{ empty_array["a"] }}', 'Key "a" does not exist as the array is empty in "%s" at line 1.', false),
|
62 |
+
array('{{ array["a"] }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1.', false),
|
63 |
+
array('{{ array_access["a"] }}', 'Key "a" in object with ArrayAccess of class "Twig_TemplateArrayAccessObject" does not exist in "%s" at line 1.', false),
|
64 |
+
array('{{ string.a }}', 'Impossible to access an attribute ("a") on a string variable ("foo") in "%s" at line 1.', false),
|
65 |
+
array('{{ string.a() }}', 'Impossible to invoke a method ("a") on a string variable ("foo") in "%s" at line 1.', false),
|
66 |
+
array('{{ null.a }}', 'Impossible to access an attribute ("a") on a null variable in "%s" at line 1.', false),
|
67 |
+
array('{{ null.a() }}', 'Impossible to invoke a method ("a") on a null variable in "%s" at line 1.', false),
|
68 |
+
array('{{ empty_array.a }}', 'Key "a" does not exist as the array is empty in "%s" at line 1.', false),
|
69 |
+
array('{{ array.a }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1.', false),
|
70 |
+
array('{{ attribute(array, -10) }}', 'Key "-10" for array with keys "foo" does not exist in "%s" at line 1.', false),
|
71 |
+
array('{{ array_access.a }}', 'Neither the property "a" nor one of the methods "a()", "geta()"/"isa()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1.', false),
|
72 |
+
array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', 'Neither the property "missing_method" nor one of the methods "missing_method()", "getmissing_method()"/"ismissing_method()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1.', false),
|
73 |
array('{{ magic_exception.test }}', 'An exception has been thrown during the rendering of a template ("Hey! Don\'t try to isset me!") in "%s" at line 1.', false),
|
74 |
+
array('{{ object["a"] }}', 'Impossible to access a key "a" on an object of class "stdClass" that does not implement ArrayAccess interface in "%s" at line 1.', false),
|
75 |
);
|
76 |
|
77 |
if (function_exists('twig_template_get_attributes')) {
|
84 |
return $tests;
|
85 |
}
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
/**
|
88 |
* @dataProvider getGetAttributeWithSandbox
|
89 |
*/
|
387 |
|
388 |
// tests when input is not an array or object
|
389 |
$tests = array_merge($tests, array(
|
390 |
+
array(false, null, 42, 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a integer variable ("42").'),
|
391 |
+
array(false, null, 'string', 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a string variable ("string").'),
|
392 |
+
array(false, null, array(), 'a', array(), $anyType, false, 'Key "a" does not exist as the array is empty.'),
|
393 |
));
|
394 |
|
395 |
// add twig_template_get_attributes tests
|
446 |
return array();
|
447 |
}
|
448 |
|
449 |
+
public function getSource()
|
450 |
+
{
|
451 |
+
return '';
|
452 |
+
}
|
453 |
+
|
454 |
protected function doGetParent(array $context)
|
455 |
{
|
456 |
}
|
468 |
}
|
469 |
}
|
470 |
}
|
|
|
|
|
471 |
|
472 |
class Twig_TemplateArrayAccessObject implements ArrayAccess
|
473 |
{
|
vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php
CHANGED
@@ -27,6 +27,18 @@ class Twig_Tests_TokenStreamTest extends PHPUnit_Framework_TestCase
|
|
27 |
);
|
28 |
}
|
29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
public function testNext()
|
31 |
{
|
32 |
$stream = new Twig_TokenStream(self::$tokens);
|
27 |
);
|
28 |
}
|
29 |
|
30 |
+
/**
|
31 |
+
* @group legacy
|
32 |
+
*/
|
33 |
+
public function testLegacyConstructorSignature()
|
34 |
+
{
|
35 |
+
$stream = new Twig_TokenStream(array(), 'foo', '{{ foo }}');
|
36 |
+
$this->assertEquals('foo', $stream->getFilename());
|
37 |
+
$this->assertEquals('{{ foo }}', $stream->getSource());
|
38 |
+
$this->assertEquals('foo', $stream->getSourceContext()->getName());
|
39 |
+
$this->assertEquals('{{ foo }}', $stream->getSourceContext()->getCode());
|
40 |
+
}
|
41 |
+
|
42 |
public function testNext()
|
43 |
{
|
44 |
$stream = new Twig_TokenStream(self::$tokens);
|
vendor/twig/twig/test/Twig/Tests/escapingTest.php
CHANGED
@@ -250,7 +250,7 @@ class Twig_Test_EscapingTest extends PHPUnit_Framework_TestCase
|
|
250 |
.chr($codepoint >> 6 & 0x3f | 0x80)
|
251 |
.chr($codepoint & 0x3f | 0x80);
|
252 |
}
|
253 |
-
throw new Exception('Codepoint requested outside of Unicode range');
|
254 |
}
|
255 |
|
256 |
public function testJavascriptEscapingEscapesOwaspRecommendedRanges()
|
250 |
.chr($codepoint >> 6 & 0x3f | 0x80)
|
251 |
.chr($codepoint & 0x3f | 0x80);
|
252 |
}
|
253 |
+
throw new Exception('Codepoint requested outside of Unicode range.');
|
254 |
}
|
255 |
|
256 |
public function testJavascriptEscapingEscapesOwaspRecommendedRanges()
|