Completed
Push — master ( 0be8e1...585ca2 )
by Daniel
59:26 queued 46:02
created

FileDataFactory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 4
dl 0
loc 6
ccs 0
cts 5
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Silverback\ApiComponentBundle\Factory;
6
7
use ApiPlatform\Core\Api\IriConverterInterface;
8
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
9
use Psr\Container\ContainerInterface;
10
use Silverback\ApiComponentBundle\Dto\File\FileData;
11
use Silverback\ApiComponentBundle\Dto\File\ImageMetadata;
12
use Silverback\ApiComponentBundle\Entity\Component\FileInterface;
13
use Silverback\ApiComponentBundle\Imagine\PathResolver;
14
use Silverback\ApiComponentBundle\Validator\ImagineSupportedFilePath;
15
use Symfony\Contracts\Service\ServiceSubscriberInterface;
16
use Symfony\Component\Routing\RouterInterface;
17
18
class FileDataFactory implements ServiceSubscriberInterface
19
{
20
    private $router;
21
    private $iriConverter;
22
    private $container;
23
    private $projectDir;
24
25
    public function __construct(RouterInterface $router, IriConverterInterface $iriConverter, ContainerInterface $container, string $projectDir)
26
    {
27
        $this->router = $router;
28
        $this->iriConverter = $iriConverter;
29
        $this->container = $container;
30
        $this->projectDir = $projectDir;
31
    }
32
33
    public static function getSubscribedServices(): array
34
    {
35
        return [
36
            '?' . PathResolver::class,
37
            '?' . CacheManager::class
38
        ];
39
    }
40
41
    public function create(FileInterface $file): ?FileData
42
    {
43
        if (!($filePath = $file->getFilePath()) || !file_exists($filePath)) {
44
            return null;
45
        }
46
        if ($file->getFileData()) {
47
            return $file->getFileData();
48
        }
49
50
        $publicPath = $this->getPublicPath($file);
51
        $imageData = null;
52
        if ($this->fileIsImage($filePath)) {
53
            $imageData = new ImageMetadata($filePath, $publicPath);
54
        }
55
56
        return new FileData($publicPath, $imageData, $this->getImagineData($file));
57
    }
58
59
    private function fileIsImage($filePath): bool
60
    {
61
        return \exif_imagetype($filePath) || mime_content_type($filePath) === 'image/svg+xml';
62
    }
63
64
    private function getPublicPath(FileInterface $file): string
65
    {
66
        $objectId = $this->iriConverter->getIriFromItem($file);
67
        return $this->router->generate(
68
            'files_upload',
69
            ['field' => 'filePath', 'id' => $objectId]
70
        );
71
    }
72
73
    private function getImagineData(FileInterface $file): ?array
74
    {
75
        $filePath = $file->getFilePath();
76
        if (!class_exists(CacheManager::class) || !ImagineSupportedFilePath::isValidFilePath($filePath)) {
77
            return null;
78
        }
79
        $imagineData = [];
80
        /** @var PathResolver $pathResolver */
81
        $pathResolver = $this->container->get(PathResolver::class);
82
        /** @var CacheManager $cacheManager */
83
        $cacheManager = $this->container->get(CacheManager::class);
84
        foreach ($file::getImagineFilters() as $returnKey => $filter) {
85
            // Strip path root from beginning of string.
86
            // Whatever image roots are set in imagine will be looped and removed from the start of the string
87
            $resolvedPath = $pathResolver->resolve($filePath);
88
            $imagineBrowserPath = $cacheManager->getBrowserPath($resolvedPath, $filter);
89
            $imagineFilePath = ltrim(
90
                parse_url(
91
                    $imagineBrowserPath,
92
                    PHP_URL_PATH
93
                ),
94
                '/'
95
            );
96
            $realPath = sprintf('%s/public/%s', $this->projectDir, $imagineFilePath);
97
            $imagineData[$returnKey] = new ImageMetadata($realPath, $imagineFilePath, $filter);
98
        }
99
        return $imagineData;
100
    }
101
}
102