QrCodeCacheMiddleware.php 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. <?php
  2. declare(strict_types=1);
  3. namespace Shlinkio\Shlink\Core\Middleware;
  4. use Doctrine\Common\Cache\Cache;
  5. use Laminas\Diactoros\Response as DiactResp;
  6. use Psr\Http\Message\ResponseInterface as Response;
  7. use Psr\Http\Message\ServerRequestInterface as Request;
  8. use Psr\Http\Server\MiddlewareInterface;
  9. use Psr\Http\Server\RequestHandlerInterface;
  10. class QrCodeCacheMiddleware implements MiddlewareInterface
  11. {
  12. private Cache $cache;
  13. public function __construct(Cache $cache)
  14. {
  15. $this->cache = $cache;
  16. }
  17. /**
  18. * Process an incoming server request and return a response, optionally delegating
  19. * to the next middleware component to create the response.
  20. *
  21. *
  22. */
  23. public function process(Request $request, RequestHandlerInterface $handler): Response
  24. {
  25. $cacheKey = $request->getUri()->getPath();
  26. // If this QR code is already cached, just return it
  27. if ($this->cache->contains($cacheKey)) {
  28. $qrData = $this->cache->fetch($cacheKey);
  29. $response = new DiactResp();
  30. $response->getBody()->write($qrData['body']);
  31. return $response->withHeader('Content-Type', $qrData['content-type']);
  32. }
  33. // If not, call the next middleware and cache it
  34. /** @var Response $resp */
  35. $resp = $handler->handle($request);
  36. $this->cache->save($cacheKey, [
  37. 'body' => $resp->getBody()->__toString(),
  38. 'content-type' => $resp->getHeaderLine('Content-Type'),
  39. ]);
  40. return $resp;
  41. }
  42. }