vendor/twig/lib/Twig/NodeVisitor/SafeAnalysis.php
author cavaliet
Mon, 07 Jul 2014 17:23:47 +0200
changeset 122 d672f7dd74dc
parent 0 7f95f8617b0b
permissions -rwxr-xr-x
Added tag V00.17 for changeset ada5f3d8b5b4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
{
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
    protected $data = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
    public function getSafe(Twig_NodeInterface $node)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
        $hash = spl_object_hash($node);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
        if (isset($this->data[$hash])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
            foreach($this->data[$hash] as $bucket) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
                if ($bucket['key'] === $node) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
                    return $bucket['value'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
        return null;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
    protected function setSafe(Twig_NodeInterface $node, array $safe)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
        $hash = spl_object_hash($node);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
        if (isset($this->data[$hash])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
            foreach($this->data[$hash] as &$bucket) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
                if ($bucket['key'] === $node) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
                    $bucket['value'] = $safe;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
                    return;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
        $this->data[$hash][] = array(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
            'key' => $node,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
            'value' => $safe,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
        );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
    public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
        return $node;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
    public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
        if ($node instanceof Twig_Node_Expression_Constant) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
            // constants are marked safe for all
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
            $this->setSafe($node, array('all'));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
        } elseif ($node instanceof Twig_Node_Expression_BlockReference) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
            // blocks are safe by definition
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
            $this->setSafe($node, array('all'));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
        } elseif ($node instanceof Twig_Node_Expression_Parent) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
            // parent block is safe by definition
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
            $this->setSafe($node, array('all'));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
        } elseif ($node instanceof Twig_Node_Expression_Conditional) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
            // intersect safeness of both operands
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
            $safe = $this->intersectSafe($this->getSafe($node->getNode('expr2')), $this->getSafe($node->getNode('expr3')));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
            $this->setSafe($node, $safe);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
        } elseif ($node instanceof Twig_Node_Expression_Filter) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
            // filter expression is safe when the filter is safe
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
            $name = $node->getNode('filter')->getAttribute('value');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
            $args = $node->getNode('arguments');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
            if (false !== $filter = $env->getFilter($name)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
                $this->setSafe($node, $filter->getSafe($args));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
                $this->setSafe($node, array());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
        } elseif ($node instanceof Twig_Node_Expression_Function) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
            // function expression is safe when the function is safe
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
            $name = $node->getNode('name')->getAttribute('name');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
            $args = $node->getNode('arguments');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
            $function = $env->getFunction($name);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
            if (false !== $function) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
                $this->setSafe($node, $function->getSafe($args));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
                $this->setSafe($node, array());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
            $this->setSafe($node, array());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
        return $node;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
    protected function intersectSafe(array $a = null, array $b = null)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
        if (null === $a || null === $b) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
            return array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
        if (in_array('all', $a)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
            return $b;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
        if (in_array('all', $b)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
            return $a;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
        return array_intersect($a, $b);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
     * {@inheritdoc}
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
    public function getPriority()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
        return 0;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
}