Completed
Push — 2.x ( 16fb45...903eb9 )
by Akihito
20s queued 14s
created

Bind::getStringName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
ccs 6
cts 6
cp 1
rs 9.4285
cc 1
eloc 6
nc 1
nop 1
crap 1
1
<?php
2
3
/**
4
 * This file is part of the Ray.Di package.
5
 *
6
 * @license http://opensource.org/licenses/MIT MIT
7
 */
8
namespace Ray\Di;
9
10
use Ray\Di\Exception\InvalidContext;
11
use Ray\Di\Exception\NotFound;
12
13
final class Bind
14
{
15
    /**
16
     * @var Container
17
     */
18
    private $container;
19
20
    /**
21
     * @var string
22
     */
23
    private $interface;
24
25
    /**
26
     * @var string
27
     */
28
    private $name = Name::ANY;
29
30
    /**
31
     * @var DependencyInterface
32
     */
33
    private $bound;
34
35
    /**
36
     * @var BindValidator
37
     */
38
    private $validate;
39
40
    /**
41
     * @var Untarget
42
     */
43
    private $untarget;
44
45
    /**
46
     * @param Container $container dependency container
47
     * @param string    $interface interface or concrete class name
48
     */
49 92
    public function __construct(Container $container, $interface)
50
    {
51 92
        $this->container = $container;
52 92
        $this->interface = $interface;
53 92
        $this->validate = new BindValidator;
54 92
        $bindUntarget = class_exists($interface) && ! (new \ReflectionClass($interface))->isAbstract() && $this->hasNotRegistered($interface);
55 92
        if ($bindUntarget) {
56 49
            $this->untarget = new Untarget($interface);
57
58 49
            return;
59
        }
60 91
        $this->validate->constructor($interface);
61 90
    }
62
63 86
    public function __destruct()
64
    {
65 86
        if ($this->untarget) {
66 43
            $this->untarget->__invoke($this->container, $this);
67 43
            $this->untarget = null;
68
        }
69 86
    }
70
71
    /**
72
     * @return string
73
     */
74 85
    public function __toString()
75
    {
76 85
        return $this->interface . '-' . $this->name;
77
    }
78
79
    /**
80
     * @param string $name
81
     *
82
     * @return $this
83
     */
84 28
    public function annotatedWith($name)
85
    {
86 28
        $this->name = $name;
87
88 28
        return $this;
89
    }
90
91
    /**
92
     * @param string $class
93
     *
94
     * @return $this
95
     */
96 60
    public function to($class)
97
    {
98 60
        $this->untarget = null;
99 60
        $this->validate->to($this->interface, $class);
100 58
        $this->bound = (new DependencyFactory)->newAnnotatedDependency(new \ReflectionClass($class));
101 58
        $this->container->add($this);
102
103 58
        return $this;
104
    }
105
106
    /**
107
     * @param string          $class           class name
108
     * @param string | array  $name            "varName=bindName,..." or [[varName=>bindName],...]
109
     * @param InjectionPoints $injectionPoints injection points
110
     * @param null            $postConstruct   method name of initialization after all dependencies are injected
111
     *
112
     * @return $this
113
     */
114 4
    public function toConstructor($class, $name, InjectionPoints $injectionPoints = null, $postConstruct = null)
115
    {
116 4
        if (is_array($name)) {
117 1
            $name = $this->getStringName($name);
118
        }
119 4
        $this->untarget = null;
120 4
        $postConstruct = $postConstruct ? new \ReflectionMethod($class, $postConstruct) : null;
121 4
        $this->bound = (new DependencyFactory)->newToConstructor(new \ReflectionClass($class), $name, $injectionPoints, $postConstruct);
122 4
        $this->container->add($this);
123
124 4
        return $this;
125
    }
126
127
    /**
128
     * @param string $provider
129
     * @param string $context
130
     *
131
     * @throws NotFound
132
     *
133
     * @return $this
134
     */
135 50
    public function toProvider($provider, $context = null)
136
    {
137 50
        if (! is_null($context) && ! is_string($context)) {
138 1
            throw new InvalidContext(gettype($context));
139
        }
140 49
        $this->untarget = null;
141 49
        $this->validate->toProvider($provider);
142 47
        $this->bound = (new DependencyFactory)->newProvider(new \ReflectionClass($provider), $context);
143 47
        $this->container->add($this);
144
145 47
        return $this;
146
    }
147
148
    /**
149
     * @param mixed $instance
150
     *
151
     * @return $this
152
     */
153 78
    public function toInstance($instance)
154
    {
155 78
        $this->untarget = null;
156 78
        $this->bound = new Instance($instance);
157 78
        $this->container->add($this);
158
159 78
        return $this;
160
    }
161
162
    /**
163
     * @param string $scope
164
     *
165
     * @return $this
166
     */
167 45
    public function in($scope)
168
    {
169 45
        if ($this->bound instanceof Dependency || $this->bound instanceof DependencyProvider) {
170 44
            $this->bound->setScope($scope);
171
        }
172 45
        if ($this->untarget) {
173 41
            $this->untarget->setScope($scope);
174
        }
175
176 45
        return $this;
177
    }
178
179
    /**
180
     * @return DependencyInterface
181
     */
182 84
    public function getBound()
183
    {
184 84
        return $this->bound;
185
    }
186
187
    /**
188
     * @param DependencyInterface $bound
189
     */
190 43
    public function setBound(DependencyInterface $bound)
191
    {
192 43
        $this->bound = $bound;
193 43
    }
194
195
    /**
196
     * @param string $interface
197
     *
198
     * @return bool
199
     */
200 49
    private function hasNotRegistered($interface)
201
    {
202 49
        $hasNotRegistered = ! isset($this->container->getContainer()[$interface . '-' . Name::ANY]);
203
204 49
        return $hasNotRegistered;
205
    }
206
207
    /**
208
     * Return string
209
     *
210
     * input: [['varA' => 'nameA'], ['varB' => 'nameB']]
211
     * output: "varA=nameA,varB=nameB"
212
     *
213
     * @param array $name
214
     *
215
     * @return string
216
     */
217
    private function getStringName(array $name)
218
    {
219 1
        $names = array_reduce(array_keys($name), function ($carry, $key) use ($name) {
220 1
            $carry[] .= $key . '=' . $name[$key];
221
222 1
            return $carry;
223 1
        }, []);
224 1
        $string = implode(',', $names);
225
226 1
        return $string;
227
    }
228
}
229