Passed
Pull Request — master (#26)
by butschster
02:08
created

FieldTrait::getFields()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 17
nc 5
nop 2
dl 0
loc 26
rs 9.7
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\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 FieldMap
51
     */
52
    protected function getFields(Entity $entity, int $field): FieldMap
53
    {
54
        $fields = new FieldMap();
55
        $keys = (array)$this->getOptions()->get($field);
56
57
        foreach ($keys as $key) {
58
            try {
59
                $field = $entity->getFields()->getByColumnName($key);
60
                $name = $entity->getFields()->getKeyByColumnName($key);
61
62
                $fields->set($name, $field);
63
            } catch (FieldException $e) {
64
                throw new RelationException(
65
                    sprintf(
66
                        'Field `%s`.`%s` does not exists, referenced by `%s`',
67
                        $entity->getRole(),
68
                        $key,
69
                        $this->source
70
                    ),
71
                    $e->getCode(),
72
                    $e
73
                );
74
            }
75
        }
76
77
        return $fields;
78
    }
79
80
    /**
81
     * @param Entity $target
82
     * @param string $name
83
     * @param Field $outer
84
     * @param bool $nullable
85
     */
86
    protected function ensureField(Entity $target, string $name, Field $outer, bool $nullable = false): void
87
    {
88
        // ensure that field will be indexed in memory for fast references
89
        $outer->setReferenced(true);
90
91
        if ($target->getFields()->hasColumn($name)) {
92
            // field already exists and defined by the user
93
            return;
94
        }
95
96
        $field = new Field();
97
        $field->setColumn($name);
98
        $field->setTypecast($outer->getTypecast());
99
100
        switch ($outer->getType()) {
101
            case 'primary':
102
                $field->setType('int');
103
                break;
104
            case 'bigPrimary':
105
                $field->setType('bigint');
106
                break;
107
            default:
108
                $field->setType($outer->getType());
109
        }
110
111
        if ($nullable) {
112
            $field->getOptions()->set(Column::OPT_NULLABLE, true);
113
        }
114
115
        $target->getFields()->set($name, $field);
116
    }
117
118
    /**
119
     * @return OptionSchema
120
     */
121
    abstract protected function getOptions(): OptionSchema;
122
}
123