Completed
Push — master ( 37ded2...9ce938 )
by Nikola
10:29 queued 04:41
created

Extension::load()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 1

Importance

Changes 4
Bugs 0 Features 1
Metric Value
c 4
b 0
f 1
dl 0
loc 16
ccs 13
cts 13
cp 1
rs 9.4286
cc 1
eloc 12
nc 1
nop 2
crap 1
1
<?php
2
/*
3
 * This file is part of the Exchange Rate Bundle, an RunOpenCode project.
4
 *
5
 * (c) 2016 RunOpenCode
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace RunOpenCode\Bundle\ExchangeRate\DependencyInjection;
11
12
use RunOpenCode\ExchangeRate\Configuration;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, RunOpenCode\Bundle\Excha...Injection\Configuration.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
13
use RunOpenCode\Bundle\ExchangeRate\DependencyInjection\Configuration as TreeConfiguration;
14
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
15
use Symfony\Component\Config\FileLocator;
16
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
use Symfony\Component\DependencyInjection\Extension\Extension as BaseExtension;
18
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
19
use Symfony\Component\DependencyInjection\Reference;
20
21
/**
22
 * Class Extension
23
 *
24
 * Bundle extension.
25
 *
26
 * @package RunOpenCode\Bundle\ExchangeRate\DependencyInjection
27
 */
