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

tito10047 / progressive-image-bundle / 20617690786

31 Dec 2025 11:04AM UTC coverage: 91.757% (+0.05%) from 91.703%
20617690786

push

github

tito10047
add `original` breakpoint support: update `LiipImagineSrcsetGenerator`, `Image` component, and tests to handle `original` width and improve `srcset` generation

4 of 4 new or added lines in 2 files covered. (100.0%)

41 existing lines in 3 files now uncovered.

423 of 461 relevant lines covered (91.76%)

129.46 hits per line

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

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

3
namespace Tito10047\ProgressiveImageBundle\DependencyInjection;
4

5
use Symfony\Component\Config\FileLocator;
6
use Symfony\Component\DependencyInjection\ContainerBuilder;
7
use Symfony\Component\DependencyInjection\Extension\Extension;
8
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
9
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
10
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
11
use Symfony\Component\DependencyInjection\Reference;
12
use Symfony\Contracts\Cache\CacheInterface;
13
use Tito10047\ProgressiveImageBundle\Resolver\AssetMapperResolver;
14
use Tito10047\ProgressiveImageBundle\Resolver\FileSystemResolver;
15
use Tito10047\ProgressiveImageBundle\Service\MetadataReader;
16
use Tito10047\ProgressiveImageBundle\Service\PreloadCollector;
17
use Tito10047\ProgressiveImageBundle\Twig\Components\Image;
18
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
19

