Completed
Push — master ( 2e5bdd...9e2471 )
by Ryuichi
05:26
created

Injector::strictInject()   B

Complexity

Conditions 5
Paths 13

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 0
cts 0
cp 0
rs 8.5906
c 0
b 0
f 0
cc 5
crap 30
eloc 16
nc 13
nop 2
1
<?php
2
namespace WebStream\DI;
3
4
use WebStream\Container\Container;
5
use WebStream\Exception\Extend\AnnotationException;
6
use PhpDocReader\PhpDocReader;
7
8
/**
9
 * Injector
10
 * @author Ryuichi TANAKA.
11
 * @since 2015/12/26
12
 * @version 0.7
13
 */
14
trait Injector
15
{
16
    /**
17
     * @var Container プロパティコンテナ
18
     */
19
    private $__propertyContainer;
20
21
    /**
22
     * オブジェクトを注入する
23
     * @param string プロパティ名
24
     * @param mixed オブジェクト
25
     * @return Injector
26
     */
27
    public function inject(string $name, $object)
28
    {
29
        $this->{$name} = $object;
30
31
        return $this;
32
    }
33
34
    /**
35
     * 型指定されたオブジェクトを注入する
36
     * @param string プロパティ名
37
     * @param mixed オブジェクト
38
     * @return Injector
39
     */
40
    public function strictInject(string $name, $object)
41
    {
42
        $reader = new PhpDocReader();
43
        try {
44
            $refClass = new \ReflectionClass($this);
45
            while ($refClass !== false) {
46
                if ($refClass->hasProperty($name)) {
47
                    $refProperty = $refClass->getProperty($name);
48
                    $classpath = $reader->getPropertyClass($refProperty);
49
                    if ($object instanceof $classpath) {
50
                        $this->inject($name, $object);
51
                    } else {
52
                        throw new AnnotationException("The type of injected property must be instance of ${classpath}");
53
                    }
54
                }
55
                $refClass = $refClass->getParentClass();
56
            }
57
        } catch (\ReflectionException $e) {
58
            throw new AnnotationException($e);
59
        }
60
61
        return $this;
62
    }
63
64
    /**
65
     * overload setter
66
     */
67
    public function __set($name, $value)
68
    {
69
        if ($this->__propertyContainer === null) {
70
            $this->__propertyContainer = new Container(false);
71
        }
72
        $this->__propertyContainer->{$name} = $value;
73
    }
74
75
    /**
76
     * overload setter
77
     */
78
    public function __get($name)
79
    {
80
        return $this->__propertyContainer !== null ? $this->__propertyContainer->{$name} : null;
81
    }
82
83
    /**
84
     * overload isset
85
     */
86
    public function __isset($name)
87
    {
88
        return $__propertyContainer === null || $__propertyContainer->{$name} === null;
89
    }
90
91
    /**
92
     * overload unset
93
     */
94
    public function __unset($name)
95
    {
96
        $this->__propertyContainer->remove($name);
97
    }
98
99
    /**
100
     * コンテナクリア
101
     */
102
    public function __clear()
103
    {
104
        $this->__propertyContainer = null;
105
    }
106
}
107