Passed
Push — master ( 6cebba...633fbf )
by SignpostMarv
04:21
created

ModifyDaftNestedObjectTreeInsertAlt()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 53
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 4.0006

Importance

Changes 0
Metric Value
cc 4
eloc 29
nc 3
nop 4
dl 0
loc 53
ccs 28
cts 29
cp 0.9655
crap 4.0006
rs 8.9849
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 BadMethodCallException;
12
use InvalidArgumentException;
13
use RuntimeException;
14
15
abstract class DaftWriteableObjectMemoryTree extends DaftObjectMemoryTree implements DaftNestedWriteableObjectTree
16
{
17
    public function ModifyDaftNestedObjectTreeInsertBefore(
18
        DaftNestedWriteableObject $newLeaf,
19
        DaftNestedWriteableObject $referenceLeaf
20
    ) : DaftNestedWriteableObject {
21
        return $this->ModifyDaftNestedObjectTreeInsert($newLeaf, $referenceLeaf, true, null);
22
    }
23
24
    public function ModifyDaftNestedObjectTreeInsertAfter(
25
        DaftNestedWriteableObject $newLeaf,
26
        DaftNestedWriteableObject $referenceLeaf
27
    ) : DaftNestedWriteableObject {
28
        return $this->ModifyDaftNestedObjectTreeInsert($newLeaf, $referenceLeaf, false, null);
29
    }
30
31
    /**
32
    * @param mixed $newLeaf
33
    * @param mixed $referenceLeaf
34
    */
35 2
    public function ModifyDaftNestedObjectTreeInsertBeforeId(
36
        $newLeaf,
37
        $referenceLeaf
38
    ) : DaftNestedWriteableObject {
39 2
        return $this->ModifyDaftNestedObjectTreeInsertId($newLeaf, $referenceLeaf, true);
40
    }
41
42
    /**
43
    * @param mixed $newLeaf
44
    * @param mixed $referenceLeaf
45
    */
46 10
    public function ModifyDaftNestedObjectTreeInsertAfterId(
47
        $newLeaf,
48
        $referenceLeaf
49
    ) : DaftNestedWriteableObject {
50 10
        return $this->ModifyDaftNestedObjectTreeInsertId($newLeaf, $referenceLeaf, false);
51
    }
52
53 4
    public function ModifyDaftNestedObjectTreeInsertBelow(
54
        DaftNestedWriteableObject $newLeaf,
55
        DaftNestedWriteableObject $referenceLeaf
56
    ) : DaftNestedWriteableObject {
57 4
        $this->ModifyDaftNestedObjectTreeInsert($referenceLeaf, $newLeaf, true, true);
58
59 4
        $newLeaf = $this->RecallDaftObject($newLeaf->GetId());
60
61 4
        if ( ! ($newLeaf instanceof DaftNestedWriteableObject)) {
62
            throw new RuntimeException('Could not recall fresh copy of argument 1!');
63
        }
64
65 4
        return $newLeaf;
66
    }
67
68
    /**
69
    * @param mixed $newLeafId
70
    * @param mixed $referenceLeafId
71
    */
72 6
    public function ModifyDaftNestedObjectTreeInsertBelowId(
73
        $newLeafId,
74
        $referenceLeafId
75
    ) : DaftNestedWriteableObject {
76
        if (
77 6
            $newLeafId === $this->GetNestedObjectTreeRootId() &&
78 6
            $referenceLeafId === $this->GetNestedObjectTreeRootId()
79
        ) {
80
            throw new InvalidArgumentException('Cannot use both root ids!');
81
        }
82
83
        /**
84
        * @var DaftNestedWriteableObject|scalar|array $wasId
85
        */
86 6
        $wasId = $newLeafId;
87
88
        /**
89
        * @var DaftNestedWriteableObject|scalar|array $wasReferenceId
90
        */
91 6
        $wasReferenceId = $referenceLeafId;
92
93
        /**
94
        * @var scalar|scalar[]
95
        */
96
        $newLeafId =
97 6
            ($newLeafId instanceof DaftNestedWriteableObject)
98 4
                ? $newLeafId->GetId()
99 6
                : $newLeafId;
100
101 6
        $newLeaf = $this->RecallDaftObject($newLeafId);
102 6
        $referenceLeaf = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $referenceLeaf is dead and can be removed.
Loading history...
103
104
        /**
105
        * @var DaftNestedWriteableObject|array $newLeaf
106
        */
107
        $newLeaf =
108 6
            ($newLeaf instanceof DaftNestedWriteableObject)
109 2
                ? $newLeaf
110 6
                : $wasId;
111
112 6
        if ($referenceLeafId instanceof DaftNestedWriteableObject) {
113 2
            $referenceLeafId = (array) $referenceLeafId->GetId();
114
        }
115
116
        if (
117 6
            $newLeafId !== $this->GetNestedObjectTreeRootId() &&
118 6
            ! ($newLeaf instanceof DaftNestedWriteableObject)
119
        ) {
120
            throw new InvalidArgumentException(sprintf(
121
                'Argument 1 passed to %s was not found to be in this instance of %s',
122
                __METHOD__,
123
                static::class
124
            ));
125
        }
126
127 6
        if ($referenceLeafId === $this->GetNestedObjectTreeRootId()) {
128 4
            return $this->ModifyDaftNestedObjectTreeInsertAfterId($newLeaf, 0);
129
        }
130
131 4
        $referenceLeaf = $this->RecallDaftObject($referenceLeafId);
132
133
        if (
134 4
            ! ($referenceLeaf instanceof DaftNestedWriteableObject) &&
135 4
            $newLeafId === $this->GetNestedObjectTreeRootId() &&
136 4
            ($wasReferenceId instanceof DaftNestedWriteableObject)
137
        ) {
138 2
            $referenceLeaf = $wasReferenceId;
139
        }
140
141 4
        if ( ! ($referenceLeaf instanceof DaftNestedWriteableObject)) {
142
            throw new InvalidArgumentException('Could not find reference leaf!');
143
        }
144
145 4
        $referenceLeaf = $this->StoreThenRetrieveFreshCopy($referenceLeaf);
146
147 4
        if ($newLeafId === $this->GetNestedObjectTreeRootId()) {
148 2
            $tree = array_filter(
149 2
                $this->RecallDaftNestedObjectFullTree(0),
150
                function (DaftNestedWriteableObject $leaf) use ($referenceLeaf) : bool {
151 2
                    return $leaf->GetId() !== $referenceLeaf->GetId();
152 2
                }
153
            );
154
155 2
            if (count($tree) < 1) {
156 2
                $referenceLeaf->SetIntNestedLeft(0);
157 2
                $referenceLeaf->SetIntNestedRight(1);
158 2
                $referenceLeaf->SetIntNestedLevel(0);
159 2
                $referenceLeaf->AlterDaftNestedObjectParentId($this->GetNestedObjectTreeRootId());
160
161 2
                return $this->StoreThenRetrieveFreshCopy($referenceLeaf);
162
            }
163
164
            /**
165
            * @var DaftNestedWriteableObject $treeEnd
166
            */
167 2
            $treeEnd = end($tree);
168
169 2
            $last = $treeEnd->GetIntNestedRight();
170
171 2
            $referenceLeaf->SetIntNestedLeft($last + 1);
172 2
            $referenceLeaf->SetIntNestedRight($last + 2);
173 2
            $referenceLeaf->SetIntNestedLevel(0);
174 2
            $referenceLeaf->AlterDaftNestedObjectParentId($this->GetNestedObjectTreeRootId());
175
176 2
            return $this->StoreThenRetrieveFreshCopy($referenceLeaf);
177
        }
178
179 2
        if ( ! ($newLeaf instanceof DaftNestedWriteableObject)) {
180
            throw new InvalidArgumentException(sprintf(
181
                'Argument 1 passed to %s was not found to be in this instance of %s',
182
                __METHOD__,
183
                static::class
184
            ));
185
        }
186
187 2
        $newLeaf = $this->StoreThenRetrieveFreshCopy($newLeaf);
188
189 2
        $newLeaf->AlterDaftNestedObjectParentId($referenceLeaf->ObtainDaftNestedObjectParentId());
190
191 2
        if ($referenceLeaf instanceof DaftNestedWriteableObject) {
0 ignored issues
show
introduced by
$referenceLeaf is always a sub-type of SignpostMarv\DaftObject\DaftNestedWriteableObject.
Loading history...
192 2
            $this->ModifyDaftNestedObjectTreeInsertBelow($newLeaf, $referenceLeaf);
193
        }
194
195 2
        $this->ForgetDaftObjectById($newLeaf->GetId());
196
197 2
        $out = $this->RecallDaftObject($newLeaf->GetId());
198
199 2
        if ( ! ($out instanceof DaftNestedWriteableObject)) {
200
            throw new RuntimeException('Could not find writeable object in repository!');
201
        }
202
203 2
        return $out;
204
    }
205
206 4
    public function ModifyDaftNestedObjectTreeInsertAbove(
207
        DaftNestedWriteableObject $newLeaf,
208
        DaftNestedWriteableObject $referenceLeaf
209
    ) : DaftNestedWriteableObject {
210 4
        return $this->ModifyDaftNestedObjectTreeInsert($newLeaf, $referenceLeaf, true, true);
211
    }
212
213
    /**
214
    * @param mixed $newLeafId
215
    * @param mixed $referenceLeafId
216
    */
217 6
    public function ModifyDaftNestedObjectTreeInsertAboveId(
218
        $newLeafId,
219
        $referenceLeafId
220
    ) : DaftNestedWriteableObject {
221 6
        if ($referenceLeafId === $this->GetNestedObjectTreeRootId()) {
222 2
            return $this->ModifyDaftNestedObjectTreeInsertBelowId($referenceLeafId, $newLeafId);
223
        }
224
225
        /**
226
        * @var DaftNestedWriteableObject|null $newLeaf
227
        */
228 4
        $newLeaf = $this->RecallDaftObject($newLeafId);
229
230
        /**
231
        * @var DaftNestedWriteableObject|null $referenceLeaf
232
        */
233 4
        $referenceLeaf = $this->RecallDaftObject($referenceLeafId);
234
235 4
        if ( ! ($newLeaf instanceof DaftNestedWriteableObject)) {
236
            throw new InvalidArgumentException(sprintf(
237
                'Argument 1 passed to %s was not found to be in this instance of %s',
238
                __METHOD__,
239
                static::class
240
            ));
241 4
        } elseif ( ! ($referenceLeaf instanceof DaftNestedWriteableObject)) {
242
            throw new InvalidArgumentException(sprintf(
243
                'Argument 2 passed to %s was not found to be in this instance of %s',
244
                __METHOD__,
245
                static::class
246
            ));
247
        }
248
249 4
        return $this->ModifyDaftNestedObjectTreeInsertAbove($newLeaf, $referenceLeaf);
250
    }
251
252 2
    public function ModifyDaftNestedObjectTreeRemoveWithObject(
253
        DaftNestedWriteableObject $root,
254
        ? DaftNestedWriteableObject $replacementRoot
255
    ) : int {
256
        if (
257 2
            $this->CountDaftNestedObjectTreeWithObject($root, false, null) > 0 &&
258 2
            is_null($replacementRoot)
259
        ) {
260
            throw new BadMethodCallException('Cannot leave orphan objects in a tree');
261
        }
262
263 2
        $root = $this->StoreThenRetrieveFreshCopy($root);
264
265 2
        $right = $root->GetIntNestedRight();
266 2
        $width = ($right - $root->GetIntNestedLeft()) + 1;
267
268 2
        $this->ModifyDaftNestedObjectTreeForRemoval($right, $width);
269
270 2
        if ( ! is_null($replacementRoot)) {
271
            $replacementRoot = $this->StoreThenRetrieveFreshCopy($replacementRoot);
272
273
            /**
274
            * @var DaftNestedWriteableObject $alter
275
            */
276
            foreach ($this->RecallDaftNestedObjectTreeWithObject($root, false, 1) as $alter) {
277
                $alter = $this->StoreThenRetrieveFreshCopy($alter);
278
                $this->ModifyDaftNestedObjectTreeInsertBelow($alter, $replacementRoot);
279
            }
280
        }
281
282 2
        $this->RemoveDaftObject($root);
283
284 2
        return $this->CountDaftNestedObjectFullTree();
285
    }
286
287
    /**
288
    * {@inheritdoc}
289
    */
290 2
    public function ModifyDaftNestedObjectTreeRemoveWithId($root, $replacementRoot) : int
291
    {
292 2
        $rootObject = $this->RecallDaftObject($root);
293
294 2
        if ( ! ($rootObject instanceof DaftNestedWriteableObject)) {
295 2
            return $this->CountDaftNestedObjectFullTree();
296
        }
297
298
        if (
299 2
            ! is_null($replacementRoot) &&
300 2
            $replacementRoot !== $this->GetNestedObjectTreeRootId()
301
        ) {
302
            $replacementRootObject = $this->RecallDaftObject($replacementRoot);
303
304
            if ( ! ($replacementRootObject instanceof DaftNestedWriteableObject)) {
305
                throw new InvalidArgumentException(
306
                    'Could not locate replacement root, cannot leave orphan objects!'
307
                );
308
            }
309
310
            return $this->ModifyDaftNestedObjectTreeRemoveWithObject(
311
                $rootObject,
312
                $replacementRootObject
313
            );
314
        }
315
316
        if (
317 2
            $this->CountDaftNestedObjectTreeWithObject($rootObject, false, null) > 0 &&
318 2
            is_null($replacementRoot)
319
        ) {
320
            throw new BadMethodCallException('Cannot leave orphan objects in a tree');
321
        }
322
323
        /**
324
        * @var DaftNestedWriteableObject $alter
325
        */
326 2
        foreach ($this->RecallDaftNestedObjectTreeWithObject($rootObject, false, null) as $alter) {
327
            $alter = $this->StoreThenRetrieveFreshCopy($alter);
328
            $alter->AlterDaftNestedObjectParentId($replacementRoot);
329
            $this->RememberDaftObject($alter);
330
        }
331
332 2
        $right = $rootObject->GetIntNestedRight();
333 2
        $width = ($right - $rootObject->GetIntNestedLeft()) + 1;
334
335 2
        $this->ModifyDaftNestedObjectTreeForRemoval($right, $width);
336
337 2
        $this->RemoveDaftObject($rootObject);
338
339 2
        return $this->CountDaftNestedObjectFullTree();
340
    }
341
342 14
    protected function RememberDaftObjectData(DefinesOwnIdPropertiesInterface $object) : void
343
    {
344 14
        static::ThrowIfNotType($object, DaftNestedWriteableObject::class, 1, __METHOD__);
345
346 14
        parent::RememberDaftObjectData($object);
347 14
    }
348
349
    /**
350
    * @param DaftObject|string $object
351
    */
352 16
    protected static function ThrowIfNotType(
353
        $object,
354
        string $type,
355
        int $argument,
356
        string $function
357
    ) : void {
358 16
        if ( ! is_a($object, DaftNestedWriteableObject::class, is_string($object))) {
359 2
            throw new DaftObjectRepositoryTypeByClassMethodAndTypeException(
360 2
                $argument,
361 2
                static::class,
362 2
                $function,
363 2
                DaftNestedWriteableObject::class,
364 2
                is_string($object) ? $object : get_class($object)
365
            );
366
        }
367
368 14
        parent::ThrowIfNotType($object, $type, $argument, $function);
369 14
    }
370
371 8
    protected function ModifyDaftNestedObjectTreeInsertAlt(
372
        DaftNestedWriteableObject $newLeaf,
373
        DaftNestedWriteableObject $referenceLeaf,
374
        bool $before,
0 ignored issues
show
Unused Code introduced by
The parameter $before is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

374
        /** @scrutinizer ignore-unused */ bool $before,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
375
        ? bool $above
376
    ) : DaftNestedWriteableObject {
377 8
        $newLeaf = $this->StoreThenRetrieveFreshCopy($newLeaf);
378 8
        $referenceLeaf = $this->StoreThenRetrieveFreshCopy($referenceLeaf);
379
380 8
        if (true === $above) {
381 8
            $refLeft = $referenceLeaf->GetIntNestedLeft();
382 8
            $refRight = $referenceLeaf->GetIntNestedRight();
0 ignored issues
show
Unused Code introduced by
The assignment to $refRight is dead and can be removed.
Loading history...
383 8
            $refWidth = ($referenceLeaf->GetIntNestedRight() - $refLeft);
384 8
            $refLevel = $referenceLeaf->GetIntNestedLevel();
385
386 8
            $newLeft = $newLeaf->GetIntNestedLeft();
387 8
            $newRight = $newLeaf->GetIntNestedRight();
388 8
            $newLevel = $newLeaf->GetIntNestedLevel();
389
390
            /**
391
            * @var DaftNestedWriteableObject $alter
392
            */
393
            foreach (
394 8
                $this->RecallDaftNestedObjectTreeWithObject($referenceLeaf, true, null) as $alter
395
            ) {
396 8
                $alterLeft = $alter->GetIntNestedLeft();
397 8
                $alterRight = $alter->GetIntNestedRight();
398 8
                $alterWidth = $alterRight - $alterLeft;
399 8
                $alterLevel = $alter->GetIntNestedLevel();
400
401 8
                $alterLeftNew = ($newLeft + 1 + ($alterLeft - $refLeft));
402
403 8
                $alter->SetIntNestedLeft($alterLeftNew);
404 8
                $alter->SetIntNestedRight($alterLeftNew + $alterWidth);
405 8
                $alter->SetIntNestedLevel($newLevel + ($alterLevel - $refLevel) + 1);
406
407 8
                $this->StoreThenRetrieveFreshCopy($alter);
408
            }
409
410 8
            $newLeaf->SetIntNestedRight($newRight + $refWidth + 1);
411 8
            $referenceLeaf = $this->RecallDaftObject($referenceLeaf->GetId());
412
413 8
            if ( ! ($referenceLeaf instanceof DaftNestedWriteableObject)) {
414
                throw new RuntimeException('Could not recall leaf from tree!');
415
            }
416
417 8
            $referenceLeaf->AlterDaftNestedObjectParentId($newLeaf->GetId());
418 8
            $this->StoreThenRetrieveFreshCopy($referenceLeaf);
419
        }
420
421 8
        $newLeaf = $this->StoreThenRetrieveFreshCopy($newLeaf);
422
423 8
        return $newLeaf;
424
    }
425
426 8
    protected function ModifyDaftNestedObjectTreeInsert(
427
        DaftNestedWriteableObject $newLeaf,
428
        DaftNestedWriteableObject $referenceLeaf,
429
        bool $before,
430
        ? bool $above
431
    ) : DaftNestedWriteableObject {
432 8
        if (true === $above) {
433 8
            return $this->ModifyDaftNestedObjectTreeInsertAlt($newLeaf, $referenceLeaf, $before, $above);
434
        }
435
436 4
        $newLeaf = $this->StoreThenRetrieveFreshCopy($newLeaf);
437 4
        $referenceLeaf = $this->StoreThenRetrieveFreshCopy($referenceLeaf);
438
439 4
        $width = ($newLeaf->GetIntNestedRight() - $newLeaf->GetIntNestedLeft());
440 4
        $refLeft = $referenceLeaf->GetIntNestedLeft();
441 4
        $refWidth = ($referenceLeaf->GetIntNestedRight() - $refLeft);
0 ignored issues
show
Unused Code introduced by
The assignment to $refWidth is dead and can be removed.
Loading history...
442
443 4
        $newLeft = $before
444 2
            ? ($referenceLeaf->GetIntNestedLeft() - $width)
445 4
            : ($referenceLeaf->GetIntNestedRight() + 1);
446
447 4
        $diff = $newLeft - $newLeaf->GetIntNestedLeft();
448
449
        /**
450
        * @var DaftNestedWriteableObject $alter
451
        */
452 4
        foreach ($this->RecallDaftNestedObjectTreeWithObject($newLeaf, false, null) as $alter) {
453
            $alterLeft = $alter->GetIntNestedLeft();
454
            $alterRight = $alter->GetIntNestedRight();
455
            $alter->SetIntNestedLeft($alterLeft + $diff);
456
            $alter->SetIntNestedRight($alterRight + $diff);
457
458
            $alter = $this->StoreThenRetrieveFreshCopy($alter);
0 ignored issues
show
Unused Code introduced by
The assignment to $alter is dead and can be removed.
Loading history...
459
        }
460
461 4
        if ( ! is_null($above)) {
462
            /**
463
            * @var DaftNestedWriteableObject|null $referenceLeaf
464
            */
465
            $referenceLeaf = $this->RecallDaftObject($referenceLeaf->GetId());
466
467
            if ( ! ($referenceLeaf instanceof DaftNestedWriteableObject)) {
468
                throw new RuntimeException(
469
                    'Reference leaf could not be freshly recalled from tree!'
470
                );
471
            }
472
        }
473
474 4
        if ( ! is_null($above)) {
475
            $newLeft = ($referenceLeaf->GetIntNestedRight() + 1);
476
477
            $referenceWidth = $referenceLeaf->GetIntNestedRight() - $newLeft - 2;
478
            $newRight = $newLeft + $referenceWidth + $width;
479
480
            $referenceParent = $referenceLeaf->ObtainDaftNestedObjectParentId();
0 ignored issues
show
Unused Code introduced by
The assignment to $referenceParent is dead and can be removed.
Loading history...
481
482
            $referenceLeaf = $this->StoreThenRetrieveFreshCopy($referenceLeaf);
483
484
            /**
485
            * @var DaftNestedWriteableObject $alter
486
            */
487
            foreach (
488
                $this->RecallDaftNestedObjectTreeWithObject($referenceLeaf, true, null) as $alter
489
            ) {
490
                $level = $alter->GetIntNestedLevel();
491
492
                $alter->SetIntNestedLevel($level + 1);
493
494
                $this->StoreThenRetrieveFreshCopy($alter);
495
            }
496
497
            /**
498
            * @var DaftNestedWriteableObject $alter
499
            */
500
            foreach ($this->RecallDaftNestedObjectFullTree() as $alter) {
501
                $alterLeft = $alter->GetIntNestedLeft();
502
503
                if ($alterLeft >= $referenceLeaf->GetIntNestedLeft()) {
504
                    $alter->SetIntNestedLeft($alterLeft - 1);
505
                    $alter->SetIntNestedRight($alter->GetIntNestedRight() - 1);
506
                }
507
508
                $this->StoreThenRetrieveFreshCopy($alter);
509
            }
510
511
            $referenceLeaf = $this->RecallDaftObject($referenceLeaf->GetId());
512
513
            if ( ! ($referenceLeaf instanceof DaftNestedWriteableObject)) {
514
                throw new RuntimeException(
515
                    'Reference leaf could not be freshly recalled from tree!'
516
                );
517
            }
518
519
            $newLeaf->SetIntNestedLeft($newLeft);
520
            $newLeaf->SetIntNestedRight($newRight + 1);
521
            $newLeaf->SetIntNestedLevel($referenceLeaf->GetIntNestedLevel() - 1);
522
523
            if ($newLeaf->ObtainDaftNestedObjectParentId() === $referenceLeaf->GetId()) {
524
                $newLeaf->AlterDaftNestedObjectParentId(
525
                    $referenceLeaf->ObtainDaftNestedObjectParentId()
526
                );
527
            }
528
        }
529
530 4
        $this->StoreThenRetrieveFreshCopy($newLeaf);
531
532 4
        $negative = array_filter(
533 4
            $this->RecallDaftNestedObjectFullTree(),
534
            function (DaftNestedWriteableObject $leaf) : bool {
535 4
                return $leaf->GetIntNestedLeft() < 0;
536 4
            }
537
        );
538
539 4
        if (count($negative) > 0) {
540
            usort(
541
                $negative,
542
                function (DaftNestedWriteableObject $a, DaftNestedWriteableObject $b) : int {
543
                    return $a->GetIntNestedLeft() <=> $b->GetIntNestedLeft();
544
                }
545
            );
546
547
            /**
548
            * @var DaftNestedWriteableObject $maxnegative
549
            */
550
            $maxnegative = current($negative);
551
552
            $diff = abs($maxnegative->GetIntNestedLeft());
553
554
            /**
555
            * @var DaftNestedWriteableObject $leaf
556
            */
557
            foreach ($this->RecallDaftNestedObjectFullTree() as $leaf) {
558
                $leaf->SetIntNestedLeft($leaf->GetIntNestedLeft() + $diff);
559
                $leaf->SetIntNestedRight($leaf->GetIntNestedRight() + $diff);
560
561
                $this->StoreThenRetrieveFreshCopy($leaf);
562
            }
563
        }
564
565 4
        $newLeaf = $this->RecallDaftObject($newLeaf->GetId());
566
567 4
        if ( ! ($newLeaf instanceof DaftNestedWriteableObject)) {
568
            throw new RuntimeException(
569
                'Reference leaf could not be freshly recalled from tree!'
570
            );
571
        }
572
573 4
        return $newLeaf;
574
    }
575
576
    /**
577
    * @param mixed $newLeafId
578
    * @param mixed $referenceLeafId
579
    */
580 10
    protected function ModifyDaftNestedObjectTreeInsertId(
581
        $newLeafId,
582
        $referenceLeafId,
583
        bool $before
584
    ) : DaftNestedWriteableObject {
585
        /**
586
        * @var DaftNestedWriteableObject|null $newLeaf
587
        */
588
        $newLeaf =
589 10
            ($newLeafId instanceof DaftNestedWriteableObject)
590 10
                ? $newLeafId
591 10
                : $this->RecallDaftObject($newLeafId);
592
593 10
        if ( ! ($newLeaf instanceof DaftNestedWriteableObject)) {
594
            throw new RuntimeException('Leaf could not be retrieved from argument 1!');
595
        }
596
597 10
        $newLeaf = $this->StoreThenRetrieveFreshCopy($newLeaf);
598
599 10
        $referenceLeaf = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $referenceLeaf is dead and can be removed.
Loading history...
600
601 10
        if ($referenceLeafId === $this->GetNestedObjectTreeRootId()) {
602 10
            $tree = array_filter(
603 10
                $this->RecallDaftNestedObjectFullTree(0),
604
                function (DaftNestedWriteableObject $leaf) use ($newLeaf) : bool {
605 10
                    return $leaf->GetId() !== $newLeaf->GetId();
606 10
                }
607
            );
608
609 10
            if (count($tree) > 0) {
610 10
                if ($before) {
611
                    /**
612
                    * @var DaftNestedWriteableObject $leaf
613
                    */
614
                    foreach ($this->RecallDaftNestedObjectFullTree() as $leaf) {
615
                        $leaf->SetIntNestedLeft($leaf->GetIntNestedLeft() + 2);
616
                        $leaf->SetIntNestedRight($leaf->GetIntNestedLeft() + 2);
617
618
                        $this->StoreThenRetrieveFreshCopy($leaf);
619
                    }
620
621
                    $newLeaf->SetIntNestedLeft(0);
622
                    $newLeaf->SetIntNestedRight(1);
623
                    $newLeaf->SetIntNestedLevel(0);
624
                    $newLeaf->AlterDaftNestedObjectParentId($this->GetNestedObjectTreeRootId());
625
626
                    return $this->StoreThenRetrieveFreshCopy($newLeaf);
627
                }
628
629
                /**
630
                * @var DaftNestedWriteableObject $treeEnd
631
                */
632 10
                $treeEnd = end($tree);
633
634 10
                $reference = $treeEnd->GetIntNestedRight();
635
636 10
                $newLeaf->SetIntNestedLeft($reference + 1);
637 10
                $newLeaf->SetIntNestedRight($reference + 2);
638 10
                $newLeaf->SetIntNestedLevel(0);
639 10
                $newLeaf->AlterDaftNestedObjectParentId($this->GetNestedObjectTreeRootId());
640
641 10
                return $this->StoreThenRetrieveFreshCopy($newLeaf);
642
            }
643 10
            $newLeaf->SetIntNestedLeft(0);
644 10
            $newLeaf->SetIntNestedRight(1);
645 10
            $newLeaf->SetIntNestedLevel(0);
646
647 10
            return $this->StoreThenRetrieveFreshCopy($newLeaf);
648
        }
649
650 4
        $referenceLeaf = $this->RecallDaftObject($referenceLeafId);
651
652 4
        if ( ! ($referenceLeaf instanceof DaftNestedWriteableObject)) {
653
            throw new InvalidArgumentException(sprintf(
654
                'Argument 2 passed to %s was not found to be in this instance of %s',
655
                __METHOD__,
656
                static::class
657
            ));
658
        }
659
660 4
        return $this->ModifyDaftNestedObjectTreeInsert($newLeaf, $referenceLeaf, $before, null);
661
    }
662
663 2
    protected function ModifyDaftNestedObjectTreeForRemoval(int $right, int $width) : void
664
    {
665
        /**
666
        * @var DaftNestedWriteableObject $alter
667
        */
668 2
        foreach ($this->RecallDaftNestedObjectFullTree() as $alter) {
669 2
            $alter = $this->StoreThenRetrieveFreshCopy($alter);
670
671 2
            $alterLeft = $alter->GetIntNestedLeft();
672 2
            $alterRight = $alter->GetIntNestedRight();
673 2
            $changed = false;
674
675 2
            if ($alterRight > $right) {
676 2
                $alter->SetIntNestedRight($alterRight - $width);
677 2
                $changed = true;
678
            }
679 2
            if ($alterLeft > $right) {
680 2
                $alter->SetIntNestedLeft($alterLeft - $width);
681 2
                $changed = true;
682
            }
683
684 2
            if ($changed) {
685 2
                $this->RememberDaftObject($alter);
686
            }
687
        }
688 2
    }
689
690 12
    protected function StoreThenRetrieveFreshCopy(
691
        DaftNestedWriteableObject $leaf
692
    ) : DaftNestedWriteableObject {
693 12
        $this->RememberDaftObject($leaf);
694 12
        $this->ForgetDaftObject($leaf);
695 12
        $this->ForgetDaftObjectById($leaf->GetId());
696
697 12
        $fresh = $this->RecallDaftObject($leaf->GetId());
698
699 12
        if ( ! ($fresh instanceof DaftNestedWriteableObject)) {
700
            throw new RuntimeException('Was not able to obtain a fresh copy of the object!');
701
        }
702
703 12
        return $fresh;
704
    }
705
}
706