Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
100.00% |
202 / 202 |
|
96.08% |
147 / 153 |
|
47.97% |
71 / 148 |
|
83.33% |
20 / 24 |
CRAP | |
0.00% |
0 / 1 |
| Container | |
100.00% |
202 / 202 |
|
96.08% |
147 / 153 |
|
47.97% |
71 / 148 |
|
100.00% |
24 / 24 |
981.30 | |
100.00% |
1 / 1 |
| __construct | |
100.00% |
8 / 8 |
|
100.00% |
4 / 4 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| scope | |
100.00% |
8 / 8 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| reset | |
100.00% |
4 / 4 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| has | |
100.00% |
5 / 5 |
|
100.00% |
5 / 5 |
|
75.00% |
3 / 4 |
|
100.00% |
1 / 1 |
3.14 | |||
| entries | |
100.00% |
7 / 7 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
3 | |||
| entry | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| get | |
100.00% |
30 / 30 |
|
95.24% |
20 / 21 |
|
66.67% |
8 / 12 |
|
100.00% |
1 / 1 |
12.00 | |||
| definition | |
100.00% |
5 / 5 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| add | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| addEntry | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| tag | |
100.00% |
17 / 17 |
|
100.00% |
9 / 9 |
|
57.14% |
4 / 7 |
|
100.00% |
1 / 1 |
6.97 | |||
| new | |
100.00% |
11 / 11 |
|
86.67% |
13 / 15 |
|
21.05% |
4 / 19 |
|
100.00% |
1 / 1 |
23.71 | |||
| resolveEntry | |
100.00% |
13 / 13 |
|
100.00% |
9 / 9 |
|
57.14% |
4 / 7 |
|
100.00% |
1 / 1 |
6.97 | |||
| resolutionContainers | |
100.00% |
5 / 5 |
|
77.78% |
7 / 9 |
|
75.00% |
3 / 4 |
|
100.00% |
1 / 1 |
4.25 | |||
| materialize | |
100.00% |
35 / 35 |
|
95.24% |
20 / 21 |
|
39.13% |
9 / 23 |
|
100.00% |
1 / 1 |
32.55 | |||
| applyCalls | |
100.00% |
6 / 6 |
|
100.00% |
4 / 4 |
|
66.67% |
2 / 3 |
|
100.00% |
1 / 1 |
2.15 | |||
| resetScope | |
100.00% |
14 / 14 |
|
100.00% |
12 / 12 |
|
13.89% |
5 / 36 |
|
100.00% |
1 / 1 |
20.96 | |||
| resetIfNeeded | |
100.00% |
7 / 7 |
|
100.00% |
5 / 5 |
|
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
| trackAndReturn | |
100.00% |
3 / 3 |
|
100.00% |
5 / 5 |
|
75.00% |
3 / 4 |
|
100.00% |
1 / 1 |
3.14 | |||
| findEntry | |
100.00% |
4 / 4 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| root | |
100.00% |
4 / 4 |
|
100.00% |
4 / 4 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| assertMutable | |
100.00% |
2 / 2 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| seal | |
100.00% |
3 / 3 |
|
100.00% |
4 / 4 |
|
66.67% |
2 / 3 |
|
100.00% |
1 / 1 |
2.15 | |||
| isRoot | |
100.00% |
1 / 1 |
|
100.00% |
5 / 5 |
|
50.00% |
2 / 4 |
|
100.00% |
1 / 1 |
4.12 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace Celemas\Container; |
| 6 | |
| 7 | use Celemas\Container\Exception\ContainerException; |
| 8 | use Celemas\Container\Exception\NotFoundException; |
| 9 | use Celemas\Wire\CallableResolver; |
| 10 | use Celemas\Wire\Creator; |
| 11 | use Celemas\Wire\Exception\WireException; |
| 12 | use Celemas\Wire\WireContainer; |
| 13 | use Closure; |
| 14 | use Override; |
| 15 | use Psr\Container\ContainerExceptionInterface; |
| 16 | use Psr\Container\ContainerInterface as PsrContainer; |
| 17 | use Throwable; |
| 18 | |
| 19 | /** @psalm-api */ |
| 20 | class Container implements WireContainer |
| 21 | { |
| 22 | protected Creator $creator; |
| 23 | protected readonly ?PsrContainer $wrappedContainer; |
| 24 | protected bool $sealed = false; |
| 25 | |
| 26 | /** @var array<string, Entry> */ |
| 27 | protected array $entries = []; |
| 28 | |
| 29 | /** @var array<string, mixed> */ |
| 30 | protected array $instances = []; |
| 31 | |
| 32 | /** @var array<non-empty-string, self> */ |
| 33 | protected array $tags = []; |
| 34 | |
| 35 | /** @var array<int, Resettable> */ |
| 36 | protected array $usedResettables = []; |
| 37 | |
| 38 | public function __construct( |
| 39 | public readonly bool $autowire = true, |
| 40 | ?PsrContainer $container = null, |
| 41 | protected readonly string $tag = '', |
| 42 | protected readonly ?Container $parent = null, |
| 43 | protected readonly bool $isScope = false, |
| 44 | ) { |
| 45 | if ($container) { |
| 46 | $this->wrappedContainer = $container; |
| 47 | $this->add(PsrContainer::class, $container); |
| 48 | $this->add($container::class, $container); |
| 49 | } else { |
| 50 | $this->wrappedContainer = null; |
| 51 | $this->add(PsrContainer::class, $this); |
| 52 | } |
| 53 | $this->add(Container::class, $this); |
| 54 | $this->creator = new Creator($this); |
| 55 | } |
| 56 | |
| 57 | public function scope(): Container |
| 58 | { |
| 59 | $root = $this->root(); |
| 60 | |
| 61 | if (!$root->sealed) { |
| 62 | $root->seal(); |
| 63 | } |
| 64 | |
| 65 | return new self( |
| 66 | autowire: $root->autowire, |
| 67 | parent: $root, |
| 68 | isScope: true, |
| 69 | ); |
| 70 | } |
| 71 | |
| 72 | public function reset(): void |
| 73 | { |
| 74 | if (!$this->isScope) { |
| 75 | return; |
| 76 | } |
| 77 | |
| 78 | $resetIds = []; |
| 79 | $this->resetScope($resetIds); |
| 80 | } |
| 81 | |
| 82 | #[Override] |
| 83 | public function has(string $id): bool |
| 84 | { |
| 85 | return ( |
| 86 | isset($this->entries[$id]) |
| 87 | || $this->parent?->has($id) |
| 88 | || $this->wrappedContainer?->has($id) |
| 89 | ); |
| 90 | } |
| 91 | |
| 92 | /** @return list<string> */ |
| 93 | public function entries(bool $includeContainer = false): array |
| 94 | { |
| 95 | $keys = array_keys($this->entries); |
| 96 | |
| 97 | if ($includeContainer) { |
| 98 | return $keys; |
| 99 | } |
| 100 | |
| 101 | return array_values(array_filter( |
| 102 | $keys, |
| 103 | static fn($item) => $item !== PsrContainer::class && !is_subclass_of($item, PsrContainer::class), |
| 104 | )); |
| 105 | } |
| 106 | |
| 107 | public function entry(string $id): Entry |
| 108 | { |
| 109 | return $this->entries[$id]; |
| 110 | } |
| 111 | |
| 112 | #[Override] |
| 113 | public function get(string $id): mixed |
| 114 | { |
| 115 | try { |
| 116 | if (array_key_exists($id, $this->instances)) { |
| 117 | return $this->trackAndReturn($this->instances[$id]); |
| 118 | } |
| 119 | |
| 120 | $resolved = $this->findEntry($id); |
| 121 | |
| 122 | if ($resolved !== null) { |
| 123 | return $this->trackAndReturn( |
| 124 | $this->resolveEntry( |
| 125 | entryOwner: $resolved[0], |
| 126 | entry: $resolved[1], |
| 127 | id: $id, |
| 128 | requester: $this, |
| 129 | ), |
| 130 | ); |
| 131 | } |
| 132 | |
| 133 | $wrappedContainer = $this->root()->wrappedContainer; |
| 134 | |
| 135 | if ($wrappedContainer?->has($id)) { |
| 136 | return $this->trackAndReturn($wrappedContainer->get($id)); |
| 137 | } |
| 138 | |
| 139 | // Autowiring: $id does not exists as an entry in the container |
| 140 | if ($this->autowire && class_exists($id)) { |
| 141 | return $this->trackAndReturn($this->creator->create($id)); |
| 142 | } |
| 143 | } catch (WireException $e) { |
| 144 | throw new NotFoundException( |
| 145 | 'Unresolvable id: ' . $id . ' - Details: ' . $e->getMessage(), |
| 146 | previous: $e, |
| 147 | ); |
| 148 | } catch (ContainerExceptionInterface $e) { |
| 149 | throw $e; |
| 150 | } catch (Throwable $e) { |
| 151 | throw new ContainerException( |
| 152 | 'Unresolvable id: ' . $id . ' - ' . $e->getMessage(), |
| 153 | previous: $e, |
| 154 | ); |
| 155 | } |
| 156 | |
| 157 | throw new NotFoundException('Unresolvable id: ' . $id); |
| 158 | } |
| 159 | |
| 160 | #[Override] |
| 161 | public function definition(string $id): mixed |
| 162 | { |
| 163 | $resolved = $this->findEntry($id); |
| 164 | $entry = $resolved[1] ?? null; |
| 165 | |
| 166 | if ($entry !== null) { |
| 167 | return $entry->definition(); |
| 168 | } |
| 169 | |
| 170 | throw new NotFoundException('Unresolvable definition - id: ' . $id); |
| 171 | } |
| 172 | |
| 173 | /** |
| 174 | * @param non-empty-string $id |
| 175 | */ |
| 176 | public function add( |
| 177 | string $id, |
| 178 | mixed $value = null, |
| 179 | ): Entry { |
| 180 | $this->assertMutable(); |
| 181 | $entry = new Entry($id, $value ?? $id); |
| 182 | $this->entries[$id] = $entry; |
| 183 | unset($this->instances[$id]); |
| 184 | |
| 185 | return $entry; |
| 186 | } |
| 187 | |
| 188 | public function addEntry( |
| 189 | Entry $entry, |
| 190 | ): Entry { |
| 191 | $this->assertMutable(); |
| 192 | $this->entries[$entry->id] = $entry; |
| 193 | unset($this->instances[$entry->id]); |
| 194 | |
| 195 | return $entry; |
| 196 | } |
| 197 | |
| 198 | /** @param non-empty-string $tag */ |
| 199 | public function tag(string $tag): Container |
| 200 | { |
| 201 | if (isset($this->tags[$tag])) { |
| 202 | return $this->tags[$tag]; |
| 203 | } |
| 204 | |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 206 | throw new ContainerException('The root container is sealed after scope() was called'); |
| 207 | } |
| 208 | |
| 209 | $parent = $this; |
| 210 | $isScope = false; |
| 211 | |
| 212 | if ($this->isScope) { |
| 213 | $root = $this->root(); |
| 214 | $parent = $root->tags[$tag] ?? $root; |
| 215 | $isScope = true; |
| 216 | } |
| 217 | |
| 218 | $this->tags[$tag] = new self( |
| 219 | autowire: $this->autowire, |
| 220 | tag: $tag, |
| 221 | parent: $parent, |
| 222 | isScope: $isScope, |
| 223 | ); |
| 224 | |
| 225 | return $this->tags[$tag]; |
| 226 | } |
| 227 | |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 233 | /** @var mixed $value */ |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 238 | return $this->new($value, ...$args); |
| 239 | } |
| 240 | |
| 241 | if (class_exists($value)) { |
| 242 | /** @psalm-suppress MixedMethodCall */ |
| 243 | return new $value(...$args); |
| 244 | } |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | if (class_exists($id)) { |
| 249 | /** @psalm-suppress MixedMethodCall */ |
| 250 | return new $id(...$args); |
| 251 | } |
| 252 | |
| 253 | throw new NotFoundException('Cannot instantiate ' . $id); |
| 254 | } |
| 255 | |
| 256 | protected function resolveEntry( |
| 257 | Container $entryOwner, |
| 258 | Entry $entry, |
| 259 | string $id, |
| 260 | Container $requester, |
| 261 | ): mixed { |
| 262 | if ($entry->shouldReturnValue()) { |
| 263 | return $entry->definition(); |
| 264 | } |
| 265 | |
| 266 | [$cacheContainer, $resolutionContext] = $this->resolutionContainers( |
| 267 | $entry, |
| 268 | $entryOwner, |
| 269 | $requester, |
| 270 | ); |
| 271 | |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 273 | return $cacheContainer->instances[$id]; |
| 274 | } |
| 275 | |
| 276 | // materialize() intentionally returns mixed because container entries may resolve to any value type. |
| 277 | /** @psalm-suppress MixedAssignment */ |
| 278 | $result = $this->materialize($entry, $resolutionContext); |
| 279 | |
| 280 | if ($cacheContainer !== null) { |
| 281 | $cacheContainer->instances[$id] = $result; |
| 282 | } |
| 283 | |
| 284 | return $result; |
| 285 | } |
| 286 | |
| 287 | /** |
| 288 | * @return array{0: null|Container, 1: Container} |
| 289 | */ |
| 290 | protected function resolutionContainers( |
| 291 | Entry $entry, |
| 292 | Container $entryOwner, |
| 293 | Container $requester, |
| 294 | ): array { |
| 295 | return match ($entry->getLifetime()) { |
| 296 | Lifetime::Shared => [$entryOwner, $entryOwner], |
| 297 | Lifetime::Scoped => [$requester, $requester], |
| 298 | Lifetime::Transient => [null, $requester], |
| 299 | }; |
| 300 | } |
| 301 | |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 309 | $constructor = $entry->getConstructor(); |
| 310 | $args = $entry->getArgs(); |
| 311 | |
| 312 | if (isset($args)) { |
| 313 | // Don't autowire if $args are given |
| 314 | if ($args instanceof Closure) { |
| 315 | $args = $args(...new CallableResolver($context->creator)->resolve($args)); |
| 316 | |
| 317 | return $this->applyCalls($entry, $context->creator->create($value, $args), $context); |
| 318 | } |
| 319 | |
| 320 | return $this->applyCalls( |
| 321 | $entry, |
| 322 | $context->creator->create( |
| 323 | $value, |
| 324 | predefinedArgs: $args, |
| 325 | constructor: $constructor ?? '', |
| 326 | ), |
| 327 | $context, |
| 328 | ); |
| 329 | } |
| 330 | |
| 331 | return $this->applyCalls( |
| 332 | $entry, |
| 333 | $context->creator->create($value, constructor: $constructor ?? ''), |
| 334 | $context, |
| 335 | ); |
| 336 | } |
| 337 | |
| 338 | if ($context->has($value)) { |
| 339 | return $context->get($value); |
| 340 | } |
| 341 | } |
| 342 | |
| 343 | if ($value instanceof Closure) { |
| 344 | $args = $entry->getArgs(); |
| 345 | |
| 346 | if (is_null($args)) { |
| 347 | $args = new CallableResolver($context->creator)->resolve($value); |
| 348 | } elseif ($args instanceof Closure) { |
| 349 | $args = $args(); |
| 350 | } |
| 351 | |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 353 | } |
| 354 | |
| 355 | if (is_object($value)) { |
| 356 | return $value; |
| 357 | } |
| 358 | |
| 359 | throw new NotFoundException('Unresolvable id: ' . (string) $value); |
| 360 | } |
| 361 | |
| 362 | protected function applyCalls(Entry $entry, mixed $value, Container $context): mixed |
| 363 | { |
| 364 | foreach ($entry->getCalls() as $call) { |
| 365 | $methodToResolve = $call->method; |
| 366 | |
| 367 | /** @var callable */ |
| 368 | $callable = [$value, $methodToResolve]; |
| 369 | $args = new CallableResolver($context->creator)->resolve($callable, $call->args); |
| 370 | $callable(...$args); |
| 371 | } |
| 372 | |
| 373 | return $value; |
| 374 | } |
| 375 | |
| 376 | /** |
| 377 | * @param array<int, true> $resetIds |
| 378 | */ |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 406 | |
| 407 | /** |
| 408 | * @param array<int, true> $resetIds |
| 409 | */ |
| 410 | protected function resetIfNeeded(mixed $value, array &$resetIds): void |
| 411 | { |
| 412 | if (!$value instanceof Resettable) { |
| 413 | return; |
| 414 | } |
| 415 | |
| 416 | $objectId = spl_object_id($value); |
| 417 | |
| 418 | if (isset($resetIds[$objectId])) { |
| 419 | return; |
| 420 | } |
| 421 | |
| 422 | $resetIds[$objectId] = true; |
| 423 | $value->reset(); |
| 424 | } |
| 425 | |
| 426 | protected function trackAndReturn(mixed $value): mixed |
| 427 | { |
| 428 | if ($this->isScope && $value instanceof Resettable) { |
| 429 | $this->usedResettables[spl_object_id($value)] = $value; |
| 430 | } |
| 431 | |
| 432 | return $value; |
| 433 | } |
| 434 | |
| 435 | /** @return array{Container, Entry}|null */ |
| 436 | protected function findEntry(string $id): ?array |
| 437 | { |
| 438 | $entry = $this->entries[$id] ?? null; |
| 439 | |
| 440 | if ($entry !== null) { |
| 441 | return [$this, $entry]; |
| 442 | } |
| 443 | |
| 444 | return $this->parent?->findEntry($id); |
| 445 | } |
| 446 | |
| 447 | protected function root(): Container |
| 448 | { |
| 449 | $container = $this; |
| 450 | |
| 451 | while ($container->parent !== null) { |
| 452 | $container = $container->parent; |
| 453 | } |
| 454 | |
| 455 | return $container; |
| 456 | } |
| 457 | |
| 458 | protected function assertMutable(): void |
| 459 | { |
| 460 | if ($this->sealed) { |
| 461 | throw new ContainerException('The root container is sealed after scope() was called'); |
| 462 | } |
| 463 | } |
| 464 | |
| 465 | protected function seal(): void |
| 466 | { |
| 467 | $this->sealed = true; |
| 468 | |
| 469 | foreach ($this->tags as $tagContainer) { |
| 470 | $tagContainer->seal(); |
| 471 | } |
| 472 | } |
| 473 | |
| 474 | protected function isRoot(): bool |
| 475 | { |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 477 | } |
| 478 | } |
Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not
necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once.
Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement
always has an else as part of its logical flow even if you didn't write one.
| 39 | public readonly bool $autowire = true, |
| 40 | ?PsrContainer $container = null, |
| 41 | protected readonly string $tag = '', |
| 42 | protected readonly ?Container $parent = null, |
| 43 | protected readonly bool $isScope = false, |
| 44 | ) { |
| 45 | if ($container) { |
| 45 | if ($container) { |
| 46 | $this->wrappedContainer = $container; |
| 53 | $this->add(Container::class, $this); |
| 54 | $this->creator = new Creator($this); |
| 55 | } |
| 39 | public readonly bool $autowire = true, |
| 40 | ?PsrContainer $container = null, |
| 41 | protected readonly string $tag = '', |
| 42 | protected readonly ?Container $parent = null, |
| 43 | protected readonly bool $isScope = false, |
| 44 | ) { |
| 45 | if ($container) { |
| 50 | $this->wrappedContainer = null; |
| 51 | $this->add(PsrContainer::class, $this); |
| 52 | } |
| 53 | $this->add(Container::class, $this); |
| 53 | $this->add(Container::class, $this); |
| 54 | $this->creator = new Creator($this); |
| 55 | } |
| 177 | string $id, |
| 178 | mixed $value = null, |
| 179 | ): Entry { |
| 180 | $this->assertMutable(); |
| 181 | $entry = new Entry($id, $value ?? $id); |
| 182 | $this->entries[$id] = $entry; |
| 183 | unset($this->instances[$id]); |
| 184 | |
| 185 | return $entry; |
| 186 | } |
| 189 | Entry $entry, |
| 190 | ): Entry { |
| 191 | $this->assertMutable(); |
| 192 | $this->entries[$entry->id] = $entry; |
| 193 | unset($this->instances[$entry->id]); |
| 194 | |
| 195 | return $entry; |
| 196 | } |
| 362 | protected function applyCalls(Entry $entry, mixed $value, Container $context): mixed |
| 363 | { |
| 364 | foreach ($entry->getCalls() as $call) { |
| 364 | foreach ($entry->getCalls() as $call) { |
| 364 | foreach ($entry->getCalls() as $call) { |
| 365 | $methodToResolve = $call->method; |
| 364 | foreach ($entry->getCalls() as $call) { |
| 364 | foreach ($entry->getCalls() as $call) { |
| 365 | $methodToResolve = $call->method; |
| 366 | |
| 367 | /** @var callable */ |
| 368 | $callable = [$value, $methodToResolve]; |
| 369 | $args = new CallableResolver($context->creator)->resolve($callable, $call->args); |
| 370 | $callable(...$args); |
| 371 | } |
| 372 | |
| 373 | return $value; |
| 374 | } |
| 362 | protected function applyCalls(Entry $entry, mixed $value, Container $context): mixed |
| 363 | { |
| 364 | foreach ($entry->getCalls() as $call) { |
| 364 | foreach ($entry->getCalls() as $call) { |
| 364 | foreach ($entry->getCalls() as $call) { |
| 365 | $methodToResolve = $call->method; |
| 366 | |
| 367 | /** @var callable */ |
| 368 | $callable = [$value, $methodToResolve]; |
| 369 | $args = new CallableResolver($context->creator)->resolve($callable, $call->args); |
| 370 | $callable(...$args); |
| 371 | } |
| 372 | |
| 373 | return $value; |
| 374 | } |
| 362 | protected function applyCalls(Entry $entry, mixed $value, Container $context): mixed |
| 363 | { |
| 364 | foreach ($entry->getCalls() as $call) { |
| 364 | foreach ($entry->getCalls() as $call) { |
| 365 | $methodToResolve = $call->method; |
| 366 | |
| 367 | /** @var callable */ |
| 368 | $callable = [$value, $methodToResolve]; |
| 369 | $args = new CallableResolver($context->creator)->resolve($callable, $call->args); |
| 370 | $callable(...$args); |
| 371 | } |
| 372 | |
| 373 | return $value; |
| 374 | } |
| 460 | if ($this->sealed) { |
| 461 | throw new ContainerException('The root container is sealed after scope() was called'); |
| 460 | if ($this->sealed) { |
| 463 | } |
| 161 | public function definition(string $id): mixed |
| 162 | { |
| 163 | $resolved = $this->findEntry($id); |
| 164 | $entry = $resolved[1] ?? null; |
| 165 | |
| 166 | if ($entry !== null) { |
| 167 | return $entry->definition(); |
| 161 | public function definition(string $id): mixed |
| 162 | { |
| 163 | $resolved = $this->findEntry($id); |
| 164 | $entry = $resolved[1] ?? null; |
| 165 | |
| 166 | if ($entry !== null) { |
| 170 | throw new NotFoundException('Unresolvable definition - id: ' . $id); |
| 171 | } |
| 93 | public function entries(bool $includeContainer = false): array |
| 94 | { |
| 95 | $keys = array_keys($this->entries); |
| 96 | |
| 97 | if ($includeContainer) { |
| 98 | return $keys; |
| 93 | public function entries(bool $includeContainer = false): array |
| 94 | { |
| 95 | $keys = array_keys($this->entries); |
| 96 | |
| 97 | if ($includeContainer) { |
| 101 | return array_values(array_filter( |
| 102 | $keys, |
| 103 | static fn($item) => $item !== PsrContainer::class && !is_subclass_of($item, PsrContainer::class), |
| 104 | )); |
| 105 | } |
| 107 | public function entry(string $id): Entry |
| 108 | { |
| 109 | return $this->entries[$id]; |
| 110 | } |
| 436 | protected function findEntry(string $id): ?array |
| 437 | { |
| 438 | $entry = $this->entries[$id] ?? null; |
| 439 | |
| 440 | if ($entry !== null) { |
| 441 | return [$this, $entry]; |
| 436 | protected function findEntry(string $id): ?array |
| 437 | { |
| 438 | $entry = $this->entries[$id] ?? null; |
| 439 | |
| 440 | if ($entry !== null) { |
| 444 | return $this->parent?->findEntry($id); |
| 445 | } |
| 113 | public function get(string $id): mixed |
| 114 | { |
| 115 | try { |
| 116 | if (array_key_exists($id, $this->instances)) { |
| 117 | return $this->trackAndReturn($this->instances[$id]); |
| 113 | public function get(string $id): mixed |
| 114 | { |
| 115 | try { |
| 116 | if (array_key_exists($id, $this->instances)) { |
| 120 | $resolved = $this->findEntry($id); |
| 121 | |
| 122 | if ($resolved !== null) { |
| 123 | return $this->trackAndReturn( |
| 124 | $this->resolveEntry( |
| 125 | entryOwner: $resolved[0], |
| 113 | public function get(string $id): mixed |
| 114 | { |
| 115 | try { |
| 116 | if (array_key_exists($id, $this->instances)) { |
| 120 | $resolved = $this->findEntry($id); |
| 121 | |
| 122 | if ($resolved !== null) { |
| 133 | $wrappedContainer = $this->root()->wrappedContainer; |
| 134 | |
| 135 | if ($wrappedContainer?->has($id)) { |
| 136 | return $this->trackAndReturn($wrappedContainer->get($id)); |
| 113 | public function get(string $id): mixed |
| 114 | { |
| 115 | try { |
| 116 | if (array_key_exists($id, $this->instances)) { |
| 120 | $resolved = $this->findEntry($id); |
| 121 | |
| 122 | if ($resolved !== null) { |
| 133 | $wrappedContainer = $this->root()->wrappedContainer; |
| 134 | |
| 135 | if ($wrappedContainer?->has($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 141 | return $this->trackAndReturn($this->creator->create($id)); |
| 113 | public function get(string $id): mixed |
| 114 | { |
| 115 | try { |
| 116 | if (array_key_exists($id, $this->instances)) { |
| 120 | $resolved = $this->findEntry($id); |
| 121 | |
| 122 | if ($resolved !== null) { |
| 133 | $wrappedContainer = $this->root()->wrappedContainer; |
| 134 | |
| 135 | if ($wrappedContainer?->has($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 141 | return $this->trackAndReturn($this->creator->create($id)); |
| 157 | throw new NotFoundException('Unresolvable id: ' . $id); |
| 158 | } |
| 113 | public function get(string $id): mixed |
| 114 | { |
| 115 | try { |
| 116 | if (array_key_exists($id, $this->instances)) { |
| 120 | $resolved = $this->findEntry($id); |
| 121 | |
| 122 | if ($resolved !== null) { |
| 133 | $wrappedContainer = $this->root()->wrappedContainer; |
| 134 | |
| 135 | if ($wrappedContainer?->has($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 141 | return $this->trackAndReturn($this->creator->create($id)); |
| 113 | public function get(string $id): mixed |
| 114 | { |
| 115 | try { |
| 116 | if (array_key_exists($id, $this->instances)) { |
| 120 | $resolved = $this->findEntry($id); |
| 121 | |
| 122 | if ($resolved !== null) { |
| 133 | $wrappedContainer = $this->root()->wrappedContainer; |
| 134 | |
| 135 | if ($wrappedContainer?->has($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 141 | return $this->trackAndReturn($this->creator->create($id)); |
| 157 | throw new NotFoundException('Unresolvable id: ' . $id); |
| 158 | } |
| 113 | public function get(string $id): mixed |
| 114 | { |
| 115 | try { |
| 116 | if (array_key_exists($id, $this->instances)) { |
| 120 | $resolved = $this->findEntry($id); |
| 121 | |
| 122 | if ($resolved !== null) { |
| 133 | $wrappedContainer = $this->root()->wrappedContainer; |
| 134 | |
| 135 | if ($wrappedContainer?->has($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 141 | return $this->trackAndReturn($this->creator->create($id)); |
| 113 | public function get(string $id): mixed |
| 114 | { |
| 115 | try { |
| 116 | if (array_key_exists($id, $this->instances)) { |
| 120 | $resolved = $this->findEntry($id); |
| 121 | |
| 122 | if ($resolved !== null) { |
| 133 | $wrappedContainer = $this->root()->wrappedContainer; |
| 134 | |
| 135 | if ($wrappedContainer?->has($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 140 | if ($this->autowire && class_exists($id)) { |
| 141 | return $this->trackAndReturn($this->creator->create($id)); |
| 157 | throw new NotFoundException('Unresolvable id: ' . $id); |
| 158 | } |
| 143 | } catch (WireException $e) { |
| 144 | throw new NotFoundException( |
| 145 | 'Unresolvable id: ' . $id . ' - Details: ' . $e->getMessage(), |
| 143 | } catch (WireException $e) { |
| 148 | } catch (ContainerExceptionInterface $e) { |
| 149 | throw $e; |
| 143 | } catch (WireException $e) { |
| 148 | } catch (ContainerExceptionInterface $e) { |
| 150 | } catch (Throwable $e) { |
| 151 | throw new ContainerException( |
| 152 | 'Unresolvable id: ' . $id . ' - ' . $e->getMessage(), |
| 83 | public function has(string $id): bool |
| 84 | { |
| 85 | return ( |
| 86 | isset($this->entries[$id]) |
| 87 | || $this->parent?->has($id) |
| 87 | || $this->parent?->has($id) |
| 88 | || $this->wrappedContainer?->has($id) |
| 88 | || $this->wrappedContainer?->has($id) |
| 89 | ); |
| 90 | } |
| 83 | public function has(string $id): bool |
| 84 | { |
| 85 | return ( |
| 86 | isset($this->entries[$id]) |
| 87 | || $this->parent?->has($id) |
| 87 | || $this->parent?->has($id) |
| 88 | || $this->wrappedContainer?->has($id) |
| 89 | ); |
| 90 | } |
| 83 | public function has(string $id): bool |
| 84 | { |
| 85 | return ( |
| 86 | isset($this->entries[$id]) |
| 87 | || $this->parent?->has($id) |
| 88 | || $this->wrappedContainer?->has($id) |
| 88 | || $this->wrappedContainer?->has($id) |
| 89 | ); |
| 90 | } |
| 83 | public function has(string $id): bool |
| 84 | { |
| 85 | return ( |
| 86 | isset($this->entries[$id]) |
| 87 | || $this->parent?->has($id) |
| 88 | || $this->wrappedContainer?->has($id) |
| 89 | ); |
| 90 | } |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 477 | } |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 477 | } |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 477 | } |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 476 | return $this->parent === null && $this->tag === '' && !$this->isScope; |
| 477 | } |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 309 | $constructor = $entry->getConstructor(); |
| 310 | $args = $entry->getArgs(); |
| 311 | |
| 312 | if (isset($args)) { |
| 314 | if ($args instanceof Closure) { |
| 315 | $args = $args(...new CallableResolver($context->creator)->resolve($args)); |
| 316 | |
| 317 | return $this->applyCalls($entry, $context->creator->create($value, $args), $context); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 309 | $constructor = $entry->getConstructor(); |
| 310 | $args = $entry->getArgs(); |
| 311 | |
| 312 | if (isset($args)) { |
| 314 | if ($args instanceof Closure) { |
| 320 | return $this->applyCalls( |
| 321 | $entry, |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 309 | $constructor = $entry->getConstructor(); |
| 310 | $args = $entry->getArgs(); |
| 311 | |
| 312 | if (isset($args)) { |
| 331 | return $this->applyCalls( |
| 332 | $entry, |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 339 | return $context->get($value); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 343 | if ($value instanceof Closure) { |
| 344 | $args = $entry->getArgs(); |
| 345 | |
| 346 | if (is_null($args)) { |
| 346 | if (is_null($args)) { |
| 347 | $args = new CallableResolver($context->creator)->resolve($value); |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 343 | if ($value instanceof Closure) { |
| 344 | $args = $entry->getArgs(); |
| 345 | |
| 346 | if (is_null($args)) { |
| 348 | } elseif ($args instanceof Closure) { |
| 349 | $args = $args(); |
| 350 | } |
| 351 | |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 343 | if ($value instanceof Closure) { |
| 344 | $args = $entry->getArgs(); |
| 345 | |
| 346 | if (is_null($args)) { |
| 348 | } elseif ($args instanceof Closure) { |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 343 | if ($value instanceof Closure) { |
| 355 | if (is_object($value)) { |
| 356 | return $value; |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 343 | if ($value instanceof Closure) { |
| 355 | if (is_object($value)) { |
| 359 | throw new NotFoundException('Unresolvable id: ' . (string) $value); |
| 360 | } |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 309 | $constructor = $entry->getConstructor(); |
| 310 | $args = $entry->getArgs(); |
| 311 | |
| 312 | if (isset($args)) { |
| 314 | if ($args instanceof Closure) { |
| 315 | $args = $args(...new CallableResolver($context->creator)->resolve($args)); |
| 316 | |
| 317 | return $this->applyCalls($entry, $context->creator->create($value, $args), $context); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 309 | $constructor = $entry->getConstructor(); |
| 310 | $args = $entry->getArgs(); |
| 311 | |
| 312 | if (isset($args)) { |
| 314 | if ($args instanceof Closure) { |
| 320 | return $this->applyCalls( |
| 321 | $entry, |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 309 | $constructor = $entry->getConstructor(); |
| 310 | $args = $entry->getArgs(); |
| 311 | |
| 312 | if (isset($args)) { |
| 331 | return $this->applyCalls( |
| 332 | $entry, |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 339 | return $context->get($value); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 343 | if ($value instanceof Closure) { |
| 344 | $args = $entry->getArgs(); |
| 345 | |
| 346 | if (is_null($args)) { |
| 346 | if (is_null($args)) { |
| 347 | $args = new CallableResolver($context->creator)->resolve($value); |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 343 | if ($value instanceof Closure) { |
| 344 | $args = $entry->getArgs(); |
| 345 | |
| 346 | if (is_null($args)) { |
| 348 | } elseif ($args instanceof Closure) { |
| 349 | $args = $args(); |
| 350 | } |
| 351 | |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 343 | if ($value instanceof Closure) { |
| 344 | $args = $entry->getArgs(); |
| 345 | |
| 346 | if (is_null($args)) { |
| 348 | } elseif ($args instanceof Closure) { |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 343 | if ($value instanceof Closure) { |
| 355 | if (is_object($value)) { |
| 356 | return $value; |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 308 | if (class_exists($value)) { |
| 338 | if ($context->has($value)) { |
| 343 | if ($value instanceof Closure) { |
| 355 | if (is_object($value)) { |
| 359 | throw new NotFoundException('Unresolvable id: ' . (string) $value); |
| 360 | } |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 343 | if ($value instanceof Closure) { |
| 344 | $args = $entry->getArgs(); |
| 345 | |
| 346 | if (is_null($args)) { |
| 346 | if (is_null($args)) { |
| 347 | $args = new CallableResolver($context->creator)->resolve($value); |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 343 | if ($value instanceof Closure) { |
| 344 | $args = $entry->getArgs(); |
| 345 | |
| 346 | if (is_null($args)) { |
| 348 | } elseif ($args instanceof Closure) { |
| 349 | $args = $args(); |
| 350 | } |
| 351 | |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 343 | if ($value instanceof Closure) { |
| 344 | $args = $entry->getArgs(); |
| 345 | |
| 346 | if (is_null($args)) { |
| 348 | } elseif ($args instanceof Closure) { |
| 352 | return $this->applyCalls($entry, $value(...$args), $context); |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 343 | if ($value instanceof Closure) { |
| 355 | if (is_object($value)) { |
| 356 | return $value; |
| 302 | protected function materialize(Entry $entry, Container $context): mixed |
| 303 | { |
| 304 | /** @var mixed $value */ |
| 305 | $value = $entry->definition(); |
| 306 | |
| 307 | if (is_string($value)) { |
| 343 | if ($value instanceof Closure) { |
| 355 | if (is_object($value)) { |
| 359 | throw new NotFoundException('Unresolvable id: ' . (string) $value); |
| 360 | } |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 238 | return $this->new($value, ...$args); |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 243 | return new $value(...$args); |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 250 | return new $id(...$args); |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 253 | throw new NotFoundException('Cannot instantiate ' . $id); |
| 254 | } |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 250 | return new $id(...$args); |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 253 | throw new NotFoundException('Cannot instantiate ' . $id); |
| 254 | } |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 243 | return new $value(...$args); |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 250 | return new $id(...$args); |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 253 | throw new NotFoundException('Cannot instantiate ' . $id); |
| 254 | } |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 250 | return new $id(...$args); |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 237 | if (interface_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 241 | if (class_exists($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 253 | throw new NotFoundException('Cannot instantiate ' . $id); |
| 254 | } |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 250 | return new $id(...$args); |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 253 | throw new NotFoundException('Cannot instantiate ' . $id); |
| 254 | } |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 250 | return new $id(...$args); |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 234 | $value = $entry->definition(); |
| 235 | |
| 236 | if (is_string($value)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 253 | throw new NotFoundException('Cannot instantiate ' . $id); |
| 254 | } |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 250 | return new $id(...$args); |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 253 | throw new NotFoundException('Cannot instantiate ' . $id); |
| 254 | } |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 250 | return new $id(...$args); |
| 228 | public function new(string $id, mixed ...$args): object |
| 229 | { |
| 230 | $entry = $this->entries[$id] ?? null; |
| 231 | |
| 232 | if ($entry) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 248 | if (class_exists($id)) { |
| 253 | throw new NotFoundException('Cannot instantiate ' . $id); |
| 254 | } |
| 74 | if (!$this->isScope) { |
| 75 | return; |
| 74 | if (!$this->isScope) { |
| 78 | $resetIds = []; |
| 79 | $this->resetScope($resetIds); |
| 80 | } |
| 410 | protected function resetIfNeeded(mixed $value, array &$resetIds): void |
| 411 | { |
| 412 | if (!$value instanceof Resettable) { |
| 413 | return; |
| 410 | protected function resetIfNeeded(mixed $value, array &$resetIds): void |
| 411 | { |
| 412 | if (!$value instanceof Resettable) { |
| 416 | $objectId = spl_object_id($value); |
| 417 | |
| 418 | if (isset($resetIds[$objectId])) { |
| 419 | return; |
| 410 | protected function resetIfNeeded(mixed $value, array &$resetIds): void |
| 411 | { |
| 412 | if (!$value instanceof Resettable) { |
| 416 | $objectId = spl_object_id($value); |
| 417 | |
| 418 | if (isset($resetIds[$objectId])) { |
| 422 | $resetIds[$objectId] = true; |
| 423 | $value->reset(); |
| 424 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 379 | protected function resetScope(array &$resetIds): void |
| 380 | { |
| 381 | // $instances stores mixed values by design, so foreach assigns mixed to $instance. |
| 382 | /** @psalm-suppress MixedAssignment */ |
| 383 | foreach ($this->instances as $instance) { |
| 383 | foreach ($this->instances as $instance) { |
| 384 | $this->resetIfNeeded($instance, $resetIds); |
| 385 | } |
| 386 | |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 387 | foreach ($this->usedResettables as $usedResettable) { |
| 388 | $this->resetIfNeeded($usedResettable, $resetIds); |
| 389 | } |
| 390 | |
| 391 | foreach ($this->tags as $tagContainer) { |
| 391 | foreach ($this->tags as $tagContainer) { |
| 392 | if (!$tagContainer->isScope) { |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | $tagContainer->resetScope($resetIds); |
| 397 | } |
| 398 | |
| 399 | $this->instances = []; |
| 400 | $this->entries = []; |
| 401 | $this->tags = []; |
| 402 | $this->usedResettables = []; |
| 403 | $this->add(PsrContainer::class, $this); |
| 404 | $this->add(Container::class, $this); |
| 405 | } |
| 291 | Entry $entry, |
| 292 | Container $entryOwner, |
| 293 | Container $requester, |
| 294 | ): array { |
| 295 | return match ($entry->getLifetime()) { |
| 296 | Lifetime::Shared => [$entryOwner, $entryOwner], |
| 297 | Lifetime::Scoped => [$requester, $requester], |
| 298 | Lifetime::Transient => [null, $requester], |
| 298 | Lifetime::Transient => [null, $requester], |
| 298 | Lifetime::Transient => [null, $requester], |
| 291 | Entry $entry, |
| 292 | Container $entryOwner, |
| 293 | Container $requester, |
| 294 | ): array { |
| 295 | return match ($entry->getLifetime()) { |
| 296 | Lifetime::Shared => [$entryOwner, $entryOwner], |
| 297 | Lifetime::Scoped => [$requester, $requester], |
| 298 | Lifetime::Transient => [null, $requester], |
| 298 | Lifetime::Transient => [null, $requester], |
| 298 | Lifetime::Transient => [null, $requester], |
| 299 | }; |
| 300 | } |
| 291 | Entry $entry, |
| 292 | Container $entryOwner, |
| 293 | Container $requester, |
| 294 | ): array { |
| 295 | return match ($entry->getLifetime()) { |
| 296 | Lifetime::Shared => [$entryOwner, $entryOwner], |
| 297 | Lifetime::Scoped => [$requester, $requester], |
| 297 | Lifetime::Scoped => [$requester, $requester], |
| 298 | Lifetime::Transient => [null, $requester], |
| 299 | }; |
| 300 | } |
| 291 | Entry $entry, |
| 292 | Container $entryOwner, |
| 293 | Container $requester, |
| 294 | ): array { |
| 295 | return match ($entry->getLifetime()) { |
| 296 | Lifetime::Shared => [$entryOwner, $entryOwner], |
| 296 | Lifetime::Shared => [$entryOwner, $entryOwner], |
| 298 | Lifetime::Transient => [null, $requester], |
| 299 | }; |
| 300 | } |
| 257 | Container $entryOwner, |
| 258 | Entry $entry, |
| 259 | string $id, |
| 260 | Container $requester, |
| 261 | ): mixed { |
| 262 | if ($entry->shouldReturnValue()) { |
| 263 | return $entry->definition(); |
| 257 | Container $entryOwner, |
| 258 | Entry $entry, |
| 259 | string $id, |
| 260 | Container $requester, |
| 261 | ): mixed { |
| 262 | if ($entry->shouldReturnValue()) { |
| 266 | [$cacheContainer, $resolutionContext] = $this->resolutionContainers( |
| 267 | $entry, |
| 268 | $entryOwner, |
| 269 | $requester, |
| 270 | ); |
| 271 | |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 273 | return $cacheContainer->instances[$id]; |
| 257 | Container $entryOwner, |
| 258 | Entry $entry, |
| 259 | string $id, |
| 260 | Container $requester, |
| 261 | ): mixed { |
| 262 | if ($entry->shouldReturnValue()) { |
| 266 | [$cacheContainer, $resolutionContext] = $this->resolutionContainers( |
| 267 | $entry, |
| 268 | $entryOwner, |
| 269 | $requester, |
| 270 | ); |
| 271 | |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 278 | $result = $this->materialize($entry, $resolutionContext); |
| 279 | |
| 280 | if ($cacheContainer !== null) { |
| 281 | $cacheContainer->instances[$id] = $result; |
| 282 | } |
| 283 | |
| 284 | return $result; |
| 284 | return $result; |
| 285 | } |
| 257 | Container $entryOwner, |
| 258 | Entry $entry, |
| 259 | string $id, |
| 260 | Container $requester, |
| 261 | ): mixed { |
| 262 | if ($entry->shouldReturnValue()) { |
| 266 | [$cacheContainer, $resolutionContext] = $this->resolutionContainers( |
| 267 | $entry, |
| 268 | $entryOwner, |
| 269 | $requester, |
| 270 | ); |
| 271 | |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 278 | $result = $this->materialize($entry, $resolutionContext); |
| 279 | |
| 280 | if ($cacheContainer !== null) { |
| 284 | return $result; |
| 285 | } |
| 257 | Container $entryOwner, |
| 258 | Entry $entry, |
| 259 | string $id, |
| 260 | Container $requester, |
| 261 | ): mixed { |
| 262 | if ($entry->shouldReturnValue()) { |
| 266 | [$cacheContainer, $resolutionContext] = $this->resolutionContainers( |
| 267 | $entry, |
| 268 | $entryOwner, |
| 269 | $requester, |
| 270 | ); |
| 271 | |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 273 | return $cacheContainer->instances[$id]; |
| 257 | Container $entryOwner, |
| 258 | Entry $entry, |
| 259 | string $id, |
| 260 | Container $requester, |
| 261 | ): mixed { |
| 262 | if ($entry->shouldReturnValue()) { |
| 266 | [$cacheContainer, $resolutionContext] = $this->resolutionContainers( |
| 267 | $entry, |
| 268 | $entryOwner, |
| 269 | $requester, |
| 270 | ); |
| 271 | |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 278 | $result = $this->materialize($entry, $resolutionContext); |
| 279 | |
| 280 | if ($cacheContainer !== null) { |
| 281 | $cacheContainer->instances[$id] = $result; |
| 282 | } |
| 283 | |
| 284 | return $result; |
| 284 | return $result; |
| 285 | } |
| 257 | Container $entryOwner, |
| 258 | Entry $entry, |
| 259 | string $id, |
| 260 | Container $requester, |
| 261 | ): mixed { |
| 262 | if ($entry->shouldReturnValue()) { |
| 266 | [$cacheContainer, $resolutionContext] = $this->resolutionContainers( |
| 267 | $entry, |
| 268 | $entryOwner, |
| 269 | $requester, |
| 270 | ); |
| 271 | |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 272 | if ($cacheContainer !== null && array_key_exists($id, $cacheContainer->instances)) { |
| 278 | $result = $this->materialize($entry, $resolutionContext); |
| 279 | |
| 280 | if ($cacheContainer !== null) { |
| 284 | return $result; |
| 285 | } |
| 449 | $container = $this; |
| 450 | |
| 451 | while ($container->parent !== null) { |
| 451 | while ($container->parent !== null) { |
| 455 | return $container; |
| 456 | } |
| 449 | $container = $this; |
| 450 | |
| 451 | while ($container->parent !== null) { |
| 451 | while ($container->parent !== null) { |
| 451 | while ($container->parent !== null) { |
| 452 | $container = $container->parent; |
| 451 | while ($container->parent !== null) { |
| 455 | return $container; |
| 456 | } |
| 59 | $root = $this->root(); |
| 60 | |
| 61 | if (!$root->sealed) { |
| 62 | $root->seal(); |
| 63 | } |
| 64 | |
| 65 | return new self( |
| 65 | return new self( |
| 66 | autowire: $root->autowire, |
| 67 | parent: $root, |
| 68 | isScope: true, |
| 69 | ); |
| 70 | } |
| 59 | $root = $this->root(); |
| 60 | |
| 61 | if (!$root->sealed) { |
| 65 | return new self( |
| 66 | autowire: $root->autowire, |
| 67 | parent: $root, |
| 68 | isScope: true, |
| 69 | ); |
| 70 | } |
| 467 | $this->sealed = true; |
| 468 | |
| 469 | foreach ($this->tags as $tagContainer) { |
| 469 | foreach ($this->tags as $tagContainer) { |
| 469 | foreach ($this->tags as $tagContainer) { |
| 470 | $tagContainer->seal(); |
| 469 | foreach ($this->tags as $tagContainer) { |
| 469 | foreach ($this->tags as $tagContainer) { |
| 470 | $tagContainer->seal(); |
| 471 | } |
| 472 | } |
| 467 | $this->sealed = true; |
| 468 | |
| 469 | foreach ($this->tags as $tagContainer) { |
| 469 | foreach ($this->tags as $tagContainer) { |
| 469 | foreach ($this->tags as $tagContainer) { |
| 470 | $tagContainer->seal(); |
| 471 | } |
| 472 | } |
| 467 | $this->sealed = true; |
| 468 | |
| 469 | foreach ($this->tags as $tagContainer) { |
| 469 | foreach ($this->tags as $tagContainer) { |
| 470 | $tagContainer->seal(); |
| 471 | } |
| 472 | } |
| 199 | public function tag(string $tag): Container |
| 200 | { |
| 201 | if (isset($this->tags[$tag])) { |
| 202 | return $this->tags[$tag]; |
| 199 | public function tag(string $tag): Container |
| 200 | { |
| 201 | if (isset($this->tags[$tag])) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 206 | throw new ContainerException('The root container is sealed after scope() was called'); |
| 199 | public function tag(string $tag): Container |
| 200 | { |
| 201 | if (isset($this->tags[$tag])) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 209 | $parent = $this; |
| 210 | $isScope = false; |
| 211 | |
| 212 | if ($this->isScope) { |
| 213 | $root = $this->root(); |
| 214 | $parent = $root->tags[$tag] ?? $root; |
| 215 | $isScope = true; |
| 216 | } |
| 217 | |
| 218 | $this->tags[$tag] = new self( |
| 218 | $this->tags[$tag] = new self( |
| 219 | autowire: $this->autowire, |
| 220 | tag: $tag, |
| 221 | parent: $parent, |
| 222 | isScope: $isScope, |
| 223 | ); |
| 224 | |
| 225 | return $this->tags[$tag]; |
| 226 | } |
| 199 | public function tag(string $tag): Container |
| 200 | { |
| 201 | if (isset($this->tags[$tag])) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 209 | $parent = $this; |
| 210 | $isScope = false; |
| 211 | |
| 212 | if ($this->isScope) { |
| 218 | $this->tags[$tag] = new self( |
| 219 | autowire: $this->autowire, |
| 220 | tag: $tag, |
| 221 | parent: $parent, |
| 222 | isScope: $isScope, |
| 223 | ); |
| 224 | |
| 225 | return $this->tags[$tag]; |
| 226 | } |
| 199 | public function tag(string $tag): Container |
| 200 | { |
| 201 | if (isset($this->tags[$tag])) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 206 | throw new ContainerException('The root container is sealed after scope() was called'); |
| 199 | public function tag(string $tag): Container |
| 200 | { |
| 201 | if (isset($this->tags[$tag])) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 209 | $parent = $this; |
| 210 | $isScope = false; |
| 211 | |
| 212 | if ($this->isScope) { |
| 213 | $root = $this->root(); |
| 214 | $parent = $root->tags[$tag] ?? $root; |
| 215 | $isScope = true; |
| 216 | } |
| 217 | |
| 218 | $this->tags[$tag] = new self( |
| 218 | $this->tags[$tag] = new self( |
| 219 | autowire: $this->autowire, |
| 220 | tag: $tag, |
| 221 | parent: $parent, |
| 222 | isScope: $isScope, |
| 223 | ); |
| 224 | |
| 225 | return $this->tags[$tag]; |
| 226 | } |
| 199 | public function tag(string $tag): Container |
| 200 | { |
| 201 | if (isset($this->tags[$tag])) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 205 | if ($this->isRoot() && $this->sealed) { |
| 209 | $parent = $this; |
| 210 | $isScope = false; |
| 211 | |
| 212 | if ($this->isScope) { |
| 218 | $this->tags[$tag] = new self( |
| 219 | autowire: $this->autowire, |
| 220 | tag: $tag, |
| 221 | parent: $parent, |
| 222 | isScope: $isScope, |
| 223 | ); |
| 224 | |
| 225 | return $this->tags[$tag]; |
| 226 | } |
| 426 | protected function trackAndReturn(mixed $value): mixed |
| 427 | { |
| 428 | if ($this->isScope && $value instanceof Resettable) { |
| 428 | if ($this->isScope && $value instanceof Resettable) { |
| 428 | if ($this->isScope && $value instanceof Resettable) { |
| 429 | $this->usedResettables[spl_object_id($value)] = $value; |
| 430 | } |
| 431 | |
| 432 | return $value; |
| 432 | return $value; |
| 433 | } |
| 426 | protected function trackAndReturn(mixed $value): mixed |
| 427 | { |
| 428 | if ($this->isScope && $value instanceof Resettable) { |
| 428 | if ($this->isScope && $value instanceof Resettable) { |
| 428 | if ($this->isScope && $value instanceof Resettable) { |
| 432 | return $value; |
| 433 | } |
| 426 | protected function trackAndReturn(mixed $value): mixed |
| 427 | { |
| 428 | if ($this->isScope && $value instanceof Resettable) { |
| 428 | if ($this->isScope && $value instanceof Resettable) { |
| 429 | $this->usedResettables[spl_object_id($value)] = $value; |
| 430 | } |
| 431 | |
| 432 | return $value; |
| 432 | return $value; |
| 433 | } |
| 426 | protected function trackAndReturn(mixed $value): mixed |
| 427 | { |
| 428 | if ($this->isScope && $value instanceof Resettable) { |
| 428 | if ($this->isScope && $value instanceof Resettable) { |
| 432 | return $value; |
| 433 | } |
| 103 | static fn($item) => $item !== PsrContainer::class && !is_subclass_of($item, PsrContainer::class), |
| 103 | static fn($item) => $item !== PsrContainer::class && !is_subclass_of($item, PsrContainer::class), |
| 103 | static fn($item) => $item !== PsrContainer::class && !is_subclass_of($item, PsrContainer::class), |
| 103 | static fn($item) => $item !== PsrContainer::class && !is_subclass_of($item, PsrContainer::class), |
| 103 | static fn($item) => $item !== PsrContainer::class && !is_subclass_of($item, PsrContainer::class), |