MappedCollection::delete()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 7
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Smoren\Containers\Structs;
4
5
use ArrayIterator;
6
use Countable;
7
use IteratorAggregate;
8
use Smoren\Containers\Exceptions\MappedCollectionException;
9
10
/**
11
 * Class MappedCollection
12
 */
13
class MappedCollection implements IteratorAggregate, Countable
14
{
15
    /**
16
     * @var array data map
17
     */
18
    protected array $itemsMap;
19
20
    /**
21
     * MappedCollection constructor.
22
     * @param array|null $itemsMap default data map
23
     */
24
    public function __construct(?array $itemsMap = null)
25
    {
26
        $this->itemsMap = $itemsMap ?? [];
27
    }
28
29
    /**
30
     * Adds element to collection
31
     * @param string $id element ID
32
     * @param mixed $item data value of element
33
     * @return $this
34
     * @throws MappedCollectionException
35
     */
36
    public function add(string $id, $item): self
37
    {
38
        $this->checkNotExist($id);
39
        $this->itemsMap[$id] = $item;
40
        return $this;
41
    }
42
43
    /**
44
     * Removes element from collection by ID
45
     * @param string $id element ID
46
     * @return mixed removed element
47
     * @throws MappedCollectionException
48
     */
49
    public function delete(string $id)
50
    {
51
        $this->checkExist($id);
52
        $result = $this->itemsMap[$id];
53
        unset($this->itemsMap[$id]);
54
55
        return $result;
56
    }
57
58
    /**
59
     * Removes element from collection by ID
60
     * @param string $id element ID
61
     * @param mixed $data data value
62
     * @return $this
63
     * @throws MappedCollectionException
64
     */
65
    public function replace(string $id, $data): self
66
    {
67
        $this->delete($id);
68
        $this->add($id, $data);
69
        return $this;
70
    }
71
72
    /**
73
     * Replace all data from source argument
74
     * @param array $source new map contents
75
     * @return $this
76
     */
77
    public function replaceAll(array $source): self
78
    {
79
        $this->clear();
80
        $this->itemsMap = $source;
81
        return $this;
82
    }
83
84
    /**
85
     * Returns element by ID
86
     * @param string $id element ID
87
     * @param mixed $default default value if element is not found
88
     * @return mixed data value of element
89
     * @throws MappedCollectionException
90
     */
91
    public function get(string $id, $default = null)
92
    {
93
        try {
94
            $this->checkExist($id);
95
        } catch(MappedCollectionException $e) {
96
            if($default !== null) {
97
                return $default;
98
            } else {
99
                throw $e;
100
            }
101
        }
102
103
        return $this->itemsMap[$id];
104
    }
105
106
    /**
107
     * Returns true if element with such ID exists in collection
108
     * @param string $id element ID
109
     * @return bool
110
     */
111
    public function exist(string $id): bool
112
    {
113
        return isset($this->itemsMap[$id]);
114
    }
115
116
    /**
117
     * Checks if element with such ID exists
118
     * @param string $id element ID
119
     * @return $this
120
     * @throws MappedCollectionException
121
     */
122
    public function checkExist(string $id): self
123
    {
124
        if(!$this->exist($id)) {
125
            throw new MappedCollectionException(
126
                "ID '{$id}' not exists",
127
                MappedCollectionException::STATUS_ID_NOT_EXIST
128
            );
129
        }
130
        return $this;
131
    }
132
133
    /**
134
     * Checks if element with such ID does not exist
135
     * @param string $id element ID
136
     * @return $this
137
     * @throws MappedCollectionException
138
     */
139
    public function checkNotExist(string $id): self
140
    {
141
        if($this->exist($id)) {
142
            throw new MappedCollectionException(
143
                "ID '{$id}' exists",
144
                MappedCollectionException::STATUS_ID_EXIST
145
            );
146
        }
147
        return $this;
148
    }
149
150
    /**
151
     * Returns map as associative array
152
     * @return array
153
     */
154
    public function getMap(): array
155
    {
156
        return $this->itemsMap;
157
    }
158
159
    /**
160
     * Converts collection to array
161
     * @return array
162
     */
163
    public function toArray(): array
164
    {
165
        return array_values($this->itemsMap);
166
    }
167
168
    /**
169
     * @inheritDoc
170
     */
171
    public function count(): int
172
    {
173
        return count($this->itemsMap);
174
    }
175
176
    /**
177
     * Sorts map via comparator callback
178
     * @param callable $comparator comparator callback
179
     * @return $this
180
     */
181
    public function sort(callable $comparator): self
182
    {
183
        uasort($this->itemsMap, $comparator);
184
        return $this;
185
    }
186
187
    /**
188
     * Clears collection
189
     * @return $this
190
     */
191
    public function clear(): self
192
    {
193
        $this->itemsMap = [];
194
        return $this;
195
    }
196
197
    /**
198
     * @inheritDoc
199
     */
200
    public function getIterator(): ArrayIterator
201
    {
202
        return new ArrayIterator($this->itemsMap);
203
    }
204
205
    /**
206
     * Magic method for cloning
207
     */
208
    public function __clone()
209
    {
210
        $itemsMap = $this->itemsMap;
211
        $this->itemsMap = [];
212
        foreach($itemsMap as $id => $value) {
213
            if(is_object($value)) {
214
                $this->itemsMap[$id] = clone $value;
215
            } else {
216
                $this->itemsMap[$id] = $value;
217
            }
218
        }
219
    }
220
}
221