MediaCacheGeneratorService::getBinary()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PiedWeb\CMSBundle\Service;
4
5
use Liip\ImagineBundle\Exception\Binary\Loader\NotLoadableException;
6
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
7
use Liip\ImagineBundle\Imagine\Data\DataManager;
8
use Liip\ImagineBundle\Imagine\Filter\FilterManager;
9
use PiedWeb\CMSBundle\Entity\MediaInterface;
10
//use WebPConvert\Convert\Converters\Stack as WebPConverter;
11
use Spatie\Async\Pool;
12
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
13
14
class MediaCacheGeneratorService
15
{
16
    protected $projectDir;
17
    protected $pool;
18
    protected $cacheManager;
19
    protected $filterManager;
20
    protected $dataManager;
21
22
    protected static $webPConverterOptions = [
23
        'converters' => ['cwebp'],
24
        //'try-cwebp'  => false,
25
        //'converters' => ['cwebp', 'gd', 'vips', 'imagick', 'gmagick', 'imagemagick', 'graphicsmagick', 'wpc', 'ewww'],
26
    ];
27
28
    public function __construct(
29
        string $projectDir,
30
        CacheManager $cacheManager,
31
        DataManager $dataManager,
32
        FilterManager $filterManager
33
    ) {
34
        $this->projectDir = $projectDir;
35
        $this->cacheManager = $cacheManager;
36
        $this->dataManager = $dataManager;
37
        $this->filterManager = $filterManager;
38
    }
39
40
    public function generateCache(MediaInterface $media)
41
    {
42
        $this->pool = Pool::create();
43
44
        $this->createWebP($media); // do i need it ?! Yes, if the generation failed, liip will use this one
45
46
        $path = '/'.$media->getRelativeDir().'/'.$media->getMedia();
47
        $binary = $this->getBinary($path);
48
        //$pathWebP = '/'.$media->getRelativeDir().'/'.$media->getSlug().'.webp';
49
50
        $filters = array_keys($this->filterManager->getFilterConfiguration()->all());
51
52
        foreach ($filters as $filter) {
53
            $this->storeImageInCache($path, $binary, $filter);
54
            $this->imgToWebP($media, $filter);
55
            //$this->storeImageInCache($pathWebP, $binary, $filter); liip not optimized...
56
        }
57
        $this->pool->wait();
58
    }
59
60
    public function getBinary($path)
61
    {
62
        try {
63
            $binary = $this->dataManager->find('default', $path);
64
        } catch (NotLoadableException $e) {
65
            throw new NotFoundHttpException('Source image could not be found', $e);
66
        }
67
68
        return $binary;
69
    }
70
71
    public function storeImageInCache($path, $binary, $filter): void
72
    {
73
        try {
74
            $this->cacheManager->store(
75
                $this->filterManager->applyFilter($binary, $filter),
76
                $path,
77
                $filter
78
            );
79
        } catch (\RuntimeException $e) {
80
            $msg = 'Unable to create image for path "%s" and filter "%s". '.'Message was "%s"';
81
82
            throw new \RuntimeException(sprintf($msg, $path, $filter, $e->getMessage()), 0, $e);
83
        }
84
    }
85
86
    /**
87
     * Todo: test the win to generate liip in multithread.
88
     */
89
    public static function storeImageInCacheStatic($path, $binary, $filter, $cacheManager, $filterManager): void
90
    {
91
        try {
92
            $cacheManager->store(
93
                $filterManager->applyFilter($binary, $filter),
94
                $path,
95
                $filter
96
            );
97
        } catch (\RuntimeException $e) {
98
            $msg = 'Unable to create image for path "%s" and filter "%s". '.'Message was "%s"';
99
100
            throw new \RuntimeException(sprintf($msg, $path, $filter, $e->getMessage()), 0, $e);
101
        }
102
    }
103
104
    public static function imgToWebPStatic($path, $webPPath, $webPConverterOptions, string $filter): void
105
    {
106
        $webPConverter = new WebPConverter(
107
            $path,
108
            $webPPath,
109
            $webPConverterOptions
110
        );
111
112
        try {
113
            $webPConverter->doConvert();
114
        } catch (\Exception $e) {
115
            $msg = 'Unable to create image for path "%s" and filter "%s". '.'Message was "%s"';
116
117
            throw new \RuntimeException(sprintf($msg, $path, $filter, $e->getMessage()), 0, $e);
118
        }
119
    }
120
121
    /**
122
     * Use the liip generated filter to generate the webp equivalent.
123
     */
124
    public function imgToWebP(MediaInterface $media, string $filter): void
125
    {
126
        $pathJpg = $this->projectDir.'/public/'.$media->getRelativeDir().'/'.$filter.'/'.$media->getMedia();
127
        $pathWebP = $this->projectDir.'/public/'.$media->getRelativeDir().'/'.$filter.'/'.$media->getSlug().'.webp';
128
        $webPConverterOptions = self::$webPConverterOptions;
129
130
        $this->pool->add(function () use ($pathJpg, $pathWebP, $webPConverterOptions, $filter) {
131
            // took 46s (vs 43s) to add liip generation in async
132
            //exec($projectDir.'/bin/console liip:imagine:cache:resolve "'.$path.'" --force --filter='.$filter
133
            //.' >/dev/null 2>&1 &');
134
            self::imgToWebPStatic($pathJpg, $pathWebP, $webPConverterOptions, $filter);
135
        });
136
    }
137
138
    public function createWebP(MediaInterface $media): void
139
    {
140
        $destination = $this->projectDir.'/'.$media->getRelativeDir().'/'.$media->getSlug().'.webp';
141
        $source = $this->projectDir.$media->getPath();
142
        //self::createWebPStatic($destination, $source);
143
144
        $this->pool->add(function () use ($destination, $source) {
145
            self::createWebPStatic($destination, $source);
146
        });
147
    }
148
149
    public static function createWebPStatic($destination, $source): void
150
    {
151
        $webPConverter = new WebPConverter($source, $destination, self::$webPConverterOptions);
152
153
        try {
154
            $webPConverter->doConvert();
155
        } catch (\Exception $e) {
156
            $msg = 'Unable to create image for path "%s" and filter "%s". '.'Message was "%s"';
157
158
            throw new \RuntimeException(sprintf($msg, $source, 'importing from img', $e->getMessage()), 0, $e);
159
        }
160
    }
161
}
162