Test Failed
Pull Request — master (#870)
by Aleksei
08:56
created

StateBinder::bindSingleton()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 4
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Core\Internal\Config;
6
7
use Spiral\Core\BinderInterface;
8
use Spiral\Core\Container\Autowire;
9
use Spiral\Core\Container\InjectableInterface;
10
use Spiral\Core\Exception\Container\ContainerException;
11
use Spiral\Core\Internal\State;
12
13
/**
14
 * @psalm-import-type TResolver from BinderInterface
15
 * @internal
16
 */
17
class StateBinder implements BinderInterface
18
{
19
    public function __construct(
20
        protected readonly State $state,
21
    ) {
22
    }
23
24
    /**
25
     * @param TResolver|object $resolver
0 ignored issues
show
Bug introduced by
The type Spiral\Core\Internal\Config\TResolver 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...
26
     */
27
    public function bind(string $alias, string|array|callable|object $resolver): void
28
    {
29
        if (\is_array($resolver) || $resolver instanceof \Closure || $resolver instanceof Autowire) {
0 ignored issues
show
introduced by
The condition is_array($resolver) is always true.
Loading history...
30
            // array means = execute me, false = not singleton
31
            $this->state->bindings[$alias] = [$resolver, false];
32
33
            return;
34
        }
35
36
        $this->state->bindings[$alias] = $resolver;
37
    }
38
39
    /**
40
     * @param TResolver|object $resolver
41
     */
42
    public function bindSingleton(string $alias, string|array|callable|object $resolver): void
43
    {
44
        if (\is_object($resolver) && !$resolver instanceof \Closure && !$resolver instanceof Autowire) {
0 ignored issues
show
introduced by
The condition is_object($resolver) is always false.
Loading history...
45
            // direct binding to an instance
46
            $this->state->bindings[$alias] = $resolver;
47
48
            return;
49
        }
50
51
        $this->state->bindings[$alias] = [$resolver, true];
52
    }
53
54
    public function hasInstance(string $alias): bool
55
    {
56
        $bindings = &$this->state->bindings;
57
58
        while (\is_string($bindings[$alias] ?? null)) {
59
            //Checking alias tree
60
            $alias = $bindings[$alias];
61
        }
62
63
        return isset($bindings[$alias]) && \is_object($bindings[$alias]);
64
    }
65
66
    public function removeBinding(string $alias): void
67
    {
68
        unset($this->state->bindings[$alias]);
69
    }
70
71
    public function bindInjector(string $class, string $injector): void
72
    {
73
        $this->state->injectors[$class] = $injector;
74
    }
75
76
    public function removeInjector(string $class): void
77
    {
78
        unset($this->state->injectors[$class]);
79
    }
80
81
    public function hasInjector(string $class): bool
82
    {
83
        try {
84
            $reflection = new \ReflectionClass($class);
85
        } catch (\ReflectionException $e) {
86
            throw new ContainerException($e->getMessage(), $e->getCode(), $e);
87
        }
88
89
        if (\array_key_exists($class, $this->state->injectors)) {
90
            return $this->state->injectors[$class] !== null;
91
        }
92
93
        if (
94
            $reflection->implementsInterface(InjectableInterface::class)
95
            && $reflection->hasConstant('INJECTOR')
96
        ) {
97
            $this->state->injectors[$class] = $reflection->getConstant('INJECTOR');
98
99
            return true;
100
        }
101
102
        // check interfaces
103
        foreach ($this->state->injectors as $target => $injector) {
104
            if (
105
                \class_exists($target, true)
106
                && $reflection->isSubclassOf($target)
107
            ) {
108
                $this->state->injectors[$class] = $injector;
109
110
                return true;
111
            }
112
113
            if (
114
                \interface_exists($target, true)
115
                && $reflection->implementsInterface($target)
116
            ) {
117
                $this->state->injectors[$class] = $injector;
118
119
                return true;
120
            }
121
        }
122
123
        return false;
124
    }
125
}
126