Completed
Pull Request — 2.x (#1347)
by Peter
01:54 queued 13s
created

FilterService::warmsUpFilterPathContainer()   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->iterateFilterPathContainers($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 string      $path
93
     * @param string      $filter
94
     * @param string|null $resolver
95
     * @param bool        $forced   Force warm up cache
96
     *
97
     * @return bool Returns true if the cache is warmed up
98
     */
99
    public function warmsUp(
100
        string $path,
101
        string $filter,
102
        ?string $resolver = null,
103
        bool $forced = false
104
    ): bool {
105
        $warmedUp = false;
106
107
        foreach ($this->iterateFilterPathContainers($path) as $filterPathContainer) {
108
            if ($this->warmsUpFilterPathContainer($filterPathContainer, $filter, $resolver, $forced)) {
109
                $warmedUp = true;
110
            }
111
        }
112
113
        return $warmedUp;
114
    }
115
116
    /**
117
     * @param string      $path
118
     * @param string      $filter
119
     * @param string|null $resolver
120
     *
121
     * @return string
122
     */
123
    public function getUrlOfFilteredImage($path, $filter, $resolver = null, bool $webpSupported = false)
124
    {
125
        foreach ($this->iterateFilterPathContainers($path) as $filterPathContainer) {
126
            $this->warmsUpFilterPathContainer($filterPathContainer, $filter, $resolver);
127
        }
128
129
        return $this->resolveFilterPathContainer(new FilterPathContainer($path), $filter, $resolver, $webpSupported);
130
    }
131
132
    /**
133
     * @param string      $path
134
     * @param string      $filter
135
     * @param string|null $resolver
136
     *
137
     * @return string
138
     */
139
    public function getUrlOfFilteredImageWithRuntimeFilters(
140
        $path,
141
        $filter,
142
        array $runtimeFilters = [],
143
        $resolver = null,
144
        bool $webpSupported = false
145
    ) {
146
        $runtimePath = $this->cacheManager->getRuntimePath($path, $runtimeFilters);
147
        $runtimeOptions = [
148
            'filters' => $runtimeFilters,
149
        ];
150
151
        foreach ($this->iterateFilterPathContainers($path, $runtimePath, $runtimeOptions) as $filterPathContainer) {
152
            $this->warmsUpFilterPathContainer($filterPathContainer, $filter, $resolver);
153
        }
154
155
        return $this->resolveFilterPathContainer(
156
            new FilterPathContainer($path, $runtimePath, $runtimeOptions),
157
            $filter,
158
            $resolver,
159
            $webpSupported
160
        );
161
    }
162
163
    /**
164
     * @param string  $source
165
     * @param string  $target
166
     * @param mixed[] $options
167
     *
168
     * @return FilterPathContainer[]
169
     */
170
    private function iterateFilterPathContainers(string $source, string $target = '', array $options = []): array
171
    {
172
        $basePathContainer = new FilterPathContainer($source, $target, $options);
173
        $filterPathContainers = [$basePathContainer];
174
175
        if ($this->webpGenerate) {
176
            $filterPathContainers[] = $basePathContainer->createWebp($this->webpOptions);
177
        }
178
179
        return $filterPathContainers;
180
    }
181
182
    /**
183
     * @param string      $filter
184
     * @param string|null $resolver
185
     * @param bool        $webpSupported
186
     *
187
     * @return string
188
     */
189
    private function resolveFilterPathContainer(
190
        FilterPathContainer $filterPathContainer,
191
        string $filter,
192
        ?string $resolver = null,
193
        bool $webpSupported = false
194
    ): string {
195
        $path = $filterPathContainer->getTarget();
196
197
        if ($webpSupported) {
198
            $path = $filterPathContainer->createWebp($this->webpOptions)->getTarget();
199
        }
200
201
        return $this->cacheManager->resolve($path, $filter, $resolver);
202
    }
203
204
    /**
205
     * @param string      $filter
206
     * @param string|null $resolver
207
     * @param bool        $forced   Force warm up cache
208
     *
209
     * @return bool Returns true if the cache is warmed up
210
     */
211
    public function warmsUpFilterPathContainer(
212
        FilterPathContainer $filterPathContainer,
213
        string $filter,
214
        ?string $resolver = null,
215
        bool $forced = false
216
    ): bool {
217
        if ($forced && !$this->cacheManager->isStored($filterPathContainer->getTarget(), $filter, $resolver)) {
218
            $this->cacheManager->store(
219
                $this->createFilteredBinary($filterPathContainer, $filter),
220
                $filterPathContainer->getTarget(),
221
                $filter,
222
                $resolver
223
            );
224
225
            return true;
226
        }
227
228
        return false;
229
    }
230
231
    /**
232
     * @throws NonExistingFilterException
233
     */
234
    private function createFilteredBinary(FilterPathContainer $filterPathContainer, string $filter): BinaryInterface
235
    {
236
        $binary = $this->dataManager->find($filter, $filterPathContainer->getSource());
237
238
        try {
239
            return $this->filterManager->applyFilter($binary, $filter, $filterPathContainer->getOptions());
240
        } catch (NonExistingFilterException $e) {
241
            $this->logger->debug(sprintf(
242
                'Could not locate filter "%s" for path "%s". Message was "%s"',
243
                $filter,
244
                $filterPathContainer->getSource(),
245
                $e->getMessage()
246
            ));
247
248
            throw $e;
249
        }
250
    }
251
}
252