OcubomTwigExtraExtension::loadHttpHeaders()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 2
dl 0
loc 12
ccs 8
cts 8
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of ocubom/twig-extra-bundle
5
 *
6
 * © Oscar Cubo Medina <https://ocubom.github.io>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ocubom\TwigExtraBundle\DependencyInjection;
13
14
use Ocubom\Twig\Extension\HtmlAttributesRuntime;
15
use Ocubom\Twig\Extension\HtmlCompressRuntime;
16
use Ocubom\Twig\Extension\HtmlExtension;
17
use Ocubom\Twig\Extension\Svg\Finder;
18
use Ocubom\Twig\Extension\Svg\FinderInterface;
19
use Ocubom\Twig\Extension\Svg\Library\FontAwesome\Finder as FontAwesomeFinder;
20
use Ocubom\Twig\Extension\Svg\Library\FontAwesomeRuntime;
21
use Ocubom\Twig\Extension\Svg\Loader\ChainLoader;
22
use Ocubom\Twig\Extension\Svg\Loader\LoaderInterface;
23
use Ocubom\Twig\Extension\Svg\Util\PathCollection;
24
use Ocubom\Twig\Extension\SvgExtension;
25
use Ocubom\Twig\Extension\SvgRuntime;
26
use Ocubom\TwigExtraBundle\DataCollector\SvgDataCollector;
27
use Ocubom\TwigExtraBundle\Extensions;
28
use Ocubom\TwigExtraBundle\Listener\AddHttpHeadersListener;
29
use Ocubom\TwigExtraBundle\Twig\WebpackEncoreExtension;
30
use Symfony\Component\Config\Definition\ConfigurationInterface;
31
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
32
use Symfony\Component\DependencyInjection\ContainerBuilder;
33
use Symfony\Component\DependencyInjection\Extension\Extension;
34
use Symfony\Component\DependencyInjection\Reference;
35
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
36
37
use function BenTools\IterableFunctions\iterable_to_array;
38
use function Ocubom\Math\base_convert;
39
40
class OcubomTwigExtraExtension extends Extension
41
{
42 14
    public function load(array $configs, ContainerBuilder $container): void
43
    {
44 14
        $configuration = $this->getConfiguration($configs, $container);
45
        assert($configuration instanceof ConfigurationInterface);
46 14
        $config = $this->processConfiguration($configuration, $configs);
47
48
        // Load enabled extensions
49 14
        foreach (array_keys(Extensions::getClasses()) as $name) {
50 14
            if ($this->isConfigEnabled($container, $config[$name])) {
51 14
                $call = str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $name)));
52
53 14
                $this->{'load'.$call}($container, $config[$name]);
54
            }
55
        }
56
57
        // Load headers listener
58 14
        $this->loadHttpHeaders($container, $config['http_headers']);
59
    }
60
61 14
    private function loadHttpHeaders(ContainerBuilder $container, array $config): void
62
    {
63
        // Filter enabled header rules
64 14
        $headers = array_filter($config, function (array $header): bool {
65 4
            return (bool) $header['enabled'];
66 14
        });
67
68
        // Only register listener if some rule is defined
69 14
        if (count($headers) > 0) {
70 4
            $container->register('ocubom_twig_extra.http_headers_listener', AddHttpHeadersListener::class)
71 4
                ->setArguments(array_values($headers))
72 4
                ->addTag('kernel.event_subscriber');
73
        }
74
    }
75
76 12
    private function loadHtml(ContainerBuilder $container, array $config): void
77
    {
78 12
        $container->register('ocubom_twig_extra.twig_html_extension', HtmlExtension::class)
79 12
            ->addTag('twig.extension');
80
81 12
        $container->register('ocubom_twig_extra.twig_html_attributes_runtime', HtmlAttributesRuntime::class)
82 12
            ->addTag('twig.runtime');
83
84 12
        $container->register('ocubom_twig_extra.twig_html_compress_runtime', HtmlCompressRuntime::class)
85 12
            ->setArguments([
86 12
                $config['compression']['force'],
87 12
                $config['compression']['level'],
88 12
            ])
89 12
            ->addTag('twig.runtime');
90
    }
