WebLinkExtension.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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\HttpFoundation\RequestStack;
  12. use Symfony\Component\WebLink\GenericLinkProvider;
  13. use Symfony\Component\WebLink\Link;
  14. use Twig\Extension\AbstractExtension;
  15. use Twig\TwigFunction;
  16. /**
  17. * Twig extension for the Symfony WebLink component.
  18. *
  19. * @author Kévin Dunglas <dunglas@gmail.com>
  20. */
  21. final class WebLinkExtension extends AbstractExtension
  22. {
  23. private $requestStack;
  24. public function __construct(RequestStack $requestStack)
  25. {
  26. $this->requestStack = $requestStack;
  27. }
  28. /**
  29. * {@inheritdoc}
  30. */
  31. public function getFunctions(): array
  32. {
  33. return [
  34. new TwigFunction('link', [$this, 'link']),
  35. new TwigFunction('preload', [$this, 'preload']),
  36. new TwigFunction('dns_prefetch', [$this, 'dnsPrefetch']),
  37. new TwigFunction('preconnect', [$this, 'preconnect']),
  38. new TwigFunction('prefetch', [$this, 'prefetch']),
  39. new TwigFunction('prerender', [$this, 'prerender']),
  40. ];
  41. }
  42. /**
  43. * Adds a "Link" HTTP header.
  44. *
  45. * @param string $rel The relation type (e.g. "preload", "prefetch", "prerender" or "dns-prefetch")
  46. * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]")
  47. *
  48. * @return string The relation URI
  49. */
  50. public function link(string $uri, string $rel, array $attributes = []): string
  51. {
  52. if (!$request = $this->requestStack->getMasterRequest()) {
  53. return $uri;
  54. }
  55. $link = new Link($rel, $uri);
  56. foreach ($attributes as $key => $value) {
  57. $link = $link->withAttribute($key, $value);
  58. }
  59. $linkProvider = $request->attributes->get('_links', new GenericLinkProvider());
  60. $request->attributes->set('_links', $linkProvider->withLink($link));
  61. return $uri;
  62. }
  63. /**
  64. * Preloads a resource.
  65. *
  66. * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['crossorigin' => 'use-credentials']")
  67. *
  68. * @return string The path of the asset
  69. */
  70. public function preload(string $uri, array $attributes = []): string
  71. {
  72. return $this->link($uri, 'preload', $attributes);
  73. }
  74. /**
  75. * Resolves a resource origin as early as possible.
  76. *
  77. * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]")
  78. *
  79. * @return string The path of the asset
  80. */
  81. public function dnsPrefetch(string $uri, array $attributes = []): string
  82. {
  83. return $this->link($uri, 'dns-prefetch', $attributes);
  84. }
  85. /**
  86. * Initiates a early connection to a resource (DNS resolution, TCP handshake, TLS negotiation).
  87. *
  88. * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]")
  89. *
  90. * @return string The path of the asset
  91. */
  92. public function preconnect(string $uri, array $attributes = []): string
  93. {
  94. return $this->link($uri, 'preconnect', $attributes);
  95. }
  96. /**
  97. * Indicates to the client that it should prefetch this resource.
  98. *
  99. * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]")
  100. *
  101. * @return string The path of the asset
  102. */
  103. public function prefetch(string $uri, array $attributes = []): string
  104. {
  105. return $this->link($uri, 'prefetch', $attributes);
  106. }
  107. /**
  108. * Indicates to the client that it should prerender this resource .
  109. *
  110. * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]")
  111. *
  112. * @return string The path of the asset
  113. */
  114. public function prerender(string $uri, array $attributes = []): string
  115. {
  116. return $this->link($uri, 'prerender', $attributes);
  117. }
  118. }