Passed
Push — master ( 6ff084...36d137 )
by SignpostMarv
02:47
created

CountDaftNestedObjectFullTree()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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