Issues (101)

src/di/Dependency.php (2 issues)

Labels
Severity
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
use ReflectionClass;
12
use ReflectionMethod;
13
14
use function assert;
15
use function method_exists;
16
use function sprintf;
17
18
/**
19
 * @psalm-import-type MethodArguments from Types
20
 * @psalm-import-type PointcutList from Types
21
 */
22
final class Dependency implements DependencyInterface, AcceptInterface
23
{
24
    /** @var NewInstance */
25
    private $newInstance;
26
27
    /** @var ?string */
28
    private $postConstruct;
29
30
    /** @var bool */
31
    private $isSingleton = false;
32
33
    /** @var ?mixed */
34
    private $instance;
35
36
    public function __construct(NewInstance $newInstance, ?ReflectionMethod $postConstruct = null)
37
    {
38
        $this->newInstance = $newInstance;
39
        $this->postConstruct = $postConstruct->name ?? null;
40
    }
41
42
    /**
43
     * @return array<string>
44
     */
45
    public function __sleep()
46
    {
47
        return ['newInstance', 'postConstruct', 'isSingleton'];
48
    }
49
50
    public function __toString(): string
51
    {
52
        return sprintf(
53
            '(dependency) %s',
54
            (string) $this->newInstance
55
        );
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61
    public function register(array &$container, Bind $bind): void
62
    {
63
        $container[(string) $bind] = $bind->getBound();
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69
    public function inject(Container $container)
70
    {
71
        // singleton ?
72
        if ($this->isSingleton === true && $this->instance !== null) {
73
            return $this->instance;
74
        }
75
76
        // create dependency injected instance
77
        $this->instance = ($this->newInstance)($container);
78
79
        // @PostConstruct
80
        if ($this->postConstruct !== null) {
81
            assert(method_exists($this->instance, $this->postConstruct));
82
            $this->instance->{$this->postConstruct}();
83
        }
84
85
        return $this->instance;
86
    }
87
88
    /**
89
     * @param MethodArguments $params
0 ignored issues
show
The type Ray\Di\MethodArguments was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
90
     *
91
     * @return mixed
92
     */
93
    public function injectWithArgs(Container $container, array $params)
94
    {
95
        // singleton ?
96
        if ($this->isSingleton === true && $this->instance !== null) {
97
            return $this->instance;
98
        }
99
100
        // create dependency injected instance
101
        $this->instance = $this->newInstance->newInstanceArgs($container, $params);
102
103
        // @PostConstruct
104
        if ($this->postConstruct !== null) {
105
            assert(method_exists($this->instance, $this->postConstruct));
106
            $this->instance->{$this->postConstruct}();
107
        }
108
109
        return $this->instance;
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function setScope($scope): void
116
    {
117
        if ($scope === Scope::SINGLETON) {
118
            $this->isSingleton = true;
119
        }
120
    }
121
122
    /**
123
     * @param PointcutList $pointcuts
0 ignored issues
show
The type Ray\Di\PointcutList was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
124
     */
125
    public function weaveAspects(CompilerInterface $compiler, array $pointcuts): void
126
    {
127
        $class = (string) $this->newInstance;
128
        if ((new ReflectionClass($class))->isFinal()) {
129
            return;
130
        }
131
132
        $isInterceptor = (new ReflectionClass($class))->implementsInterface(MethodInterceptor::class);
133
        $isWeaved = (new ReflectionClass($class))->implementsInterface(WeavedInterface::class);
134
        if ($isInterceptor || $isWeaved) {
135
            return;
136
        }
137
138
        $bind = new AopBind();
139
        $className = (string) $this->newInstance;
140
        $bind->bind($className, $pointcuts);
141
        if (! $bind->getBindings()) {
142
            return;
143
        }
144
145
        $class = $compiler->compile($className, $bind);
146
        $this->newInstance->weaveAspects($class, $bind);
147
    }
148
149
    /** @inheritDoc */
150
    public function accept(VisitorInterface $visitor)
151
    {
152
        return $visitor->visitDependency(
153
            $this->newInstance,
154
            $this->postConstruct,
155
            $this->isSingleton
156
        );
157
    }
158
159
    public function isSingleton(): bool
160
    {
161
        return $this->isSingleton;
162
    }
163
}
164