Completed
Push — master ( 780256...071430 )
by Eric
08:39
created

IvorySerializerExtension::getConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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