Completed
Push — master ( 0607e4...55b776 )
by Eric
08:27
created

IvorySerializerExtension::loadMappingCache()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 2

Importance

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