Completed
Pull Request — 2.x (#1347)
by Peter
02:04
created

FilterService::warmsUpCacheFilterPathContainer()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.6333
c 0
b 0
f 0
cc 3
nc 2
nop 4
1
<?php
2
3
/*
4
 * This file is part of the `liip/LiipImagineBundle` project.
5
 *
6
 * (c) https://github.com/liip/LiipImagineBundle/graphs/contributors
7
 *
8
 * For the full copyright and license information, please view the LICENSE.md
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Liip\ImagineBundle\Service;
13
14
use Liip\ImagineBundle\Binary\BinaryInterface;
15
use Liip\ImagineBundle\Exception\Imagine\Filter\NonExistingFilterException;
16
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
17
use Liip\ImagineBundle\Imagine\Data\DataManager;
18
use Liip\ImagineBundle\Imagine\Filter\FilterManager;
19
use Psr\Log\LoggerInterface;
20
use Psr\Log\NullLogger;
21
22
class FilterService
23
{
24
    /**
25
     * @var DataManager
26
     */
27
    private $dataManager;
28
29
    /**
30
     * @var FilterManager
31
     */
32
    private $filterManager;
33
34
    /**
35
     * @var CacheManager
36
     */
37
    private $cacheManager;
38
39
    /**
40
     * @var LoggerInterface
41
     */
42
    private $logger;
43
44
    /**
45
     * @var bool
46
     */
47
    private $webpGenerate;
48
49
    /**
50
     * @var mixed[]
51
     */
52
    private $webpOptions;
53
54
    public function __construct(
55
        DataManager $dataManager,
56
        FilterManager $filterManager,
57
        CacheManager $cacheManager,
58
        bool $webpGenerate,
59
        array $webpOptions,
60
        ?LoggerInterface $logger = null
61
    ) {
62
        $this->dataManager = $dataManager;
63
        $this->filterManager = $filterManager;
64
        $this->cacheManager = $cacheManager;
65
        $this->webpGenerate = $webpGenerate;
66
        $this->webpOptions = $webpOptions;
67
        $this->logger = $logger ?: new NullLogger();
68
    }
69
70
    /**
71
     * @param string $path
72
     * @param string $filter
73
     *
74
     * @return bool Returns true if the cache is busted
75
     */
76
    public function bustCache($path, $filter)
77
    {
78
        $busted = false;
79
80
        foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
81
            if ($this->cacheManager->isStored($filterPathContainer->getTarget(), $filter)) {
82
                $this->cacheManager->remove($filterPathContainer->getTarget(), $filter);
83
84
                $busted = true;
85
            }
86
        }
87
88
        return $busted;
89
    }
90
91
    /**
92
     * @param bool $forced Force warm up cache
93
     *
94
     * @return bool Returns true if the cache is warmed up
95
     */
96
    public function warmsUpCache(
97
        string $path,
98
        string $filter,
99
        ?string $resolver = null,
100
        bool $forced = false
101
    ): bool {
102
        $warmedUp = false;
103
104
        foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
105
            if ($this->warmsUpCacheFilterPathContainer($filterPathContainer, $filter, $resolver, $forced)) {
106
                $warmedUp = true;
107
            }
108
        }
109
110
        return $warmedUp;
111
    }
112
113
    /**
114
     * @param string      $path
115
     * @param string      $filter
116
     * @param string|null $resolver
117
     *
118
     * @return string
119
     */
120
    public function getUrlOfFilteredImage($path, $filter, $resolver = null, bool $webpSupported = false)
121
    {
122
        foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
123
            $this->warmsUpCacheFilterPathContainer($filterPathContainer, $filter, $resolver);
124
        }
125
126
        return $this->resolveFilterPathContainer(new FilterPathContainer($path), $filter, $resolver, $webpSupported);
127
    }
128
129
    /**
130
     * @param string      $path
131
     * @param string      $filter
132
     * @param string|null $resolver
133
     *
134
     * @return string
135
     */
136
    public function getUrlOfFilteredImageWithRuntimeFilters(
137
        $path,
138
        $filter,
139
        array $runtimeFilters = [],
140
        $resolver = null,
141
        bool $webpSupported = false
142
    ) {
143
        $runtimePath = $this->cacheManager->getRuntimePath($path, $runtimeFilters);
144
        $runtimeOptions = [
145
            'filters' => $runtimeFilters,
146
        ];
147
148
        foreach ($this->buildFilterPathContainers($path, $runtimePath, $runtimeOptions) as $filterPathContainer) {
149
            $this->warmsUpCacheFilterPathContainer($filterPathContainer, $filter, $resolver);
150
        }
151
152
        return $this->resolveFilterPathContainer(
153
            new FilterPathContainer($path, $runtimePath, $runtimeOptions),
154
            $filter,
155
            $resolver,
156
            $webpSupported
157
        );
158
    }
159
160
    /**
161
     * @param mixed[] $options
162
     *
163
     * @return FilterPathContainer[]
164
     */
165
    private function buildFilterPathContainers(string $source, string $target = '', array $options = []): array
166
    {
167
        $basePathContainer = new FilterPathContainer($source, $target, $options);
168
        $filterPathContainers = [$basePathContainer];
169
170
        if ($this->webpGenerate) {
171
            $filterPathContainers[] = $basePathContainer->createWebp($this->webpOptions);
172
        }
173
174
        return $filterPathContainers;
175
    }
176
177
    private function resolveFilterPathContainer(
178
        FilterPathContainer $filterPathContainer,
179
        string $filter,
180
        ?string $resolver = null,
181
        bool $webpSupported = false
182
    ): string {
183
        $path = $filterPathContainer->getTarget();
184
185
        if ($webpSupported) {
186
            $path = $filterPathContainer->createWebp($this->webpOptions)->getTarget();
187
        }
188
189
        return $this->cacheManager->resolve($path, $filter, $resolver);
190
    }
191
192
    /**
193
     * @param bool $forced Force warm up cache
194
     *
195
     * @return bool Returns true if the cache is warmed up
196
     */
197
    private function warmsUpCacheFilterPathContainer(
198
        FilterPathContainer $filterPathContainer,
199
        string $filter,
200
        ?string $resolver = null,
201
        bool $forced = false
202
    ): bool {
203
        if ($forced || !$this->cacheManager->isStored($filterPathContainer->getTarget(), $filter, $resolver)) {
204
            $this->cacheManager->store(
205
                $this->createFilteredBinary($filterPathContainer, $filter),
206
                $filterPathContainer->getTarget(),
207
                $filter,
208
                $resolver
209
            );
210
211
            return true;
212
        }
213
214
        return false;
215
    }
216
217
    /**
218
     * @throws NonExistingFilterException
219
     */
220
    private function createFilteredBinary(FilterPathContainer $filterPathContainer, string $filter): BinaryInterface
221
    {
222
        $binary = $this->dataManager->find($filter, $filterPathContainer->getSource());
223
224
        try {
225
            return $this->filterManager->applyFilter($binary, $filter, $filterPathContainer->getOptions());
226
        } catch (NonExistingFilterException $e) {
227
            $this->logger->debug(sprintf(
228
                'Could not locate filter "%s" for path "%s". Message was "%s"',
229
                $filter,
230
                $filterPathContainer->getSource(),
231
                $e->getMessage()
232
            ));
233
234
            throw $e;
235
        }
236
    }
237
}
238