Completed
Push — master ( 1bae27...fe1a3e )
by Andreas
02:24
created

PimpleContainerAdapter::createAliasFactory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace TomPHP\ContainerConfigurator\Pimple;
4
5
use Assert\Assertion;
6
use Pimple\Container;
7
use TomPHP\ContainerConfigurator\ApplicationConfig;
8
use TomPHP\ContainerConfigurator\ContainerAdapter;
9
use TomPHP\ContainerConfigurator\Exception\UnsupportedFeatureException;
10
use TomPHP\ContainerConfigurator\InflectorConfig;
11
use TomPHP\ContainerConfigurator\ServiceConfig;
12
use TomPHP\ContainerConfigurator\ServiceDefinition;
13
14
final class PimpleContainerAdapter implements ContainerAdapter
15
{
16
    /**
17
     * @var Container
18
     */
19
    private $container;
20
21
    /**
22
     * @param Container $container
23
     */
24
    public function setContainer($container)
25
    {
26
        $this->container = $container;
27
    }
28
29
    public function addApplicationConfig(ApplicationConfig $config, $prefix = 'config')
30
    {
31
        Assertion::string($prefix);
32
33
        if (!empty($prefix)) {
34
            $prefix .= $config->getSeparator();
35
        }
36
37
        foreach ($config as $key => $value) {
38
            $this->container[$prefix . $key] = $value;
39
        }
40
    }
41
42
    public function addServiceConfig(ServiceConfig $config)
43
    {
44
        foreach ($config as $definition) {
45
            $this->addServiceToContainer($definition);
46
        }
47
    }
48
49
    /**
50
     * @throws UnsupportedFeatureException
51
     */
52
    public function addInflectorConfig(InflectorConfig $config)
53
    {
54
        throw UnsupportedFeatureException::forInflectors('Pimple');
55
    }
56
57
    private function addServiceToContainer(ServiceDefinition $definition)
58
    {
59
        $factory = $this->createFactory($definition);
60
61
        if (!$definition->isSingleton()) {
62
            $factory = $this->container->factory($factory);
63
        }
64
65
        $this->container[$definition->getName()] = $factory;
66
    }
67
68
    /**
69
     * @param ServiceDefinition $definition
70
     *
71
     * @return \Closure
72
     */
73
    private function createFactory(ServiceDefinition $definition)
74
    {
75
        if ($definition->isFactory()) {
76
            return $this->createFactoryFactory($definition);
77
        }
78
79
        if ($definition->isAlias()) {
80
            return $this->createAliasFactory($definition);
81
        }
82
83
        return $this->createInstanceFactory($definition);
84
    }
85
86
    /**
87
     * @param ServiceDefinition $definition
88
     *
89
     * @return \Closure
90
     */
91 View Code Duplication
    private function createFactoryFactory(ServiceDefinition $definition)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
92
    {
93
        return function () use ($definition) {
94
            $className = $definition->getClass();
95
            $factory   = new $className();
96
97
            return $factory(...$this->resolveArguments($definition->getArguments()));
98
        };
99
    }
100
101
    /**
102
     * @param ServiceDefinition $definition
103
     *
104
     * @return \Closure
105
     */
106
    private function createAliasFactory(ServiceDefinition $definition)
107
    {
108
        return function () use ($definition) {
109
            return $this->container[$definition->getClass()];
110
        };
111
    }
112
113
    /**
114
     * @param ServiceDefinition $definition
115
     *
116
     * @return \Closure
117
     */
118
    private function createInstanceFactory(ServiceDefinition $definition)
119
    {
120
        return function () use ($definition) {
121
            $className = $definition->getClass();
122
            $instance  = new $className(...$this->resolveArguments($definition->getArguments()));
123
124
            foreach ($definition->getMethods() as $name => $args) {
125
                $instance->$name(...$this->resolveArguments($args));
126
            }
127
128
            return $instance;
129
        };
130
    }
131
132
    /**
133
     * @param array $arguments
134
     *
135
     * @return array
136
     */
137
    private function resolveArguments(array $arguments)
138
    {
139
        return array_map(
140
            function ($argument) {
141
                if (!is_string($argument)) {
142
                    return $argument;
143
                }
144
145
                if (isset($this->container[$argument])) {
146
                    return $this->container[$argument];
147
                }
148
149
                return $argument;
150
            },
151
            $arguments
152
        );
153
    }
154
}
155