Passed
Push — master ( 1791d6...48fae4 )
by Anton
01:59
created

src/Relation/Traits/MorphTrait.php (1 issue)

Labels
Severity
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\Column;
16
17
trait MorphTrait
18
{
19
    /**
20
     * @param Registry $registry
21
     * @param string   $interface
22
     * @return \Generator
23
     */
24
    protected function findTargets(Registry $registry, string $interface): \Generator
25
    {
26
        foreach ($registry as $entity) {
27
            $class = $entity->getClass();
28
            if ($class === null || !in_array($interface, class_implements($class))) {
29
                continue;
30
            }
31
32
            yield $entity;
33
        }
34
    }
35
36
    /**
37
     * @param Registry $registry
38
     * @param string   $interface
39
     * @return array Tuple [name, Field]
40
     *
41
     * @throws RelationException
42
     */
43
    protected function findOuterKey(Registry $registry, string $interface): array
44
    {
45
        /** @var Field|null $field */
46
        $key = null;
47
        $field = null;
48
49
        foreach ($this->findTargets($registry, $interface) as $entity) {
50
            $primaryKey = $this->getPrimary($entity);
0 ignored issues
show
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

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