Completed
Push — master ( c62646...583a7d )
by Eric
02:58
created

IvorySerializerExtension::loadInternal()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

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