• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

liip / LiipImagineBundle / 22198012024

19 Feb 2026 08:04PM UTC coverage: 81.034% (+0.9%) from 80.126%
22198012024

Pull #1651

github

web-flow
Merge 5909f3aa5 into 69d2df3c6
Pull Request #1651: Deprecate `webp` configuration in favor of `alternative_formats` and …

221 of 238 new or added lines in 8 files covered. (92.86%)

16 existing lines in 3 files now uncovered.

2367 of 2921 relevant lines covered (81.03%)

98.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.19
/Service/FilterService.php
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 array
46
     */
47
    private $alternativeFormats;
48

49
    /**
50
     * @param array|bool $alternativeFormats (previously webpGenerate)
51
     */
52
    public function __construct(
53
        DataManager $dataManager,
54
        FilterManager $filterManager,
55
        CacheManager $cacheManager,
56
                bool $webpGenerate = false,
57
        array $webpOptions = [],
58
        ?LoggerInterface $logger = null,
59
                $alternativeFormats = [],
60
    ) {
61
        $this->dataManager = $dataManager;
264✔
62
        $this->filterManager = $filterManager;
264✔
63
        $this->cacheManager = $cacheManager;
264✔
64
        $this->logger = $logger ?: new NullLogger();
264✔
65

66
        if ($webpGenerate!==false) {
264✔
67
            @trigger_error('Passing a boolean as the 4th argument to '.__METHOD__.' is deprecated since 2.12 and will be removed in 3.0. Pass an array of alternative formats instead.', E_USER_DEPRECATED);
143✔
68
            $this->alternativeFormats = ['webp' => array_merge(['generate' => $webpGenerate], $webpOptions)];
143✔
69
        } else {
70
            $this->alternativeFormats = (array) $alternativeFormats;
121✔
71
        }
72
    }
73

74
    /**
75
     * @param string $path
76
     * @param string $filter
77
     *
78
     * @return bool Returns true if we removed at least one cached image
79
     */
80
    public function bustCache($path, $filter)
81
    {
82
        $busted = false;
22✔
83

84
        foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
22✔
85
            if ($this->cacheManager->isStored($filterPathContainer->getTarget(), $filter)) {
22✔
86
                $this->cacheManager->remove($filterPathContainer->getTarget(), $filter);
11✔
87

88
                $busted = true;
11✔
89
            }
90
        }
91

92
        return $busted;
22✔
93
    }
94

95
    /**
96
     * @param bool $forced Force warm up cache
97
     *
98
     * @return bool Returns true if the cache is warmed up
99
     */
100
    public function warmUpCache(
101
        string $path,
102
        string $filter,
103
        ?string $resolver = null,
104
        bool $forced = false
105
    ): bool {
106
        $warmedUp = false;
110✔
107

108
        foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
110✔
109
            if ($this->warmUpCacheFilterPathContainer($filterPathContainer, $filter, $resolver, $forced)) {
110✔
110
                $warmedUp = true;
66✔
111
            }
112
        }
113

114
        return $warmedUp;
88✔
115
    }
116

117
    /**
118
     * @param string      $path
119
     * @param string      $filter
120
     * @param string|null $resolver
121
     * @param bool        $webpSupported
122
     *
123
     * @return string
124
     */
125
    public function getUrlOfFilteredImage($path, $filter, $resolver = null, bool $webpSupported = false, array $alternativeFormatsSupported = [])
126
    {
127
        if (true === $webpSupported && !\in_array('webp', $alternativeFormatsSupported, true)) {
66✔
NEW
128
            @trigger_error('The $webpSupported argument is deprecated since 2.12 and will be removed in 3.0. Use the $alternativeFormatsSupported argument instead.', E_USER_DEPRECATED);
×
NEW
129
            $alternativeFormatsSupported[] = 'webp';
×
130
        }
131

132
        foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
66✔
133
            $this->warmUpCacheFilterPathContainer($filterPathContainer, $filter, $resolver);
66✔
134
        }
135

136
        return $this->resolveFilterPathContainer(new FilterPathContainer($path), $filter, $resolver, $alternativeFormatsSupported);
44✔
137
    }
138

139
    /**
140
     * @param string      $path
141
     * @param string      $filter
142
     * @param string|null $resolver
143
     * @param bool        $webpSupported
144
     *
145
     * @return string
146
     */
