Version 1
[yaffs-website] / web / core / lib / Drupal / Core / Render / MetadataBubblingUrlGenerator.php
1 <?php
2
3 namespace Drupal\Core\Render;
4
5 use Drupal\Core\GeneratedUrl;
6 use Drupal\Core\Routing\UrlGeneratorInterface;
7 use Symfony\Component\Routing\RequestContext as SymfonyRequestContext;
8
9 /**
10  * Decorator for the URL generator, which bubbles bubbleable URL metadata.
11  *
12  * Implements a decorator for the URL generator that allows to automatically
13  * collect and bubble up bubbleable metadata associated with URLs due to
14  * outbound path and route processing. This approach helps keeping the render
15  * and the routing subsystems decoupled.
16  *
17  * @see \Drupal\Core\RouteProcessor\OutboundRouteProcessorInterface
18  * @see \Drupal\Core\PathProcessor\OutboundPathProcessorInterface
19  * @see \Drupal\Core\Render\BubbleableMetadata
20  */
21 class MetadataBubblingUrlGenerator implements UrlGeneratorInterface {
22
23   /**
24    * The non-bubbling URL generator.
25    *
26    * @var \Drupal\Core\Routing\UrlGeneratorInterface
27    */
28   protected $urlGenerator;
29
30   /**
31    * The renderer.
32    *
33    * @var \Drupal\Core\Render\RendererInterface
34    */
35   protected $renderer;
36
37   /**
38    * Constructs a new bubbling URL generator service.
39    *
40    * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
41    *   The non-bubbling URL generator.
42    * @param \Drupal\Core\Render\RendererInterface $renderer
43    *   The renderer.
44    */
45   public function __construct(UrlGeneratorInterface $url_generator, RendererInterface $renderer) {
46     $this->urlGenerator = $url_generator;
47     $this->renderer = $renderer;
48   }
49
50   /**
51    * {@inheritdoc}
52    */
53   public function setContext(SymfonyRequestContext $context) {
54     $this->urlGenerator->setContext($context);
55   }
56
57   /**
58    * {@inheritdoc}
59    */
60   public function getContext() {
61     return $this->urlGenerator->getContext();
62   }
63
64   /**
65    * {@inheritdoc}
66    */
67   public function getPathFromRoute($name, $parameters = []) {
68     return $this->urlGenerator->getPathFromRoute($name, $parameters);
69   }
70
71   /**
72    * Bubbles the bubbleable metadata to the current render context.
73    *
74    * @param \Drupal\Core\GeneratedUrl $generated_url
75    *   The generated URL whose bubbleable metadata to bubble.
76    * @param array $options
77    *   (optional) The URL options. Defaults to none.
78    */
79   protected function bubble(GeneratedUrl $generated_url, array $options = []) {
80     // Bubbling metadata makes sense only if the code is executed inside a
81     // render context. All code running outside controllers has no render
82     // context by default, so URLs used there are not supposed to affect the
83     // response cacheability.
84     if ($this->renderer->hasRenderContext()) {
85       $build = [];
86       $generated_url->applyTo($build);
87       $this->renderer->render($build);
88     }
89   }
90
91   /**
92    * {@inheritdoc}
93    */
94   public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH) {
95     $options['absolute'] = is_bool($referenceType) ? $referenceType : $referenceType === self::ABSOLUTE_URL;
96     $generated_url = $this->generateFromRoute($name, $parameters, $options, TRUE);
97     $this->bubble($generated_url);
98     return $generated_url->getGeneratedUrl();
99   }
100
101   /**
102    * {@inheritdoc}
103    */
104   public function generateFromRoute($name, $parameters = [], $options = [], $collect_bubbleable_metadata = FALSE) {
105     $generated_url = $this->urlGenerator->generateFromRoute($name, $parameters, $options, TRUE);
106     if (!$collect_bubbleable_metadata) {
107       $this->bubble($generated_url, $options);
108     }
109     return $collect_bubbleable_metadata ? $generated_url : $generated_url->getGeneratedUrl();
110   }
111
112   /**
113    * {@inheritdoc}
114    */
115   public function supports($name) {
116     return $this->urlGenerator->supports($name);
117   }
118
119   /**
120    * {@inheritdoc}
121    */
122   public function getRouteDebugMessage($name, array $parameters = []) {
123     return $this->urlGenerator->getRouteDebugMessage($name, $parameters);
124   }
125
126 }