annotate core/modules/big_pipe/src/Controller/BigPipeController.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\big_pipe\Controller;
Chris@0 4
Chris@0 5 use Drupal\big_pipe\Render\Placeholder\BigPipeStrategy;
Chris@0 6 use Drupal\Core\Cache\CacheableMetadata;
Chris@0 7 use Drupal\Core\Routing\LocalRedirectResponse;
Chris@0 8 use Symfony\Component\HttpFoundation\Cookie;
Chris@0 9 use Symfony\Component\HttpFoundation\Request;
Chris@0 10 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
Chris@0 11 use Symfony\Component\HttpKernel\Exception\HttpException;
Chris@0 12
Chris@0 13 /**
Chris@0 14 * Returns responses for BigPipe module routes.
Chris@0 15 */
Chris@0 16 class BigPipeController {
Chris@0 17
Chris@0 18 /**
Chris@0 19 * Sets a BigPipe no-JS cookie, redirects back to the original location.
Chris@0 20 *
Chris@0 21 * @param \Symfony\Component\HttpFoundation\Request $request
Chris@0 22 * The current request.
Chris@0 23 *
Chris@0 24 * @return \Drupal\Core\Routing\LocalRedirectResponse
Chris@0 25 * A response that sets the no-JS cookie and redirects back to the original
Chris@0 26 * location.
Chris@0 27 *
Chris@0 28 * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
Chris@0 29 * Thrown when the no-JS cookie is already set or when there is no session.
Chris@0 30 * @throws \Symfony\Component\HttpKernel\Exception\HttpException
Chris@0 31 * Thrown when the original location is missing, i.e. when no 'destination'
Chris@0 32 * query argument is set.
Chris@0 33 *
Chris@0 34 * @see \Drupal\big_pipe\Render\Placeholder\BigPipeStrategy
Chris@0 35 */
Chris@0 36 public function setNoJsCookie(Request $request) {
Chris@0 37 // This controller may only be accessed when the browser does not support
Chris@0 38 // JavaScript. It is accessed automatically when that's the case thanks to
Chris@0 39 // big_pipe_page_attachments(). When this controller is executed, deny
Chris@0 40 // access when either:
Chris@0 41 // - the no-JS cookie is already set: this indicates a redirect loop, since
Chris@0 42 // the cookie was already set, yet the user is executing this controller;
Chris@0 43 // - there is no session, in which case BigPipe is not enabled anyway, so it
Chris@0 44 // is pointless to set this cookie.
Chris@18 45 if ($request->cookies->has(BigPipeStrategy::NOJS_COOKIE) || !$request->hasSession()) {
Chris@0 46 throw new AccessDeniedHttpException();
Chris@0 47 }
Chris@0 48
Chris@0 49 if (!$request->query->has('destination')) {
Chris@0 50 throw new HttpException(400, 'The original location is missing.');
Chris@0 51 }
Chris@0 52
Chris@0 53 $response = new LocalRedirectResponse($request->query->get('destination'));
Chris@0 54 // Set cookie without httpOnly, so that JavaScript can delete it.
Chris@18 55 $response->headers->setCookie(new Cookie(BigPipeStrategy::NOJS_COOKIE, TRUE, 0, '/', NULL, FALSE, FALSE, FALSE, NULL));
Chris@0 56 $response->addCacheableDependency((new CacheableMetadata())->addCacheContexts(['cookies:' . BigPipeStrategy::NOJS_COOKIE, 'session.exists']));
Chris@0 57 return $response;
Chris@0 58 }
Chris@0 59
Chris@0 60 }