Completed
Pull Request — master (#126)
by Phil
13:49
created

Definition   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 218
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 27
lcom 1
cbo 4
dl 0
loc 218
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A setAlias() 0 6 1
A getAlias() 0 4 1
A setShared() 0 6 1
A isShared() 0 4 1
A addArgument() 0 6 1
A addArguments() 0 8 2
A addMethodCall() 0 9 1
A addMethodCalls() 0 8 2
D resolve() 0 34 10
A resolveCallable() 0 7 2
A resolveClass() 0 8 2
A invokeMethods() 0 9 2
1
<?php declare(strict_types=1);
2
3
namespace League\Container\Definition;
4
5
use League\Container\Argument\{
6
    ArgumentResolverInterface, ArgumentResolverTrait, ClassNameInterface, RawArgumentInterface
7
};
8
use League\Container\ContainerAwareTrait;
9
use ReflectionClass;
10
11
class Definition implements ArgumentResolverInterface, DefinitionInterface
12
{
13
    use ArgumentResolverTrait;
14
    use ContainerAwareTrait;
15
16
    /**
17
     * @var string
18
     */
19
    protected $alias;
20
21
    /**
22
     * @var mixed
23
     */
24
    protected $concrete;
25
26
    /**
27
     * @var boolean
28
     */
29
    protected $shared = false;
30
31
    /**
32
     * @var array
33
     */
34
    protected $arguments = [];
35
36
    /**
37
     * @var array
38
     */
39
    protected $methods = [];
40
41
    /**
42
     * @var mixed
43
     */
44
    protected $resolved;
45
46
    /**
47
     * Constructor.
48
     *
49
     * @param string $id
50
     * @param mixed  $concrete
51
     */
52
    public function __construct(string $id, $concrete)
53
    {
54
        $this->alias    = $id;
55
        $this->concrete = $concrete;
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61
    public function setAlias(string $id): DefinitionInterface
62
    {
63
        $this->alias = $id;
64
65
        return $this;
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    public function getAlias(): string
72
    {
73
        return $this->alias;
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79
    public function setShared(bool $shared): DefinitionInterface
80
    {
81
        $this->shared = $shared;
82
83
        return $this;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function isShared(): bool
90
    {
91
        return $this->shared;
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    public function addArgument($arg): DefinitionInterface
98
    {
99
        $this->arguments[] = $arg;
100
101
        return $this;
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function addArguments(array $args): DefinitionInterface
108
    {
109
        foreach ($args as $arg) {
110
            $this->addArgument($arg);
111
        }
112
113
        return $this;
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function addMethodCall(string $method, array $args = []): DefinitionInterface
120
    {
121
        $this->methods[] = [
122
            'method'    => $method,
123
            'arguments' => $args
124
        ];
125
126
        return $this;
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132
    public function addMethodCalls(array $methods = []): DefinitionInterface
133
    {
134
        foreach ($methods as $method => $args) {
135
            $this->addMethodCall($method, $args);
136
        }
137
138
        return $this;
139
    }
140
141
    /**
142
     * {@inheritdoc}
143
     */
144
    public function resolve(array $args = [], bool $new = false)
145
    {
146
        $concrete = $this->concrete;
147
148
        if ($this->isShared() && ! is_null($this->resolved) && $new === false) {
149
            return $this->resolved;
150
        }
151
152
        if (is_callable($concrete)) {
153
            $concrete = $this->resolveCallable($concrete, $args);
154
        }
155
156
        if ($concrete instanceof RawArgumentInterface) {
157
            $this->resolved = $concrete->getValue();
158
159
            return $concrete->getValue();
160
        }
161
162
        if ($concrete instanceof ClassNameInterface) {
163
            $concrete = $concrete->getValue();
164
        }
165
166
        if (is_string($concrete) && class_exists($concrete)) {
167
            $concrete = $this->resolveClass($concrete, $args);
168
        }
169
170
        if (is_object($concrete)) {
171
            $concrete = $this->invokeMethods($concrete);
172
        }
173
174
        $this->resolved = $concrete;
175
176
        return $concrete;
177
    }
178
179
    /**
180
     * Resolve a callable.
181
     *
182
     * @param callable $concrete
183
     * @param array    $args
184
     *
185
     * @return mixed
186
     */
187
    protected function resolveCallable(callable $concrete, array $args = [])
188
    {
189
        $args     = (empty($args)) ? $this->arguments : $args;
190
        $resolved = $this->resolveArguments($args);
191
192
        return call_user_func_array($concrete, $resolved);
193
    }
194
195
    /**
196
     * Resolve a class.
197
     *
198
     * @param string $concrete
199
     * @param array  $args
200
     *
201
     * @return object
202
     */
203
    protected function resolveClass(string $concrete, array $args = [])
204
    {
205
        $args       = (empty($args)) ? $this->arguments : $args;
206
        $resolved   = $this->resolveArguments($args);
207
        $reflection = new ReflectionClass($concrete);
208
209
        return $reflection->newInstanceArgs($resolved);
210
    }
211
212
    /**
213
     * Invoke methods on resolved instance.
214
     *
215
     * @param object $instance
216
     *
217
     * @return object
218
     */
219
    protected function invokeMethods($instance)
220
    {
221
        foreach ($this->methods as $method) {
222
            $args = $this->resolveArguments($method['arguments']);
223
            call_user_func_array([$instance, $method['method']], $args);
224
        }
225
226
        return $instance;
227
    }
228
}
229