Passed
Pull Request — master (#211)
by Dmitriy
02:18
created

CompositeContainer::detach()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 3
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Di;
6
7
use Psr\Container\ContainerInterface;
8
use Yiisoft\Factory\Exception\NotFoundException;
9
10
/**
11
 * This class implements a composite container for use with containers that support the delegate lookup feature.
12
 * The goal of the implementation is simplicity.
13
 */
14
final class CompositeContainer implements ContainerInterface
15
{
16
    /**
17
     * Containers to look into starting from the beginning of the array.
18
     *
19
     * @var ContainerInterface[] The list of containers
20
     */
21
    private array $containers = [];
22
23 31
    public function get($id)
24
    {
25 31
        if ($id === StateResetterInterface::class) {
26 2
            $resetters = [];
27 2
            foreach ($this->containers as $container) {
28 2
                if ($container->has(StateResetterInterface::class)) {
29 2
                    $resetters[] = $container->get(StateResetterInterface::class);
30
                }
31
            }
32 2
            return new StateResetter($resetters);
33
        }
34 31
        if ($id === StateResetter::class) {
35 1
            $resetters = [];
36 1
            foreach ($this->containers as $container) {
37 1
                if ($container->has(StateResetter::class)) {
38 1
                    $resetters[] = $container->get(StateResetter::class);
39
                }
40
            }
41 1
            return new StateResetter($resetters);
42
        }
43
44 31
        if ($this->isTagAlias($id)) {
45 2
            $tags = [];
46 2
            foreach ($this->containers as $container) {
47 2
                if (!$container instanceof Container) {
48
                    continue;
49
                }
50 2
                if ($container->has($id)) {
51 2
                    $tags = array_merge($container->get($id), $tags);
0 ignored issues
show
Bug introduced by
It seems like $container->get($id) can also be of type object; however, parameter $arrays of array_merge() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

51
                    $tags = array_merge(/** @scrutinizer ignore-type */ $container->get($id), $tags);
Loading history...
52
                }
53
            }
54
55 2
            return $tags;
56
        }
57
58 29
        foreach ($this->containers as $container) {
59 29
            if ($container->has($id)) {
60 26
                return $container->get($id);
61
            }
62
        }
63 5
        throw new NotFoundException($id);
64
    }
65
66 8
    public function has($id): bool
67
    {
68 8
        foreach ($this->containers as $container) {
69 8
            if ($container->has($id)) {
70 8
                return true;
71
            }
72
        }
73
        return false;
74
    }
75
76
    /**
77
     * Attaches a container to the composite container.
78
     *
79
     * @param ContainerInterface $container
80
     */
81 33
    public function attach(ContainerInterface $container): void
82
    {
83 33
        array_unshift($this->containers, $container);
84 33
    }
85
86
    /**
87
     * Removes a container from the list of containers.
88
     *
89
     * @param ContainerInterface $container
90
     */
91 2
    public function detach(ContainerInterface $container): void
92
    {
93 2
        foreach ($this->containers as $i => $c) {
94 2
            if ($container === $c) {
95 2
                unset($this->containers[$i]);
96
            }
97
        }
98 2
    }
99
100 31
    private function isTagAlias(string $id): bool
101
    {
102 31
        return strpos($id, 'tag@') === 0;
103
    }
104
}
105