Passed
Push — v1.x ( 9eac6f...b30d34 )
by Saulius
07:54
created

ObjectManagerCollection::setConcreteManager()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the sauls/object-registry-bundle package.
4
 *
5
 * @author    Saulius Vaičeliūnas <[email protected]>
6
 * @link      http://saulius.vaiceliunas.lt
7
 * @copyright 2018
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace Sauls\Bundle\ObjectRegistryBundle\Collection;
14
15
use Sauls\Bundle\ObjectRegistryBundle\Exception\UnsupportedManagerClassException;
16
use Sauls\Bundle\ObjectRegistryBundle\Manager\ConcreteManagerInterface;
17
use Sauls\Bundle\ObjectRegistryBundle\Manager\ManagerInterface;
18
use Sauls\Bundle\ObjectRegistryBundle\Manager\NamedManagerInterface;
19
use Sauls\Component\Collection\ArrayCollection;
20
21
class ObjectManagerCollection extends ArrayCollection implements ObjectManagerCollectionInterface
22
{
23
    public const LOOSE_MANAGERS_KEY = 'loose';
24
    public const NAMED_MANAGERS_KEY = 'named';
25
    public const CONCRETE_MANAGERS_KEY = 'concrete';
26
27
    public function set($key, $value): void
28
    {
29
        $this->setConcreteManager($value);
30
        $this->setNamedManager($value);
31
        $this->setLooseManager($key, $value);
32
        $this->throwUnsupportedManagerClassException($value);
33
    }
34
35
    /**
36
     * @param $value
37
     */
38
    private function setConcreteManager(object $value): void
39
    {
40
        if (\is_subclass_of($value, ConcreteManagerInterface::class)) {
41
            parent::set(
42
                $this->glueKeyNameWithValue(self::CONCRETE_MANAGERS_KEY, $value->getObjectClass()), $value
43
            );
44
            return;
45
        }
46
    }
47
48
    private function glueKeyNameWithValue(string $keyName, string $value): string
49
    {
50
        return \sprintf('%s.%s', $keyName, $value);
51
    }
52
53
    /**
54
     * @param $value
55
     */
56
    private function setNamedManager(object $value): void
57
    {
58
        if (\is_subclass_of($value, NamedManagerInterface::class)) {
59
            parent::set(
60
                $this->glueKeyNameWithValue(self::NAMED_MANAGERS_KEY, $value->getName()), $value
61
            );
62
            return;
63
        }
64
    }
65
66
    /**
67
     * @param $key
68
     * @param $value
69
     */
70
    private function setLooseManager($key, object $value): void
71
    {
72
        if (\is_subclass_of($value, ManagerInterface::class)) {
73
            parent::set(
74
                $this->glueKeyNameWithValue(self::LOOSE_MANAGERS_KEY, $key), $value
75
            );
76
            return;
77
        }
78
    }
79
80
    /**
81
     * @param $value
82
     */
83
    private function throwUnsupportedManagerClassException(object $value): void
84
    {
85
        if ($this->isNotSupportedObjectClass($value)) {
86
            throw new UnsupportedManagerClassException(
87
                sprintf(
88
                    'Given `%s` class should implement one of [%s] interfaces',
89
                    \get_class($value),
90
                    \implode(', ', $this->getSupportedManagerClasses())
91
                )
92
            );
93
        }
94
    }
95
96
    private function isNotSupportedObjectClass(object $value): bool
97
    {
98
        return false === $this->isSupportedObjectClass($value);
99
    }
100
101
    private function isSupportedObjectClass(object $value): bool
102
    {
103
        foreach ($this->getSupportedManagerClasses() as $supportedObjectClass) {
104
            if ($value instanceof $supportedObjectClass) {
105
                return true;
106
            }
107
        }
108
109
        return false;
110
    }
111
112
    private function getSupportedManagerClasses(): array
113
    {
114
        return [
115
            ManagerInterface::class,
116
            ConcreteManagerInterface::class,
117
            NamedManagerInterface::class
118
        ];
119
    }
120
121
    public function get($key, $default = null)
122
    {
123
        foreach ($this->getSupportedManagerGroups() as $managerGroup) {
124
            $managerGroupKey = $this->glueKeyNameWithValue($managerGroup, $key);
125
            if ($this->keyExists($managerGroupKey)) {
126
                return parent::get($managerGroupKey, $default);
127
            }
128
        }
129
130
        return $default;
131
    }
132
133
    private function getSupportedManagerGroups(): array
134
    {
135
        return [
136
            self::CONCRETE_MANAGERS_KEY,
137
            self::NAMED_MANAGERS_KEY,
138
            self::LOOSE_MANAGERS_KEY
139
        ];
140
    }
141
142
    public function count(): int
143
    {
144
        $total = 0;
145
146
        foreach ($this->all() as $group => $managers) {
147
            $total += \count($managers);
148
        }
149
150
        return $total;
151
    }
152
153
    public function clear(): void
154
    {
155
        foreach ($this->getSupportedManagerGroups() as $group) {
156
            parent::set($group, []);
157
        }
158
    }
159
160
}
161