91
92
    /** @psalm-suppress UndefinedClass */
93 12
    private function loadSvg(ContainerBuilder $container, array $config): void
94
    {
95 12
        if (empty($config['providers'])) {
96
            return;
97
        }
98
99
        // Register the extension
100 12
        $container->register('ocubom_twig_extra.twig_svg_extension', SvgExtension::class)
101 12
            ->addTag('twig.extension');
102
103
        switch (true) {
104 12
            case interface_exists(LoaderInterface::class):
105 6
                $this->loadSvgLoaders($container, $config);
106 6
                break;
107
108 6
            case interface_exists(FinderInterface::class):
109 6
                $this->loadSvgFinders($container, $config);
110 6
                break;
111
        }
112
    }
113
114 6
    private function loadSvgLoaders(ContainerBuilder $container, array $config): void
115
    {
116
        // Register global loader
117 6
        $container->register('ocubom_twig_extra.svg_loader', ChainLoader::class)
118 6
            ->setArguments([
119 6
                new TaggedIteratorArgument('ocubom_twig_extra.svg_loader'),
120 6
            ])
121 6
            ->addTag('monolog.logger', ['channel' => 'svg_extension']);
122
123
        // Register global runtime
124 6
        $container->register('ocubom_twig_extra.twig_svg_runtime', SvgRuntime::class)
125 6
            ->setArguments([
126 6
                new Reference('ocubom_twig_extra.svg_loader'),
127 6
            ])
128 6
            ->setAutowired(true)
129 6
            ->setAutoconfigured(true)
130 6
            ->addTag('monolog.logger', ['channel' => 'svg_extension'])
131 6
            ->addTag('twig.runtime');
132
133
        // Register Data Collector
134 6
        if (interface_exists(DataCollectorInterface::class)) {
135 6
            $container->register('data_collector.svg', SvgDataCollector::class)
136 6
                ->addTag('monolog.logger', ['channel' => 'svg_extension'])
137 6
                ->addTag('data_collector', [
138 6
                    'template' => '@OcubomTwigExtra/Collector/svg.html.twig',
139 6
                    'id' => 'svg',
140 6
                    // 'priority' => 100,
141 6
                ]);
142
        }
143
144
        // Register individual providers
145 6
        foreach ($config['providers'] as $name => $provider) {
146 6
            if (!$provider['enabled']) {
147
                continue; // @codeCoverageIgnore
148
            }
149
150 6
            $case = str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $name)));
151
152
            // Loader
153 6
            $loaderClass = "Ocubom\\Twig\\Extension\\Svg\\Provider\\{$case}\\{$case}Loader";
154 6
            $loaderIdent = "ocubom_twig_extra.svg_loader.{$name}";
155 6
            if (class_exists($loaderClass)) {
156
                // Register the path collection (when necessary)
157 6
                $pathsIdent = base_convert(sha1(serialize($provider['paths'])), 16, 62);
158 6
                $pathsIdent = ".ocubom_twig_extra.svg_path_collection.{$pathsIdent}";
159 6
                if (!$container->has($pathsIdent)) {
160 6
                    $container->register($pathsIdent, PathCollection::class)
161 6
                        ->setArguments($provider['paths'])
162 6
                        ->setPublic(false);
163
                }
164
165
                // Register loader
166 6
                $container->register($loaderIdent, $loaderClass)
167 6
                    ->setArguments(iterable_to_array(call_user_func(function () use ($provider, $pathsIdent) {
168 6
                        yield new Reference($pathsIdent);
169
170
                        // Pass custom loader options
171 6
                        if (isset($provider['loader'])) {
172 6
                            yield $provider['loader'];
173
                        }
174 6
                    })))
175 6
                    ->setAutowired(true)
176 6
                    ->setAutoconfigured(true)
177 6
                    ->addTag('monolog.logger', ['channel' => 'svg_extension'])
178 6
                    ->addTag('ocubom_twig_extra.svg_loader');
179
            }
180
181
            // Runtime
182 6
            $runtimeClass = "Ocubom\\Twig\\Extension\\Svg\\Provider\\{$case}\\{$case}Runtime";
183 6
            $runtimeIdent = "ocubom_twig_extra.twig_svg_{$name}_runtime";
