Passed
Push — master ( 6c8dfe...6e67eb )
by SignpostMarv
03:14
created

CountDaftNestedObjectPathToId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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