Passed
Pull Request — master (#26)
by Aleksei
02:07
created

MorphTrait::mergeIndex()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 3
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Cycle ORM Schema Builder.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Cycle\Schema\Relation\Traits;
13
14
use Cycle\Schema\Definition\Entity;
15
use Cycle\Schema\Definition\Field;
16
use Cycle\Schema\Definition\Map\FieldMap;
17
use Cycle\Schema\Exception\RelationException;
18
use Cycle\Schema\Registry;
19
use Cycle\Schema\Table\Column;
20
use Generator;
21
22
trait MorphTrait
23
{
24
    /**
25
     * @psalm-param class-string $interface
26
     *
27
     * @return Entity[]|Generator
28
     * @psalm-return Generator<int, Entity, mixed, null>
29
     */
30
    protected function findTargets(Registry $registry, string $interface): Generator
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
            yield $entity;
39
        }
40
    }
41
42
    /**
43
     * @return array Tuple [name, Field]
44
     *
45
     * @throws RelationException
46
     */
47
    protected function findOuterKey(Registry $registry, string $interface): array
48
    {
49
        $keys = null;
50
        $fields = null;
51
        $prevEntity = null;
52
53
        foreach ($this->findTargets($registry, $interface) as $entity) {
54
            $primaryFields = $entity->getPrimaryFields();
55
            $primaryKeys = $primaryFields->getColumnNames();
56
57
            if (is_null($keys)) {
58
                $keys = $primaryKeys;
59
                $fields = $primaryFields;
60
                $prevEntity = $entity;
61
            } elseif ($keys !== $primaryKeys) {
62
                throw new RelationException(sprintf(
63
                    "Inconsistent primary key reference (%s). PKs: (%s). Required PKs [%s]: (%s).",
64
                    $entity->getRole(),
65
                    implode(',', $primaryKeys),
66
                    $prevEntity->getRole(),
0 ignored issues
show
Bug introduced by
The method getRole() does not exist on null. ( Ignorable by Annotation )

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

66
                    $prevEntity->/** @scrutinizer ignore-call */ 
67
                                 getRole(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
67
                    implode(',', $keys)
68
                ));
69
            }
70
        }
71
72
        if (is_null($fields)) {
73
            throw new RelationException('Unable to find morphed parent.');
74
        }
75
76
        return [$keys, $fields];
77
    }
78
79
    protected function ensureMorphField(Entity $target, string $name, int $length, bool $nullable = false): void
80
    {
81
        if ($target->getFields()->has($name)) {
82
            // field already exists and defined by the user
83
            return;
84
        }
85
86
        $field = new Field();
87
        $field->setColumn($name);
88
        $field->setType(sprintf('string(%s)', $length));
89
90
        if ($nullable) {
91
            $field->getOptions()->set(Column::OPT_NULLABLE, true);
92
        }
93
94
        $target->getFields()->set($name, $field);
95
    }
96
97
    protected function mergeIndex(Registry $registry, Entity $source, FieldMap ...$mergeMaps): void
98
    {
99
        $table = $registry->getTableSchema($source);
100
101
        if ($this->options->get(self::INDEX_CREATE)) {
0 ignored issues
show
Bug introduced by
The constant Cycle\Schema\Relation\Tr...orphTrait::INDEX_CREATE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
102
            $index = array_merge(array_map(
103
                static function (FieldMap $map): array {
104
                    return $map->getColumnNames();
105
                },
106
                $mergeMaps
107
            ));
108
            if (count($index) > 0) {
109
                $table->index($index);
110
            }
111
        }
112
    }
113
}
114