Completed
Pull Request — master (#31)
by Tom
02:48
created

Configurator::addApplicationConfig()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 10
rs 9.4285
cc 3
eloc 5
nc 4
nop 3
1
<?php
2
3
namespace TomPHP\ConfigServiceProvider\Pimple;
4
5
use Pimple\Container;
6
use ReflectionClass;
7
use TomPHP\ConfigServiceProvider\ApplicationConfig;
8
use TomPHP\ConfigServiceProvider\ContainerConfigurator;
9
use TomPHP\ConfigServiceProvider\Exception\UnsupportedFeatureException;
10
use TomPHP\ConfigServiceProvider\InflectorConfig;
11
use TomPHP\ConfigServiceProvider\ServiceConfig;
12
use TomPHP\ConfigServiceProvider\ServiceDefinition;
13
14
final class Configurator implements ContainerConfigurator
15
{
16
    /**
17
     * @var Container
18
     */
19
    private $container;
20
21
    public function addApplicationConfig($container, ApplicationConfig $config, $prefix = 'config')
22
    {
23
        if (!empty($prefix)) {
24
            $prefix .= $config->getSeparator();
25
        }
26
27
        foreach ($config as $key => $value) {
28
            $container[$prefix . $key] = $value;
29
        }
30
    }
31
32
    public function addServiceConfig($container, ServiceConfig $config)
33
    {
34
        $this->container = $container;
35
36
        foreach ($config as $definition) {
37
            $this->addServiceToContainer($definition);
38
        }
39
    }
40
41
    public function addInflectorConfig($container, InflectorConfig $config)
42
    {
43
        throw UnsupportedFeatureException::forInflectors('Pimple');
44
    }
45
46
    private function addServiceToContainer(ServiceDefinition $definition)
47
    {
48
        $factory = function () use ($definition) {
49
            $reflection = new ReflectionClass($definition->getClass());
50
51
            $instance = $reflection->newInstanceArgs($this->resolveArguments($definition->getArguments()));
52
53
            foreach ($definition->getMethods() as $name => $args) {
54
                call_user_func_array([$instance, $name], $this->resolveArguments($args));
55
            }
56
57
            return $instance;
58
        };
59
60
        if (!$definition->isSingleton()) {
61
            $factory = $this->container->factory($factory);
62
        }
63
64
        $this->container[$definition->getName()] = $factory;
65
    }
66
67
    private function resolveArguments(array $arguments)
68
    {
69
        return array_map(
70
            function ($argument) {
71
                return isset($this->container[$argument]) ? $this->container[$argument] : $argument;
72
            },
73
            $arguments
74
        );
75
    }
76
}
77