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

liip / LiipImagineBundle / 22202859951

19 Feb 2026 10:31PM UTC coverage: 81.146% (+1.0%) from 80.126%
22202859951

Pull #1651

github

web-flow
Merge 0e2f73596 into 69d2df3c6
Pull Request #1651: Add support for alternatiwe image formats like webp and avif

249 of 268 new or added lines in 8 files covered. (92.91%)

3 existing lines in 1 file now uncovered.

2393 of 2949 relevant lines covered (81.15%)

99.86 hits per line

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

82.41
/DependencyInjection/LiipImagineExtension.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\DependencyInjection;
13

14
use Imagine\Vips\Imagine;
15
use Liip\ImagineBundle\DependencyInjection\Factory\Loader\LoaderFactoryInterface;
16
use Liip\ImagineBundle\DependencyInjection\Factory\Resolver\ResolverFactoryInterface;
17
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
18
use Liip\ImagineBundle\Imagine\Data\DataManager;
19
use Liip\ImagineBundle\Imagine\Filter\FilterManager;
20
use Symfony\Component\Config\Definition\ConfigurationInterface;
21
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
22
use Symfony\Component\Config\FileLocator;
23
use Symfony\Component\Config\Loader\LoaderInterface;
24
use Symfony\Component\DependencyInjection\Alias;
25
use Symfony\Component\DependencyInjection\ContainerBuilder;
26
use Symfony\Component\DependencyInjection\Definition;
27
use Symfony\Component\DependencyInjection\Exception\LogicException;
28
use Symfony\Component\DependencyInjection\Extension\Extension;
29
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
30
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
31
use Symfony\Component\DependencyInjection\Reference;
32
use Symfony\Component\Messenger\MessageBusInterface;
33
use Symfony\Component\Mime\MimeTypeGuesserInterface;
34
use Symfony\Component\Mime\MimeTypes;
35

