Passed
Push — master ( 97dd58...4109cd )
by Dev
10:22
created

MediaCacheGeneratorService   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 66
dl 0
loc 141
rs 10
c 1
b 0
f 0
wmc 15

9 Methods

Rating   Name   Duplication   Size   Complexity  
A createWebP() 0 8 1
A imgToWebPStatic() 0 13 2
A storeImageInCacheStatic() 0 11 2
A __construct() 0 10 1
A imgToWebP() 0 11 1
A getBinary() 0 9 2
A generateCache() 0 18 2
A createWebPStatic() 0 9 2
A storeImageInCache() 0 11 2
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
            throw new \RuntimeException(sprintf($msg, $path, $filter, $e->getMessage()), 0, $e);
82
        }
83
    }
84
85
    /**
86
     * Todo: test the win to generate liip in multithread.
87
     */
88
    public static function storeImageInCacheStatic($path, $binary, $filter, $cacheManager, $filterManager): void
89
    {
90
        try {
91
            $cacheManager->store(
92
                $filterManager->applyFilter($binary, $filter),
93
                $path,
94
                $filter
95
            );
96
        } catch (\RuntimeException $e) {
97
            $msg = 'Unable to create image for path "%s" and filter "%s". '.'Message was "%s"';
98
            throw new \RuntimeException(sprintf($msg, $path, $filter, $e->getMessage()), 0, $e);
99
        }
100
    }
101
102
    public static function imgToWebPStatic($path, $webPPath, $webPConverterOptions, string $filter): void
103
    {
104
        $webPConverter = new WebPConverter(
105
            $path,
106
            $webPPath,
107
            $webPConverterOptions
108
        );
109
110
        try {
111
            $webPConverter->doConvert();
112
        } catch (\Exception $e) {
113
            $msg = 'Unable to create image for path "%s" and filter "%s". '.'Message was "%s"';
114
            throw new \RuntimeException(sprintf($msg, $path, $filter, $e->getMessage()), 0, $e);
115
        }
116
    }
117
118
    /**
119
     * Use the liip generated filter to generate the webp equivalent.
120
     */
121
    public function imgToWebP(MediaInterface $media, string $filter): void
122
    {
123
        $pathJpg = $this->projectDir.'/public/'.$media->getRelativeDir().'/'.$filter.'/'.$media->getMedia();
124
        $pathWebP = $this->projectDir.'/public/'.$media->getRelativeDir().'/'.$filter.'/'.$media->getSlug().'.webp';
125
        $webPConverterOptions = self::$webPConverterOptions;
126
127
        $this->pool->add(function () use ($pathJpg, $pathWebP, $webPConverterOptions, $filter) {
128
            // took 46s (vs 43s) to add liip generation in async
129
            //exec($projectDir.'/bin/console liip:imagine:cache:resolve "'.$path.'" --force --filter='.$filter
130
            //.' >/dev/null 2>&1 &');
131
            self::imgToWebPStatic($pathJpg, $pathWebP, $webPConverterOptions, $filter);
132
        });
133
    }
134
135
    public function createWebP(MediaInterface $media): void
136
    {
137
        $destination = $this->projectDir.'/'.$media->getRelativeDir().'/'.$media->getSlug().'.webp';
138
        $source = $this->projectDir.$media->getPath();
139
        //self::createWebPStatic($destination, $source);
140
141
        $this->pool->add(function () use ($destination, $source) {
142
            self::createWebPStatic($destination, $source);
143
        });
144
    }
145
146
    public static function createWebPStatic($destination, $source): void
147
    {
148
        $webPConverter = new WebPConverter($source, $destination, self::$webPConverterOptions);
149
150
        try {
151
            $webPConverter->doConvert();
152
        } catch (\Exception $e) {
153
            $msg = 'Unable to create image for path "%s" and filter "%s". '.'Message was "%s"';
154
            throw new \RuntimeException(sprintf($msg, $source, 'importing from img', $e->getMessage()), 0, $e);
155
        }
156
    }
157
}
158