Issues (101)

src/di/AbstractModule.php (2 issues)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Di;
6
7
use Ray\Aop\AbstractMatcher;
8
use Ray\Aop\Matcher;
9
use Ray\Aop\Pointcut;
10
use Ray\Aop\PriorityPointcut;
11
12
use function assert;
13
use function class_exists;
14
use function interface_exists;
15
16
/**
17
 * @psalm-import-type BindableInterface from Types
18
 * @psalm-import-type PointcutList from Types
19
 * @psalm-import-type InterceptorClassList from Types
20
 */
21
abstract class AbstractModule
22
{
23
    /** @var Matcher */
24
    protected $matcher;
25
26
    /** @var ?AbstractModule */
27
    protected $lastModule;
28
29
    /** @var ?Container */
30
    private $container;
31
32
    public function __construct(
33
        ?self $module = null
34
    ) {
35
        $this->lastModule = $module;
36
        $this->activate();
37
        assert($this->container instanceof Container);
38
        if ($module instanceof self) {
39
            $this->container->merge($module->getContainer());
40
        }
41
    }
42
43
    public function __toString(): string
44
    {
45
        return (new ModuleString())($this->getContainer(), $this->getContainer()->getPointcuts());
46
    }
47
48
    /**
49
     * Install module
50
     */
51
    public function install(self $module): void
52
    {
53
        $this->getContainer()->merge($module->getContainer());
54
    }
55
56
    /**
57
     * Override module
58
     */
59
    public function override(self $module): void
60
    {
61
        $module->getContainer()->merge($this->getContainer());
62
        $this->container = $module->getContainer();
63
    }
64
65
    /**
66
     * Return activated container
67
     */
68
    public function getContainer(): Container
69
    {
70
        if (! $this->container instanceof Container) {
71
            $this->activate();
72
            assert($this->container instanceof Container);
73
        }
74
75
        return $this->container;
76
    }
77
78
    /**
79
     * Bind interceptor
80
     *
81
     * @param InterceptorClassList $interceptors
0 ignored issues
show
The type Ray\Di\InterceptorClassList 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...
82
     */
83
    public function bindInterceptor(AbstractMatcher $classMatcher, AbstractMatcher $methodMatcher, array $interceptors): void
84
    {
85
        $pointcut = new Pointcut($classMatcher, $methodMatcher, $interceptors);
86
        $this->getContainer()->addPointcut($pointcut);
87
        foreach ($interceptors as $interceptor) {
88
            if (class_exists($interceptor)) {
89
                (new Bind($this->getContainer(), $interceptor))->to($interceptor)->in(Scope::SINGLETON);
90
91
                return;
92
            }
93
94
            assert(interface_exists($interceptor));
95
            (new Bind($this->getContainer(), $interceptor))->in(Scope::SINGLETON);
96
        }
97
    }
98
99
    /**
100
     * Bind interceptor early
101
     *
102
     * @param InterceptorClassList $interceptors
103
     */
104
    public function bindPriorityInterceptor(AbstractMatcher $classMatcher, AbstractMatcher $methodMatcher, array $interceptors): void
105
    {
106
        $pointcut = new PriorityPointcut($classMatcher, $methodMatcher, $interceptors);
107
        $this->getContainer()->addPointcut($pointcut);
108
        foreach ($interceptors as $interceptor) {
109
            (new Bind($this->getContainer(), $interceptor))->to($interceptor)->in(Scope::SINGLETON);
110
        }
111
    }
112
113
    /**
114
     * Rename binding name
115
     *
116
     * @param string $interface       Interface
117
     * @param string $newName         New binding name
118
     * @param string $sourceName      Original binding name
119
     * @param string $targetInterface Original interface
120
     */
121
    public function rename(string $interface, string $newName, string $sourceName = Name::ANY, string $targetInterface = ''): void
122
    {
123
        $targetInterface = $targetInterface ?: $interface;
124
        if ($this->lastModule instanceof self) {
125
            $this->lastModule->getContainer()->move($interface, $sourceName, $targetInterface, $newName);
126
        }
127
    }
128
129
    /**
130
     * Configure binding
131
     *
132
     * @return void
133
     *
134
     * @noinspection ReturnTypeCanBeDeclaredInspection
135
     */
136
    abstract protected function configure();
137
138
    /**
139
     * Bind interface
140
     *
141
     * @param BindableInterface $interface
0 ignored issues
show
The type Ray\Di\BindableInterface 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...
142
     */
143
    protected function bind(string $interface = ''): Bind
144
    {
145
        return new Bind($this->getContainer(), $interface);
146
    }
147
148
    /**
149
     * Activate bindings
150
     */
151
    private function activate(): void
152
    {
153
        $this->container = new Container();
154
        $this->matcher = new Matcher();
155
        $this->configure();
156
    }
157
}
158