Completed
Push — master ( e0fd03...97dbe0 )
by Jesse
07:35
created

Whitelist::idOf()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Stratadox\IdentityMap;
5
6
use function get_class;
7
use function in_array;
8
9
/**
10
 * Whitelist for the Identity Map.
11
 *
12
 * Used for whitelisting entities while loading objects.
13
 *
14
 * @see IdentityMap
15
 *
16
 * @author Stratadox
17
 */
18
final class Whitelist implements MapsObjectsByIdentity
19
{
20
    private $allow;
21
    private $map;
22
23
    private function __construct(array $allow, MapsObjectsByIdentity $map)
24
    {
25
        $this->allow = $allow;
26
        $this->map = $map;
27
    }
28
29
    /**
30
     * Constructs a whitelist for the identity map.
31
     *
32
     * @param MapsObjectsByIdentity $mapped            The actual identity map.
33
     * @param string                ...$allowedClasses The whitelisted classes.
34
     * @return MapsObjectsByIdentity                   The wrapped identity map.
35
     * @throws NoSuchObject                            Probably won't though.
36
     */
37
    public static function forThe(
38
        MapsObjectsByIdentity $mapped,
39
        string ...$allowedClasses
40
    ): MapsObjectsByIdentity {
41
        foreach ($mapped->objects() as $object) {
42
            if (Whitelist::doesNotHave($object, $allowedClasses)) {
43
                $mapped = $mapped->removeThe($object);
44
            }
45
        }
46
        return new Whitelist($allowedClasses, $mapped);
47
    }
48
49
    /**
50
     * Whitelists the given classes in the identity map.
51
     *
52
     * @param string ...$classes     The whitelisted classes.
53
     * @return MapsObjectsByIdentity The wrapped identity map.
54
     */
55
    public static function the(string ...$classes): MapsObjectsByIdentity
56
    {
57
        return new Whitelist($classes, IdentityMap::startEmpty());
58
    }
59
60
    /** @inheritdoc */
61
    public function has(string $class, string $id): bool
62
    {
63
        return $this->map->has($class, $id);
64
    }
65
66
    /** @inheritdoc */
67
    public function hasThe(object $object): bool
68
    {
69
        return $this->map->hasThe($object);
70
    }
71
72
    /** @inheritdoc */
73
    public function get(string $class, string $id): object
74
    {
75
        return $this->map->get($class, $id);
76
    }
77
78
    /** @inheritdoc */
79
    public function idOf(object $object): string
80
    {
81
        return $this->map->idOf($object);
82
    }
83
84
    /** @inheritdoc */
85
    public function add(string $id, object $object): MapsObjectsByIdentity
86
    {
87
        if (!in_array(get_class($object), $this->allow)) {
88
            return $this;
89
        }
90
        return $this->newMap($this->map->add($id, $object));
91
    }
92
93
    /** @inheritdoc */
94
    public function remove(string $class, string $id): MapsObjectsByIdentity
95
    {
96
        return $this->newMap($this->map->remove($class, $id));
97
    }
98
99
    /** @inheritdoc */
100
    public function removeThe(object $object): MapsObjectsByIdentity
101
    {
102
        return $this->newMap($this->map->removeThe($object));
103
    }
104
105
    /** @inheritdoc */
106
    public function objects(): array
107
    {
108
        return $this->map->objects();
109
    }
110
111
    private function newMap(MapsObjectsByIdentity $map): MapsObjectsByIdentity
112
    {
113
        return new Whitelist($this->allow, $map);
114
    }
115
116
    private static function doesNotHave(
117
        object $mapped,
118
        array $allowedClasses
119
    ): bool {
120
        foreach ($allowedClasses as $class) {
121
            if ($mapped instanceof $class) {
122
                return false;
123
            }
124
        }
125
        return true;
126
    }
127
}
128