Passed
Push — master ( 1e65a5...6cebba )
by SignpostMarv
03:39
created

ModifyDaftNestedObjectTreeInsertAbove()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
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 5
rs 9.4285
c 0
b 0
f 0
ccs 2
cts 2
cp 1
crap 1
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 2
    public function ModifyDaftNestedObjectTreeInsertAfter(
25
        DaftNestedWriteableObject $newLeaf,
26
        DaftNestedWriteableObject $referenceLeaf
27
    ) : DaftNestedWriteableObject {
28 2
        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 2
    public function ModifyDaftNestedObjectTreeInsertAfterId(
47
        $newLeaf,
48
        $referenceLeaf
49
    ) : DaftNestedWriteableObject {
50 2
        return $this->ModifyDaftNestedObjectTreeInsertId($newLeaf, $referenceLeaf, false);
51
    }
52
53 2
    public function ModifyDaftNestedObjectTreeInsertBelow(
54
        DaftNestedWriteableObject $newLeaf,
55
        DaftNestedWriteableObject $referenceLeaf
56
    ) : DaftNestedWriteableObject {
57 2
        $this->ModifyDaftNestedObjectTreeInsert($referenceLeaf, $newLeaf, true, true);
58
59 2
        $newLeaf = $this->RecallDaftObject($newLeaf->GetId());
60
61 2
        if ( ! ($newLeaf instanceof DaftNestedWriteableObject)) {
62
            throw new RuntimeException('Could not recall fresh copy of argument 1!');
63
        }
64
65 2
        return $newLeaf;
66
    }
67
68
    /**
69
    * @param mixed $newLeafId
70
    * @param mixed $referenceLeafId
71
    */
72 2
    public function ModifyDaftNestedObjectTreeInsertBelowId(
73
        $newLeafId,
74
        $referenceLeafId
75
    ) : DaftNestedWriteableObject {
76
        if (
77 2
            $newLeafId === $this->GetNestedObjectTreeRootId() &&
78 2
            $referenceLeafId === $this->GetNestedObjectTreeRootId()
79
        ) {
80
            throw new InvalidArgumentException('Cannot use both root ids!');
81
        }
82
83
        /**
84
        * @var DaftNestedWriteableObject|scalar|array $wasId
85
        */
86 2
        $wasId = $newLeafId;
87
88
        /**
89
        * @var DaftNestedWriteableObject|scalar|array $wasReferenceId
90
        */
91 2
        $wasReferenceId = $referenceLeafId;
92
93
        /**
94
        * @var scalar|scalar[]
95
        */
96
        $newLeafId =
97 2
            ($newLeafId instanceof DaftNestedWriteableObject)
98 2
                ? $newLeafId->GetId()
99 2
                : $newLeafId;
100
101 2
        $newLeaf = $this->RecallDaftObject($newLeafId);
102 2
        $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 2
            ($newLeaf instanceof DaftNestedWriteableObject)
109 2
                ? $newLeaf
110 2
                : $wasId;
111
112 2
        if ($referenceLeafId instanceof DaftNestedWriteableObject) {
113 2
            $referenceLeafId = (array) $referenceLeafId->GetId();
114
        }
115
116
        if (
117 2
            $newLeafId !== $this->GetNestedObjectTreeRootId() &&
118 2
            ! ($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 2
        if ($referenceLeafId === $this->GetNestedObjectTreeRootId()) {
128 2
            return $this->ModifyDaftNestedObjectTreeInsertAfterId($newLeaf, 0);
129
        }
130
131 2
        $referenceLeaf = $this->RecallDaftObject($referenceLeafId);
132
133
        if (
134 2
            ! ($referenceLeaf instanceof DaftNestedWriteableObject) &&
135 2
            $newLeafId === $this->GetNestedObjectTreeRootId() &&
136 2
            ($wasReferenceId instanceof DaftNestedWriteableObject)
137
        ) {
138 2
            $referenceLeaf = $wasReferenceId;
139
        }
140
141 2
        if ( ! ($referenceLeaf instanceof DaftNestedWriteableObject)) {
142
            throw new InvalidArgumentException('Could not find reference leaf!');
143
        }
144
145 2
        $referenceLeaf = $this->StoreThenRetrieveFreshCopy($referenceLeaf);
146
147 2
        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 2
    public function ModifyDaftNestedObjectTreeInsertAbove(
207
        DaftNestedWriteableObject $newLeaf,
208
        DaftNestedWriteableObject $referenceLeaf
209
    ) : DaftNestedWriteableObject {
210 2
        return $this->ModifyDaftNestedObjectTreeInsert($newLeaf, $referenceLeaf, true, true);
211
    }
212
213
    /**
214
    * @param mixed $newLeafId
215
    * @param mixed $referenceLeafId
216
    */
217 2
    public function ModifyDaftNestedObjectTreeInsertAboveId(
218
        $newLeafId,
219
        $referenceLeafId
220
    ) : DaftNestedWriteableObject {
221 2
        if ($referenceLeafId === $this->GetNestedObjectTreeRootId()) {
222 2
            return $this->ModifyDaftNestedObjectTreeInsertBelowId($referenceLeafId, $newLeafId);
223
        }
224
225
        /**
226
        * @var DaftNestedWriteableObject|null $newLeaf
227
        */
228 2
        $newLeaf = $this->RecallDaftObject($newLeafId);
229
230
        /**
231
        * @var DaftNestedWriteableObject|null $referenceLeaf
232
        */
233 2
        $referenceLeaf = $this->RecallDaftObject($referenceLeafId);
234
235 2
        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 2
        } 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 2
        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 4
    protected function RememberDaftObjectData(DefinesOwnIdPropertiesInterface $object) : void
343
    {
344 4
        static::ThrowIfNotType($object, DaftNestedWriteableObject::class, 1, __METHOD__);
345
346 4
        parent::RememberDaftObjectData($object);
347 4
    }
348
349
    /**
350
    * @param DaftObject|string $object
351
    */
352 6
    protected static function ThrowIfNotType(
353
        $object,
354
        string $type,
355
        int $argument,
356
        string $function
357
    ) : void {
358 6
        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 4
        parent::ThrowIfNotType($object, $type, $argument, $function);
369 4
    }
370
371 2
    protected function ModifyDaftNestedObjectTreeInsert(
372
        DaftNestedWriteableObject $newLeaf,
373
        DaftNestedWriteableObject $referenceLeaf,
374
        bool $before,
375
        ? bool $above
376
    ) : DaftNestedWriteableObject {
377 2
        $newLeaf = $this->StoreThenRetrieveFreshCopy($newLeaf);
378 2
        $referenceLeaf = $this->StoreThenRetrieveFreshCopy($referenceLeaf);
379
380 2
        $width = ($newLeaf->GetIntNestedRight() - $newLeaf->GetIntNestedLeft());
381 2
        $refLeft = $referenceLeaf->GetIntNestedLeft();
382 2
        $refWidth = ($referenceLeaf->GetIntNestedRight() - $refLeft);
0 ignored issues
show
Unused Code introduced by
The assignment to $refWidth is dead and can be removed.
Loading history...
383
384 2
        $newLeft = $before
385 2
            ? ($referenceLeaf->GetIntNestedLeft() - $width)
386 2
            : ($referenceLeaf->GetIntNestedRight() + 1);
387
388 2
        $diff = $newLeft - $newLeaf->GetIntNestedLeft();
389
390
        /**
391
        * @var DaftNestedWriteableObject $alter
392
        */
393 2
        foreach ($this->RecallDaftNestedObjectTreeWithObject($newLeaf, false, null) as $alter) {
394
            $alterLeft = $alter->GetIntNestedLeft();
395
            $alterRight = $alter->GetIntNestedRight();
396
            $alter->SetIntNestedLeft($alterLeft + $diff);
397
            $alter->SetIntNestedRight($alterRight + $diff);
398
399
            $alter = $this->StoreThenRetrieveFreshCopy($alter);
0 ignored issues
show
Unused Code introduced by
The assignment to $alter is dead and can be removed.
Loading history...
400
        }
401
402 2
        if ( ! is_null($above)) {
403 2
            $referenceLeaf = $this->RecallDaftObject($referenceLeaf->GetId());
404
405 2
            if ( ! ($referenceLeaf instanceof DaftNestedWriteableObject)) {
406
                throw new RuntimeException(
407
                    'Reference leaf could not be freshly recalled from tree!'
408
                );
409
            }
410
        }
411
412 2
        if ( ! is_null($above)) {
413
            $newLeft =
414 2
                $above
415 2
                    ? ($referenceLeaf->GetIntNestedLeft() - 2)
416 2
                    : ($referenceLeaf->GetIntNestedRight() + 1);
417
418 2
            $referenceWidth = $referenceLeaf->GetIntNestedRight() - $newLeft - 2;
419 2
            $newRight = $newLeft + $referenceWidth + $width;
420
421 2
            $referenceParent = $referenceLeaf->ObtainDaftNestedObjectParentId();
0 ignored issues
show
Unused Code introduced by
The assignment to $referenceParent is dead and can be removed.
Loading history...
422
423 2
            $referenceLeaf = $this->StoreThenRetrieveFreshCopy($referenceLeaf);
424
425
            /**
426
            * @var DaftNestedWriteableObject $alter
427
            */
428
            foreach (
429 2
                $this->RecallDaftNestedObjectTreeWithObject($referenceLeaf, true, null) as $alter
430
            ) {
431 2
                $level = $alter->GetIntNestedLevel();
432
433 2
                $alter->SetIntNestedLevel($level + 1);
434
435 2
                $this->StoreThenRetrieveFreshCopy($alter);
436
            }
437
438
            /**
439
            * @var DaftNestedWriteableObject $alter
440
            */
441 2
            foreach ($this->RecallDaftNestedObjectFullTree() as $alter) {
442 2
                $alterLeft = $alter->GetIntNestedLeft();
443
444 2
                if ($alterLeft >= $referenceLeaf->GetIntNestedLeft()) {
445 2
                    $alter->SetIntNestedLeft($alterLeft - 1);
446 2
                    $alter->SetIntNestedRight($alter->GetIntNestedRight() - 1);
447
                }
448
449 2
                $this->StoreThenRetrieveFreshCopy($alter);
450
            }
451
452 2
            $referenceLeaf = $this->RecallDaftObject($referenceLeaf->GetId());
453
454 2
            if ( ! ($referenceLeaf instanceof DaftNestedWriteableObject)) {
455
                throw new RuntimeException(
456
                    'Reference leaf could not be freshly recalled from tree!'
457
                );
458
            }
459
460 2
            $newLeaf->SetIntNestedLeft($newLeft);
461 2
            $newLeaf->SetIntNestedRight($newRight + 1);
462 2
            $newLeaf->SetIntNestedLevel($referenceLeaf->GetIntNestedLevel() - 1);
463
464 2
            if ($newLeaf->ObtainDaftNestedObjectParentId() === $referenceLeaf->GetId()) {
465
                $newLeaf->AlterDaftNestedObjectParentId(
466
                    $referenceLeaf->ObtainDaftNestedObjectParentId()
467
                );
468
            }
469
        }
470
471 2
        $this->StoreThenRetrieveFreshCopy($newLeaf);
472
473 2
        $negative = array_filter(
474 2
            $this->RecallDaftNestedObjectFullTree(),
475
            function (DaftNestedWriteableObject $leaf) : bool {
476 2
                return $leaf->GetIntNestedLeft() < 0;
477 2
            }
478
        );
479
480 2
        if (count($negative) > 0) {
481
            usort(
482
                $negative,
483
                function (DaftNestedWriteableObject $a, DaftNestedWriteableObject $b) : int {
484
                    return $a->GetIntNestedLeft() <=> $b->GetIntNestedLeft();
485
                }
486
            );
487
488
            /**
489
            * @var DaftNestedWriteableObject $maxnegative
490
            */
491
            $maxnegative = current($negative);
492
493
            $diff = abs($maxnegative->GetIntNestedLeft());
494
495
            /**
496
            * @var DaftNestedWriteableObject $leaf
497
            */
498
            foreach ($this->RecallDaftNestedObjectFullTree() as $leaf) {
499
                $leaf->SetIntNestedLeft($leaf->GetIntNestedLeft() + $diff);
500
                $leaf->SetIntNestedRight($leaf->GetIntNestedRight() + $diff);
501
502
                $this->StoreThenRetrieveFreshCopy($leaf);
503
            }
504
        }
505
506 2
        $newLeaf = $this->RecallDaftObject($newLeaf->GetId());
507
508 2
        if ( ! ($newLeaf instanceof DaftNestedWriteableObject)) {
509
            throw new RuntimeException(
510
                'Reference leaf could not be freshly recalled from tree!'
511
            );
512
        }
513
514 2
        return $newLeaf;
515
    }
516
517
    /**
518
    * @param mixed $newLeafId
519
    * @param mixed $referenceLeafId
520
    */
521 2
    protected function ModifyDaftNestedObjectTreeInsertId(
522
        $newLeafId,
523
        $referenceLeafId,
524
        bool $before
525
    ) : DaftNestedWriteableObject {
526
        /**
527
        * @var DaftNestedWriteableObject|null $newLeaf
528
        */
529
        $newLeaf =
530 2
            ($newLeafId instanceof DaftNestedWriteableObject)
531 2
                ? $newLeafId
532 2
                : $this->RecallDaftObject($newLeafId);
533
534 2
        if ( ! ($newLeaf instanceof DaftNestedWriteableObject)) {
535
            throw new RuntimeException('Leaf could not be retrieved from argument 1!');
536
        }
537
538 2
        $newLeaf = $this->StoreThenRetrieveFreshCopy($newLeaf);
539
540 2
        $referenceLeaf = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $referenceLeaf is dead and can be removed.
Loading history...
541
542 2
        if ($referenceLeafId === $this->GetNestedObjectTreeRootId()) {
543 2
            $tree = array_filter(
544 2
                $this->RecallDaftNestedObjectFullTree(0),
545
                function (DaftNestedWriteableObject $leaf) use ($newLeaf) : bool {
546 2
                    return $leaf->GetId() !== $newLeaf->GetId();
547 2
                }
548
            );
549
550 2
            if (count($tree) > 0) {
551 2
                if ($before) {
552
                    /**
553
                    * @var DaftNestedWriteableObject $leaf
554
                    */
555
                    foreach ($this->RecallDaftNestedObjectFullTree() as $leaf) {
556
                        $leaf->SetIntNestedLeft($leaf->GetIntNestedLeft() + 2);
557
                        $leaf->SetIntNestedRight($leaf->GetIntNestedLeft() + 2);
558
559
                        $this->StoreThenRetrieveFreshCopy($leaf);
560
                    }
561
562
                    $newLeaf->SetIntNestedLeft(0);
563
                    $newLeaf->SetIntNestedRight(1);
564
                    $newLeaf->SetIntNestedLevel(0);
565
                    $newLeaf->AlterDaftNestedObjectParentId($this->GetNestedObjectTreeRootId());
566
567
                    return $this->StoreThenRetrieveFreshCopy($newLeaf);
568
                }
569
570
                /**
571
                * @var DaftNestedWriteableObject $treeEnd
572
                */
573 2
                $treeEnd = end($tree);
574
575 2
                $reference = $treeEnd->GetIntNestedRight();
576
577 2
                $newLeaf->SetIntNestedLeft($reference + 1);
578 2
                $newLeaf->SetIntNestedRight($reference + 2);
579 2
                $newLeaf->SetIntNestedLevel(0);
580 2
                $newLeaf->AlterDaftNestedObjectParentId($this->GetNestedObjectTreeRootId());
581
582 2
                return $this->StoreThenRetrieveFreshCopy($newLeaf);
583
            }
584 2
            $newLeaf->SetIntNestedLeft(0);
585 2
            $newLeaf->SetIntNestedRight(1);
586 2
            $newLeaf->SetIntNestedLevel(0);
587
588 2
            return $this->StoreThenRetrieveFreshCopy($newLeaf);
589
        }
590
591 2
        $referenceLeaf = $this->RecallDaftObject($referenceLeafId);
592
593 2
        if ( ! ($referenceLeaf instanceof DaftNestedWriteableObject)) {
594
            throw new InvalidArgumentException(sprintf(
595
                'Argument 2 passed to %s was not found to be in this instance of %s',
596
                __METHOD__,
597
                static::class
598
            ));
599
        }
600
601 2
        return $this->ModifyDaftNestedObjectTreeInsert($newLeaf, $referenceLeaf, $before, null);
602
    }
603
604 2
    protected function ModifyDaftNestedObjectTreeForRemoval(int $right, int $width) : void
605
    {
606
        /**
607
        * @var DaftNestedWriteableObject $alter
608
        */
609 2
        foreach ($this->RecallDaftNestedObjectFullTree() as $alter) {
610 2
            $alter = $this->StoreThenRetrieveFreshCopy($alter);
611
612 2
            $alterLeft = $alter->GetIntNestedLeft();
613 2
            $alterRight = $alter->GetIntNestedRight();
614 2
            $changed = false;
615
616 2
            if ($alterRight > $right) {
617 2
                $alter->SetIntNestedRight($alterRight - $width);
618 2
                $changed = true;
619
            }
620 2
            if ($alterLeft > $right) {
621 2
                $alter->SetIntNestedLeft($alterLeft - $width);
622 2
                $changed = true;
623
            }
624
625 2
            if ($changed) {
626 2
                $this->RememberDaftObject($alter);
627
            }
628
        }
629 2
    }
630
631 2
    protected function StoreThenRetrieveFreshCopy(
632
        DaftNestedWriteableObject $leaf
633
    ) : DaftNestedWriteableObject {
634 2
        $this->RememberDaftObject($leaf);
635 2
        $this->ForgetDaftObject($leaf);
636 2
        $this->ForgetDaftObjectById($leaf->GetId());
637
638 2
        $fresh = $this->RecallDaftObject($leaf->GetId());
639
640 2
        if ( ! ($fresh instanceof DaftNestedWriteableObject)) {
641
            throw new RuntimeException('Was not able to obtain a fresh copy of the object!');
642
        }
643
644 2
        return $fresh;
645
    }
646
}
647