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

liip / LiipImagineBundle / 22193657053

19 Feb 2026 05:58PM UTC coverage: 80.526% (+0.4%) from 80.126%
22193657053

Pull #1651

github

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

149 of 167 new or added lines in 7 files covered. (89.22%)

17 existing lines in 4 files now uncovered.

2295 of 2850 relevant lines covered (80.53%)

94.87 hits per line

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

87.84
/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
        $alternativeFormats = [],
57
        array $webpOptions = [],
58
        ?LoggerInterface $logger = null
59
    ) {
60
        $this->dataManager = $dataManager;
264✔
61
        $this->filterManager = $filterManager;
264✔
62
        $this->cacheManager = $cacheManager;
264✔
63
        $this->logger = $logger ?: new NullLogger();
264✔
64

65
        if (\is_bool($alternativeFormats)) {
264✔
66
            @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);
264✔
67
            $this->alternativeFormats = ['webp' => array_merge(['generate' => $alternativeFormats], $webpOptions)];
264✔
68
        } else {
NEW
69
            $this->alternativeFormats = $alternativeFormats;
×
70
        }
71
    }
72

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

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

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

91
        return $busted;
22✔
92
    }
93

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

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

113
        return $warmedUp;
88✔
114
    }
115

116
    /**
117
     * @param string      $path
118
     * @param string      $filter
119
     * @param string|null $resolver
120
     * @param bool        $webpSupported
121
     *
122
     * @return string
123
     */
124
    public function getUrlOfFilteredImage($path, $filter, $resolver = null, $webpSupported = false, array $alternativeFormatsSupported = [])
125
    {
126
        if (true === $webpSupported && !\in_array('webp', $alternativeFormatsSupported, true)) {
66✔
NEW
127
            @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
128
            $alternativeFormatsSupported[] = 'webp';
×
129
        }
130

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

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

138
    /**
139
     * @param string      $path
140
     * @param string      $filter
141
     * @param string|null $resolver
142
     * @param bool        $webpSupported
143
     *
144
     * @return string
145
     */
146
    public function getUrlOfFilteredImageWithRuntimeFilters(
147
        $path,
148
        $filter,
149
        array $runtimeFilters = [],
150
        $resolver = null,
151
        $webpSupported = false,
152
        array $alternativeFormatsSupported = []
153
    ) {
154
        if (false !== $webpSupported) {
66✔
NEW
155
            @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
156
            if (!\in_array('webp', $alternativeFormatsSupported, true)) {
×
NEW
157
                $alternativeFormatsSupported[] = 'webp';
×
158
            }
159
        }
160

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

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

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

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

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

196
        return $filterPathContainers;
264✔
197
    }
198

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

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

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

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

236
            return true;
110✔
237
        }
238

239
        return false;
66✔
240
    }
241

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

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

259
            throw $e;
66✔
260
        }
261
    }
262
}
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