28
class Extension extends BaseExtension
29
{
30
    /**
31
     * {@inheritdoc}
32
     */
33 4
    public function getAlias()
34
    {
35 4
        return "run_open_code_exchange_rate";
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41 2
    public function load(array $config, ContainerBuilder $container)
42
    {
43 2
        $configuration = new TreeConfiguration();
44 2
        $config = $this->processConfiguration($configuration, $config);
45
46 2
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
47 2
        $loader->load('services.xml');
48
49 2
        $this->configureExchangeRateService($config, $container);
50 2
        $this->configureSourcesRegistry($config, $container);
51 2
        $this->configureProcessorsRegistry($config, $container);
52 2
        $this->configureRatesRegistry($config, $container);
53 2
        $this->configureFileRepository($config, $container);
54 2
        $this->configureController($config, $container);
55 2
        $this->configureDebugCommand($config, $container);
56 2
    }
57
58
    /**
59
     * Configure exchange rate service.
60
     *
61
     * @param array $config
62
     * @param ContainerBuilder $container
63
     */
64 2
    protected function configureExchangeRateService(array $config, ContainerBuilder $container)
65
    {
66 2
        if ($container->hasDefinition('run_open_code.exchange_rate')) {
67
68 2
            $definition = $container->getDefinition('run_open_code.exchange_rate');
69
70 2
            $definition->setArguments(array(
71 2
                $config['base_currency'],
72 2
                new Reference($config['repository']),
73 2
                new Reference('run_open_code.exchange_rate.registry.sources'),
74 2
                new Reference('run_open_code.exchange_rate.registry.processors'),
75 2
                new Reference('run_open_code.exchange_rate.registry.rates')
76 1
            ));
77 1
        }
78 2
    }
79
80
    /**
81
     * Configure sources registry.
82
     *
83
     * @param array $config
84
     * @param ContainerBuilder $container
85
     */
86 2
    protected function configureSourcesRegistry(array $config, ContainerBuilder $container)
87
    {
88 2
        if ($container->hasDefinition('run_open_code.exchange_rate.registry.sources')) {
89
90 2
            $definition = $container->getDefinition('run_open_code.exchange_rate.registry.sources');
91 2
            $requiredSources = $this->getRequiredSources($config);
92
93
94 2
            foreach ($container->findTaggedServiceIds('run_open_code.exchange_rate.source') as $id => $tags) {
95
96 2
                foreach ($tags as $attributes) {
97
98 2
                    if (array_key_exists($attributes['alias'], $requiredSources)) {
99
100 2
                        $definition->addMethodCall('add', array(
101 2
                            new Reference($id)
102 1
                        ));
103
104 2
                        unset($requiredSources[$attributes['alias']]);
105 1
                    }
106 1
                }
107 1
            }
108
109 2
            if (count($requiredSources) > 0) {
110
                throw new InvalidConfigurationException(sprintf('Required source(s) "%s" does not exists.', implode(', ', $requiredSources)));
111
            }
112 1
        }
113 2
    }
114
115
    /**
116
     * Configure processors registry.
117
     *
118
     * @param array $config
119
     * @param ContainerBuilder $container
120
     */
121 2
    protected function configureProcessorsRegistry(array $config, ContainerBuilder $container)
122
    {
123 2
        if ($container->hasDefinition('run_open_code.exchange_rate.registry.processors')) {
124
125 2
            $definition = $container->getDefinition('run_open_code.exchange_rate.registry.processors');
126
127 2
            $processors = array();
128
129 2
            foreach ($container->findTaggedServiceIds('run_open_code.exchange_rate.processor') as $id => $tags) {
130
131 2
                if (!in_array($id, $config['processors'], true)) {
132 2
                    continue;
133
                }
134
135 2
                foreach ($tags as $attributes) {
136 2
                    $processors[$id] = (isset($attributes['priority'])) ? intval($attributes['priority']) : 0;
137 1
                }
138 1
            }
139
140 2
            asort($processors);
141
142 2
            foreach ($processors as $id => $processor) {
143 2
                $definition->addMethodCall('add', array(
144 2
                    new Reference($id)
145 1
                ));
146 1
            }
147 1
        }
148 2
    }
149
150
    /**
151
     * Configure rates.
152
     *
153
     * @param array $config
154
     * @param ContainerBuilder $container
155
     */
156 2
    protected function configureRatesRegistry(array $config, ContainerBuilder $container)
157
    {
158 2
        if ($container->hasDefinition('run_open_code.exchange_rate.registry.rates')) {
159
160 2
            $definition = $container->getDefinition('run_open_code.exchange_rate.registry.rates');
161
162 2
            $aliases = array();
163
164 2
            foreach ($config['rates'] as $rateConfiguration) {
165
166 2
                if ($rateConfiguration['alias'] === null) {
167 2
                    continue;
168
                }
169
170
                if (array_key_exists($rateConfiguration['alias'], $aliases)) {
171
                    throw new InvalidConfigurationException(sprintf('Rate with alias "%s" is already defined.', $rateConfiguration['alias']));
172
                }
173
174
                $aliases[$rateConfiguration['alias']] = $rateConfiguration;
175 1
            }
176
177 2
            $definition->setArguments(array(array_values($config['rates'])));
178 1
        }
179 2
    }
180
181
    /**
182
     * Configure file registry, if used.
183
     *
184
     * @param array $config
185
     * @param ContainerBuilder $container
186
     */
187 2
    protected function configureFileRepository(array $config, ContainerBuilder $container)
188
    {
189
        if (
190 2
            $config['repository'] === 'run_open_code.exchange_rate.repository.file_repository'
191 1
            &&
192 2
            $container->hasDefinition('run_open_code.exchange_rate.repository.file_repository')
193 1
        ) {
194
195 2
            if (!empty($config['file_repository']) && !empty($config['file_repository']['path'])) {
196 2
                $definition = $container->getDefinition('run_open_code.exchange_rate.repository.file_repository');
197 2
                $definition->setArguments(array(
198 2
                    $config['file_repository']['path']
199 1
                ));
200 1
            } else {
201 1
                throw new InvalidConfigurationException('You must configure location to the file where file repository will store exchange rates.');
202
            }
203
204 1
        } elseif ($config['repository'] === 'run_open_code.exchange_rate.repository.file_repository') {
205
            throw new InvalidConfigurationException('File repository is used to store exchange rates, but it is not available in container.');
206
        } else {
207
            $container->removeDefinition('run_open_code.exchange_rate.repository.file_repository');
208
        }
209 2
    }
210
211
    /**
212
     * Configure controller - view layer.
213
     *
214
     * @param array $config
215
     * @param ContainerBuilder $container
216
     */
217 2
    protected function configureController(array $config, ContainerBuilder $container)
218
    {
219 2
        if ($container->has('run_open_code.exchange_rate.controller')) {
220 2
            $definition = $container->getDefinition('run_open_code.exchange_rate.controller');
221 2
            $definition->setArguments(array(
222 2
                new Reference($config['repository']),
223 2
                $config['base_currency'],
224 2
                $config['view']
225 1
            ));
226 1
        }
227 2
    }
228
229
    /**
230
     * Configure debug command.
231
     *
232
     * @param array $config
233
     * @param ContainerBuilder $container
234
     */
235 2
    protected function configureDebugCommand(array $config, ContainerBuilder $container)
236
    {
237 2
        if ($container->has('run_open_code.exchange_rate.command.configuration_debug')) {
238 2
            $definition = $container->getDefinition('run_open_code.exchange_rate.command.configuration_debug');
239
240 2
            $arguments = $definition->getArguments();
241 2
            $arguments[3] = new Reference($config['repository']);
242
243 2
            $definition->setArguments($arguments);
244 1
        }
245 2
    }
246
247
    /**
248
     * Extract name of only required sources from configuration.
249
     *
250
     * @param array $config
251
     * @return array
252
     */
253 2
    protected function getRequiredSources(array $config)
254
    {
255 2
        $requiredSources = array();
256
257 2
        foreach ($config['rates'] as $rate) {
258 2
            $requiredSources[$rate['source']] = $rate['source'];
259 1
        }
260
261 2
        return $requiredSources;
262
    }
263
}
264