Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / modules / big_pipe / src / Render / BigPipeResponse.php
1 <?php
2
3 namespace Drupal\big_pipe\Render;
4
5 use Drupal\Core\Render\HtmlResponse;
6
7 /**
8  * A response that is sent in chunks by the BigPipe service.
9  *
10  * Note we cannot use \Symfony\Component\HttpFoundation\StreamedResponse because
11  * it makes the content inaccessible (hidden behind a callback), which means no
12  * middlewares are able to modify the content anymore.
13  *
14  * @see \Drupal\big_pipe\Render\BigPipe
15  *
16  * @internal
17  *   This is a temporary solution until a generic response emitter interface is
18  *   created in https://www.drupal.org/node/2577631. Only code internal to
19  *   BigPipe should instantiate or type hint to this class.
20  */
21 class BigPipeResponse extends HtmlResponse {
22
23   /**
24    * The BigPipe service.
25    *
26    * @var \Drupal\big_pipe\Render\BigPipe
27    */
28   protected $bigPipe;
29
30   /**
31    * The original HTML response.
32    *
33    * Still contains placeholders. Its cacheability metadata and attachments are
34    * for everything except the placeholders (since those are not yet rendered).
35    *
36    * @see \Drupal\Core\Render\StreamedResponseInterface
37    * @see ::getStreamedResponse()
38    *
39    * @var \Drupal\Core\Render\HtmlResponse
40    */
41   protected $originalHtmlResponse;
42
43   /**
44    * Constructs a new BigPipeResponse.
45    *
46    * @param \Drupal\Core\Render\HtmlResponse $response
47    *   The original HTML response.
48    */
49   public function __construct(HtmlResponse $response) {
50     parent::__construct('', $response->getStatusCode(), []);
51
52     $this->originalHtmlResponse = $response;
53
54     $this->populateBasedOnOriginalHtmlResponse();
55   }
56
57   /**
58    * Returns the original HTML response.
59    *
60    * @return \Drupal\Core\Render\HtmlResponse
61    *   The original HTML response.
62    */
63   public function getOriginalHtmlResponse() {
64     return $this->originalHtmlResponse;
65   }
66
67   /**
68    * Populates this BigPipeResponse object based on the original HTML response.
69    */
70   protected function populateBasedOnOriginalHtmlResponse() {
71     // Clone the HtmlResponse's data into the new BigPipeResponse.
72     $this->headers = clone $this->originalHtmlResponse->headers;
73     $this
74       ->setStatusCode($this->originalHtmlResponse->getStatusCode())
75       ->setContent($this->originalHtmlResponse->getContent())
76       ->setAttachments($this->originalHtmlResponse->getAttachments())
77       ->addCacheableDependency($this->originalHtmlResponse->getCacheableMetadata());
78
79     // A BigPipe response can never be cached, because it is intended for a
80     // single user.
81     // @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
82     $this->setPrivate();
83
84     // Inform surrogates how they should handle BigPipe responses:
85     // - "no-store" specifies that the response should not be stored in cache;
86     //   it is only to be used for the original request
87     // - "content" identifies what processing surrogates should perform on the
88     //   response before forwarding it. We send, "BigPipe/1.0", which surrogates
89     //   should not process at all, and in fact, they should not even buffer it
90     //   at all.
91     // @see http://www.w3.org/TR/edge-arch/
92     $this->headers->set('Surrogate-Control', 'no-store, content="BigPipe/1.0"');
93
94     // Add header to support streaming on NGINX + php-fpm (nginx >= 1.5.6).
95     $this->headers->set('X-Accel-Buffering', 'no');
96   }
97
98   /**
99    * Sets the BigPipe service to use.
100    *
101    * @param \Drupal\big_pipe\Render\BigPipe $big_pipe
102    *   The BigPipe service.
103    */
104   public function setBigPipeService(BigPipe $big_pipe) {
105     $this->bigPipe = $big_pipe;
106   }
107
108   /**
109    * {@inheritdoc}
110    */
111   public function sendContent() {
112     $this->bigPipe->sendContent($this);
113
114     // All BigPipe placeholders are processed, so update this response's
115     // attachments.
116     unset($this->attachments['big_pipe_placeholders']);
117     unset($this->attachments['big_pipe_nojs_placeholders']);
118
119     return $this;
120   }
121
122 }