source: pro-violet-viettel/sourcecode/application/third_party/Twig/NodeVisitor/Escaper.php @ 345

Last change on this file since 345 was 345, checked in by quyenla, 11 years ago

collaborator page

File size: 4.6 KB
Line 
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 * Twig_NodeVisitor_Escaper implements output escaping.
14 *
15 * @package    twig
16 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17 */
18class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
19{
20    protected $statusStack = array();
21    protected $blocks = array();
22
23    protected $safeAnalysis;
24    protected $traverser;
25
26    function __construct()
27    {
28        $this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis();
29    }
30
31    /**
32     * Called before child nodes are visited.
33     *
34     * @param Twig_NodeInterface $node The node to visit
35     * @param Twig_Environment   $env  The Twig environment instance
36     *
37     * @param Twig_NodeInterface The modified node
38     */
39    public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
40    {
41        if ($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        }
46
47        return $node;
48    }
49
50    /**
51     * Called after child nodes are visited.
52     *
53     * @param Twig_NodeInterface $node The node to visit
54     * @param Twig_Environment   $env  The Twig environment instance
55     *
56     * @param Twig_NodeInterface The modified node
57     */
58    public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
59    {
60        if ($node instanceof Twig_Node_Expression_Filter) {
61            return $this->preEscapeFilterNode($node, $env);
62        } elseif ($node instanceof Twig_Node_Print) {
63            return $this->escapePrintNode($node, $env, $this->needEscaping($env));
64        }
65
66        if ($node instanceof Twig_Node_AutoEscape || $node instanceof Twig_Node_Block) {
67            array_pop($this->statusStack);
68        } elseif ($node instanceof Twig_Node_BlockReference) {
69            $this->blocks[$node->getAttribute('name')] = $this->needEscaping($env);
70        }
71
72        return $node;
73    }
74
75    protected function escapePrintNode(Twig_Node_Print $node, Twig_Environment $env, $type)
76    {
77        if (false === $type) {
78            return $node;
79        }
80
81        $expression = $node->getNode('expr');
82
83        if ($this->isSafeFor($type, $expression, $env)) {
84            return $node;
85        }
86
87        $class = get_class($node);
88
89        return new $class(
90            $this->getEscaperFilter($type, $expression),
91            $node->getLine()
92        );
93    }
94
95    protected function preEscapeFilterNode(Twig_Node_Expression_Filter $filter, Twig_Environment $env)
96    {
97        $name = $filter->getNode('filter')->getAttribute('value');
98
99        if (false !== $f = $env->getFilter($name)) {
100            $type = $f->getPreEscape();
101            if (null === $type) {
102                return $filter;
103            }
104
105            $node = $filter->getNode('node');
106            if ($this->isSafeFor($type, $node, $env)) {
107                return $filter;
108            }
109
110            $filter->setNode('node', $this->getEscaperFilter($type, $node));
111
112            return $filter;
113        }
114
115        return $filter;
116    }
117
118    protected function isSafeFor($type, Twig_NodeInterface $expression, $env)
119    {
120        $safe = $this->safeAnalysis->getSafe($expression);
121
122        if (null === $safe) {
123            if (null === $this->traverser) {
124                $this->traverser = new Twig_NodeTraverser($env, array($this->safeAnalysis));
125            }
126            $this->traverser->traverse($expression);
127            $safe = $this->safeAnalysis->getSafe($expression);
128        }
129
130        return in_array($type, $safe) || in_array('all', $safe);
131    }
132
133    protected function needEscaping(Twig_Environment $env)
134    {
135        if (count($this->statusStack)) {
136            return $this->statusStack[count($this->statusStack) - 1];
137        }
138
139        if ($env->hasExtension('escaper') && $env->getExtension('escaper')->isGlobal()) {
140            return 'html';
141        }
142
143        return false;
144    }
145
146    protected function getEscaperFilter($type, Twig_NodeInterface $node)
147    {
148        $line = $node->getLine();
149        $name = new Twig_Node_Expression_Constant('escape', $line);
150        $args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line)));
151        return new Twig_Node_Expression_Filter($node, $name, $args, $line);
152    }
153
154    /**
155     * {@inheritdoc}
156     */
157    public function getPriority()
158    {
159        return 0;
160    }
161}
Note: See TracBrowser for help on using the repository browser.