184 6
            if ($container->has($loaderIdent) && class_exists($runtimeClass)) {
185
                // Register runtime
186 6
                $container
187 6
                    ->register($runtimeIdent, $runtimeClass)
188 6
                    ->setArguments(iterable_to_array(call_user_func(function () use ($provider, $loaderIdent) {
189 6
                        yield new Reference($loaderIdent);
190
191
                        // Pass custom runtime options
192 6
                        if (isset($provider['runtime'])) {
193 6
                            yield $provider['runtime'];
194
                        }
195 6
                    })))
196 6
                    ->setAutowired(true)
197 6
                    ->setAutoconfigured(true)
198 6
                    ->addTag('monolog.logger', ['channel' => 'svg_extension'])
199 6
                    ->addTag('twig.runtime');
200
            }
201
        }
202
    }
203
204
    /** @psalm-suppress UndefinedClass */
205 6
    private function loadSvgFinders(ContainerBuilder $container, array $config): void
206
    {
207 6
        foreach ($config['providers'] as $name => $provider) {
208 6
            if (!$provider['enabled']) {
209
                continue;
210
            }
211
212
            // Path colletion
213 6
            $pathsIdent = sha1(serialize($provider['paths']));
214 6
            $pathsIdent = ".ocubom_twig_extra.svg.finder.{$pathsIdent}";
215 6
            if (!$container->has($pathsIdent)) {
216 6
                $container->register($pathsIdent, Finder::class)
217 6
                    ->setArguments($provider['paths'])
218 6
                    ->setPublic(false)
219 6
                    ->addTag('ocubom_twig_extra.svg_finder');
220
            }
221
222
            // Create a hidden alias
223 6
            $container->setAlias(".ocubom_twig_extra.svg.{$name}_finder.inner", $pathsIdent);
224
        }
225
226
        // Register default runtime
227 6
        if ($container->has('.ocubom_twig_extra.svg.file_system_finder.inner')) {
228
            // Register runtime
229 6
            $container->register('ocubom_twig_extra.twig_svg_runtime', SvgRuntime::class)
230 6
                ->setArguments([
231 6
                    new Reference('.ocubom_twig_extra.svg.file_system_finder.inner'),
232 6
                ])
233 6
                ->setAutowired(true)
234 6
                ->setAutoconfigured(true)
235 6
                ->addTag('twig.runtime');
236
237
            // Create default finder (just an alias)
238 6
            $container->setAlias('ocubom_twig_extra.svg.default_finder', '.ocubom_twig_extra.svg.file_system_finder.inner');
239
240
            // Create class aliases
241
            // $container->setAlias(FinderInterface::class, 'ocubom_twig_extra.svg.default_finder');
242
        }
243
244
        // Register fontawesome runtime
245 6
        if ($container->has('.ocubom_twig_extra.svg.font_awesome_finder.inner')) {
246
            // Register runtime
247 6
            $container->register('ocubom_twig_extra.twig_fontawesome_runtime', FontAwesomeRuntime::class)
248 6
                ->setArguments([
249 6
                    new Reference('ocubom_twig_extra.svg.fontawesome_finder'),
250 6
                ])
251 6
                ->addTag('twig.runtime');
252
253
            // Create fontawesome finder
254 6
            $container->register('ocubom_twig_extra.svg.fontawesome_finder', FontAwesomeFinder::class)
255 6
                ->setArguments([
256 6
                    new Reference('.ocubom_twig_extra.svg.font_awesome_finder.inner'),
257 6
                ]);
258
259
            // Create class aliases
260
            // $container->setAlias(FontAwesomeFinder::class, 'ocubom_twig_extra.svg.fontawesome_finder');
261
        }
262
    }
263
264 12
    private function loadWebpackEncore(ContainerBuilder $container, array $config): void
265
    {
266 12
        $container->register('ocubom_twig_extra.twig_webpack_encore_extension', WebpackEncoreExtension::class)
267 12
            ->setArguments([
268 12
                new Reference('webpack_encore.entrypoint_lookup_collection'),
269 12
                $config['output_paths'],
270 12
            ])
271 12
            ->addTag('twig.extension');
272
    }
273
}
274