vendor/symfony/twig-bridge/Extension/RoutingExtension.php line 48

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  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 Symfony\Bridge\Twig\Extension;
  11. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  12. use Twig\Extension\AbstractExtension;
  13. use Twig\Node\Expression\ArrayExpression;
  14. use Twig\Node\Expression\ConstantExpression;
  15. use Twig\Node\Node;
  16. use Twig\TwigFunction;
  17. /**
  18.  * Provides integration of the Routing component with Twig.
  19.  *
  20.  * @author Fabien Potencier <fabien@symfony.com>
  21.  */
  22. final class RoutingExtension extends AbstractExtension
  23. {
  24.     private UrlGeneratorInterface $generator;
  25.     public function __construct(UrlGeneratorInterface $generator)
  26.     {
  27.         $this->generator $generator;
  28.     }
  29.     /**
  30.      * {@inheritdoc}
  31.      */
  32.     public function getFunctions(): array
  33.     {
  34.         return [
  35.             new TwigFunction('url'$this->getUrl(...), ['is_safe_callback' => $this->isUrlGenerationSafe(...)]),
  36.             new TwigFunction('path'$this->getPath(...), ['is_safe_callback' => $this->isUrlGenerationSafe(...)]),
  37.         ];
  38.     }
  39.     public function getPath(string $name, array $parameters = [], bool $relative false): string
  40.     {
  41.         return $this->generator->generate($name$parameters$relative UrlGeneratorInterface::RELATIVE_PATH UrlGeneratorInterface::ABSOLUTE_PATH);
  42.     }
  43.     public function getUrl(string $name, array $parameters = [], bool $schemeRelative false): string
  44.     {
  45.         return $this->generator->generate($name$parameters$schemeRelative UrlGeneratorInterface::NETWORK_PATH UrlGeneratorInterface::ABSOLUTE_URL);
  46.     }
  47.     /**
  48.      * Determines at compile time whether the generated URL will be safe and thus
  49.      * saving the unneeded automatic escaping for performance reasons.
  50.      *
  51.      * The URL generation process percent encodes non-alphanumeric characters. So there is no risk
  52.      * that malicious/invalid characters are part of the URL. The only character within an URL that
  53.      * must be escaped in html is the ampersand ("&") which separates query params. So we cannot mark
  54.      * the URL generation as always safe, but only when we are sure there won't be multiple query
  55.      * params. This is the case when there are none or only one constant parameter given.
  56.      * E.g. we know beforehand this will be safe:
  57.      * - path('route')
  58.      * - path('route', {'param': 'value'})
  59.      * But the following may not:
  60.      * - path('route', var)
  61.      * - path('route', {'param': ['val1', 'val2'] }) // a sub-array
  62.      * - path('route', {'param1': 'value1', 'param2': 'value2'})
  63.      * If param1 and param2 reference placeholder in the route, it would still be safe. But we don't know.
  64.      *
  65.      * @param Node $argsNode The arguments of the path/url function
  66.      *
  67.      * @return array An array with the contexts the URL is safe
  68.      */
  69.     public function isUrlGenerationSafe(Node $argsNode): array
  70.     {
  71.         // support named arguments
  72.         $paramsNode $argsNode->hasNode('parameters') ? $argsNode->getNode('parameters') : (
  73.             $argsNode->hasNode(1) ? $argsNode->getNode(1) : null
  74.         );
  75.         if (null === $paramsNode || $paramsNode instanceof ArrayExpression && \count($paramsNode) <= &&
  76.             (!$paramsNode->hasNode(1) || $paramsNode->getNode(1) instanceof ConstantExpression)
  77.         ) {
  78.             return ['html'];
  79.         }
  80.         return [];
  81.     }
  82. }