Passed
Pull Request — master (#516)
by Alejandro
09:29
created

QrCodeAction::getSizeParam()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.072

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
ccs 4
cts 5
cp 0.8
crap 3.072
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Shlinkio\Shlink\Core\Action;
6
7
use Endroid\QrCode\QrCode;
8
use Psr\Http\Message\ResponseInterface as Response;
9
use Psr\Http\Message\ServerRequestInterface as Request;
10
use Psr\Http\Server\MiddlewareInterface;
11
use Psr\Http\Server\RequestHandlerInterface;
12
use Psr\Log\LoggerInterface;
13
use Psr\Log\NullLogger;
14
use Shlinkio\Shlink\Common\Response\QrCodeResponse;
15
use Shlinkio\Shlink\Core\Action\Util\ErrorResponseBuilderTrait;
16
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
17
use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
18
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
19
use Zend\Expressive\Router\Exception\RuntimeException;
20
use Zend\Expressive\Router\RouterInterface;
21
22
class QrCodeAction implements MiddlewareInterface
23
{
24
    use ErrorResponseBuilderTrait;
25
26
    private const DEFAULT_SIZE = 300;
27
    private const MIN_SIZE = 50;
28
    private const MAX_SIZE = 1000;
29
30
    /** @var RouterInterface */
31
    private $router;
32
    /** @var UrlShortenerInterface */
33
    private $urlShortener;
34
    /** @var LoggerInterface */
35
    private $logger;
36
37 3
    public function __construct(
38
        RouterInterface $router,
39
        UrlShortenerInterface $urlShortener,
40
        ?LoggerInterface $logger = null
41
    ) {
42 3
        $this->router = $router;
43 3
        $this->urlShortener = $urlShortener;
44 3
        $this->logger = $logger ?: new NullLogger();
45
    }
46
47
    /**
48
     * Process an incoming server request and return a response, optionally delegating
49
     * to the next middleware component to create the response.
50
     *
51
     * @param Request $request
52
     * @param RequestHandlerInterface $handler
53
     *
54
     * @return Response
55
     * @throws \InvalidArgumentException
56
     * @throws RuntimeException
57
     */
58 3
    public function process(Request $request, RequestHandlerInterface $handler): Response
59
    {
60
        // Make sure the short URL exists for this short code
61 3
        $shortCode = $request->getAttribute('shortCode');
62 3
        $domain = $request->getUri()->getAuthority();
63
64
        try {
65 3
            $this->urlShortener->shortCodeToUrl($shortCode, $domain);
66 2
        } catch (InvalidShortCodeException | EntityDoesNotExistException $e) {
67 2
            $this->logger->warning('An error occurred while creating QR code. {e}', ['e' => $e]);
68 2
            return $this->buildErrorResponse($request, $handler);
69
        }
70
71 1
        $path = $this->router->generateUri('long-url-redirect', ['shortCode' => $shortCode]);
72 1
        $size = $this->getSizeParam($request);
73
74 1
        $qrCode = new QrCode((string) $request->getUri()->withPath($path)->withQuery(''));
75 1
        $qrCode->setSize($size);
76 1
        $qrCode->setMargin(0);
77 1
        return new QrCodeResponse($qrCode);
78
    }
79
80
    /**
81
     * @param Request $request
82
     * @return int
83
     */
84 1
    private function getSizeParam(Request $request): int
85
    {
86 1
        $size = (int) $request->getAttribute('size', self::DEFAULT_SIZE);
87 1
        if ($size < self::MIN_SIZE) {
88
            return self::MIN_SIZE;
89
        }
90
91 1
        return $size > self::MAX_SIZE ? self::MAX_SIZE : $size;
92
    }
93
}
94