Passed
Push — master ( 9676b0...44a032 )
by Anton
02:07
created

AbstractRelation::isNullable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Cycle DataMapper ORM
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
declare(strict_types=1);
9
10
namespace Cycle\ORM\Relation;
11
12
use Cycle\ORM\Exception\RelationException;
13
use Cycle\ORM\Heap\Node;
14
use Cycle\ORM\MapperInterface;
15
use Cycle\ORM\ORMInterface;
16
use Cycle\ORM\Promise\PromiseInterface;
17
use Cycle\ORM\Promise\ReferenceInterface;
18
use Cycle\ORM\Relation;
19
use Cycle\ORM\Schema;
20
use Cycle\ORM\Select\SourceInterface;
21
use Cycle\ORM\Select\SourceProviderInterface;
22
23
abstract class AbstractRelation implements RelationInterface
24
{
25
    use Traits\ContextTrait;
26
27
    /** @var ORMInterface|SourceProviderInterface @internal */
28
    protected $orm;
29
30
    /** @var string */
31
    protected $name;
32
33
    /** @var string */
34
    protected $target;
35
36
    /** @var array */
37
    protected $schema;
38
39
    /** @var string */
40
    protected $innerKey;
41
42
    /** @var string */
43
    protected $outerKey;
44
45
    /**
46
     * @param ORMInterface $orm
47
     * @param string       $name
48
     * @param string       $target
49
     * @param array        $schema
50
     */
51
    public function __construct(ORMInterface $orm, string $name, string $target, array $schema)
52
    {
53
        $this->orm = $orm;
54
        $this->name = $name;
55
        $this->target = $target;
56
        $this->schema = $schema;
57
        $this->innerKey = $schema[Relation::INNER_KEY];
58
        $this->outerKey = $schema[Relation::OUTER_KEY];
59
    }
60
61
    /**
62
     * @inheritdoc
63
     */
64
    public function getName(): string
65
    {
66
        return $this->name;
67
    }
68
69
    /**
70
     * @inheritdoc
71
     */
72
    public function isCascade(): bool
73
    {
74
        return $this->schema[Relation::CASCADE] ?? false;
75
    }
76
77
    /**
78
     * @inheritdoc
79
     */
80
    public function init(array $data): array
81
    {
82
        $item = $this->orm->make($this->target, $data, Node::MANAGED);
0 ignored issues
show
Bug introduced by
The method make() 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

82
        /** @scrutinizer ignore-call */ 
83
        $item = $this->orm->make($this->target, $data, Node::MANAGED);
Loading history...
83
84
        return [$item, $item];
85
    }
86
87
    /**
88
     * @inheritdoc
89
     */
90
    public function extract($data)
91
    {
92
        return $data;
93
    }
94
95
    /**
96
     * @return string
97
     */
98
    public function __toString()
99
    {
100
        // this is incorrect class
101
        return sprintf("%s(%s)->%s", $this->name, get_class($this), $this->target);
102
    }
103
104
    /**
105
     * Indicates that relation can not be nullable.
106
     *
107
     * @return bool
108
     */
109
    protected function isNullable(): bool
110
    {
111
        if (array_key_exists(Relation::NULLABLE, $this->schema)) {
112
            return !$this->schema[Relation::NULLABLE];
113
        }
114
115
        return true;
116
    }
117
118
    /**
119
     * Get Node for the given entity. Null if entity does not exists. Automatically
120
     * register entity claims.
121
     *
122
     * @param object $entity
123
     * @param int    $claim
124
     * @return Node|null
125
     */
126
    protected function getNode($entity, int $claim = 0): ?Node
127
    {
128
        if (is_null($entity)) {
129
            return null;
130
        }
131
132
        if ($entity instanceof ReferenceInterface) {
133
            return new Node(Node::PROMISED, $entity->__scope(), $entity->__role());
134
        }
135
136
        $node = $this->orm->getHeap()->get($entity);
0 ignored issues
show
Bug introduced by
The method getHeap() 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

136
        $node = $this->orm->/** @scrutinizer ignore-call */ getHeap()->get($entity);
Loading history...
137
138
        if (is_null($node)) {
139
            $node = new Node(Node::NEW, [], $this->orm->getMapper($entity)->getRole());
0 ignored issues
show
Bug introduced by
The method getMapper() 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

139
            $node = new Node(Node::NEW, [], $this->orm->/** @scrutinizer ignore-call */ getMapper($entity)->getRole());
Loading history...
140
            $this->orm->getHeap()->attach($entity, $node);
141
        }
142
143
        if ($claim === 1) {
144
            $node->getState()->addClaim();
145
        }
146
147
        if ($claim === -1) {
148
            $node->getState()->decClaim();
149
        }
150
151
        return $node;
152
    }
153
154
    /**
155
     * Get the source associated with the role.
156
     *
157
     * @param string|null $role
158
     * @return SourceInterface
159
     */
160
    protected function getSource(string $role = null): SourceInterface
161
    {
162
        return $this->orm->getSource($role ?? $this->target);
163
    }
164
165
    /**
166
     * Get the mapper associated with a role.
167
     *
168
     * @param string|null $role
169
     * @return MapperInterface
170
     */
171
    protected function getMapper(string $role = null): MapperInterface
172
    {
173
        return $this->orm->getMapper($role ?? $this->target);
174
    }
175
176
    /**
177
     * @param Node   $node
178
     * @param string $field
179
     * @return string
180
     */
181
    protected function columnName(Node $node, string $field): string
182
    {
183
        return $this->orm->getSchema()->define($node->getRole(), Schema::COLUMNS)[$field] ?? $field;
0 ignored issues
show
Bug introduced by
The method getSchema() 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

183
        return $this->orm->/** @scrutinizer ignore-call */ getSchema()->define($node->getRole(), Schema::COLUMNS)[$field] ?? $field;
Loading history...
184
    }
185
186
    /**
187
     * Assert that given entity is allowed for the relation.
188
     *
189
     * @param Node $related
190
     *
191
     * @throws RelationException
192
     */
193
    protected function assertValid(Node $related)
194
    {
195
        if ($related->getRole() != $this->target) {
196
            throw new RelationException(sprintf("Unable to link %s, given `%s`", $this, $related->getRole()));
197
        }
198
    }
199
200
    /**
201
     * Resolve the reference to the object.
202
     *
203
     * @param ReferenceInterface $reference
204
     * @return mixed|null
205
     */
206
    protected function resolve(ReferenceInterface $reference)
207
    {
208
        if ($reference instanceof PromiseInterface) {
209
            return $reference->__resolve();
210
        }
211
212
        $scope = $reference->__scope();
213
        return $this->orm->get($reference->__role(), key($scope), current($scope), true);
0 ignored issues
show
Bug introduced by
The method get() 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

213
        return $this->orm->/** @scrutinizer ignore-call */ get($reference->__role(), key($scope), current($scope), true);
Loading history...
214
    }
215
}