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

FieldTrait   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Importance

Changes 6
Bugs 1 Features 0
Metric Value
eloc 46
dl 0
loc 98
rs 10
c 6
b 1
f 0
wmc 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getField() 0 14 2
A ensureField() 0 30 5
A getFields() 0 24 3
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()->get($key);
60
                $fields->set($field->getColumn(), $field);
61
            } catch (FieldException $e) {
62
                throw new RelationException(
63
                    sprintf(
64
                        'Field `%s`.`%s` does not exists, referenced by `%s`',
65
                        $entity->getRole(),
66
                        $key,
67
                        $this->source
68
                    ),
69
                    $e->getCode(),
70
                    $e
71
                );
72
            }
73
        }
74
75
        return $fields;
76
    }
77
78
    /**
79
     * @param Entity $target
80
     * @param string $name
81
     * @param Field $outer
82
     * @param bool $nullable
83
     */
84
    protected function ensureField(Entity $target, string $name, Field $outer, bool $nullable = false): void
85
    {
86
        // ensure that field will be indexed in memory for fast references
87
        $outer->setReferenced(true);
88
89
        if ($target->getFields()->has($name)) {
90
            // field already exists and defined by the user
91
            return;
92
        }
93
94
        $field = new Field();
95
        $field->setColumn($name);
96
        $field->setTypecast($outer->getTypecast());
97
98
        switch ($outer->getType()) {
99
            case 'primary':
100
                $field->setType('int');
101
                break;
102
            case 'bigPrimary':
103
                $field->setType('bigint');
104
                break;
105
            default:
106
                $field->setType($outer->getType());
107
        }
108
109
        if ($nullable) {
110
            $field->getOptions()->set(Column::OPT_NULLABLE, true);
111
        }
112
113
        $target->getFields()->set($name, $field);
114
    }
115
116
    /**
117
     * @return OptionSchema
118
     */
119
    abstract protected function getOptions(): OptionSchema;
120
}
121