ShadowBelongsTo   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Test Coverage

Coverage 63.89%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 32
dl 0
loc 79
ccs 23
cts 36
cp 0.6389
rs 10
c 1
b 0
f 0
wmc 18

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getInnerKeys() 0 3 1
A isCascade() 0 3 1
A __construct() 0 7 1
A getName() 0 3 1
A checkFieldsExists() 0 9 3
A getTarget() 0 3 1
A prepare() 0 5 1
A registerWaitingFields() 0 4 2
A isNullable() 0 3 1
A queue() 0 10 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\ORM\Relation;
6
7
use Cycle\ORM\Heap\State;
8
use Cycle\ORM\Relation;
9
use Cycle\ORM\Transaction\Pool;
10
use Cycle\ORM\Transaction\Tuple;
11
12
/**
13
 * @internal
14
 */
15
class ShadowBelongsTo implements ReversedRelationInterface, DependencyInterface
16
{
17
    private string $name;
18
    private string $target;
19
    private array $schema;
20
21
    private array $innerKeys;
22
    private bool $cascade;
23
24 3648
    public function __construct(string $name, string $target, array $schema)
25
    {
26 3648
        $this->name = $target . '.' . $name . ':' . $schema[Relation::TARGET];
27 3648
        $this->target = $target;
28 3648
        $this->schema = $schema;
29 3648
        $this->innerKeys = (array)($schema[Relation::SCHEMA][Relation::OUTER_KEY] ?? []);
30 3648
        $this->cascade = (bool)($schema[Relation::SCHEMA][Relation::CASCADE] ?? false);
31
    }
32
33
    public function getInnerKeys(): array
34
    {
35
        return $this->innerKeys;
36
    }
37
38
    public function prepare(Pool $pool, Tuple $tuple, mixed $related, bool $load = true): void
39
    {
40
        $tuple->state->setRelation($this->getName(), $related);
41
        $this->registerWaitingFields($tuple->state, !$this->isNullable());
42
        $tuple->state->setRelationStatus($this->getName(), RelationInterface::STATUS_PROCESS);
43
    }
44
45 1264
    public function queue(Pool $pool, Tuple $tuple): void
46
    {
47 1264
        $status = $tuple->state->getRelationStatus($this->getName());
48 1264
        if ($status === RelationInterface::STATUS_PREPARE && $this->isNullable()) {
49 214
            $tuple->state->setRelationStatus($this->getName(), RelationInterface::STATUS_DEFERRED);
50
        }
51 1264
        if ($tuple->status >= Tuple::STATUS_WAITED) {
52
            // Check fields
53 1152
            if ($this->isNullable() || $this->checkFieldsExists($tuple->state)) {
54 1120
                $tuple->state->setRelationStatus($this->getName(), RelationInterface::STATUS_RESOLVED);
55
            }
56
        }
57
    }
58
59 3648
    public function getName(): string
60
    {
61 3648
        return $this->name;
62
    }
63
64
    public function getTarget(): string
65
    {
66
        return $this->target;
67
    }
68
69
    public function isCascade(): bool
70
    {
71
        return $this->cascade;
72
    }
73
74 1264
    public function isNullable(): bool
75
    {
76 1264
        return (bool)($this->schema[Relation::SCHEMA][Relation::NULLABLE] ?? false);
77
    }
78
79 1016
    private function checkFieldsExists(State $state): bool
80
    {
81 1016
        $data = $state->getData();
82 1016
        foreach ($this->innerKeys as $key) {
83 880
            if (!isset($data[$key])) {
84 97
                return false;
85
            }
86
        }
87 984
        return true;
88
    }
89
90
    private function registerWaitingFields(State $state, bool $required = true): void
91
    {
92
        foreach ($this->innerKeys as $key) {
93
            $state->waitField($key, $required);
94
        }
95
    }
96
}
97