You are here

class Twig_NodeVisitor_Escaper in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php \Twig_NodeVisitor_Escaper

Twig_NodeVisitor_Escaper implements output escaping.

@author Fabien Potencier <fabien@symfony.com>

Hierarchy

Expanded class hierarchy of Twig_NodeVisitor_Escaper

File

vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php, line 17

View source
class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor {
  protected $statusStack = array();
  protected $blocks = array();
  protected $safeAnalysis;
  protected $traverser;
  protected $defaultStrategy = false;
  protected $safeVars = array();
  public function __construct() {
    $this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis();
  }

  /**
   * {@inheritdoc}
   */
  protected function doEnterNode(Twig_Node $node, Twig_Environment $env) {
    if ($node instanceof Twig_Node_Module) {
      if ($env
        ->hasExtension('escaper') && ($defaultStrategy = $env
        ->getExtension('escaper')
        ->getDefaultStrategy($node
        ->getAttribute('filename')))) {
        $this->defaultStrategy = $defaultStrategy;
      }
      $this->safeVars = array();
    }
    elseif ($node instanceof Twig_Node_AutoEscape) {
      $this->statusStack[] = $node
        ->getAttribute('value');
    }
    elseif ($node instanceof Twig_Node_Block) {
      $this->statusStack[] = isset($this->blocks[$node
        ->getAttribute('name')]) ? $this->blocks[$node
        ->getAttribute('name')] : $this
        ->needEscaping($env);
    }
    elseif ($node instanceof Twig_Node_Import) {
      $this->safeVars[] = $node
        ->getNode('var')
        ->getAttribute('name');
    }
    return $node;
  }

  /**
   * {@inheritdoc}
   */
  protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) {
    if ($node instanceof Twig_Node_Module) {
      $this->defaultStrategy = false;
      $this->safeVars = array();
    }
    elseif ($node instanceof Twig_Node_Expression_Filter) {
      return $this
        ->preEscapeFilterNode($node, $env);
    }
    elseif ($node instanceof Twig_Node_Print) {
      return $this
        ->escapePrintNode($node, $env, $this
        ->needEscaping($env));
    }
    if ($node instanceof Twig_Node_AutoEscape || $node instanceof Twig_Node_Block) {
      array_pop($this->statusStack);
    }
    elseif ($node instanceof Twig_Node_BlockReference) {
      $this->blocks[$node
        ->getAttribute('name')] = $this
        ->needEscaping($env);
    }
    return $node;
  }
  protected function escapePrintNode(Twig_Node_Print $node, Twig_Environment $env, $type) {
    if (false === $type) {
      return $node;
    }
    $expression = $node
      ->getNode('expr');
    if ($this
      ->isSafeFor($type, $expression, $env)) {
      return $node;
    }
    $class = get_class($node);
    return new $class($this
      ->getEscaperFilter($type, $expression), $node
      ->getLine());
  }
  protected function preEscapeFilterNode(Twig_Node_Expression_Filter $filter, Twig_Environment $env) {
    $name = $filter
      ->getNode('filter')
      ->getAttribute('value');
    $type = $env
      ->getFilter($name)
      ->getPreEscape();
    if (null === $type) {
      return $filter;
    }
    $node = $filter
      ->getNode('node');
    if ($this
      ->isSafeFor($type, $node, $env)) {
      return $filter;
    }
    $filter
      ->setNode('node', $this
      ->getEscaperFilter($type, $node));
    return $filter;
  }
  protected function isSafeFor($type, Twig_NodeInterface $expression, $env) {
    $safe = $this->safeAnalysis
      ->getSafe($expression);
    if (null === $safe) {
      if (null === $this->traverser) {
        $this->traverser = new Twig_NodeTraverser($env, array(
          $this->safeAnalysis,
        ));
      }
      $this->safeAnalysis
        ->setSafeVars($this->safeVars);
      $this->traverser
        ->traverse($expression);
      $safe = $this->safeAnalysis
        ->getSafe($expression);
    }
    return in_array($type, $safe) || in_array('all', $safe);
  }
  protected function needEscaping(Twig_Environment $env) {
    if (count($this->statusStack)) {
      return $this->statusStack[count($this->statusStack) - 1];
    }
    return $this->defaultStrategy ? $this->defaultStrategy : false;
  }
  protected function getEscaperFilter($type, Twig_NodeInterface $node) {
    $line = $node
      ->getLine();
    $name = new Twig_Node_Expression_Constant('escape', $line);
    $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),
    ));
    return new Twig_Node_Expression_Filter($node, $name, $args, $line);
  }

  /**
   * {@inheritdoc}
   */
  public function getPriority() {
    return 0;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Twig_BaseNodeVisitor::enterNode final public function Called before child nodes are visited. Overrides Twig_NodeVisitorInterface::enterNode
Twig_BaseNodeVisitor::leaveNode final public function Called after child nodes are visited. Overrides Twig_NodeVisitorInterface::leaveNode
Twig_NodeVisitor_Escaper::$blocks protected property
Twig_NodeVisitor_Escaper::$defaultStrategy protected property
Twig_NodeVisitor_Escaper::$safeAnalysis protected property
Twig_NodeVisitor_Escaper::$safeVars protected property
Twig_NodeVisitor_Escaper::$statusStack protected property
Twig_NodeVisitor_Escaper::$traverser protected property
Twig_NodeVisitor_Escaper::doEnterNode protected function Called before child nodes are visited. Overrides Twig_BaseNodeVisitor::doEnterNode
Twig_NodeVisitor_Escaper::doLeaveNode protected function Called after child nodes are visited. Overrides Twig_BaseNodeVisitor::doLeaveNode
Twig_NodeVisitor_Escaper::escapePrintNode protected function
Twig_NodeVisitor_Escaper::getEscaperFilter protected function
Twig_NodeVisitor_Escaper::getPriority public function Returns the priority for this visitor. Overrides Twig_NodeVisitorInterface::getPriority
Twig_NodeVisitor_Escaper::isSafeFor protected function
Twig_NodeVisitor_Escaper::needEscaping protected function
Twig_NodeVisitor_Escaper::preEscapeFilterNode protected function
Twig_NodeVisitor_Escaper::__construct public function