| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 | 
							- <?php
 
- /*
 
-  * This file is part of the Symfony package.
 
-  *
 
-  * (c) Fabien Potencier <fabien@symfony.com>
 
-  *
 
-  * For the full copyright and license information, please view the LICENSE
 
-  * file that was distributed with this source code.
 
-  */
 
- namespace Symfony\Component\ExpressionLanguage\Node;
 
- use Symfony\Component\ExpressionLanguage\Compiler;
 
- use Symfony\Component\ExpressionLanguage\SyntaxError;
 
- /**
 
-  * @author Fabien Potencier <fabien@symfony.com>
 
-  *
 
-  * @internal
 
-  */
 
- class BinaryNode extends Node
 
- {
 
-     private const OPERATORS = [
 
-         '~' => '.',
 
-         'and' => '&&',
 
-         'or' => '||',
 
-     ];
 
-     private const FUNCTIONS = [
 
-         '**' => 'pow',
 
-         '..' => 'range',
 
-         'in' => 'in_array',
 
-         'not in' => '!in_array',
 
-     ];
 
-     public function __construct(string $operator, Node $left, Node $right)
 
-     {
 
-         parent::__construct(
 
-             ['left' => $left, 'right' => $right],
 
-             ['operator' => $operator]
 
-         );
 
-     }
 
-     public function compile(Compiler $compiler)
 
-     {
 
-         $operator = $this->attributes['operator'];
 
-         if ('matches' == $operator) {
 
-             if ($this->nodes['right'] instanceof ConstantNode) {
 
-                 $this->evaluateMatches($this->nodes['right']->evaluate([], []), '');
 
-             }
 
-             $compiler
 
-                 ->raw('(static function ($regexp, $str) { set_error_handler(function ($t, $m) use ($regexp, $str) { throw new \Symfony\Component\ExpressionLanguage\SyntaxError(sprintf(\'Regexp "%s" passed to "matches" is not valid\', $regexp).substr($m, 12)); }); try { return preg_match($regexp, (string) $str); } finally { restore_error_handler(); } })(')
 
-                 ->compile($this->nodes['right'])
 
-                 ->raw(', ')
 
-                 ->compile($this->nodes['left'])
 
-                 ->raw(')')
 
-             ;
 
-             return;
 
-         }
 
-         if (isset(self::FUNCTIONS[$operator])) {
 
-             $compiler
 
-                 ->raw(sprintf('%s(', self::FUNCTIONS[$operator]))
 
-                 ->compile($this->nodes['left'])
 
-                 ->raw(', ')
 
-                 ->compile($this->nodes['right'])
 
-                 ->raw(')')
 
-             ;
 
-             return;
 
-         }
 
-         if (isset(self::OPERATORS[$operator])) {
 
-             $operator = self::OPERATORS[$operator];
 
-         }
 
-         $compiler
 
-             ->raw('(')
 
-             ->compile($this->nodes['left'])
 
-             ->raw(' ')
 
-             ->raw($operator)
 
-             ->raw(' ')
 
-             ->compile($this->nodes['right'])
 
-             ->raw(')')
 
-         ;
 
-     }
 
-     public function evaluate(array $functions, array $values)
 
-     {
 
-         $operator = $this->attributes['operator'];
 
-         $left = $this->nodes['left']->evaluate($functions, $values);
 
-         if (isset(self::FUNCTIONS[$operator])) {
 
-             $right = $this->nodes['right']->evaluate($functions, $values);
 
-             if ('not in' === $operator) {
 
-                 return !\in_array($left, $right);
 
-             }
 
-             $f = self::FUNCTIONS[$operator];
 
-             return $f($left, $right);
 
-         }
 
-         switch ($operator) {
 
-             case 'or':
 
-             case '||':
 
-                 return $left || $this->nodes['right']->evaluate($functions, $values);
 
-             case 'and':
 
-             case '&&':
 
-                 return $left && $this->nodes['right']->evaluate($functions, $values);
 
-         }
 
-         $right = $this->nodes['right']->evaluate($functions, $values);
 
-         switch ($operator) {
 
-             case '|':
 
-                 return $left | $right;
 
-             case '^':
 
-                 return $left ^ $right;
 
-             case '&':
 
-                 return $left & $right;
 
-             case '==':
 
-                 return $left == $right;
 
-             case '===':
 
-                 return $left === $right;
 
-             case '!=':
 
-                 return $left != $right;
 
-             case '!==':
 
-                 return $left !== $right;
 
-             case '<':
 
-                 return $left < $right;
 
-             case '>':
 
-                 return $left > $right;
 
-             case '>=':
 
-                 return $left >= $right;
 
-             case '<=':
 
-                 return $left <= $right;
 
-             case 'not in':
 
-                 return !\in_array($left, $right);
 
-             case 'in':
 
-                 return \in_array($left, $right);
 
-             case '+':
 
-                 return $left + $right;
 
-             case '-':
 
-                 return $left - $right;
 
-             case '~':
 
-                 return $left.$right;
 
-             case '*':
 
-                 return $left * $right;
 
-             case '/':
 
-                 if (0 == $right) {
 
-                     throw new \DivisionByZeroError('Division by zero.');
 
-                 }
 
-                 return $left / $right;
 
-             case '%':
 
-                 if (0 == $right) {
 
-                     throw new \DivisionByZeroError('Modulo by zero.');
 
-                 }
 
-                 return $left % $right;
 
-             case 'matches':
 
-                 return $this->evaluateMatches($right, $left);
 
-         }
 
-     }
 
-     public function toArray()
 
-     {
 
-         return ['(', $this->nodes['left'], ' '.$this->attributes['operator'].' ', $this->nodes['right'], ')'];
 
-     }
 
-     private function evaluateMatches(string $regexp, ?string $str): int
 
-     {
 
-         set_error_handler(function ($t, $m) use ($regexp) {
 
-             throw new SyntaxError(sprintf('Regexp "%s" passed to "matches" is not valid', $regexp).substr($m, 12));
 
-         });
 
-         try {
 
-             return preg_match($regexp, (string) $str);
 
-         } finally {
 
-             restore_error_handler();
 
-         }
 
-     }
 
- }
 
 
  |