Passed
Push — master ( 6e67eb...aff4f7 )
by SignpostMarv
03:24
created

DaftObjectMemoryTree   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 232
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 77
dl 0
loc 232
ccs 92
cts 92
cp 1
rs 10
c 0
b 0
f 0
wmc 29

15 Methods

Rating   Name   Duplication   Size   Complexity  
A CountDaftNestedObjectTreeWithObject() 0 7 1
A RecallDaftNestedObjectFullTree() 0 42 3
A RecallDaftNestedObjectTreeWithObject() 0 21 3
A CountDaftNestedObjectFullTree() 0 3 1
A CountDaftNestedObjectPathToObject() 0 5 1
A MapDataToObject() 0 9 1
A CountDaftNestedObjectPathToId() 0 3 1
A RememberDaftObjectData() 0 7 1
A FilterLeaf() 0 11 4
A RecallDaftNestedObjectPathToId() 0 8 2
A RecallDaftNestedObjectPathToObject() 0 16 3
A ThrowIfNotType() 0 15 3
A CountDaftNestedObjectTreeWithId() 0 9 1
A RecallDaftNestedObjectTreeWithId() 0 18 3
A CompareObjects() 0 3 1
1
<?php
2
/**
3
* Base daft objects.
4
*
5
* @author SignpostMarv
6
*/
7
declare(strict_types=1);
8
9
namespace SignpostMarv\DaftObject;
10
11
abstract class DaftObjectMemoryTree extends DaftObjectMemoryRepository implements DaftNestedObjectTree
12
{
13 114
    public function RecallDaftNestedObjectFullTree(int $relativeDepthLimit = null) : array
14
    {
15
        /**
16
        * @var DaftNestedObject[] $out
17
        */
18 114
        $out = $this->memory;
19
20 114
        $outIds = [];
21
22 114
        foreach ($out as $obj) {
23
            /**
24
            * @var array<int, scalar|scalar[]> $id
25
            */
26 68
            $id = $obj->GetId();
27
28 68
            $outIds[] = $id;
29
        }
30
31
        /**
32
        * @var DaftNestedObject[] $fromMemory
33
        */
34 114
        $fromMemory = array_filter(
35 114
            array_map([$this, 'MapDataToObject'], $this->data),
36
            function (DaftNestedObject $leaf) use ($outIds) : bool {
37 88
                return ! in_array($leaf->GetId(), $outIds, true);
38 114
            }
39
        );
40
41 114
        $out = array_merge($out, $fromMemory);
42
43
        usort($out, function (DaftNestedObject $a, DaftNestedObject $b) : int {
44 64
            return $a->GetIntNestedLeft() <=> $b->GetIntNestedLeft();
45 114
        });
46
47 114
        if (is_int($relativeDepthLimit)) {
48
            $filter = function (DaftNestedObject $e) use ($relativeDepthLimit) : bool {
49 32
                return $e->GetIntNestedLevel() <= $relativeDepthLimit;
50 32
            };
51 32
            $out = array_filter($out, $filter);
52
        }
53
54 114
        return $out;
55
    }
56
57 114
    public function CountDaftNestedObjectFullTree(int $relativeDepthLimit = null) : int
58
    {
59 114
        return count($this->RecallDaftNestedObjectFullTree($relativeDepthLimit));
60
    }
61
62
    /**
63
    * {@inheritdoc}
64
    */
65 44
    public function RecallDaftNestedObjectTreeWithObject(
66
        DaftNestedObject $root,
67
        bool $includeRoot,
68
        ? int $limit
69
    ) : array {
70 44
        $left = $root->GetIntNestedLeft();
71 44
        $right = $root->GetIntNestedRight();
72 44
        $limit = is_int($limit) ? ($root->GetIntNestedLevel() + $limit) : null;
73
74 44
        $leaves = $this->RecallDaftNestedObjectFullTree();
75
76 44
        if (is_int($limit)) {
77
            $leaves = array_filter($leaves, function (DaftNestedObject $e) use ($limit) : bool {
78 38
                return $e->GetIntNestedLevel() <= $limit;
79 38
            });
80
        }
81
82 44
        return array_values(array_filter(
83 44
            $leaves,
84
            function (DaftNestedObject $e) use ($includeRoot, $left, $right) : bool {
85 44
                return $this->FilterLeaf($includeRoot, $left, $right, $e);
86 44
            }
87
        ));
88
    }
89
90 20
    public function CountDaftNestedObjectTreeWithObject(
91
        DaftNestedObject $root,
92
        bool $includeRoot,
93
        ? int $relativeDepthLimit
94
    ) : int {
95 20
        return count(
96 20
            $this->RecallDaftNestedObjectTreeWithObject($root, $includeRoot, $relativeDepthLimit)
97
        );
98
    }
99
100
    /**
101
    * @param mixed $id
102
    */
103 56
    public function RecallDaftNestedObjectTreeWithId(
104
        $id,
105
        bool $includeRoot,
106
        ? int $relativeDepthLimit
107
    ) : array {
108 56
        $object = $this->RecallDaftObject($id);
109
110
        return
111 56
            ($object instanceof DaftNestedObject)
112 28
                ? $this->RecallDaftNestedObjectTreeWithObject(
113 28
                    $object,
114 28
                    $includeRoot,
115 28
                    $relativeDepthLimit
116
                )
117
                : (
118 32
                    ((array) $id === (array) $this->GetNestedObjectTreeRootId())
119 32
                        ? $this->RecallDaftNestedObjectFullTree($relativeDepthLimit)
120 56
                        : []
121
                );
122
    }
123
124
    /**
125
    * @param mixed $id
126
    */
127 4
    public function CountDaftNestedObjectTreeWithId(
128
        $id,
129
        bool $includeRoot,
130
        ? int $relativeDepthLimit
131
    ) : int {
132 4
        return count($this->RecallDaftNestedObjectTreeWithId(
133 4
            $id,
134 4
            $includeRoot,
135 4
            $relativeDepthLimit
136
        ));
137
    }
138
139 4
    public function RecallDaftNestedObjectPathToObject(
140
        DaftNestedObject $leaf,
141
        bool $includeLeaf
142
    ) : array {
143 4
        $left = $leaf->GetIntNestedLeft();
144 4
        $right = $leaf->GetIntNestedRight();
145
146 4
        if ( ! $includeLeaf) {
147 4
            --$left;
148 4
            ++$right;
149
        }
150
151 4
        return array_values(array_filter(
152 4
            $this->RecallDaftNestedObjectFullTree(),
153
            function (DaftNestedObject $e) use ($left, $right) : bool {
154 4
                return $e->GetIntNestedLeft() <= $left && $e->GetIntNestedRight() >= $right;
155 4
            }
156
        ));
157
    }
158
159 4
    public function CountDaftNestedObjectPathToObject(
160
        DaftNestedObject $leaf,
161
        bool $includeLeaf
162
    ) : int {
163 4
        return count($this->RecallDaftNestedObjectPathToObject($leaf, $includeLeaf));
164
    }
165
166
    /**
167
    * @param mixed $id
168
    */
169 4
    public function RecallDaftNestedObjectPathToId($id, bool $includeLeaf) : array
170
    {
171 4
        $object = $this->RecallDaftObject($id);
172
173
        return
174 4
            ($object instanceof DaftNestedObject)
175 4
                ? $this->RecallDaftNestedObjectPathToObject($object, $includeLeaf)
176 4
                : [];
177
    }
178
179
    /**
180
    * @param mixed $id
181
    */
182 4
    public function CountDaftNestedObjectPathToId($id, bool $includeLeaf) : int
183
    {
184 4
        return count($this->RecallDaftNestedObjectPathToId($id, $includeLeaf));
185
    }
186
187 60
    public function CompareObjects(DaftNestedObject $a, DaftNestedObject $b) : int
188
    {
189 60
        return $a->GetIntNestedSortOrder() <=> $b->GetIntNestedSortOrder();
190
    }
191
192 118
    public function RememberDaftObjectData(
193
        DefinesOwnIdPropertiesInterface $object,
194
        bool $assumeDoesNotExist = false
195
    ) : void {
196 118
        static::ThrowIfNotType($object, DaftNestedObject::class, 1, __METHOD__);
197
198 118
        parent::RememberDaftObjectData($object, $assumeDoesNotExist);
199 118
    }
200
201 88
    protected function MapDataToObject(array $row) : DaftNestedObject
202
    {
203 88
        $type = $this->type;
204
        /**
205
        * @var DaftNestedObject $out
206
        */
207 88
        $out = new $type($row);
208
209 88
        return $out;
210
    }
211
212 44
    protected function FilterLeaf(
213
        bool $includeRoot,
214
        int $left,
215
        int $right,
216
        DaftNestedObject $e
217
    ) : bool {
218 44
        if ($includeRoot) {
219 4
            return $e->GetIntNestedLeft() >= $left && $e->GetIntNestedRight() <= $right;
220
        }
221
222 44
        return $e->GetIntNestedLeft() > $left && $e->GetIntNestedRight() < $right;
223
    }
224
225
    /**
226
    * @param DaftObject|string $object
227
    */
228 156
    protected static function ThrowIfNotType(
229
        $object,
230
        string $type,
231
        int $argument,
232
        string $function
233
    ) : void {
234 156
        parent::ThrowIfNotType($object, $type, $argument, $function);
235
236 156
        if ( ! is_a($object, DaftNestedObject::class, is_string($object))) {
237 2
            throw new DaftObjectRepositoryTypeByClassMethodAndTypeException(
238 2
                $argument,
239 2
                static::class,
240 2
                $function,
241 2
                DaftNestedObject::class,
242 2
                is_string($object) ? $object : get_class($object)
243
            );
244
        }
245 154
    }
246
}
247