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

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