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;
}
}
