client_hints-8.x-1.0-alpha3/src/Controller/Redirect.php
src/Controller/Redirect.php
<?php namespace Drupal\client_hints\Controller; use Drupal\client_hints\Service\ClientHints; use Drupal\Core\Cache\CacheableRedirectResponse; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Render\RenderContext; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; /** * Redirect controller. */ class Redirect implements ContainerInjectionInterface { /** * The client hints service. * * @var \Drupal\client_hints\Service\ClientHints */ protected $clientHints; /** * Constructs a redirect controller. * * @param \Drupal\client_hints\Service\ClientHints $client_hints * The client hints service. */ public function __construct(ClientHints $client_hints) { $this->clientHints = $client_hints; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static($container->get('client_hints')); } /** * Image URL redirect. */ public function image(Request $request) { // Get request parameters. $image_uri = $request->query->get('file'); $dpr = $request->query->getInt('dpr', 1); $width = $request->query->getInt('width', 0); // Get corresponding image style redirect URL. // Generating the URL for a URI using a stream wrapper ends up calling // StreamWrapperInterface::getExternalUrl(), which in turn can result in // early rendering, for example for the private stream. Therefore, we // generate the URL inside of a fake render context and subsequently add the // "leaked" cacheability metadata to the response. /* @see \Drupal\Core\StreamWrapper\PrivateStream::getExternalUrl() */ $context = new RenderContext(); $image_style_url = \Drupal::service('renderer')->executeInRenderContext($context, function () use ($image_uri, $dpr, $width) { return $this->clientHints->getImageRedirectUrl($image_uri, $dpr, $width); }); $response = new CacheableRedirectResponse($image_style_url); // Add cacheability metadata. $response->getCacheableMetadata()->addCacheContexts(['url.query_args:file', 'url.query_args:dpr', 'url.query_args:width']); if (!$context->isEmpty()) { $response->addCacheableDependency($context->pop()); } return $response; } }