BigPipeController.php

Same filename in other branches
  1. 9 core/modules/big_pipe/src/Controller/BigPipeController.php
  2. 8.9.x core/modules/big_pipe/src/Controller/BigPipeController.php
  3. 10 core/modules/big_pipe/src/Controller/BigPipeController.php

Namespace

Drupal\big_pipe\Controller

File

core/modules/big_pipe/src/Controller/BigPipeController.php

View source
<?php

namespace Drupal\big_pipe\Controller;

use Drupal\big_pipe\Render\Placeholder\BigPipeStrategy;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Routing\LocalRedirectResponse;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException;

/**
 * Returns responses for BigPipe module routes.
 */
class BigPipeController {
    
    /**
     * Sets a BigPipe no-JS cookie, redirects back to the original location.
     *
     * @param \Symfony\Component\HttpFoundation\Request $request
     *   The current request.
     *
     * @return \Drupal\Core\Routing\LocalRedirectResponse
     *   A response that sets the no-JS cookie and redirects back to the original
     *   location.
     *
     * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
     *   Thrown when the no-JS cookie is already set or when there is no session.
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
     *   Thrown when the original location is missing, i.e. when no 'destination'
     *   query argument is set.
     *
     * @see \Drupal\big_pipe\Render\Placeholder\BigPipeStrategy
     */
    public function setNoJsCookie(Request $request) {
        // This controller may only be accessed when the browser does not support
        // JavaScript. It is accessed automatically when that's the case thanks to
        // big_pipe_page_attachments(). When this controller is executed, deny
        // access when either:
        // - the no-JS cookie is already set: this indicates a redirect loop, since
        //   the cookie was already set, yet the user is executing this controller;
        // - there is no session, in which case BigPipe is not enabled anyway, so it
        //   is pointless to set this cookie.
        if ($request->cookies
            ->has(BigPipeStrategy::NOJS_COOKIE)) {
            throw new AccessDeniedHttpException();
        }
        if (!$request->query
            ->has('destination')) {
            throw new HttpException(400, 'The original location is missing.');
        }
        $response = new LocalRedirectResponse($request->query
            ->get('destination'));
        // Set cookie without httpOnly, so that JavaScript can delete it.
        $response->headers
            ->setCookie(new Cookie(BigPipeStrategy::NOJS_COOKIE, TRUE, 0, '/', NULL, FALSE, FALSE, FALSE, NULL));
        $response->addCacheableDependency((new CacheableMetadata())->addCacheContexts([
            'cookies:' . BigPipeStrategy::NOJS_COOKIE,
            'session.exists',
        ]));
        return $response;
    }

}

Classes

Title Deprecated Summary
BigPipeController Returns responses for BigPipe module routes.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.