36
class LiipImagineExtension extends Extension implements PrependExtensionInterface
37
{
38
    /**
39
     * @var ResolverFactoryInterface[]
40
     */
41
    private $resolversFactories = [];
42

43
    /**
44
     * @var LoaderFactoryInterface[]
45
     */
46
    private $loadersFactories = [];
47

48
    public function addResolverFactory(ResolverFactoryInterface $resolverFactory)
49
    {
50
        $this->resolversFactories[$resolverFactory->getName()] = $resolverFactory;
132✔
51
    }
52

53
    public function addLoaderFactory(LoaderFactoryInterface $loaderFactory)
54
    {
55
        $this->loadersFactories[$loaderFactory->getName()] = $loaderFactory;
132✔
56
    }
57

58
    public function getConfiguration(array $config, ContainerBuilder $container): ?ConfigurationInterface
59
    {
60
        return new Configuration($this->resolversFactories, $this->loadersFactories);
143✔
61
    }
62

63
    /**
64
     * @see \Symfony\Component\DependencyInjection\Extension.ExtensionInterface::load()
65
     */
66
    public function load(array $configs, ContainerBuilder $container): void
67
    {
68
        $config = $this->processConfiguration(
143✔
69
            $this->getConfiguration($configs, $container),
143✔
70
            $configs
143✔
71
        );
143✔
72

73
        if (interface_exists(MimeTypeGuesserInterface::class)) {
132✔
74
            $mimeTypes = new Definition(MimeTypes::class);
132✔
75
            $mimeTypes->setFactory([MimeTypes::class, 'getDefault']);
132✔
76

77
            $container->setDefinition('liip_imagine.mime_types', $mimeTypes);
132✔
78
        }
79

80
        $container->setParameter('liip_imagine.resolvers', $config['resolvers']);
132✔
81
        $container->setParameter('liip_imagine.loaders', $config['loaders']);
132✔
82

83
        $this->loadResolvers($config['resolvers'], $container);
132✔
84
        $this->loadLoaders($config['loaders'], $container);
132✔
85

86
        $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
132✔
87
        $loader->load('imagine.php');
132✔
88

89
        if ('none' !== $config['twig']['mode']) {
132✔
90
            $this->loadTwig($config['twig'], $loader, $container);
132✔
91
        }
92

93
        $loader->load('commands.php');
132✔
94

95
        if ($this->isConfigEnabled($container, $config['messenger'])) {
132✔
96
            $this->registerMessengerConfiguration($loader);
×
97
        }
98

99
        if ($config['enqueue']) {
132✔
100
            $loader->load('enqueue.php');
×
101
        }
102

103
        if ($config['templating']) {
132✔
104
            $loader->load('templating.php');
121✔
105
        }
106

107
        $driver = $config['driver'];
132✔
108
        if ('vips' === $driver) {
132✔
109
            if (!class_exists(Imagine::class)) {
×
110
                $vipsImagineClass = Imagine::class;
×
111

112
                throw new \RuntimeException("Unable to use 'vips' driver without '{$vipsImagineClass}' class.");
×
113
            }
114

115
            $loader->load('imagine_vips.php');
×
116
        }
117

118
        $container->setParameter('liip_imagine.driver_service', "liip_imagine.{$driver}");
132✔
119

120
        $container
132✔
121
            ->getDefinition('liip_imagine.controller.config')
132✔
122
            ->replaceArgument(0, $config['controller']['redirect_response_code']);
132✔
123

124
        $container->setAlias('liip_imagine', new Alias("liip_imagine.{$driver}"));
132✔
125
        $container->setAlias(CacheManager::class, new Alias('liip_imagine.cache.manager', false));
132✔
126
        $container->setAlias(DataManager::class, new Alias('liip_imagine.data.manager', false));
132✔
127
        $container->setAlias(FilterManager::class, new Alias('liip_imagine.filter.manager', false));
132✔
128

129
        $container->setParameter('liip_imagine.cache.resolver.default', $config['cache']);
132✔
130

131
        $container->setParameter('liip_imagine.default_image', $config['default_image']);
132✔
132

133
        $filterSets = $this->createFilterSets($config['default_filter_set_settings'], $config['filter_sets']);
132✔
134

135
        $container->setParameter('liip_imagine.filter_sets', $filterSets);
132✔
136
        $container->setParameter('liip_imagine.binary.loader.default', $config['data_loader']);
132✔
137

138
        $container->setParameter('liip_imagine.controller.filter_action', $config['controller']['filter_action']);
132✔
139
        $container->setParameter('liip_imagine.controller.filter_runtime_action', $config['controller']['filter_runtime_action']);
132✔
140

141
        if ($container->hasDefinition('liip_imagine.mime_types')) {
132✔
142
            $mimeTypes = $container->getDefinition('liip_imagine.mime_types');
132✔
143
            $container->getDefinition('liip_imagine.binary.mime_type_guesser')
132✔
144
                ->replaceArgument(0, $mimeTypes);
132✔
145

146
            $container->getDefinition('liip_imagine.data.manager')
132✔
147
                ->replaceArgument(1, $mimeTypes);
132✔
148
        }
149

150
        $alternativeFormats = $config['alternative_formats'] ?? [];
132✔
151
        $container->setParameter('liip_imagine.alternative_formats', $alternativeFormats);
132✔
152

153
        $mimeMap = [];
132✔
154
        foreach ($alternativeFormats as $format => $formatConfig) {
132✔
155
            if (!empty($formatConfig['mime_types'])) {
22✔
156
                $mimeMap[$format] = $formatConfig['mime_types'];
22✔
157
            }
158
        }
159
        $container->setParameter('liip_imagine.format_negotiator.mime_map', $mimeMap);
132✔
160

161
        $postProcessorsMap = [];
132✔
162
        foreach ($alternativeFormats as $format => $formatConfig) {
132✔
163
            if (!empty($formatConfig['post_processors'])) {
22✔
NEW
164
                $postProcessorsMap[$format] = $formatConfig['post_processors'];
×
165
            }
166
        }
167
        $container->setParameter('liip_imagine.post_processors.map', $postProcessorsMap);
132✔
168

169
        $formatNegotiatorDefinition = new Definition('Liip\ImagineBundle\Service\FormatNegotiator');
132✔
170
        $formatNegotiatorDefinition->setArguments([
132✔
171
            $container->getParameter('liip_imagine.format_negotiator.mime_map'),
132✔
172
            new Reference('logger', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE),
132✔
173
        ]);
132✔
174
        $container->setDefinition('liip_imagine.format_negotiator', $formatNegotiatorDefinition);
132✔
175

176
        $container->setParameter('liip_imagine.alternative_formats', $alternativeFormats);
132✔
177

178
        $container->getDefinition('liip_imagine.service.filter')
132✔
179
            ->replaceArgument(6, $alternativeFormats);
132✔
180

181
        $this->setWebpCompatibilityParameters($container, $alternativeFormats);
132✔
182
    }
183

184
    private function setWebpCompatibilityParameters(ContainerBuilder $container, array $alternativeFormats): void
185
    {
186
        $webpConfig = $alternativeFormats['webp'] ?? [
132✔
187
            'generate' => false,
132✔
188
            'quality' => 100,
132✔
189
            'cache' => null,
132✔
190
            'data_loader' => null,
132✔
191
            'post_processors' => [],
132✔
192
        ];
193

194
        $container->setParameter('liip_imagine.webp.generate', $webpConfig['generate']);
132✔
195
        $container->setParameter('liip_imagine.webp.quality', $webpConfig['quality']);
132✔
196
        $container->setParameter('liip_imagine.webp.cache', $webpConfig['cache']);
132✔
197
        $container->setParameter('liip_imagine.webp.data_loader', $webpConfig['data_loader']);
132✔
198
        $container->setParameter('liip_imagine.webp.post_processors', $webpConfig['post_processors']);
132✔
199
    }
200

201
    public function prepend(ContainerBuilder $container): void
202
    {
203
        if ($container->hasExtension('twig')) {
×
204
            $container->prependExtensionConfig('twig', ['form_themes' => ['@LiipImagine/Form/form_div_layout.html.twig']]);
×
205
        }
206
    }
207

208
    private function createFilterSets(array $defaultFilterSets, array $filterSets): array
209
    {
210
        return array_map(function (array $filterSet) use ($defaultFilterSets) {
132✔
211
            return array_replace_recursive($defaultFilterSets, $filterSet);
22✔
212
        }, $filterSets);
132✔
213
    }
214

215
    private function loadResolvers(array $config, ContainerBuilder $container)
216
    {
217
        $this->createFactories($this->resolversFactories, $config, $container);
132✔
218
    }
219

220
    private function loadLoaders(array $config, ContainerBuilder $container)
221
    {
222
        $this->createFactories($this->loadersFactories, $config, $container);
132✔
223
    }
224

225
    private function createFactories(array $factories, array $configurations, ContainerBuilder $container)
226
    {
227
        foreach ($configurations as $name => $conf) {
132✔
228
            $factories[key($conf)]->create($container, $name, $conf[key($conf)]);
132✔
229
        }
230
    }
231

232
    private function registerMessengerConfiguration(LoaderInterface $loader): void
233
    {
234
        if (!interface_exists(MessageBusInterface::class)) {
×
235
            throw new LogicException('Messenger support cannot be enabled as the Messenger component is not installed. Try running "composer require symfony/messenger".');
×
236
        }
237

238
        $loader->load('messenger.php');
×
239
    }
240

241
    private function loadTwig(array $config, LoaderInterface $loader, ContainerBuilder $container): void
242
    {
243
        if ('legacy' === $config['mode']) {
132✔
244
            $loader->load('imagine_twig_mode_legacy.php');
132✔
245

246
            return;
132✔
247
        }
248

249
        if ('lazy' === $config['mode']) {
×
250
            $loader->load('imagine_twig_mode_lazy.php');
×
251
            if (\array_key_exists('assets_version', $config) && null !== $config['assets_version']) {
×
252
                $runtime = $container->getDefinition('liip_imagine.templating.filter_runtime');
×
253
                $runtime->setArgument(1, $config['assets_version']);
×
254
            }
255

256
            return;
×
257
        }
258

259
        throw new InvalidConfigurationException('Unexpected twig mode '.$config['mode']);
×
260
    }
261
}
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