Passed
Push — master ( cf49ea...268884 )
by SignpostMarv
03:01
created

RecallDaftNestedObjectFullTree()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 1
dl 0
loc 42
ccs 18
cts 18
cp 1
crap 3
rs 9.248
c 0
b 0
f 0
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'], (array) $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 56
    public function RecallDaftNestedObjectTreeWithId(
101
        $id,
102
        bool $includeRoot,
103
        ? int $relativeDepthLimit
104
    ) : array {
105 56
        $object = $this->RecallDaftObject($id);
106
107
        return
108 56
            ($object instanceof DaftNestedObject)
109 28
                ? $this->RecallDaftNestedObjectTreeWithObject(
110 28
                    $object,
111 28
                    $includeRoot,
112 28
                    $relativeDepthLimit
113
                )
114
                : (
115 32
                    ((array) $id === (array) $this->GetNestedObjectTreeRootId())
116 32
                        ? $this->RecallDaftNestedObjectFullTree($relativeDepthLimit)
117 56
                        : []
118
                );
119
    }
120
121 4
    public function CountDaftNestedObjectTreeWithId(
122
        $id,
123
        bool $includeRoot,
124
        ? int $relativeDepthLimit
125
    ) : int {
126 4
        return count($this->RecallDaftNestedObjectTreeWithId(
127 4
            $id,
128 4
            $includeRoot,
129 4
            $relativeDepthLimit
130
        ));
131
    }
132
133 4
    public function RecallDaftNestedObjectPathToObject(
134
        DaftNestedObject $leaf,
135
        bool $includeLeaf
136
    ) : array {
137 4
        $left = $leaf->GetIntNestedLeft();
138 4
        $right = $leaf->GetIntNestedRight();
139
140 4
        if ( ! $includeLeaf) {
141 4
            --$left;
142 4
            ++$right;
143
        }
144
145 4
        return array_values(array_filter(
146 4
            $this->RecallDaftNestedObjectFullTree(),
147
            function (DaftNestedObject $e) use ($left, $right) : bool {
148 4
                return $e->GetIntNestedLeft() <= $left && $e->GetIntNestedRight() >= $right;
149 4
            }
150
        ));
151
    }
152
153 4
    public function CountDaftNestedObjectPathToObject(
154
        DaftNestedObject $leaf,
155
        bool $includeLeaf
156
    ) : int {
157 4
        return count($this->RecallDaftNestedObjectPathToObject($leaf, $includeLeaf));
158
    }
159
160 4
    public function RecallDaftNestedObjectPathToId($id, bool $includeLeaf) : array
161
    {
162 4
        $object = $this->RecallDaftObject($id);
163
164
        return
165 4
            ($object instanceof DaftNestedObject)
166 4
                ? $this->RecallDaftNestedObjectPathToObject($object, $includeLeaf)
167 4
                : [];
168
    }
169
170
    /*
171
    * @param mixed $id
172
    */
173 4
    public function CountDaftNestedObjectPathToId($id, bool $includeLeaf) : int
174
    {
175 4
        return count($this->RecallDaftNestedObjectPathToId($id, $includeLeaf));
176
    }
177
178 60
    public function CompareObjects(DaftNestedObject $a, DaftNestedObject $b) : int
179
    {
180 60
        return $a->GetIntNestedSortOrder() <=> $b->GetIntNestedSortOrder();
181
    }
182
183 88
    protected function MapDataToObject(array $row) : DaftNestedObject
184
    {
185 88
        $type = $this->type;
186
        /**
187
        * @var DaftNestedObject $out
188
        */
189 88
        $out = new $type($row);
190
191 88
        return $out;
192
    }
193
194 44
    protected function FilterLeaf(
195
        bool $includeRoot,
196
        int $left,
197
        int $right,
198
        DaftNestedObject $e
199
    ) : bool {
200 44
        if ($includeRoot) {
201 4
            return $e->GetIntNestedLeft() >= $left && $e->GetIntNestedRight() <= $right;
202
        }
203
204 44
        return $e->GetIntNestedLeft() > $left && $e->GetIntNestedRight() < $right;
205
    }
206
207 118
    protected function RememberDaftObjectData(DefinesOwnIdPropertiesInterface $object) : void
208
    {
209 118
        static::ThrowIfNotType($object, DaftNestedObject::class, 1, __METHOD__);
210
211 118
        parent::RememberDaftObjectData($object);
212 118
    }
213
214
    /**
215
    * @param DaftObject|string $object
216
    */
217 156
    protected static function ThrowIfNotType(
218
        $object,
219
        string $type,
220
        int $argument,
221
        string $function
222
    ) : void {
223 156
        parent::ThrowIfNotType($object, $type, $argument, $function);
224
225 156
        if ( ! is_a($object, DaftNestedObject::class, is_string($object))) {
226 2
            throw new DaftObjectRepositoryTypeByClassMethodAndTypeException(
227 2
                $argument,
228 2
                static::class,
229 2
                $function,
230 2
                DaftNestedObject::class,
231 2
                is_string($object) ? $object : get_class($object)
232
            );
233
        }
234 154
    }
235
}
236