20
class ProgressiveImageExtension extends Extension implements PrependExtensionInterface {
21

22
    public function getAlias(): string
23
    {
24
        return 'progressive_image';
232✔
25
    }
26

27
        public function prepend(ContainerBuilder $builder): void
28
        {
29
                $builder->prependExtensionConfig('framework', [
232✔
30
                        'asset_mapper' => [
232✔
31
                                'paths' => [
232✔
32
                                        __DIR__.'/../../assets' => 'tito10047/progressive-image-bundle',
232✔
33
                                ],
232✔
34
                        ],
232✔
35
                ]);
232✔
36
                $builder->prependExtensionConfig('twig_component', [
232✔
37
                        'defaults' => [
232✔
38
                                'Tito10047\ProgressiveImageBundle\Twig\Components\\' => [
232✔
39
                                        'template_directory' => '@ProgressiveImage/components/',
232✔
40
                                        'name_prefix' => 'pgi',
232✔
41
                                ],
232✔
42
                        ],
232✔
43
                ]);
232✔
44

45
                $configs = $builder->getExtensionConfig($this->getAlias());
232✔
46
                $configs = $this->processConfiguration(new Configuration(), $configs);
232✔
47

48
                if (isset($configs['responsive_strategy']['breakpoints'])) {
232✔
UNCOV
49
                        $breakpoints = $configs['responsive_strategy']['breakpoints'];
84✔
UNCOV
50
                        $liipConfigs = $builder->getExtensionConfig('liip_imagine');
84✔
51

UNCOV
52
                        $newFilterSets = [];
84✔
UNCOV
53
                        foreach ($liipConfigs as $liipConfig) {
84✔
UNCOV
54
                                if (isset($liipConfig['filter_sets'])) {
84✔
UNCOV
55
                                        foreach ($liipConfig['filter_sets'] as $setName => $setConfig) {
84✔
UNCOV
56
                                                foreach ($breakpoints as $breakpointName => $width) {
84✔
UNCOV
57
                                                        $newSetName = $setName . '_' . $breakpointName;
84✔
UNCOV
58
                                                        if (isset($newFilterSets[$newSetName])) {
84✔
59
                                                                continue;
×
60
                                                        }
UNCOV
61
                                                        $newSetConfig = $setConfig;
84✔
62

UNCOV
63
                                                        if (isset($newSetConfig['filters']['thumbnail']['size'])) {
84✔
UNCOV
64
                                                                [$origWidth, $origHeight] = $newSetConfig['filters']['thumbnail']['size'];
84✔
UNCOV
65
                                                                if ($origWidth > 0 && $origHeight > 0) {
84✔
UNCOV
66
                                                                        $ratio = $origHeight / $origWidth;
84✔
UNCOV
67
                                                                        $newHeight = (int) round($width * $ratio);
84✔
UNCOV
68
                                                                        $newSetConfig['filters']['thumbnail']['size'] = [$width, $newHeight];
84✔
69
                                                                } else {
70
                                                                        $newSetConfig['filters']['thumbnail']['size'] = [$width, $width];
×
71
                                                                }
72
                                                        }
73

UNCOV
74
                                                        $newFilterSets[$newSetName] = $newSetConfig;
84✔
75
                                                }
76
                                        }
77
                                }
78
                        }
79

UNCOV
80
                        if (!empty($newFilterSets)) {
84✔
UNCOV
81
                                $builder->prependExtensionConfig('liip_imagine', [
84✔
UNCOV
82
                                        'filter_sets' => $newFilterSets,
84✔
UNCOV
83
                                ]);
84✔
84
                        }
85
                }
86
        }
87

88

89

90
        public function load(array $configs, ContainerBuilder $container): void {
91

92
                $configs = $this->processConfiguration(new Configuration(), $configs);
232✔
93

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

98
                $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../../config'));
232✔
99
                $loader->load('services.php');
232✔
100

101
                $this->configureResolvers($configs, $container);
232✔
102

103
                $driver = $configs['driver'] ?? 'gd';
232✔
104
                $analyzerId = match ($driver) {
232✔
105
                        "imagick" => "progressive_image.analyzer.imagick",
×
106
                        "gd" => "progressive_image.analyzer.gd",
232✔
107
                        default => $driver,
×
108
                };
232✔
109

110
                $resolver   = $configs['resolver']??'default';
232✔
111
                $maybeService = 'progressive_image.resolver.' . $resolver;
232✔
112
                if ($container->hasDefinition($maybeService)) {
232✔
113
                        $resolverId = $maybeService;
232✔
114
                }else{
115
                        $resolverId = $resolver;
×
116
                }
117
                $loaderId = $configs['loader']??'progressive_image.filesystem.loader';
232✔
118
                $cacheId = $configs['cache']??CacheInterface::class;
232✔
119

120
                $definition = $container->getDefinition(MetadataReader::class);
232✔
121
                $definition->setArgument('$analyzer', new Reference($analyzerId))
232✔
122
                        ->setArgument('$loader', new Reference($loaderId))
232✔
123
                        ->setArgument('$pathResolver', new Reference($resolverId))
232✔
124
                        ->setArgument('$cache', new Reference($cacheId))
232✔
125
                ;
232✔
126

127
                if (isset($configs['ttl'])) {
232✔
128
                        $definition->setArgument('$ttl', $configs['ttl']);
×
129
                }
130

131
                if (isset($configs['fallback_image'])) {
232✔
132
                        $definition->setArgument('$fallbackPath', $configs['fallback_image']);
15✔
133
                }
134

135
                $responsiveConfig = $configs['responsive_strategy'] ?? [];
232✔
136
                $breakpoints = $responsiveConfig['breakpoints'] ?? [];
232✔
137
                $defaultPreset = [
232✔
138
                        'widths' => $responsiveConfig['fallback_widths'] ?? [],
232✔
139
                        'sizes' => $responsiveConfig['fallback_sizes'] ?? '100vw',
232✔
140
                ];
232✔
141
                $presets = $responsiveConfig['presets'] ?? [];
232✔
142
                $generatorId = $responsiveConfig['generator'] ?? null;
232✔
143

144
                $container->register(Image::class, Image::class)
232✔
145
                        ->setArgument(0, new Reference(MetadataReader::class))
232✔
146
                        ->setArgument(1, array_map(fn($id) => new Reference($id), $configs['path_decorators'] ?? []))
232✔
147
                        ->setArgument(2, new Reference(PreloadCollector::class))
232✔
148
                        ->setArgument(3, $generatorId ? new Reference($generatorId) : null)
232✔
149
                        ->setArgument(4, $breakpoints)
232✔
150
                        ->setArgument(5, $defaultPreset)
232✔
151
                        ->setArgument(6, $presets)
232✔
152
            ->setShared(false)
232✔
153
                        ->addTag('twig.component')
232✔
154
                        ->setPublic(true);
232✔
155

156

157
        }
158

159

160
        private function configureResolvers(array $config, ContainerBuilder $container): void
161
        {
162
                $resolvers = $config['resolvers'] ?? [];
232✔
163
                foreach ($resolvers as $name => $resolverConfig) {
232✔
164
                        $id = 'progressive_image.resolver.' . $name;
116✔
165

166
                        if ('filesystem' === $resolverConfig['type']) {
116✔
167
                                $container->register($id, FileSystemResolver::class)
116✔
168
                                        ->setArgument('$roots', $resolverConfig['roots'] ?? ["%kernel.project_dir%/public"])
116✔
169
                                        ->setArgument('$allowUnresolvable', $resolverConfig['allowUnresolvable'] ?? false);
116✔
170
                        } elseif ('asset_mapper' === $resolverConfig['type']) {
×
171
                                $container->register($id, AssetMapperResolver::class);
×
172
                        }
173
                        // Chain resolver logic can be added here if needed
174
                }
175

176
                if (isset($config['resolver']) && !isset($resolvers[$config['resolver']])) {
232✔
177
                        // If a default resolver type is used but not defined in resolvers array
178
                        if (in_array($config['resolver'], ['filesystem', 'asset_mapper'])) {
×
179
                                // handle basic types if they are used as string directly
180
                        }
181
                }
182

183
                // Register a default alias if possible
184
                if (isset($config['resolver']) && isset($resolvers[$config['resolver']])) {
232✔
185
                        $container->setAlias('progressive_image.resolver.default', 'progressive_image.resolver.' . $config['resolver']);
116✔
186
                } elseif (!empty($resolvers)) {
116✔
187
                        $firstResolver = array_key_first($resolvers);
×
188
                        $container->setAlias('progressive_image.resolver.default', 'progressive_image.resolver.' . $firstResolver);
×
189
                } else {
190
                        // Fallback if no resolvers defined, register a basic one to avoid ServiceNotFoundException
191
                        $container->register('progressive_image.resolver.default', FileSystemResolver::class)
116✔
192
                                ->setArgument('$roots', ['%kernel.project_dir%/public'])
116✔
193
                                ->setArgument('$allowUnresolvable', true);
116✔
194
                }
195
        }
196
}
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

© 2025 Coveralls, Inc