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

tito10047 / progressive-image-bundle / 20675022582

03 Jan 2026 08:51AM UTC coverage: 86.782%. Remained the same
20675022582

push

github

tito10047
update copyright in LICENSE.md

604 of 696 relevant lines covered (86.78%)

175.71 hits per line

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

76.3
/src/DependencyInjection/ProgressiveImageExtension.php
1
<?php
2

3
/*
4
 * This file is part of the Progressive Image Bundle.
5
 *
6
 * (c) Jozef Môstka <https://github.com/tito10047/progressive-image-bundle>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
namespace Tito10047\ProgressiveImageBundle\DependencyInjection;
12

13
use Liip\ImagineBundle\LiipImagineBundle;
14
use Symfony\Component\Config\FileLocator;
15
use Symfony\Component\DependencyInjection\ContainerBuilder;
16
use Symfony\Component\DependencyInjection\Extension\Extension;
17
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
18
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
19
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
20
use Symfony\Component\DependencyInjection\Parameter;
21
use Symfony\Component\DependencyInjection\Reference;
22
use Symfony\Contracts\Cache\TagAwareCacheInterface;
23
use Tito10047\ProgressiveImageBundle\Resolver\AssetMapperResolver;
24
use Tito10047\ProgressiveImageBundle\Resolver\FileSystemResolver;
25
use Tito10047\ProgressiveImageBundle\Service\LiipImagineRuntimeConfigGenerator;
26
use Tito10047\ProgressiveImageBundle\Service\MetadataReader;
27
use Tito10047\ProgressiveImageBundle\Service\PreloadCollector;
28
use Tito10047\ProgressiveImageBundle\Service\ResponsiveAttributeGenerator;
29
use Tito10047\ProgressiveImageBundle\Twig\TransparentCacheExtension;
30
use Tito10047\ProgressiveImageBundle\Event\TransparentImageCacheSubscriber;
31
use Tito10047\ProgressiveImageBundle\Twig\Components\Image;
32
use Tito10047\ProgressiveImageBundle\UrlGenerator\LiipImagineResponsiveImageUrlGenerator;
33
use Tito10047\ProgressiveImageBundle\UrlGenerator\ResponsiveImageUrlGeneratorInterface;
34
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
35

36
final class ProgressiveImageExtension extends Extension implements PrependExtensionInterface {
37

38
    public function getAlias(): string
39
    {
40
        return 'progressive_image';
332✔
41
    }
42

43
        public function prepend(ContainerBuilder $builder): void
44
        {
45
                $builder->prependExtensionConfig('framework', [
332✔
46
                        'asset_mapper' => [
332✔
47
                                'paths' => [
332✔
48
                                        __DIR__.'/../../assets' => 'tito10047/progressive-image-bundle',
332✔
49
                                ],
332✔
50
                        ],
332✔
51
                ]);
332✔
52
                $builder->prependExtensionConfig('twig_component', [
332✔
53
                        'defaults' => [
332✔
54
                                'Tito10047\ProgressiveImageBundle\Twig\Components\\' => [
332✔
55
                                        'template_directory' => '@ProgressiveImage/components/',
332✔
56
                                        'name_prefix' => 'pgi',
332✔
57
                                ],
332✔
58
                        ],
332✔
59
                ]);
332✔
60

61
                $configs = $builder->getExtensionConfig($this->getAlias());
332✔
62
                $configs = $this->processConfiguration(new Configuration(), $configs);
332✔
63

64
                if (isset($configs['responsive_strategy']['breakpoints'])) {
332✔
65
                        $breakpoints = $configs['responsive_strategy']['breakpoints'];
×
66
                        $liipConfigs = $builder->getExtensionConfig('liip_imagine');
×
67

68
                        $newFilterSets = [];
×
69
                        foreach ($liipConfigs as $liipConfig) {
×
70
                                if (isset($liipConfig['filter_sets'])) {
×
71
                                        foreach ($liipConfig['filter_sets'] as $setName => $setConfig) {
×
72
                                                foreach ($breakpoints as $breakpointName => $width) {
×
73
                                                        $newSetName = $setName . '_' . $breakpointName;
×
74
                                                        if (isset($newFilterSets[$newSetName])) {
×
75
                                                                continue;
×
76
                                                        }
77
                                                        $newSetConfig = $setConfig;
×
78

79
                                                        if (isset($newSetConfig['filters']['thumbnail']['size'])) {
×
80
                                                                [$origWidth, $origHeight] = $newSetConfig['filters']['thumbnail']['size'];
×
81
                                                                if ($origWidth > 0 && $origHeight > 0) {
×
82
                                                                        $ratio = $origHeight / $origWidth;
×
83
                                                                        $newHeight = (int) round($width * $ratio);
×
84
                                                                        $newSetConfig['filters']['thumbnail']['size'] = [$width, $newHeight];
×
85
                                                                } else {
86
                                                                        $newSetConfig['filters']['thumbnail']['size'] = [$width, $width];
×
87
                                                                }
88
                                                        }
89

90
                                                        $newFilterSets[$newSetName] = $newSetConfig;
×
91
                                                }
92
                                        }
93
                                }
94
                        }
95

96
                        if (!empty($newFilterSets)) {
×
97
                                $builder->prependExtensionConfig('liip_imagine', [
×
98
                                        'filter_sets' => $newFilterSets,
×
99
                                ]);
×
100
                        }
101
                }
102
        }
103

104

105

106
        public function load(array $configs, ContainerBuilder $container): void {
107

108
                $configs = $this->processConfiguration(new Configuration(), $configs);
332✔
109

110
                if (!isset($container->getParameter('kernel.bundles')['TwigBundle'])) {
332✔
111
                        throw new \LogicException('The TwigBundle is not registered in your application. Try running "composer require symfony/twig-bundle".');
×
112
                }
113

114
                $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../../config'));
332✔
115
                $loader->load('services.php');
332✔
116

117
                $this->configureResolvers($configs, $container);
332✔
118

119
                $driver = $configs['driver'] ?? 'gd';
332✔
120
                $analyzerId = match ($driver) {
332✔
121
                        "imagick" => "progressive_image.analyzer.imagick",
×
122
                        "gd" => "progressive_image.analyzer.gd",
332✔
123
                        default => $driver,
×
124
                };
332✔
125

126
                $resolver   = $configs['resolver']??'default';
332✔
127
                $maybeService = 'progressive_image.resolver.' . $resolver;
332✔
128
                if ($container->hasDefinition($maybeService)) {
332✔
129
                        $resolverId = $maybeService;
332✔
130
                }else{
131
                        $resolverId = $resolver;
×
132
                }
133
                $loaderId = $configs['loader']??'progressive_image.filesystem.loader';
332✔
134
                $cacheId = $configs['cache']??'cache.app';
332✔
135
                $imageCacheServiceId = $configs['image_cache_service'] ?? 'cache.app';
332✔
136
                $imageCacheEnabled = $configs['image_cache_enabled'] ?? false;
332✔
137
                $ttl = $configs['ttl'] ?? null;
332✔
138

139
                if (!$imageCacheEnabled) {
332✔
140
                        $imageCacheServiceReference = null;
15✔
141
                } else {
142
                        $imageCacheServiceReference = new Reference('progressive_image.image_cache_service');
317✔
143
                }
144

145
                $definition = $container->getDefinition(MetadataReader::class);
332✔
146
                $definition->setArgument('$analyzer', new Reference($analyzerId))
332✔
147
                        ->setArgument('$loader', new Reference($loaderId))
332✔
148
                        ->setArgument('$pathResolver', new Reference($resolverId))
332✔
149
                        ->setArgument('$cache', new Reference($cacheId))
332✔
150
            ->setArgument('$ttl', $configs['ttl'] ?? null)
332✔
151
            ->setArgument('$fallbackPath', $configs['fallback_image'] ?? null)
332✔
152
                ;
332✔
153
                $container->setParameter('progressive_image.image_cache_enabled', $imageCacheEnabled);
332✔
154
                $container->setParameter('progressive_image.ttl', $ttl);
332✔
155
                $container->setAlias('progressive_image.image_cache_service', $imageCacheServiceId);
332✔
156

157

158
                $container->register(TransparentCacheExtension::class)
332✔
159
                        ->setArgument('$ttl', new Parameter('progressive_image.ttl'))
332✔
160
                        ->setArgument('$cache', $imageCacheServiceReference)
332✔
161
                        ->addTag('twig.extension')
332✔
162
                ;
332✔
163

164
                $container->register(TransparentImageCacheSubscriber::class)
332✔
165
                        ->setArgument('$enabled', new Parameter('progressive_image.image_cache_enabled'))
332✔
166
                        ->setArgument('$ttl', new Parameter('progressive_image.ttl'))
332✔
167
                        ->setArgument('$cache', $imageCacheServiceReference)
332✔
168
                        ->addTag('kernel.event_subscriber')
332✔
169
                ;
332✔
170

171
                if (class_exists(LiipImagineBundle::class)) {
332✔
172
                        $container->register(LiipImagineResponsiveImageUrlGenerator::class)
322✔
173
                                ->setArgument('$cacheManager', new Reference('liip_imagine.cache.manager'))
322✔
174
                                ->setArgument('$router', new Reference('router'))
322✔
175
                                ->setArgument('$uriSigner', new Reference('uri_signer'))
322✔
176
                                ->setArgument('$runtimeConfigGenerator', new Reference(LiipImagineRuntimeConfigGenerator::class))
322✔
177
                                ->setArgument('$filterConfiguration', new Reference('liip_imagine.filter.configuration'))
322✔
178
                                ->setArgument('$cache', $imageCacheServiceReference)
322✔
179
                                ->setPublic(true);
322✔
180

181
                        $container->setAlias(ResponsiveImageUrlGeneratorInterface::class, LiipImagineResponsiveImageUrlGenerator::class);
322✔
182
                }
183
                $responsiveConfig = $configs['responsive_strategy'] ?? [];
332✔
184
                $generatorId = $responsiveConfig['generator'] ?? null;
332✔
185

186
        if ($generatorId || class_exists(\Liip\ImagineBundle\LiipImagineBundle::class)) {
332✔
187
            $container->register(ResponsiveAttributeGenerator::class, ResponsiveAttributeGenerator::class)
322✔
188
                ->setArgument('$gridConfig', $responsiveConfig['grid'] ?? [])
322✔
189
                ->setArgument('$ratioConfig', $responsiveConfig['ratios'] ?? [])
322✔
190
                ->setArgument('$preloadCollector', new Reference(PreloadCollector::class))
322✔
191
                ->setArgument('$urlGenerator', $generatorId ? new Reference($generatorId) : new Reference(ResponsiveImageUrlGeneratorInterface::class))
322✔
192
            ;
322✔
193
        }
194

195
                $container->register(Image::class, Image::class)
332✔
196
                        ->setArgument('$analyzer', new Reference(MetadataReader::class))
332✔
197
                        ->setArgument('$pathDecorator', array_map(fn($id) => new Reference($id), $configs['path_decorators'] ?? []))
332✔
198
            ->setArgument('$responsiveAttributeGenerator', $generatorId || class_exists(\Liip\ImagineBundle\LiipImagineBundle::class) ? new Reference(ResponsiveAttributeGenerator::class) : null)
332✔
199
                        ->setArgument('$preloadCollector', new Reference(PreloadCollector::class))
332✔
200
            ->setShared(false)
332✔
201
                        ->addTag('twig.component')
332✔
202
                        ->setPublic(true);
332✔
203

204

205
        }
206

207

208
        private function configureResolvers(array $config, ContainerBuilder $container): void
209
        {
210
                $resolvers = $config['resolvers'] ?? [];
332✔
211
                foreach ($resolvers as $name => $resolverConfig) {
332✔
212
                        $id = 'progressive_image.resolver.' . $name;
185✔
213

214
                        if ('filesystem' === $resolverConfig['type']) {
185✔
215
                                $container->register($id, FileSystemResolver::class)
185✔
216
                                        ->setArgument('$roots', $resolverConfig['roots'] ?? ["%kernel.project_dir%/public"])
185✔
217
                                        ->setArgument('$allowUnresolvable', $resolverConfig['allowUnresolvable'] ?? false);
185✔
218
                        } elseif ('asset_mapper' === $resolverConfig['type']) {
×
219
                                $container->register($id, AssetMapperResolver::class);
×
220
                        }
221
                        // Chain resolver logic can be added here if needed
222
                }
223

224
                if (isset($config['resolver']) && !isset($resolvers[$config['resolver']])) {
332✔
225
                        // If a default resolver type is used but not defined in resolvers array
226
                        if (in_array($config['resolver'], ['filesystem', 'asset_mapper'])) {
×
227
                                // handle basic types if they are used as string directly
228
                        }
229
                }
230

231
                // Register a default alias if possible
232
                if (isset($config['resolver']) && isset($resolvers[$config['resolver']])) {
332✔
233
                        $container->setAlias('progressive_image.resolver.default', 'progressive_image.resolver.' . $config['resolver']);
185✔
234
                } elseif (!empty($resolvers)) {
147✔
235
                        $firstResolver = array_key_first($resolvers);
×
236
                        $container->setAlias('progressive_image.resolver.default', 'progressive_image.resolver.' . $firstResolver);
×
237
                } else {
238
                        // Fallback if no resolvers defined, register a basic one to avoid ServiceNotFoundException
239
                        $container->register('progressive_image.resolver.default', FileSystemResolver::class)
147✔
240
                                ->setArgument('$roots', ['%kernel.project_dir%/public'])
147✔
241
                                ->setArgument('$allowUnresolvable', true);
147✔
242
                }
243
        }
244
}
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