Added the Search API Synonym module to deal specifically with licence and license...
[yaffs-website] / vendor / twig / twig / lib / Twig / NodeVisitor / Escaper.php
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  * Twig_NodeVisitor_Escaper implements output escaping.
14  *
15  * @final
16  *
17  * @author Fabien Potencier <fabien@symfony.com>
18  */
19 class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
20 {
21     protected $statusStack = array();
22     protected $blocks = array();
23     protected $safeAnalysis;
24     protected $traverser;
25     protected $defaultStrategy = false;
26     protected $safeVars = array();
27
28     public function __construct()
29     {
30         $this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis();
31     }
32
33     protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
34     {
35         if ($node instanceof Twig_Node_Module) {
36             if ($env->hasExtension('Twig_Extension_Escaper') && $defaultStrategy = $env->getExtension('Twig_Extension_Escaper')->getDefaultStrategy($node->getTemplateName())) {
37                 $this->defaultStrategy = $defaultStrategy;
38             }
39             $this->safeVars = array();
40             $this->blocks = array();
41         } elseif ($node instanceof Twig_Node_AutoEscape) {
42             $this->statusStack[] = $node->getAttribute('value');
43         } elseif ($node instanceof Twig_Node_Block) {
44             $this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env);
45         } elseif ($node instanceof Twig_Node_Import) {
46             $this->safeVars[] = $node->getNode('var')->getAttribute('name');
47         }
48
49         return $node;
50     }
51
52     protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
53     {
54         if ($node instanceof Twig_Node_Module) {
55             $this->defaultStrategy = false;
56             $this->safeVars = array();
57             $this->blocks = array();
58         } elseif ($node instanceof Twig_Node_Expression_Filter) {
59             return $this->preEscapeFilterNode($node, $env);
60         } elseif ($node instanceof Twig_Node_Print) {
61             return $this->escapePrintNode($node, $env, $this->needEscaping($env));
62         }
63
64         if ($node instanceof Twig_Node_AutoEscape || $node instanceof Twig_Node_Block) {
65             array_pop($this->statusStack);
66         } elseif ($node instanceof Twig_Node_BlockReference) {
67             $this->blocks[$node->getAttribute('name')] = $this->needEscaping($env);
68         }
69
70         return $node;
71     }
72
73     protected function escapePrintNode(Twig_Node_Print $node, Twig_Environment $env, $type)
74     {
75         if (false === $type) {
76             return $node;
77         }
78
79         $expression = $node->getNode('expr');
80
81         if ($this->isSafeFor($type, $expression, $env)) {
82             return $node;
83         }
84
85         $class = get_class($node);
86
87         return new $class(
88             $this->getEscaperFilter($type, $expression),
89             $node->getTemplateLine()
90         );
91     }
92
93     protected function preEscapeFilterNode(Twig_Node_Expression_Filter $filter, Twig_Environment $env)
94     {
95         $name = $filter->getNode('filter')->getAttribute('value');
96
97         $type = $env->getFilter($name)->getPreEscape();
98         if (null === $type) {
99             return $filter;
100         }
101
102         $node = $filter->getNode('node');
103         if ($this->isSafeFor($type, $node, $env)) {
104             return $filter;
105         }
106
107         $filter->setNode('node', $this->getEscaperFilter($type, $node));
108
109         return $filter;
110     }
111
112     protected function isSafeFor($type, Twig_NodeInterface $expression, $env)
113     {
114         $safe = $this->safeAnalysis->getSafe($expression);
115
116         if (null === $safe) {
117             if (null === $this->traverser) {
118                 $this->traverser = new Twig_NodeTraverser($env, array($this->safeAnalysis));
119             }
120
121             $this->safeAnalysis->setSafeVars($this->safeVars);
122
123             $this->traverser->traverse($expression);
124             $safe = $this->safeAnalysis->getSafe($expression);
125         }
126
127         return in_array($type, $safe) || in_array('all', $safe);
128     }
129
130     protected function needEscaping(Twig_Environment $env)
131     {
132         if (count($this->statusStack)) {
133             return $this->statusStack[count($this->statusStack) - 1];
134         }
135
136         return $this->defaultStrategy ? $this->defaultStrategy : false;
137     }
138
139     protected function getEscaperFilter($type, Twig_NodeInterface $node)
140     {
141         $line = $node->getTemplateLine();
142         $name = new Twig_Node_Expression_Constant('escape', $line);
143         $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)));
144
145         return new Twig_Node_Expression_Filter($node, $name, $args, $line);
146     }
147
148     public function getPriority()
149     {
150         return 0;
151     }
152 }
153
154 class_alias('Twig_NodeVisitor_Escaper', 'Twig\NodeVisitor\EscaperNodeVisitor', false);