RoutingExtension.php 3.5 KB

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