git-svn-id: http://svn.twig-project.org/trunk@226 93ef8e89-cb99-4229-a87c-7fa0fa45744b
... | ... |
@@ -16,6 +16,7 @@ class Twig_Environment |
16 | 16 |
protected $charset; |
17 | 17 |
protected $loader; |
18 | 18 |
protected $trimBlocks; |
19 |
+ protected $strictMode; |
|
19 | 20 |
protected $debug; |
20 | 21 |
protected $autoReload; |
21 | 22 |
protected $cache; |
... | ... |
@@ -56,6 +57,11 @@ class Twig_Environment |
56 | 57 |
* * auto_reload: Whether to reload the template is the original source changed. |
57 | 58 |
* If you don't provide the auto_reload option, it will be |
58 | 59 |
* determined automatically base on the debug value. |
60 |
+ * |
|
61 |
+ * * strict_mode: Whether to enable the strict mode or not. If enabled, |
|
62 |
+ * everything must be explicit. For instance, all variables must be |
|
63 |
+ * declared at the top of the template, you must pass explicitely the variables |
|
64 |
+ * when including another template, and so on. If not, a StrictError is thrown. |
|
59 | 65 |
*/ |
60 | 66 |
public function __construct(Twig_LoaderInterface $loader = null, $options = array()) |
61 | 67 |
{ |
... | ... |
@@ -64,6 +70,7 @@ class Twig_Environment |
64 | 70 |
$this->setLoader($loader); |
65 | 71 |
} |
66 | 72 |
|
73 |
+ $this->strictMode = isset($options['strict_mode']) ? (bool) $options['strict_mode'] : false; |
|
67 | 74 |
$this->debug = isset($options['debug']) ? (bool) $options['debug'] : false; |
68 | 75 |
$this->trimBlocks = isset($options['trim_blocks']) ? (bool) $options['trim_blocks'] : false; |
69 | 76 |
$this->charset = isset($options['charset']) ? $options['charset'] : 'UTF-8'; |
... | ... |
@@ -84,6 +91,21 @@ class Twig_Environment |
84 | 91 |
$this->baseTemplateClass = $class; |
85 | 92 |
} |
86 | 93 |
|
94 |
+ public function enableStrictMode() |
|
95 |
+ { |
|
96 |
+ $this->strictMode = true; |
|
97 |
+ } |
|
98 |
+ |
|
99 |
+ public function disableStrictMode() |
|
100 |
+ { |
|
101 |
+ $this->strictMode = false; |
|
102 |
+ } |
|
103 |
+ |
|
104 |
+ public function isStrictMode() |
|
105 |
+ { |
|
106 |
+ return $this->strictMode; |
|
107 |
+ } |
|
108 |
+ |
|
87 | 109 |
public function enableDebug() |
88 | 110 |
{ |
89 | 111 |
$this->debug = true; |
... | ... |
@@ -30,6 +30,7 @@ class Twig_Extension_Core extends Twig_Extension |
30 | 30 |
new Twig_TokenParser_Import(), |
31 | 31 |
new Twig_TokenParser_Set(), |
32 | 32 |
new Twig_TokenParser_Debug(), |
33 |
+ new Twig_TokenParser_Use(), |
|
33 | 34 |
); |
34 | 35 |
} |
35 | 36 |
|
... | ... |
@@ -40,7 +41,10 @@ class Twig_Extension_Core extends Twig_Extension |
40 | 41 |
*/ |
41 | 42 |
public function getNodeVisitors() |
42 | 43 |
{ |
43 |
- return array(new Twig_NodeVisitor_Filter()); |
|
44 |
+ return array( |
|
45 |
+ new Twig_NodeVisitor_Filter(), |
|
46 |
+ new Twig_NodeVisitor_StrictMode() |
|
47 |
+ ); |
|
44 | 48 |
} |
45 | 49 |
|
46 | 50 |
/** |
... | ... |
@@ -12,6 +12,7 @@ |
12 | 12 |
class Twig_Node_Expression_Name extends Twig_Node_Expression |
13 | 13 |
{ |
14 | 14 |
protected $name; |
15 |
+ protected $declared = false; |
|
15 | 16 |
|
16 | 17 |
public function __construct($name, $lineno) |
17 | 18 |
{ |
... | ... |
@@ -26,11 +27,23 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression |
26 | 27 |
|
27 | 28 |
public function compile($compiler) |
28 | 29 |
{ |
29 |
- $compiler->raw(sprintf('(isset($context[\'%s\']) ? $context[\'%s\'] : null)', $this->name, $this->name)); |
|
30 |
+ if ($this->declared) |
|
31 |
+ { |
|
32 |
+ $compiler->raw(sprintf('$context[\'%s\']', $this->name)); |
|
33 |
+ } |
|
34 |
+ else |
|
35 |
+ { |
|
36 |
+ $compiler->raw(sprintf('(isset($context[\'%s\']) ? $context[\'%s\'] : null)', $this->name, $this->name)); |
|
37 |
+ } |
|
30 | 38 |
} |
31 | 39 |
|
32 | 40 |
public function getName() |
33 | 41 |
{ |
34 | 42 |
return $this->name; |
35 | 43 |
} |
44 |
+ |
|
45 |
+ public function setDeclared() |
|
46 |
+ { |
|
47 |
+ $this->declared = true; |
|
48 |
+ } |
|
36 | 49 |
} |
... | ... |
@@ -84,26 +84,38 @@ class Twig_Token |
84 | 84 |
{ |
85 | 85 |
switch ($type) |
86 | 86 |
{ |
87 |
- case 0: |
|
88 |
- return 'TEXT_TYPE'; |
|
89 |
- case -1: |
|
90 |
- return 'EOF_TYPE'; |
|
91 |
- case 1: |
|
92 |
- return 'BLOCK_START_TYPE'; |
|
93 |
- case 2: |
|
94 |
- return 'VAR_START_TYPE'; |
|
95 |
- case 3: |
|
96 |
- return 'BLOCK_END_TYPE'; |
|
97 |
- case 4: |
|
98 |
- return 'VAR_END_TYPE'; |
|
99 |
- case 5: |
|
100 |
- return 'NAME_TYPE'; |
|
101 |
- case 6: |
|
102 |
- return 'NUMBER_TYPE'; |
|
103 |
- case 7: |
|
104 |
- return 'STRING_TYPE'; |
|
105 |
- case 8: |
|
106 |
- return 'OPERATOR_TYPE'; |
|
87 |
+ case self::EOF_TYPE: |
|
88 |
+ $name = 'EOF_TYPE'; |
|
89 |
+ break; |
|
90 |
+ case self::TEXT_TYPE: |
|
91 |
+ $name = 'TEXT_TYPE'; |
|
92 |
+ break; |
|
93 |
+ case self::BLOCK_START_TYPE: |
|
94 |
+ $name = 'BLOCK_START_TYPE'; |
|
95 |
+ break; |
|
96 |
+ case self::VAR_START_TYPE: |
|
97 |
+ $name = 'VAR_START_TYPE'; |
|
98 |
+ break; |
|
99 |
+ case selg::BLOCK_END_TYPE: |
|
100 |
+ $name = 'BLOCK_END_TYPE'; |
|
101 |
+ break; |
|
102 |
+ case self::VAR_END_TYPE: |
|
103 |
+ $name = 'VAR_END_TYPE'; |
|
104 |
+ break; |
|
105 |
+ case self::NAME_TYPE: |
|
106 |
+ $name = 'NAME_TYPE'; |
|
107 |
+ break; |
|
108 |
+ case self::NUMBER_TYPE: |
|
109 |
+ $name = 'NUMBER_TYPE'; |
|
110 |
+ break; |
|
111 |
+ case self::STRING_TYPE: |
|
112 |
+ $name = 'STRING_TYPE'; |
|
113 |
+ break; |
|
114 |
+ case self::OPERATOR_TYPE: |
|
115 |
+ $name = 'OPERATOR_TYPE'; |
|
116 |
+ break; |
|
117 |
+ default: |
|
118 |
+ throw new InvalidArgumentException(sprintf('Token of type %s does not exist.', $type)); |
|
107 | 119 |
} |
108 | 120 |
|
109 | 121 |
return $short ? $name : 'Twig_Token::'.$name; |