Code

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