Completed
Push — master ( 0791b6...17ebe1 )
by
unknown
07:38
created

SonataSeoExtension::load()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
cc 2
eloc 15
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\SeoBundle\DependencyInjection;
15
16
use Symfony\Component\Config\FileLocator;
17
use Symfony\Component\DependencyInjection\ContainerBuilder;
18
use Symfony\Component\DependencyInjection\ContainerInterface;
19
use Symfony\Component\DependencyInjection\Definition;
20
use Symfony\Component\DependencyInjection\Loader;
21
use Symfony\Component\DependencyInjection\Reference;
22
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
23
24
/**
25
 * This is the class that loads and manages your bundle configuration.
26
 */
27
class SonataSeoExtension extends Extension
28
{
29
    /**
30
     * {@inheritdoc}
31
     */
32
    public function load(array $configs, ContainerBuilder $container): void
33
    {
34
        $configuration = new Configuration();
35
        $config = $this->processConfiguration($configuration, $configs);
36
        $config = $this->fixConfiguration($config);
37
38
        $bundles = $container->getParameter('kernel.bundles');
39
40
        $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
41
42
        if (isset($bundles['SonataBlockBundle'], $bundles['KnpMenuBundle'])) {
43
            $loader->load('blocks.xml');
44
        }
45
46
        $loader->load('event.xml');
47
        $loader->load('services.xml');
48
        $loader->load('commands.xml');
49
50
        $this->configureSeoPage($config['page'], $container);
51
        $this->configureSitemap($config['sitemap'], $container);
52
53
        $container->getDefinition('sonata.seo.twig.extension')
54
            ->replaceArgument(1, $config['encoding']);
55
    }
56
57
    /**
58
     * Configure the default seo page.
59
     *
60
     * @param array            $config
61
     * @param ContainerBuilder $container
62
     */
63
    protected function configureSeoPage(array $config, ContainerBuilder $container): void
64
    {
65
        $definition = $container->getDefinition($config['default']);
66
67
        $definition->addMethodCall('setTitle', [$config['title']]);
68
        $definition->addMethodCall('setMetas', [$config['metas']]);
69
        $definition->addMethodCall('setHtmlAttributes', [$config['head']]);
70
        $definition->addMethodCall('setSeparator', [$config['separator']]);
71
72
        $container->setAlias('sonata.seo.page', $config['default']);
73
    }
74
75
    /**
76
     * Configure the sitemap source manager.
77
     *
78
     * @param array            $config
79
     * @param ContainerBuilder $container
80
     */
81
    protected function configureSitemap(array $config, ContainerBuilder $container): void
82
    {
83
        $source = $container->getDefinition('sonata.seo.sitemap.manager');
84
85
        if (method_exists($source, 'setShared')) { // Symfony 2.8+
86
            $source->setShared(false);
87
        } else {
88
            // For Symfony <2.8 compatibility
89
            $source->setScope(ContainerInterface::SCOPE_PROTOTYPE);
0 ignored issues
show
Bug introduced by
The method setScope() does not seem to exist on object<Symfony\Component...cyInjection\Definition>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
90
        }
91
92
        foreach ($config['doctrine_orm'] as $pos => $sitemap) {
93
            // define the connectionIterator
94
            $connectionIteratorId = 'sonata.seo.source.doctrine_connection_iterator_'.$pos;
95
96
            $connectionIterator = new Definition('%sonata.seo.exporter.database_source_iterator.class%', [
97
                new Reference($sitemap['connection']),
98
                $sitemap['query'],
99
            ]);
100
101
            $connectionIterator->setPublic(false);
102
            $container->setDefinition($connectionIteratorId, $connectionIterator);
103
104
            // define the sitemap proxy iterator
105
            $sitemapIteratorId = 'sonata.seo.source.doctrine_sitemap_iterator_'.$pos;
106
107
            $sitemapIterator = new Definition('%sonata.seo.exporter.sitemap_source_iterator.class%', [
108
                new Reference($connectionIteratorId),
109
                new Reference('router'),
110
                $sitemap['route'],
111
                $sitemap['parameters'],
112
            ]);
113
114
            $sitemapIterator->setPublic(false);
115
116
            $container->setDefinition($sitemapIteratorId, $sitemapIterator);
117
118
            $source->addMethodCall('addSource', [$sitemap['group'], new Reference($sitemapIteratorId), $sitemap['types']]);
119
        }
120
121
        foreach ($config['services'] as $service) {
122
            $source->addMethodCall('addSource', [$service['group'], new Reference($service['id']), $service['types']]);
123
        }
124
    }
125
126
    /**
127
     * Fix the sitemap configuration.
128
     *
129
     * @param array $config
130
     *
131
     * @return array
132
     */
133
    protected function fixConfiguration(array $config)
134
    {
135
        foreach ($config['sitemap']['doctrine_orm'] as $pos => $sitemap) {
136
            $sitemap['group'] = $sitemap['group'] ?? false;
137
            $sitemap['types'] = $sitemap['types'] ?? [];
138
            $sitemap['connection'] = $sitemap['connection'] ?? 'doctrine.dbal.default_connection';
139
            $sitemap['route'] = $sitemap['route'] ?? false;
140
            $sitemap['parameters'] = $sitemap['parameters'] ?? false;
141
            $sitemap['query'] = $sitemap['query'] ?? false;
142
143
            if (false === $sitemap['route']) {
144
                throw new \RuntimeException('Route cannot be empty, please review the sonata_seo.sitemap configuration');
145
            }
146
147
            if (false === $sitemap['query']) {
148
                throw new \RuntimeException('Query cannot be empty, please review the sonata_seo.sitemap configuration');
149
            }
150
151
            if (false === $sitemap['parameters']) {
152
                throw new \RuntimeException('Route\'s parameters cannot be empty, please review the sonata_seo.sitemap configuration');
153
            }
154
155
            $config['sitemap']['doctrine_orm'][$pos] = $sitemap;
156
        }
157
158
        foreach ($config['sitemap']['services'] as $pos => $sitemap) {
159
            if (!is_array($sitemap)) {
160
                $sitemap = [
161
                    'group' => false,
162
                    'types' => [],
163
                    'id' => $sitemap,
164
                ];
165
            } else {
166
                $sitemap['group'] = $sitemap['group'] ?? false;
167
                $sitemap['types'] = $sitemap['types'] ?? [];
168
169
                if (!isset($sitemap['id'])) {
170
                    throw new \RuntimeException('Service id must to be defined, please review the sonata_seo.sitemap configuration');
171
                }
172
            }
173
174
            $config['sitemap']['services'][$pos] = $sitemap;
175
        }
176
177
        return $config;
178
    }
179
}
180