Completed
Push — with-args ( 95d9fd )
by Akihito
01:35
created

Dependency::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Di;
6
7
use Ray\Aop\Bind as AopBind;
8
use Ray\Aop\CompilerInterface;
9
use Ray\Aop\MethodInterceptor;
10
use Ray\Aop\WeavedInterface;
11
12
final class Dependency implements DependencyInterface
13
{
14
    /**
15
     * @var NewInstance
16
     */
17
    private $newInstance;
18
19
    /**
20
     * @var null|string
21
     */
22
    private $postConstruct;
23
24
    /**
25
     * @var bool
26
     */
27
    private $isSingleton = false;
28
29
    /**
30
     * @var mixed
31
     */
32
    private $instance;
33
34
    /**
35
     * @var string
36
     */
37
    private $index;
38
39
    /**
40
     * @param \ReflectionMethod $postConstruct
41
     */
42
    public function __construct(NewInstance $newInstance, \ReflectionMethod $postConstruct = null)
43
    {
44
        $this->newInstance = $newInstance;
45
        $this->postConstruct = $postConstruct ? $postConstruct->name : null;
46
    }
47
48
    public function __sleep()
49
    {
50
        return ['newInstance', 'postConstruct', 'isSingleton'];
51
    }
52
53
    public function __toString()
54
    {
55
        return sprintf(
56
            '(dependency) %s',
57
            (string) $this->newInstance
58
        );
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function register(array &$container, Bind $bind)
65
    {
66
        $this->index = $index = (string) $bind;
67
        $container[$index] = $bind->getBound();
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73
    public function inject(Container $container)
74
    {
75
        // singleton ?
76
        if ($this->isSingleton === true && $this->instance) {
77
            return $this->instance;
78
        }
79
80
        // create dependency injected instance
81
        $this->instance = ($this->newInstance)($container);
82
83
        // @PostConstruct
84
        if ($this->postConstruct) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->postConstruct of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
85
            $this->instance->{$this->postConstruct}();
86
        }
87
88
        return $this->instance;
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function injectWithArgs(Container $container, array $params)
95
    {
96
        // singleton ?
97
        if ($this->isSingleton === true && $this->instance) {
98
            return $this->instance;
99
        }
100
101
        // create dependency injected instance
102
        $this->instance = $this->newInstance->newInstanceArgs($container, $params);
103
104
        // @PostConstruct
105
        if ($this->postConstruct) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->postConstruct of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
106
            $this->instance->{$this->postConstruct}();
107
        }
108
109
        return $this->instance;
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function setScope($scope)
116
    {
117
        if ($scope === Scope::SINGLETON) {
118
            $this->isSingleton = true;
119
        }
120
    }
121
122
    public function weaveAspects(CompilerInterface $compiler, array $pointcuts)
123
    {
124
        $class = (string) $this->newInstance;
125
        $isInterceptor = (new \ReflectionClass($class))->implementsInterface(MethodInterceptor::class);
126
        $isWeaved = (new \ReflectionClass($class))->implementsInterface(WeavedInterface::class);
127
        if ($isInterceptor || $isWeaved) {
128
            return;
129
        }
130
        $bind = new AopBind;
131
        $bind->bind((string) $this->newInstance, $pointcuts);
132
        if (! $bind->getBindings()) {
133
            return;
134
        }
135
        $class = $compiler->compile((string) $this->newInstance, $bind);
136
        $this->newInstance->weaveAspects($class, $bind);
137
    }
138
}
139