Passed
Pull Request — master (#26)
by butschster
03:01
created

FieldTrait::getFields()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 15
nc 3
nop 2
dl 0
loc 23
rs 9.7666
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\ORM\Relation;
15
use Cycle\Schema\Definition\Entity;
16
use Cycle\Schema\Definition\Field;
17
use Cycle\Schema\Exception\FieldException;
18
use Cycle\Schema\Exception\RelationException;
19
use Cycle\Schema\Relation\OptionSchema;
20
use Cycle\Schema\Table\Column;
21
22
trait FieldTrait
23
{
24
    /**
25
     * @param Entity $entity
26
     * @param int $field
27
     * @return Field
28
     */
29
    protected function getField(Entity $entity, int $field): Field
30
    {
31
        try {
32
            return $entity->getFields()->get($this->getOptions()->get($field));
0 ignored issues
show
Bug introduced by
It seems like $this->getOptions()->get($field) can also be of type array; however, parameter $name of Cycle\Schema\Definition\Map\FieldMap::get() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

32
            return $entity->getFields()->get(/** @scrutinizer ignore-type */ $this->getOptions()->get($field));
Loading history...
33
        } catch (FieldException $e) {
34
            throw new RelationException(
35
                sprintf(
36
                    'Field `%s`.`%s` does not exists, referenced by `%s`',
37
                    $entity->getRole(),
38
                    $this->getOptions()->get($field),
0 ignored issues
show
Bug introduced by
It seems like $this->getOptions()->get($field) can also be of type array; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check? ( Ignorable by Annotation )

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

38
                    /** @scrutinizer ignore-type */ $this->getOptions()->get($field),
Loading history...
39
                    $this->source
40
                ),
41
                $e->getCode(),
42
                $e
43
            );
44
        }
45
    }
46
47
    /**
48
     * @param Entity $entity
49
     * @param int $field
50
     * @return array<Field>
51
     */
52
    protected function getFields(Entity $entity, int $field): array
53
    {
54
        $fields = [];
55
        $keys = (array)$this->getOptions()->get($field);
56
57
        foreach ($keys as $key) {
58
            try {
59
                $fields[] = $entity->getFields()->get($key);
60
            } catch (FieldException $e) {
61
                throw new RelationException(
62
                    sprintf(
63
                        'Field `%s`.`%s` does not exists, referenced by `%s`',
64
                        $entity->getRole(),
65
                        $key,
66
                        $this->source
67
                    ),
68
                    $e->getCode(),
69
                    $e
70
                );
71
            }
72
        }
73
74
        return $fields;
75
    }
76
77
    /**
78
     * @param Entity $target
79
     * @param string $name
80
     * @param Field $outer
81
     * @param bool $nullable
82
     */
83
    protected function ensureField(Entity $target, string $name, Field $outer, bool $nullable = false): void
84
    {
85
        // ensure that field will be indexed in memory for fast references
86
        $outer->setReferenced(true);
87
88
        if ($target->getFields()->has($name)) {
89
            // field already exists and defined by the user
90
            return;
91
        }
92
93
        $field = new Field();
94
        $field->setColumn($name);
95
        $field->setTypecast($outer->getTypecast());
96
97
        switch ($outer->getType()) {
98
            case 'primary':
99
                $field->setType('int');
100
                break;
101
            case 'bigPrimary':
102
                $field->setType('bigint');
103
                break;
104
            default:
105
                $field->setType($outer->getType());
106
        }
107
108
        if ($nullable) {
109
            $field->getOptions()->set(Column::OPT_NULLABLE, true);
110
        }
111
112
        $target->getFields()->set($name, $field);
113
    }
114
115
    /**
116
     * @return OptionSchema
117
     */
118
    abstract protected function getOptions(): OptionSchema;
119
}
120