Passed
Push — master ( b06d89...3acf20 )
by SignpostMarv
07:01
created

DaftObjectMemoryTree::CompareObjects()   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 2
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
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 118
    public function RememberDaftObjectData(
188
        DefinesOwnIdPropertiesInterface $object,
189
        bool $assumeDoesNotExist = false
190
    ) : void {
191 118
        static::ThrowIfNotType($object, DaftNestedObject::class, 1, __METHOD__);
192
193 118
        parent::RememberDaftObjectData($object, $assumeDoesNotExist);
194 118
    }
195
196 88
    protected function MapDataToObject(array $row) : DaftNestedObject
197
    {
198 88
        $type = $this->type;
199
        /**
200
        * @var DaftNestedObject $out
201
        */
202 88
        $out = new $type($row);
203
204 88
        return $out;
205
    }
206
207 44
    protected function FilterLeaf(
208
        bool $includeRoot,
209
        int $left,
210
        int $right,
211
        DaftNestedObject $e
212
    ) : bool {
213 44
        if ($includeRoot) {
214 4
            return $e->GetIntNestedLeft() >= $left && $e->GetIntNestedRight() <= $right;
215
        }
216
217 44
        return $e->GetIntNestedLeft() > $left && $e->GetIntNestedRight() < $right;
218
    }
219
220
    /**
221
    * @param DaftObject|string $object
222
    */
223 156
    protected static function ThrowIfNotType(
224
        $object,
225
        string $type,
226
        int $argument,
227
        string $function
228
    ) : void {
229 156
        parent::ThrowIfNotType($object, $type, $argument, $function);
230
231 156
        if ( ! is_a($object, DaftNestedObject::class, is_string($object))) {
232 2
            throw new DaftObjectRepositoryTypeByClassMethodAndTypeException(
233 2
                $argument,
234 2
                static::class,
235 2
                $function,
236 2
                DaftNestedObject::class,
237 2
                is_string($object) ? $object : get_class($object)
238
            );
239
        }
240 154
    }
241
}
242