Passed
Push — master ( 42cf54...db577f )
by Anton
01:58
created

MorphTrait::findOuterKey()   B

Complexity

Conditions 8
Paths 10

Size

Total Lines 34
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 19
nc 10
nop 2
dl 0
loc 34
rs 8.4444
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
9
namespace Cycle\Schema\Relation\Traits;
10
11
use Cycle\Schema\Definition\Entity;
12
use Cycle\Schema\Definition\Field;
13
use Cycle\Schema\Exception\RelationException;
14
use Cycle\Schema\Registry;
15
use Cycle\Schema\Table\ColumnSchema;
16
17
trait MorphTrait
18
{
19
    /**
20
     * @param Registry $registry
21
     * @param string   $interface
22
     * @return array Tuple [name, Field]
23
     *
24
     * @throws RelationException
25
     */
26
    protected function findOuterKey(Registry $registry, string $interface): array
27
    {
28
        /** @var Field|null $field */
29
        $key = null;
30
        $field = null;
31
32
        foreach ($registry as $entity) {
33
            $class = $entity->getClass();
34
            if ($class === null || !in_array($interface, class_implements($class))) {
35
                continue;
36
            }
37
38
            $primaryKey = $this->getPrimary($entity);
0 ignored issues
show
Bug introduced by
It seems like getPrimary() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

38
            /** @scrutinizer ignore-call */ 
39
            $primaryKey = $this->getPrimary($entity);
Loading history...
39
            $primaryField = $entity->getFields()->get($primaryKey);
40
41
            if (is_null($field)) {
42
                $key = $primaryKey;
43
                $field = $primaryField;
44
            } else {
45
                if ($key != $primaryKey) {
46
                    throw new RelationException("Inconsistent primary key reference (name)");
47
                }
48
49
                if ($field->getType() != $primaryField->getType()) {
50
                    throw new RelationException("Inconsistent primary key reference (type)");
51
                }
52
            }
53
        }
54
55
        if (is_null($field)) {
56
            throw new RelationException("Unable to find morphed parent");
57
        }
58
59
        return [$key, $field];
60
    }
61
62
    /**
63
     * @param Entity $target
64
     * @param string $name
65
     * @param int    $lenght
66
     * @param bool   $nullable
67
     */
68
    protected function ensureMorphField(Entity $target, string $name, int $lenght, bool $nullable = false)
69
    {
70
        if ($target->getFields()->has($name)) {
71
            // field already exists and defined by the user
72
            return;
73
        }
74
75
        $field = new Field();
76
        $field->setColumn($name);
77
        $field->setType(sprintf("string(%s)", $lenght));
78
79
        if ($nullable) {
80
            $field->getOptions()->set(ColumnSchema::OPT_NULLABLE, true);
81
        }
82
83
        $target->getFields()->set($name, $field);
84
    }
85
}