Completed
Pull Request — master (#5)
by Eric
08:04
created

IvorySerializerExtension   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 239
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 99.3%

Importance

Changes 0
Metric Value
wmc 23
lcom 1
cbo 10
dl 0
loc 239
ccs 142
cts 143
cp 0.993
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
B loadInternal() 0 27 2
B loadCache() 0 26 3
A loadEvent() 0 18 2
C loadMapping() 0 48 9
A loadTypes() 0 11 1
A loadVisitors() 0 49 1
B resolveMappingPaths() 0 22 5
1
<?php
2
3
/*
4
 * This file is part of the Ivory Serializer bundle package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ivory\SerializerBundle\DependencyInjection;
13
14
use Ivory\Serializer\Mapping\Loader\AnnotationClassMetadataLoader;
15
use Ivory\Serializer\Mapping\Loader\DirectoryClassMetadataLoader;
16
use Ivory\Serializer\Mapping\Loader\FileClassMetadataLoader;
17
use Ivory\Serializer\Mapping\Loader\ReflectionClassMetadataLoader;
18
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPass;
19
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
20
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
21
use Symfony\Component\Config\FileLocator;
22
use Symfony\Component\Config\Resource\DirectoryResource;
23
use Symfony\Component\Config\Resource\FileResource;
24
use Symfony\Component\DependencyInjection\ContainerBuilder;
25
use Symfony\Component\DependencyInjection\Definition;
26
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
27
use Symfony\Component\DependencyInjection\Reference;
28
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
29
30
/**
31
 * @author GeLo <[email protected]>
32
 */
33
class IvorySerializerExtension extends ConfigurableExtension
34
{
35
    /**
36
     * {@inheritdoc}
37
     */
38 234
    protected function loadInternal(array $config, ContainerBuilder $container)
39
    {
40 234
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
41
42
        $resources = [
43 234
            'cache',
44 182
            'common',
45 182
            'event',
46 182
            'fos',
47 182
            'mapping',
48 182
            'navigator',
49 182
            'registry',
50 182
            'serializer',
51 182
            'type',
52 182
            'visitor',
53 182
        ];
54
55 234
        foreach ($resources as $resource) {
56 234
            $loader->load($resource.'.xml');
57 182
        }
58
59 234
        $this->loadCache($config, $container);
60 234
        $this->loadEvent($config['event'], $container);
61 234
        $this->loadMapping($config['mapping'], $container);
62 225
        $this->loadTypes($config['types'], $container);
63 225
        $this->loadVisitors($config['visitors'], $container);
64 225
    }
65
66
    /**
67
     * @param mixed[]          $config
68
     * @param ContainerBuilder $container
69
     */
70 234
    private function loadCache(array $config, ContainerBuilder $container)
71
    {
72
        $container
73 234
            ->getDefinition('ivory.serializer.mapping.factory')
74 234
            ->addArgument($cache = new Reference($config['mapping']['cache']['pool']))
75 234
            ->addArgument($config['mapping']['cache']['prefix']);
76
77
        $container
78 234
            ->getDefinition('ivory.serializer.cache_warmer')
79 234
            ->addArgument($cache);
80
81 234
        if (class_exists(CachePoolPass::class)) {
82 52
            return;
83
        }
84
85 182
        $definition = $container->getDefinition('ivory.serializer.mapping.factory');
86 182
        $cache = (string) $definition->getArgument(1);
87
88 182
        if ($container->hasDefinition($cache)) {
89
            return;
90
        }
91
92 182
        $cachePath = $container->getParameterBag()->get('kernel.cache_dir');
93 182
        $container->setDefinition($cache, new Definition(FilesystemAdapter::class, ['', 0, $cachePath]));
94 182
        $definition->replaceArgument(1, new Reference($cache));
95 182
    }
96
97
    /**
98
     * @param mixed[]          $config
99
     * @param ContainerBuilder $container
100
     */
101 234
    private function loadEvent(array $config, ContainerBuilder $container)
102
    {
103 234
        if ($config['enabled']) {
104
            $container
105 225
                ->getDefinition('ivory.serializer.mapping.factory')
106 225
                ->replaceArgument(0, new Reference('ivory.serializer.mapping.factory.event'));
107
108 225
            $container->setAlias('ivory.serializer.navigator', 'ivory.serializer.navigator.event');
109
110 225
            return;
111
        }
112
113 9
        $container->removeDefinition('ivory.serializer.event.dispatcher');
114 9
        $container->removeDefinition('ivory.serializer.mapping.factory.event');
115 9
        $container->removeDefinition('ivory.serializer.navigator.event');
116
117 9
        $container->setAlias('ivory.serializer.navigator', 'ivory.serializer.navigator.default');
118 9
    }
119
120
    /**
121
     * @param mixed[]          $config
122
     * @param ContainerBuilder $container
123
     */
124 234
    private function loadMapping(array $config, ContainerBuilder $container)
125
    {
126 234
        $directories = $files = [];
127
128 234
        foreach ($this->resolveMappingPaths($config, $container) as $path) {
129 36
            if (is_dir($path)) {
130 27
                $directories[] = $path;
131 27
                $container->addResource(new DirectoryResource($path));
132 36
            } elseif (is_file($path)) {
133 27
                $files[] = $path;
134 27
                $container->addResource(new FileResource($path));
135 21
            } else {
136 15
                throw new InvalidConfigurationException(sprintf('The path "%s" does not exist.', $path));
137
            }
138 175
        }
139
140 225
        $loaders = [];
141 225
        $typeParser = new Reference('ivory.serializer.type.parser');
142
143 225
        if ($config['reflection']) {
144 216
            $loaders['reflection'] = new Definition(ReflectionClassMetadataLoader::class, [
145 216
                new Reference('property_info', ContainerBuilder::NULL_ON_INVALID_REFERENCE),
146 216
                $typeParser,
147 168
            ]);
148 168
        }
149
150 225
        if ($config['annotation']) {
151 207
            $loaders['annotation'] = new Definition(AnnotationClassMetadataLoader::class, [
152 207
                new Reference('annotation_reader'),
153 207
                $typeParser,
154 161
            ]);
155 161
        }
156
157 225
        if (!empty($directories)) {
158 27
            $loaders['directory'] = new Definition(DirectoryClassMetadataLoader::class, [$directories, $typeParser]);
159 21
        }
160
161 225
        foreach ($files as $file) {
162 27
            $loaders['file_'.sha1($file)] = new Definition(FileClassMetadataLoader::class, [$file, $typeParser]);
163 175
        }
164
165 225
        foreach ($loaders as $key => $loader) {
166 216
            $container->setDefinition(
167 216
                'ivory.serializer.mapping.loader.'.$key,
168 216
                $loader->addTag('ivory.serializer.loader')
169 168
            );
170 175
        }
171 225
    }
172
173
    /**
174
     * @param mixed[]          $config
175
     * @param ContainerBuilder $container
176
     */
177 225
    private function loadTypes(array $config, ContainerBuilder $container)
178
    {
179
        $container
180 225
            ->getDefinition('ivory.serializer.type.date_time')
181 225
            ->addArgument($config['date_time']['format'])
182 225
            ->addArgument($config['date_time']['timezone']);
183
184
        $container
185 225
            ->getDefinition('ivory.serializer.type.exception')
186 225
            ->addArgument($config['exception']['debug']);
187 225
    }
188
189
    /**
190
     * @param mixed[]          $config
191
     * @param ContainerBuilder $container
192
     */
193 225
    private function loadVisitors(array $config, ContainerBuilder $container)
194
    {
195
        $container
196 225
            ->getDefinition('ivory.serializer.visitor.csv.serialization')
197 225
            ->addArgument($config['csv']['delimiter'])
198 225
            ->addArgument($config['csv']['enclosure'])
199 225
            ->addArgument($config['csv']['escape_char'])
200 225
            ->addArgument($config['csv']['key_separator']);
201
202
        $container
203 225
            ->getDefinition('ivory.serializer.visitor.csv.deserialization')
204 225
            ->addArgument($config['csv']['delimiter'])
205 225
            ->addArgument($config['csv']['enclosure'])
206 225
            ->addArgument($config['csv']['escape_char'])
207 225
            ->addArgument($config['csv']['key_separator']);
208
209
        $container
210 225
            ->getDefinition('ivory.serializer.visitor.json.serialization')
211 225
            ->addArgument($config['json']['options']);
212
213
        $container
214 225
            ->getDefinition('ivory.serializer.visitor.json.deserialization')
215 225
            ->addArgument($config['json']['max_depth'])
216 225
            ->addArgument($config['json']['options']);
217
218
        $container
219 225
            ->getDefinition('ivory.serializer.visitor.xml.serialization')
220 225
            ->addArgument($config['xml']['version'])
221 225
            ->addArgument($config['xml']['encoding'])
222 225
            ->addArgument($config['xml']['format_output'])
223 225
            ->addArgument($config['xml']['root'])
224 225
            ->addArgument($config['xml']['entry'])
225 225
            ->addArgument($config['xml']['entry_attribute']);
226
227
        $container
228 225
            ->getDefinition('ivory.serializer.visitor.xml.deserialization')
229 225
            ->addArgument($config['xml']['entry'])
230 225
            ->addArgument($config['xml']['entry_attribute']);
231
232
        $container
233 225
            ->getDefinition('ivory.serializer.visitor.yaml.serialization')
234 225
            ->addArgument($config['yaml']['inline'])
235 225
            ->addArgument($config['yaml']['indent'])
236 225
            ->addArgument($config['yaml']['options']);
237
238
        $container
239 225
            ->getDefinition('ivory.serializer.visitor.yaml.deserialization')
240 225
            ->addArgument($config['yaml']['options']);
241 225
    }
242
243
    /**
244
     * @param mixed[]          $config
245
     * @param ContainerBuilder $container
246
     *
247
     * @return string[]
248
     */
249 234
    private function resolveMappingPaths(array $config, ContainerBuilder $container)
250
    {
251 234
        $paths = [];
252
253 234
        if ($config['auto']['enabled']) {
254 216
            $bundles = $container->getParameter('kernel.bundles');
255
256 216
            foreach ($bundles as $bundle) {
257 18
                $bundlePath = dirname((new \ReflectionClass($bundle))->getFileName());
258
259 18
                foreach ($config['auto']['paths'] as $relativePath) {
260 18
                    $path = $bundlePath.'/'.$relativePath;
261
262 18
                    if (file_exists($path)) {
263 18
                        $paths[] = $path;
264 14
                    }
265 14
                }
266 168
            }
267 168
        }
268
269 234
        return array_merge($paths, $config['paths']);
270
    }
271
}
272