Skip to content

Instantly share code, notes, and snippets.

@mikemix
Last active September 3, 2022 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikemix/8167cc3da8b19890e638e99325a6d81d to your computer and use it in GitHub Desktop.
Save mikemix/8167cc3da8b19890e638e99325a6d81d to your computer and use it in GitHub Desktop.
<?php
final class IndexAction
{
private const YEAR = 31536000;
public function __construct(
private readonly ChecksumValidatorInterface $checksumValidator,
private readonly SupportedImagesInterface $supportedFormats,
private readonly SizeFactoryInterface $sizeFactory,
private readonly ResizeStrategyFactoryInterface $resizeStrategyFactory,
private readonly ImageSourceFactoryInterface $sourceFactory,
private readonly ThumbnailProcessorInterface $thumbnailProcessor,
private readonly LoggerInterface $logger,
) {}
/**
* @throws Exception
*/
public function __invoke(Request $request): Response
{
/** @var non-empty-string $checksum */
$checksum = $request->attributes->get('checksum');
/** @var non-empty-string $strategyName */
$strategyName = $request->attributes->get('strategy');
/** @var non-empty-string $sizeFormat */
$sizeFormat = $request->attributes->get('size');
/** @var non-empty-string $imageFormat */
$imageFormat = $request->attributes->get('format');
/** @var non-empty-string $imageId */
$imageId = $request->attributes->get('id');
if (false === ($this->checksumValidator)($strategyName, $sizeFormat, $imageId, $imageFormat, $checksum)) {
return new Response('Invalid checksum', Response::HTTP_FORBIDDEN);
}
if (false === $this->supportedFormats->isSupported($imageFormat)) {
return new Response('Unsupported format', Response::HTTP_BAD_REQUEST);
}
try {
$strategy = ($this->resizeStrategyFactory)($strategyName);
$size = ($this->sizeFactory)($sizeFormat);
} catch (ResizeStrategyException|SizeException) {
return new Response('Unsupported size format', Response::HTTP_BAD_REQUEST);
}
$source = ($this->sourceFactory)();
try {
$image = ($source)($imageId, $imageFormat);
} catch (ImageNotFoundException) {
return new Response('No such image', Response::HTTP_NOT_FOUND);
} catch (ImageException) {
return new Response('Invalid image requested', Response::HTTP_BAD_REQUEST);
} catch (Exception $exception) {
$this->logger->error(
'Failed serving the thumbnail from the source',
\array_merge($request->attributes->all(), ['exception' => $exception])
);
return new Response(
'Failed serving the request from the store',
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
try {
$thumbnail = ($this->thumbnailProcessor)($image, $strategy, $size);
} catch (Exception $exception) {
$this->logger->error(
'Failed serving the thumbnail',
\array_merge($request->attributes->all(), ['exception' => $exception])
);
return new Response(
'Failed serving the request',
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
$response = (new Response($thumbnail))
->setPublic()
->setImmutable()
->setMaxAge(self::YEAR);
$response->headers->set(
'Content-Type',
\sprintf('image/%s', $image->getRequestedFormat())
);
$response->headers->set(
'Content-Disposition',
'inline'
);
return $response;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment