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

liip / LiipImagineBundle / 6108084806

07 Sep 2023 09:41AM UTC coverage: 81.998% (-0.1%) from 82.101%
6108084806

push

github

web-flow
Merge pull request #1528 from liip/phpstan-php8

run phpstan with php8 to run latest versions of dependencies

2241 of 2733 relevant lines covered (82.0%)

103.45 hits per line

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

97.25
/DependencyInjection/Configuration.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 Liip\ImagineBundle\Config\Controller\ControllerConfig;
15
use Liip\ImagineBundle\Controller\ImagineController;
16
use Liip\ImagineBundle\DependencyInjection\Factory\FactoryInterface;
17
use Liip\ImagineBundle\DependencyInjection\Factory\Loader\LoaderFactoryInterface;
18
use Liip\ImagineBundle\DependencyInjection\Factory\Resolver\ResolverFactoryInterface;
19
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
20
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
21
use Symfony\Component\Config\Definition\ConfigurationInterface;
22
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
23

24
class Configuration implements ConfigurationInterface
25
{
26
    /**
27
     * @var ResolverFactoryInterface[]
28
     */
29
    protected $resolversFactories;
30

31
    /**
32
     * @var LoaderFactoryInterface[]
33
     */
34
    protected $loadersFactories;
35

36
    /**
37
     * @param ResolverFactoryInterface[] $resolversFactories
38
     * @param LoaderFactoryInterface[]   $loadersFactories
39
     */
40
    public function __construct(array $resolversFactories, array $loadersFactories)
41
    {
42
        $this->resolversFactories = $resolversFactories;
364✔
43
        $this->loadersFactories = $loadersFactories;
364✔
44
    }
224✔
45

46
    public function getConfigTreeBuilder(): TreeBuilder
47
    {
48
        $treeBuilder = new TreeBuilder('liip_imagine');
351✔
49
        $rootNode = method_exists(TreeBuilder::class, 'getRootNode')
351✔
50
            ? $treeBuilder->getRootNode()
324✔
51
            : $treeBuilder->root('liip_imagine');
216✔
52

53
        $resolversPrototypeNode = $rootNode
135✔
54
            ->children()
351✔
55
                ->arrayNode('resolvers')
351✔
56
                    ->useAttributeAsKey('name')
351✔
57
                    ->prototype('array')
351✔
58
                        ->performNoDeepMerging();
351✔
59
        $this->addResolversSections($resolversPrototypeNode);
351✔
60

61
        $loadersPrototypeNode = $rootNode
135✔
62
            ->children()
351✔
63
                ->arrayNode('loaders')
351✔
64
                    ->useAttributeAsKey('name')
351✔
65
                    ->prototype('array');
351✔
66
        $this->addLoadersSections($loadersPrototypeNode);
351✔
67

68
        $rootNode
135✔
69
            ->beforeNormalization()
351✔
70
                ->ifTrue(function ($v) {
135✔
71
                    return
125✔
72
                        empty($v['loaders'])
325✔
73
                        || empty($v['loaders']['default'])
157✔
74
                        || empty($v['resolvers'])
133✔
75
                        || empty($v['resolvers']['default']);
325✔
76
                })
351✔
77
                ->then(function ($v) {
135✔
78
                    if (empty($v['loaders'])) {
325✔
79
                        $v['loaders'] = [];
273✔
80
                    }
81

82
                    if (false === \is_array($v['loaders'])) {
325✔
83
                        throw new \LogicException('Loaders has to be array');
13✔
84
                    }
85

86
                    if (false === \array_key_exists('default', $v['loaders'])) {
312✔
87
                        $v['loaders']['default'] = ['filesystem' => null];
299✔
88
                    }
89

90
                    if (empty($v['resolvers'])) {
312✔
91
                        $v['resolvers'] = [];
260✔
92
                    }
93

94
                    if (false === \is_array($v['resolvers'])) {
312✔
95
                        throw new \LogicException('Resolvers has to be array');
13✔
96
                    }
97

98
                    if (false === \array_key_exists('default', $v['resolvers'])) {
299✔
99
                        $v['resolvers']['default'] = ['web_path' => null];
286✔
100
                    }
101

102
                    return $v;
299✔
103
                })
351✔
104
            ->end();
351✔
105

106
        $rootNode
135✔
107
            ->fixXmlConfig('filter_set', 'filter_sets')
351✔
108
            ->children()
351✔
109
                ->scalarNode('driver')->defaultValue('gd')
351✔
110
                    ->validate()
351✔
111
                        ->ifTrue(function ($v) {
135✔
112
                            return !\in_array($v, ['gd', 'imagick', 'gmagick', 'vips'], true);
×
113
                        })
351✔
114
                        ->thenInvalid('Invalid imagine driver specified: %s')
351✔
115
                    ->end()
351✔
116
                ->end()
351✔
117
                ->scalarNode('cache')->defaultValue('default')->end()
351✔
118
                ->scalarNode('cache_base_path')->defaultValue('')->end()
351✔
119
                ->scalarNode('data_loader')->defaultValue('default')->end()
351✔
120
                ->scalarNode('default_image')->defaultNull()->end()
351✔
121
                ->arrayNode('default_filter_set_settings')
351✔
122
                    ->addDefaultsIfNotSet()
351✔
123
                    ->children()
351✔
124
                        ->scalarNode('quality')->defaultValue(100)->end()
351✔
125
                        ->scalarNode('jpeg_quality')->defaultNull()->end()
351✔
126
                        ->scalarNode('png_compression_level')->defaultNull()->end()
351✔
127
                        ->scalarNode('png_compression_filter')->defaultNull()->end()
351✔
128
                        ->scalarNode('format')->defaultNull()->end()
351✔
129
                        ->booleanNode('animated')->defaultFalse()->end()
351✔
130
                        ->scalarNode('cache')->defaultNull()->end()
351✔
131
                        ->scalarNode('data_loader')->defaultNull()->end()
351✔
132
                        ->scalarNode('default_image')->defaultNull()->end()
351✔
133
                        ->arrayNode('filters')
351✔
134
                            ->useAttributeAsKey('name')
351✔
135
                            ->prototype('array')
351✔
136
                                ->useAttributeAsKey('name')
351✔
137
                                ->ignoreExtraKeys(false)
351✔
138
                                ->prototype('variable')->end()
351✔
139
                            ->end()
351✔
140
                        ->end()
351✔
141
                        ->arrayNode('post_processors')
351✔
142
                            ->defaultValue([])
351✔
143
                            ->useAttributeAsKey('name')
351✔
144
                            ->prototype('array')
351✔
145
                                ->useAttributeAsKey('name')
351✔
146
                                ->ignoreExtraKeys(false)
351✔
147
                                ->prototype('variable')->end()
351✔
148
                            ->end()
351✔
149
                        ->end()
351✔
150
                    ->end()
351✔
151
                ->end()
351✔
152
                ->arrayNode('controller')
351✔
153
                    ->addDefaultsIfNotSet()
351✔
154
                    ->children()
351✔
155
                        ->scalarNode('filter_action')->defaultValue(sprintf('%s::filterAction', ImagineController::class))->end()
351✔
156
                        ->scalarNode('filter_runtime_action')->defaultValue(sprintf('%s::filterRuntimeAction', ImagineController::class))->end()
351✔
157
                        ->integerNode('redirect_response_code')->defaultValue(302)
351✔
158
                            ->validate()
351✔
159
                                ->ifTrue(function ($redirectResponseCode) {
135✔
160
                                    return !\in_array($redirectResponseCode, ControllerConfig::REDIRECT_RESPONSE_CODES, true);
×
161
                                })
351✔
162
                                ->thenInvalid('Invalid redirect response code "%s" (must be 201, 301, 302, 303, 307, or 308).')
351✔
163
                            ->end()
351✔
164
                        ->end()
351✔
165
                    ->end()
351✔
166
                ->end()
351✔
167
                ->arrayNode('filter_sets')
351✔
168
                    ->useAttributeAsKey('name')
351✔
169
                    ->prototype('array')
351✔
170
                        ->fixXmlConfig('filter', 'filters')
351✔
171
                        ->children()
351✔
172
                            ->scalarNode('quality')->end()
351✔
173
                            ->scalarNode('jpeg_quality')->end()
351✔
174
                            ->scalarNode('png_compression_level')->end()
351✔
175
                            ->scalarNode('png_compression_filter')->end()
351✔
176
                            ->scalarNode('format')->end()
351✔
177
                            ->booleanNode('animated')->end()
351✔
178
                            ->scalarNode('cache')->end()
351✔
179
                            ->scalarNode('data_loader')->end()
351✔
180
                            ->scalarNode('default_image')->end()
351✔
181
                            ->arrayNode('filters')
351✔
182
                                ->useAttributeAsKey('name')
351✔
183
                                ->prototype('array')
351✔
184
                                    ->useAttributeAsKey('name')
351✔
185
                                    ->ignoreExtraKeys(false)
351✔
186
                                    ->prototype('variable')->end()
351✔
187
                                ->end()
351✔
188
                            ->end()
351✔
189
                            ->arrayNode('post_processors')
351✔
190
                                ->defaultValue([])
351✔
191
                                ->useAttributeAsKey('name')
351✔
192
                                ->prototype('array')
351✔
193
                                    ->useAttributeAsKey('name')
351✔
194
                                    ->ignoreExtraKeys(false)
351✔
195
                                    ->prototype('variable')->end()
351✔
196
                                ->end()
351✔
197
                        ->end()
351✔
198
                    ->end()
351✔
199
                ->end()
351✔
200
            ->end()
351✔
201
            ->arrayNode('twig')
351✔
202
                ->addDefaultsIfNotSet()
351✔
203
                ->children()
351✔
204
                    ->enumNode('mode')
351✔
205
                        ->defaultValue('legacy')
351✔
206
                        ->info('Twig mode: none/lazy/legacy (default)')
351✔
207
                        ->values(['none', 'lazy', 'legacy'])
351✔
208
                        ->validate()
351✔
209
                            ->ifTrue(function ($v) {
135✔
210
                                return 'legacy' === $v;
×
211
                            })
351✔
212
                            ->then(function ($v) {
135✔
213
                                @trigger_error('Twig "legacy" mode has been deprecated and will be removed in 3.0. Use "none" or "lazy".', E_USER_DEPRECATED);
×
214

215
                                return $v;
×
216
                            })
351✔
217
                        ->end()
351✔
218
                    ->end()
351✔
219
                    ->scalarNode('assets_version')->defaultNull()->end()
351✔
220
                ->end()
351✔
221
            ->end()
351✔
222
            ->booleanNode('enqueue')
351✔
223
                ->defaultFalse()
351✔
224
                ->info('Enables integration with enqueue if set true. Allows resolve image caches in background by sending messages to MQ.')
351✔
225
            ->end()
351✔
226
            ->arrayNode('messenger')
351✔
227
                ->canBeEnabled()
351✔
228
                ->info('Enables integration with symfony/messenger if set true. Warmup image caches in background by sending messages to MQ.')
351✔
229
            ->end()
351✔
230
            ->booleanNode('templating')
351✔
231
                ->defaultTrue()
351✔
232
                ->info('Enables integration with symfony/templating component')
351✔
233
                ->validate()
351✔
234
                    ->ifTrue()
351✔
235
                    ->then(function ($v) {
135✔
236
                        @trigger_error('Symfony templating integration has been deprecated since LiipImagineBundle 2.2 and will be removed in 3.0. Use Twig and use "false" as "liip_imagine.templating" value instead.', E_USER_DEPRECATED);
13✔
237

238
                        return $v;
13✔
239
                    })
351✔
240
                ->end()
351✔
241
            ->end()
351✔
242
        ->end();
351✔
243

244
        $rootNode
135✔
245
            ->children()
351✔
246
                ->arrayNode('webp')
351✔
247
                    ->addDefaultsIfNotSet()
351✔
248
                    ->children()
351✔
249
                        ->booleanNode('generate')->defaultFalse()->end()
351✔
250
                        ->integerNode('quality')->defaultValue(100)->end()
351✔
251
                        ->scalarNode('cache')->defaultNull()->end()
351✔
252
                        ->scalarNode('data_loader')->defaultNull()->end()
351✔
253
                        ->arrayNode('post_processors')
351✔
254
                            ->defaultValue([])
351✔
255
                            ->useAttributeAsKey('name')
351✔
256
                            ->prototype('array')
351✔
257
                                ->useAttributeAsKey('name')
351✔
258
                                ->ignoreExtraKeys(false)
351✔
259
                                ->prototype('variable')->end()
351✔
260
                            ->end()
351✔
261
                    ->end()
351✔
262
                ->end()
351✔
263
            ->end();
351✔
264

265
        return $treeBuilder;
351✔
266
    }
267

268
    private function addResolversSections(ArrayNodeDefinition $resolversPrototypeNode)
269
    {
270
        $this->addConfigurationSections($this->resolversFactories, $resolversPrototypeNode, 'resolver');
351✔
271
    }
216✔
272

273
    private function addLoadersSections(ArrayNodeDefinition $resolversPrototypeNode)
274
    {
275
        $this->addConfigurationSections($this->loadersFactories, $resolversPrototypeNode, 'loader');
351✔
276
    }
216✔
277

278
    /**
279
     * @param FactoryInterface[] $factories
280
     */
281
    private function addConfigurationSections(array $factories, ArrayNodeDefinition $definition, $type)
282
    {
283
        foreach ($factories as $f) {
351✔
284
            $f->addConfiguration($definition->children()->arrayNode($f->getName()));
325✔
285
        }
286

287
        $definition->end()
351✔
288
            ->validate()
351✔
289
            ->ifTrue(function ($array) use ($type) {
135✔
290
                foreach ($array as $name => $element) {
286✔
291
                    if (!$element) {
286✔
292
                        throw new InvalidConfigurationException(ucfirst($type).' "'.$name.'" must have a factory configured');
×
293
                    }
294
                }
295

296
                return false;
286✔
297
            })
351✔
298
            ->thenInvalid('Each '.$type.' must have a factory configured')
351✔
299
            ->end();
351✔
300
    }
216✔
301
}
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