comparison core/modules/big_pipe/src/EventSubscriber/HtmlResponseBigPipeSubscriber.php @ 0:c75dbcec494b

Initial commit from drush-created site
author Chris Cannam
date Thu, 05 Jul 2018 14:24:15 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:c75dbcec494b
1 <?php
2
3 namespace Drupal\big_pipe\EventSubscriber;
4
5 use Drupal\Core\Render\HtmlResponse;
6 use Drupal\big_pipe\Render\BigPipe;
7 use Drupal\big_pipe\Render\BigPipeResponse;
8 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
9 use Symfony\Component\HttpKernel\KernelEvents;
10 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
11
12 /**
13 * Response subscriber to replace the HtmlResponse with a BigPipeResponse.
14 *
15 * @see \Drupal\big_pipe\Render\BigPipe
16 *
17 * @todo Refactor once https://www.drupal.org/node/2577631 lands.
18 */
19 class HtmlResponseBigPipeSubscriber implements EventSubscriberInterface {
20
21 /**
22 * The BigPipe service.
23 *
24 * @var \Drupal\big_pipe\Render\BigPipe
25 */
26 protected $bigPipe;
27
28 /**
29 * Constructs a HtmlResponseBigPipeSubscriber object.
30 *
31 * @param \Drupal\big_pipe\Render\BigPipe $big_pipe
32 * The BigPipe service.
33 */
34 public function __construct(BigPipe $big_pipe) {
35 $this->bigPipe = $big_pipe;
36 }
37
38 /**
39 * Adds markers to the response necessary for the BigPipe render strategy.
40 *
41 * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
42 * The event to process.
43 */
44 public function onRespondEarly(FilterResponseEvent $event) {
45 $response = $event->getResponse();
46 if (!$response instanceof HtmlResponse) {
47 return;
48 }
49
50 // Wrap the scripts_bottom placeholder with a marker before and after,
51 // because \Drupal\big_pipe\Render\BigPipe needs to be able to extract that
52 // markup if there are no-JS BigPipe placeholders.
53 // @see \Drupal\big_pipe\Render\BigPipe::sendPreBody()
54 $attachments = $response->getAttachments();
55 if (isset($attachments['html_response_attachment_placeholders']['scripts_bottom'])) {
56 $scripts_bottom_placeholder = $attachments['html_response_attachment_placeholders']['scripts_bottom'];
57 $content = $response->getContent();
58 $content = str_replace($scripts_bottom_placeholder, '<drupal-big-pipe-scripts-bottom-marker>' . $scripts_bottom_placeholder . '<drupal-big-pipe-scripts-bottom-marker>', $content);
59 $response->setContent($content);
60 }
61 }
62
63 /**
64 * Transforms a HtmlResponse to a BigPipeResponse.
65 *
66 * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
67 * The event to process.
68 */
69 public function onRespond(FilterResponseEvent $event) {
70 $response = $event->getResponse();
71 if (!$response instanceof HtmlResponse) {
72 return;
73 }
74
75 $attachments = $response->getAttachments();
76
77 // If there are no no-JS BigPipe placeholders, unwrap the scripts_bottom
78 // markup.
79 // @see onRespondEarly()
80 // @see \Drupal\big_pipe\Render\BigPipe::sendPreBody()
81 if (empty($attachments['big_pipe_nojs_placeholders'])) {
82 $content = $response->getContent();
83 $content = str_replace('<drupal-big-pipe-scripts-bottom-marker>', '', $content);
84 $response->setContent($content);
85 }
86
87 // If there are neither BigPipe placeholders nor no-JS BigPipe placeholders,
88 // there isn't anything dynamic in this response, and we can return early:
89 // there is no point in sending this response using BigPipe.
90 if (empty($attachments['big_pipe_placeholders']) && empty($attachments['big_pipe_nojs_placeholders'])) {
91 return;
92 }
93
94 $big_pipe_response = new BigPipeResponse($response);
95 $big_pipe_response->setBigPipeService($this->getBigPipeService($event));
96 $event->setResponse($big_pipe_response);
97 }
98
99 /**
100 * Returns the BigPipe service to use to send the current response.
101 *
102 * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
103 * A response event.
104 *
105 * @return \Drupal\big_pipe\Render\BigPipe
106 * The BigPipe service.
107 */
108 protected function getBigPipeService(FilterResponseEvent $event) {
109 return $this->bigPipe;
110 }
111
112 /**
113 * {@inheritdoc}
114 */
115 public static function getSubscribedEvents() {
116 // Run after HtmlResponsePlaceholderStrategySubscriber (priority 5), i.e.
117 // after BigPipeStrategy has been applied, but before normal (priority 0)
118 // response subscribers have been applied, because by then it'll be too late
119 // to transform it into a BigPipeResponse.
120 $events[KernelEvents::RESPONSE][] = ['onRespondEarly', 3];
121
122 // Run as the last possible subscriber.
123 $events[KernelEvents::RESPONSE][] = ['onRespond', -10000];
124
125 return $events;
126 }
127
128 }