Passed
Push — master ( a1e60a...ad8bf2 )
by Anton
02:58
created

HasOne::queue()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 37
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 19
nc 24
nop 5
dl 0
loc 37
rs 8.8333
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
namespace Cycle\ORM\Relation;
11
12
use Cycle\ORM\Command\Branch\Condition;
13
use Cycle\ORM\Command\Branch\ContextSequence;
14
use Cycle\ORM\Command\Branch\Nil;
15
use Cycle\ORM\Command\CommandInterface;
16
use Cycle\ORM\Command\ContextCarrierInterface as CC;
17
use Cycle\ORM\Heap\Node;
18
use Cycle\ORM\Promise\ReferenceInterface;
19
use Cycle\ORM\Relation\Traits\PromiseOneTrait;
20
21
/**
22
 * Provides the ability to own and forward context values to child entity.
23
 */
24
class HasOne extends AbstractRelation
25
{
26
    use PromiseOneTrait;
27
28
    /**
29
     * @inheritdoc
30
     */
31
    public function queue(CC $parentStore, $parentEntity, Node $parentNode, $related, $original): CommandInterface
32
    {
33
        if ($original instanceof ReferenceInterface) {
34
            $original = $this->resolve($original);
35
        }
36
37
        if ($related instanceof ReferenceInterface) {
38
            $related = $this->resolve($related);
39
        }
40
41
        if (is_null($related)) {
42
            if ($related === $original) {
43
                // no changes
44
                return new Nil();
45
            }
46
47
            if (!is_null($original)) {
48
                return $this->deleteOriginal($original);
49
            }
50
        }
51
52
        $resStore = $this->orm->queueStore($related);
0 ignored issues
show
Bug introduced by
The method queueStore() does not exist on Cycle\ORM\Select\SourceProviderInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Cycle\ORM\Select\SourceProviderInterface. ( Ignorable by Annotation )

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

52
        /** @scrutinizer ignore-call */ 
53
        $resStore = $this->orm->queueStore($related);
Loading history...
53
        $relNode = $this->getNode($related, +1);
54
        $this->assertValid($relNode);
0 ignored issues
show
Bug introduced by
It seems like $relNode can also be of type null; however, parameter $relNode of Cycle\ORM\Relation\AbstractRelation::assertValid() does only seem to accept Cycle\ORM\Heap\Node, maybe add an additional type check? ( Ignorable by Annotation )

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

54
        $this->assertValid(/** @scrutinizer ignore-type */ $relNode);
Loading history...
55
56
        // store command with mounted context paths
57
        $relStore = $this->forwardContext($parentNode, $this->innerKey, $resStore, $relNode, $this->outerKey);
58
59
        if (is_null($original)) {
60
            return $relStore;
61
        }
62
63
        $sequence = new ContextSequence();
64
        $sequence->addCommand($this->deleteOriginal($original));
65
        $sequence->addPrimary($relStore);
66
67
        return $sequence;
68
    }
69
70
    /**
71
     * Delete original related entity of no other objects reference to it.
72
     *
73
     * @param object $original
74
     * @return CommandInterface
75
     */
76
    protected function deleteOriginal($original): CommandInterface
77
    {
78
        $relNode = $this->getNode($original);
79
80
        // only delete original child when no other objects claim it
81
        return new Condition($this->orm->queueDelete($original), function () use ($relNode) {
0 ignored issues
show
Bug introduced by
The method queueDelete() does not exist on Cycle\ORM\Select\SourceProviderInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Cycle\ORM\Select\SourceProviderInterface. ( Ignorable by Annotation )

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

81
        return new Condition($this->orm->/** @scrutinizer ignore-call */ queueDelete($original), function () use ($relNode) {
Loading history...
82
            return !$relNode->getState()->hasClaims();
83
        });
84
    }
85
}