Entry::negotiateReify()   B
last analyzed

Complexity

Conditions 8
Paths 6

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 8

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 11
dl 0
loc 19
ccs 11
cts 11
cp 1
rs 8.4444
c 1
b 0
f 0
cc 8
nc 6
nop 1
crap 8
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Conia\Chuck\Di;
6
7
use Closure;
8
use Conia\Chuck\Exception\ContainerException;
9
10
/**
11
 * @psalm-api
12
 *
13
 * @psalm-type Args array<string|mixed>|Closure(): array<string|mixed>
14
 */
15
class Entry
16
{
17
    /** @psalm-var null|Args */
18
    protected array|Closure|null $args = null;
19
    protected ?string $constructor = null;
20
    protected bool $asIs = false;
21
    protected bool $reify;
22
    protected mixed $instance = null;
23
24
    /** @psalm-var list<Call> */
25
    protected array $calls = [];
26
27
    /**
28
     * @psalm-param non-empty-string $id
29
     * */
30 163
    public function __construct(
31
        readonly protected string $id,
32
        protected mixed $definition
33
    ) {
34 163
        $this->reify = $this->negotiateReify($definition);
35
    }
36
37 3
    public function reify(bool $reify = true): static
38
    {
39 3
        $this->reify = $reify;
40
41 3
        return $this;
42
    }
43
44 96
    public function shouldReify(): bool
45
    {
46 96
        return $this->reify;
47
    }
48
49 3
    public function asIs(bool $asIs = true): static
50
    {
51
        // An update call is unecessary
52 3
        if ($asIs) {
53 3
            $this->reify = false;
54
        }
55
56 3
        $this->asIs = $asIs;
57
58 3
        return $this;
59
    }
60
61 103
    public function shouldReturnAsIs(): bool
62
    {
63 103
        return $this->asIs;
64
    }
65
66 130
    public function args(mixed ...$args): static
67
    {
68 130
        $numArgs = count($args);
69
70 130
        if ($numArgs === 1) {
71 7
            if (is_string(array_key_first($args))) {
72
                /** @psalm-var Args */
73 1
                $this->args = $args;
74 6
            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
75
                /** @psalm-var Args */
76 5
                $this->args = $args[0];
77
            } else {
78 7
                throw new ContainerException(
79 7
                    'Registry entry arguments can be passed as a single associative array, ' .
80 7
                    'as named arguments, or as a Closure'
81 7
                );
82
            }
83 125
        } elseif ($numArgs > 1) {
84 125
            if (!is_string(array_key_first($args))) {
85 1
                throw new ContainerException(
86 1
                    'Registry entry arguments can be passed as a single associative array, ' .
87 1
                    'as named arguments, or as a Closure'
88 1
                );
89
            }
90
91 124
            $this->args = $args;
92
        }
93
94 128
        return $this;
95
    }
96
97 96
    public function getArgs(): array|Closure|null
98
    {
99 96
        return $this->args;
100
    }
101
102 123
    public function constructor(string $methodName): static
103
    {
104 123
        $this->constructor = $methodName;
105
106 123
        return $this;
107
    }
108
109 91
    public function getConstructor(): ?string
110
    {
111 91
        return $this->constructor;
112
    }
113
114 2
    public function call(string $method, mixed ...$args): static
115
    {
116 2
        $this->calls[] = new Call($method, ...$args);
117
118 2
        return $this;
119
    }
120
121
    /** @psalm-return list<Call> */
122 95
    public function getCalls(): array
123
    {
124 95
        return $this->calls;
125
    }
126
127 10
    public function definition(): mixed
128
    {
129 10
        return $this->definition;
130
    }
131
132 3
    public function instance(): mixed
133
    {
134 3
        return $this->instance;
135
    }
136
137 102
    public function get(): mixed
138
    {
139 102
        return $this->instance ?? $this->definition;
140
    }
141
142 94
    public function set(mixed $instance): void
143
    {
144 94
        $this->instance = $instance;
145
    }
146
147 163
    protected function negotiateReify(mixed $definition): bool
148
    {
149 163
        if (is_string($definition)) {
150 143
            if (is_callable($definition)) {
151 1
                return true;
152
            }
153
154 143
            if (!class_exists($definition)) {
155 143
                return false;
156
            }
157 161
        } elseif ($definition instanceof Closure) {
158 99
            return true;
159
        } else {
160 161
            if (is_scalar($definition) || is_array($definition) || is_object($definition)) {
161 161
                return false;
162
            }
163
        }
164
165 142
        return true;
166
    }
167
}
168