vendor/twig/twig/src/Extension/EscaperExtension.php line 172

  1. <?php
  2. /*
  3.  * This file is part of Twig.
  4.  *
  5.  * (c) Fabien Potencier
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Twig\Extension;
  11. use Twig\Environment;
  12. use Twig\FileExtensionEscapingStrategy;
  13. use Twig\Node\Expression\ConstantExpression;
  14. use Twig\Node\Node;
  15. use Twig\NodeVisitor\EscaperNodeVisitor;
  16. use Twig\Runtime\EscaperRuntime;
  17. use Twig\TokenParser\AutoEscapeTokenParser;
  18. use Twig\TwigFilter;
  19. final class EscaperExtension extends AbstractExtension
  20. {
  21.     private $environment;
  22.     private $escapers = [];
  23.     private $escaper;
  24.     private $defaultStrategy;
  25.     /**
  26.      * @param string|false|callable $defaultStrategy An escaping strategy
  27.      *
  28.      * @see setDefaultStrategy()
  29.      */
  30.     public function __construct($defaultStrategy 'html')
  31.     {
  32.         $this->setDefaultStrategy($defaultStrategy);
  33.     }
  34.     public function getTokenParsers(): array
  35.     {
  36.         return [new AutoEscapeTokenParser()];
  37.     }
  38.     public function getNodeVisitors(): array
  39.     {
  40.         return [new EscaperNodeVisitor()];
  41.     }
  42.     public function getFilters(): array
  43.     {
  44.         return [
  45.             new TwigFilter('escape', [EscaperRuntime::class, 'escape'], ['is_safe_callback' => [self::class, 'escapeFilterIsSafe']]),
  46.             new TwigFilter('e', [EscaperRuntime::class, 'escape'], ['is_safe_callback' => [self::class, 'escapeFilterIsSafe']]),
  47.             new TwigFilter('raw', [self::class, 'raw'], ['is_safe' => ['all']]),
  48.         ];
  49.     }
  50.     /**
  51.      * @deprecated since Twig 3.10
  52.      */
  53.     public function setEnvironment(Environment $environmentbool $triggerDeprecation true): void
  54.     {
  55.         if ($triggerDeprecation) {
  56.             trigger_deprecation('twig/twig''3.10''The "%s()" method is deprecated and not needed if you are using methods from "Twig\Runtime\EscaperRuntime".'__METHOD__);
  57.         }
  58.         $this->environment $environment;
  59.         $this->escaper $environment->getRuntime(EscaperRuntime::class);
  60.     }
  61.     /**
  62.      * @deprecated since Twig 3.10
  63.      */
  64.     public function setEscaperRuntime(EscaperRuntime $escaper)
  65.     {
  66.         trigger_deprecation('twig/twig''3.10''The "%s()" method is deprecated and not needed if you are using methods from "Twig\Runtime\EscaperRuntime".'__METHOD__);
  67.         $this->escaper $escaper;
  68.     }
  69.     /**
  70.      * Sets the default strategy to use when not defined by the user.
  71.      *
  72.      * The strategy can be a valid PHP callback that takes the template
  73.      * name as an argument and returns the strategy to use.
  74.      *
  75.      * @param string|false|callable(string $templateName): string $defaultStrategy An escaping strategy
  76.      */
  77.     public function setDefaultStrategy($defaultStrategy): void
  78.     {
  79.         if ('name' === $defaultStrategy) {
  80.             $defaultStrategy = [FileExtensionEscapingStrategy::class, 'guess'];
  81.         }
  82.         $this->defaultStrategy $defaultStrategy;
  83.     }
  84.     /**
  85.      * Gets the default strategy to use when not defined by the user.
  86.      *
  87.      * @param string $name The template name
  88.      *
  89.      * @return string|false The default strategy to use for the template
  90.      */
  91.     public function getDefaultStrategy(string $name)
  92.     {
  93.         // disable string callables to avoid calling a function named html or js,
  94.         // or any other upcoming escaping strategy
  95.         if (!\is_string($this->defaultStrategy) && false !== $this->defaultStrategy) {
  96.             return \call_user_func($this->defaultStrategy$name);
  97.         }
  98.         return $this->defaultStrategy;
  99.     }
  100.     /**
  101.      * Defines a new escaper to be used via the escape filter.
  102.      *
  103.      * @param string                                $strategy The strategy name that should be used as a strategy in the escape call
  104.      * @param callable(Environment, string, string) $callable A valid PHP callable
  105.      *
  106.      * @deprecated since Twig 3.10
  107.      */
  108.     public function setEscaper($strategy, callable $callable)
  109.     {
  110.         trigger_deprecation('twig/twig''3.10''The "%s()" method is deprecated, use the "Twig\Runtime\EscaperRuntime::setEscaper()" method instead (be warned that Environment is not passed anymore to the callable).'__METHOD__);
  111.         if (!isset($this->environment)) {
  112.             throw new \LogicException(sprintf('You must call "setEnvironment()" before calling "%s()".'__METHOD__));
  113.         }
  114.         $this->escapers[$strategy] = $callable;
  115.         $callable = function ($string$charset) use ($callable) {
  116.             return $callable($this->environment$string$charset);
  117.         };
  118.         $this->escaper->setEscaper($strategy$callable);
  119.     }
  120.     /**
  121.      * Gets all defined escapers.
  122.      *
  123.      * @return array<callable(Environment, string, string)> An array of escapers
  124.      *
  125.      * @deprecated since Twig 3.10
  126.      */
  127.     public function getEscapers()
  128.     {
  129.         trigger_deprecation('twig/twig''3.10''The "%s()" method is deprecated, use the "Twig\Runtime\EscaperRuntime::getEscaper()" method instead.'__METHOD__);
  130.         return $this->escapers;
  131.     }
  132.     /**
  133.      * @deprecated since Twig 3.10
  134.      */
  135.     public function setSafeClasses(array $safeClasses = [])
  136.     {
  137.         trigger_deprecation('twig/twig''3.10''The "%s()" method is deprecated, use the "Twig\Runtime\EscaperRuntime::setSafeClasses()" method instead.'__METHOD__);
  138.         if (!isset($this->escaper)) {
  139.             throw new \LogicException(sprintf('You must call "setEnvironment()" before calling "%s()".'__METHOD__));
  140.         }
  141.         $this->escaper->setSafeClasses($safeClasses);
  142.     }
  143.     /**
  144.      * @deprecated since Twig 3.10
  145.      */
  146.     public function addSafeClass(string $class, array $strategies)
  147.     {
  148.         trigger_deprecation('twig/twig''3.10''The "%s()" method is deprecated, use the "Twig\Runtime\EscaperRuntime::addSafeClass()" method instead.'__METHOD__);
  149.         if (!isset($this->escaper)) {
  150.             throw new \LogicException(sprintf('You must call "setEnvironment()" before calling "%s()".'__METHOD__));
  151.         }
  152.         $this->escaper->addSafeClass($class$strategies);
  153.     }
  154.     /**
  155.      * Marks a variable as being safe.
  156.      *
  157.      * @param string $string A PHP variable
  158.      *
  159.      * @internal
  160.      */
  161.     public static function raw($string)
  162.     {
  163.         return $string;
  164.     }
  165.     /**
  166.      * @internal
  167.      */
  168.     public static function escapeFilterIsSafe(Node $filterArgs)
  169.     {
  170.         foreach ($filterArgs as $arg) {
  171.             if ($arg instanceof ConstantExpression) {
  172.                 return [$arg->getAttribute('value')];
  173.             }
  174.             return [];
  175.         }
  176.         return ['html'];
  177.     }
  178. }