147
    public function getUrlOfFilteredImageWithRuntimeFilters(
148
        $path,
149
        $filter,
150
        array $runtimeFilters = [],
151
        $resolver = null,
152
                bool $webpSupported = false,
153
        array $alternativeFormatsSupported = []
154
    ) {
155
        if (false !== $webpSupported) {
66✔
NEW
156
            @trigger_error('The $webpSupported argument is deprecated since 2.12 and will be removed in 3.0. Use the $alternativeFormatsSupported argument instead.', E_USER_DEPRECATED);
×
NEW
157
            if (!\in_array('webp', $alternativeFormatsSupported, true)) {
×
NEW
158
                $alternativeFormatsSupported[] = 'webp';
×
159
            }
160
        }
161

162
        $runtimePath = $this->cacheManager->getRuntimePath($path, $runtimeFilters);
66✔
163
        $runtimeOptions = [
66✔
164
            'filters' => $runtimeFilters,
66✔
165
        ];
66✔
166

167
        foreach ($this->buildFilterPathContainers($path, $runtimePath, $runtimeOptions) as $filterPathContainer) {
66✔
168
            $this->warmUpCacheFilterPathContainer($filterPathContainer, $filter, $resolver);
66✔
169
        }
170

171
        return $this->resolveFilterPathContainer(
44✔
172
            new FilterPathContainer($path, $runtimePath, $runtimeOptions),
44✔
173
            $filter,
44✔
174
            $resolver,
44✔
175
            $alternativeFormatsSupported
44✔
176
        );
44✔
177
    }
178

179
    /**
180
     * @param mixed[] $options
181
     *
182
     * @return FilterPathContainer[]
183
     */
184
    private function buildFilterPathContainers(string $source, string $target = '', array $options = []): array
185
    {
186
        $basePathContainer = new FilterPathContainer($source, $target, $options);
264✔
187
        $filterPathContainers = [$basePathContainer];
264✔
188

189
        foreach ($this->alternativeFormats as $format => $formatOptions) {
264✔
190
            if (isset($formatOptions['generate']) && $formatOptions['generate']) {
143✔
191
                $cleanOptions = $formatOptions;
143✔
192
                unset($cleanOptions['generate']);
143✔
193
                $filterPathContainers[] = $basePathContainer->createAlternative($format, $cleanOptions);
143✔
194
            }
195
        }
196

197
        return $filterPathContainers;
264✔
198
    }
199

200
    private function resolveFilterPathContainer(
201
        FilterPathContainer $filterPathContainer,
202
        string $filter,
203
        ?string $resolver = null,
204
        array $clientSupportedFormats = []
205
    ): string {
206
        foreach ($this->alternativeFormats as $format => $formatOptions) {
88✔
207
            if (isset($formatOptions['generate']) && $formatOptions['generate'] && \in_array($format, $clientSupportedFormats, true)) {
44✔
NEW
208
                $cleanOptions = $formatOptions;
×
NEW
209
                unset($cleanOptions['generate']);
×
210

NEW
211
                return $this->cacheManager->resolve($filterPathContainer->createAlternative($format, $cleanOptions)->getTarget(), $filter, $resolver);
×
212
            }
213
        }
214

215
        return $this->cacheManager->resolve($filterPathContainer->getTarget(), $filter, $resolver);
88✔
216
    }
217

218
    /**
219
     * @param bool $forced Force warm up cache
220
     *
221
     * @return bool Returns true if the cache is warmed up
222
     */
223
    private function warmUpCacheFilterPathContainer(
224
        FilterPathContainer $filterPathContainer,
225
        string $filter,
226
        ?string $resolver = null,
227
        bool $forced = false
228
    ): bool {
229
        if ($forced || !$this->cacheManager->isStored($filterPathContainer->getTarget(), $filter, $resolver)) {
242✔
230
            $this->cacheManager->store(
176✔
231
                $this->createFilteredBinary($filterPathContainer, $filter),
176✔
232
                $filterPathContainer->getTarget(),
176✔
233
                $filter,
176✔
234
                $resolver
176✔
235
            );
176✔
236

237
            return true;
110✔
238
        }
239

240
        return false;
66✔
241
    }
242

243
    /**
244
     * @throws NonExistingFilterException
245
     */
246
    private function createFilteredBinary(FilterPathContainer $filterPathContainer, string $filter): BinaryInterface
247
    {
248
        $binary = $this->dataManager->find($filter, $filterPathContainer->getSource());
176✔
249

250
        try {
251
            return $this->filterManager->applyFilter($binary, $filter, $filterPathContainer->getOptions());
176✔
252
        } catch (NonExistingFilterException $e) {
66✔
253
            $this->logger->debug(\sprintf(
66✔
254
                'Could not locate filter "%s" for path "%s". Message was "%s"',
66✔
255
                $filter,
66✔
256
                $filterPathContainer->getSource(),
66✔
257
                $e->getMessage()
66✔
258
            ));
66✔
259

260
            throw $e;
66✔
261
        }
262
    }
263
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc