Passed
Push — master ( 89f24e...8c4dad )
by Sylvain
08:05
created

ImageHandler   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Test Coverage

Coverage 84.62%

Importance

Changes 0
Metric Value
eloc 26
c 0
b 0
f 0
dl 0
loc 60
ccs 22
cts 26
cp 0.8462
rs 10
wmc 7

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B handle() 0 39 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ecodev\Felix\Handler;
6
7
use Doctrine\Persistence\ObjectRepository;
8
use Ecodev\Felix\Model\Image;
9
use Ecodev\Felix\Service\ImageResizer;
10
use Laminas\Diactoros\Response;
11
use Psr\Http\Message\ResponseInterface;
12
use Psr\Http\Message\ServerRequestInterface;
13
14
final class ImageHandler extends AbstractHandler
15
{
16
    /**
17
     * @var ObjectRepository
18
     */
19
    private $imageRepository;
20
21
    /**
22
     * @var ImageResizer
23
     */
24
    private $imageResizer;
25
26 2
    public function __construct(ObjectRepository $imageRepository, ImageResizer $imageService)
27
    {
28 2
        $this->imageRepository = $imageRepository;
29 2
        $this->imageResizer = $imageService;
30 2
    }
31
32
    /**
33
     * Serve an image from disk, with optional dynamic resizing
34
     */
35 2
    public function handle(ServerRequestInterface $request): ResponseInterface
36
    {
37 2
        $id = $request->getAttribute('id');
38
39
        /** @var null|Image $image */
40 2
        $image = $this->imageRepository->find($id);
41 2
        if (!$image) {
42
            return $this->createError("Image $id not found in database");
43
        }
44
45 2
        $path = $image->getPath();
46 2
        if (!is_readable($path)) {
47
            return $this->createError("Image for image $id not found on disk, or not readable");
48
        }
49
50 2
        $maxHeight = (int) $request->getAttribute('maxHeight');
51 2
        if ($maxHeight) {
52 2
            $accept = $request->getHeaderLine('accept');
53 2
            $useWebp = mb_strpos($accept, 'image/webp') !== false;
54
55 2
            $path = $this->imageResizer->resize($image, $maxHeight, $useWebp);
56
        }
57
58 2
        $resource = fopen($path, 'rb');
59 2
        if ($resource === false) {
60
            return $this->createError("Cannot open file for image $id on disk");
61
        }
62
63 2
        $size = filesize($path);
64 2
        $type = mime_content_type($path);
65
66
        // Be sure that browser show SVG instead of downloading
67 2
        if ($type === 'image/svg') {
68
            $type = 'image/svg+xml';
69
        }
70
71 2
        $response = new Response($resource, 200, ['content-type' => $type, 'content-length' => $size]);
72
73 2
        return $response;
74
    }
75
}
76