shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

Escaper.php (5150B)


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