Completed
Push — master ( faef87...f73ae5 )
by Daniel
13:43
created

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