InefficientDaftNestedRebuild::__construct()   A
last analyzed

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
/**
12
* @template T as DaftNestedWriteableObject
13
* @template TRepo as DaftNestedWriteableObjectTree
14
*/
15
class InefficientDaftNestedRebuild
16
{
17
    const INT_RESET_NESTED_VALUE = 0;
18
19
    /**
20
    * @var DaftNestedWriteableObjectTree
21
    *
22
    * @psalm-var TRepo
23
    */
24
    protected $tree;
25
26
    /**
27
    * @var array<int, scalar|(scalar|array|object|null)[]>
28
    */
29
    protected $parentIdXref = [];
30
31
    /**
32
    * @var array<int, array<int, DaftNestedWriteableObject>>
33
    *
34
    * @psalm-var array<int, array<int, T>>
35
    */
36
    protected $children = [[]];
37
38
    /**
39
    * @var array<int, scalar|(scalar|array|object|null)[]>
40
    */
41
    protected $idXref = [];
42
43
    /**
44
    * @psalm-param TRepo $tree
45
    */
46 60
    public function __construct(DaftNestedWriteableObjectTree $tree)
47
    {
48 60
        $this->tree = $tree;
49 60
    }
50
51 60
    public function RebuildTree() : void
52
    {
53 60
        $this->ProcessTree();
54
55 60
        $n = 0;
56
57 60
        foreach ($this->children[0] as $rootLeaf) {
58 60
            $n = $this->InefficientRebuild(
59 60
                $rootLeaf,
60 60
                0,
61 60
                $n,
62 60
                $this->parentIdXref,
63 60
                $this->idXref
64
            );
65
        }
66 60
    }
67
68 60
    private function Reset() : void
69
    {
70 60
        $parentIdXref = [$this->tree->GetNestedObjectTreeRootId()];
71
72
        /**
73
        * @var array<int, array<int, DaftNestedWriteableObject>>
74
        *
75
        * @psalm-var array<int, array<int, T>>
76
        */
77 60
        $children = [[]];
78
79
        /**
80
        * @var array<int, scalar|(scalar|array|object|null)[]>
81
        */
82 60
        $idXref = [];
83
84 60
        $this->parentIdXref = $parentIdXref;
85 60
        $this->children = $children;
86 60
        $this->idXref = $idXref;
87 60
    }
88
89 60
    private function ProcessTree() : void
90
    {
91 60
        $this->Reset();
92
93
        /**
94
        * @var array<int, DaftNestedWriteableObject>
95
        *
96
        * @psalm-var array<int, T>
97
        */
98 60
        $tree = $this->tree->RecallDaftNestedObjectFullTree();
99
100 60
        usort(
101 60
            $tree,
102
            /**
103
            * @psalm-param T $a
104
            * @psalm-param T $b
105
            */
106
            function (DaftNestedWriteableObject $a, DaftNestedWriteableObject $b) : int {
107 60
                return $a->CompareToDaftSortableObject($b);
108 60
            }
109
        );
110
111 60
        foreach ($tree as $i => $leaf) {
112 60
            $leafParentId = $leaf->GetDaftNestedObjectParentId();
113 60
            $pos = NestedTypeParanoia::MaybeFoundInArray($leafParentId, $this->parentIdXref);
114
115 60
            if (is_null($pos)) {
116 54
                $this->parentIdXref[] = $leafParentId;
117
118
                /**
119
                * @var int
120
                */
121 54
                $pos = NestedTypeParanoia::MaybeFoundInArray($leafParentId, $this->parentIdXref);
122
123 54
                $this->children[$pos] = [];
124
            }
125
126 60
            if ( ! in_array($leaf, $this->children[$pos], true)) {
127 60
                $this->children[$pos][] = $leaf;
128
            }
129
130
            /**
131
            * @var scalar|(scalar|array|object|null)[]
132
            */
133 60
            $leafId = $leaf->GetId();
134
135 60
            if ( ! in_array($leafId, $this->idXref, true)) {
136 60
                $this->idXref[] = $leafId;
137
            }
138
139 60
            $leaf->SetIntNestedLeft(self::INT_RESET_NESTED_VALUE);
140 60
            $leaf->SetIntNestedRight(self::INT_RESET_NESTED_VALUE);
141 60
            $leaf->SetIntNestedLevel(self::INT_RESET_NESTED_VALUE);
142
143 60
            $tree[$i] = $this->tree->StoreThenRetrieveFreshLeaf($leaf);
144
        }
145 60
    }
146
147
    /**
148
    * @psalm-param T $leaf
149
    */
150 60
    private function InefficientRebuild(
151
        DaftNestedWriteableObject $leaf,
152
        int $level,
153
        int $n,
154
        array $parents,
155
        array $ids
156
    ) : int {
157
        /**
158
        * @var scalar|(scalar|array|object|null)[]
159
        */
160 60
        $id = $leaf->GetId();
161
162 60
        $leaf->SetIntNestedLevel($level);
163 60
        $leaf->SetIntNestedLeft($n);
164
165 60
        ++$n;
166
167
        /**
168
        * @var int|false
169
        */
170 60
        $parentPos = NestedTypeParanoia::MaybeFoundInArray((array) $id, $parents);
171
172 60
        if (is_int($parentPos)) {
173 54
            foreach ($this->children[$parentPos] as $child) {
174 54
                $n = $this->InefficientRebuild($child, $level + 1, $n, $parents, $ids);
175
            }
176
        }
177
178 60
        $leaf->SetIntNestedRight($n);
179
180 60
        $this->tree->StoreThenRetrieveFreshLeaf($leaf);
181
182 60
        return $n + 1;
183
    }
184
}
185