Passed
Branch feature-validator (55f4e3)
by Thomas
03:27
created

Column::validate()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 11
cts 11
cp 1
rs 8.6737
c 0
b 0
f 0
cc 6
eloc 11
nc 5
nop 1
crap 6
1
<?php
2
3
namespace ORM\Dbal;
4
5
use ORM\Dbal\Error\NotValid;
6
7
/**
8
 * Describes a column of a database table
9
 *
10
 * @package ORM\Dbal
11
 * @author  Thomas Flori <[email protected]>
12
 *
13
 * @property string name
14
 * @property Type type
15
 * @property mixed default
16
 * @property bool nullable
17
 */
18
class Column
19
{
20
    /** @var string[] */
21
    protected static $registeredTypes = [];
22
23
    /**
24
     * Register $type for describe
25
     *
26
     * @param string $type The full qualified class name
27
     */
28 7
    public static function registerType($type)
29
    {
30 7
        if (!in_array($type, static::$registeredTypes)) {
31 7
            array_unshift(static::$registeredTypes, $type);
32
        }
33 7
    }
34
35
    /**
36
     * Get the registered type for $columnDefinition
37
     *
38
     * @param array $columnDefinition
39
     * @return string
40
     */
41 7
    protected static function getRegisteredType(array $columnDefinition)
42
    {
43 7
        foreach (self::$registeredTypes as $class) {
44 4
            if (call_user_func([$class, 'fits'], $columnDefinition)) {
45 4
                return $class;
46
            }
47
        }
48
49 6
        return null;
50
    }
51
52
    /** @var array */
53
    protected $columnDefinition;
54
55
    /** @var Dbal */
56
    protected $dbal;
57
58
    /** @var TypeInterface */
59
    protected $type;
60
61
    /** @var bool */
62
    protected $hasDefault;
63
64
    /** @var bool */
65
    protected $isNullable;
66
67
    /**
68
     * Column constructor.
69
     *
70
     * @param Dbal  $dbal
71
     * @param array $columnDefinition
72
     */
73 133
    public function __construct(Dbal $dbal, array $columnDefinition)
74
    {
75 133
        $this->dbal = $dbal;
76 133
        $this->columnDefinition = $columnDefinition;
77 133
    }
78
79 6
    public function validate($value)
80
    {
81 6
        if ($value === null) {
82 3
            if ($this->nullable || $this->hasDefault()) {
83 2
                return true;
84
            }
85
86 1
            return new Error\NotNullable($this);
87
        }
88
89 3
        $valid = $this->getType()->validate($value);
90
91 3
        if ($valid === false) {
92 1
            return new NotValid($this, new Error());
93
        }
94
95 2
        if ($valid instanceof Error) {
96 1
            return new NotValid($this, $valid);
97
        }
98
99 1
        return true;
100
    }
101
102 115
    public function __get($name)
103
    {
104
        switch ($name) {
105 115
            case 'name':
106 109
                return $this->columnDefinition['column_name'];
107 50
            case 'type':
108 28
                return $this->getType();
109 22
            case 'default':
110 13
                return $this->columnDefinition['column_default'];
111 11
            case 'nullable':
112 10
                return $this->columnDefinition['is_nullable'] === true ||
113 10
                       $this->columnDefinition['is_nullable'] === 'YES';
114
            default:
115 1
                return isset($this->columnDefinition[$name]) ? $this->columnDefinition[$name] : null;
116
        }
117
    }
118
119 12
    public function hasDefault()
120
    {
121 12
        return $this->default !== null;
122
    }
123
124
    /**
125
     * @return Type
126
     */
127 102
    public function getType()
128
    {
129 102
        if (!$this->type) {
130 102
            if (!isset($this->columnDefinition['type'])) {
131 7
                $class = self::getRegisteredType($this->columnDefinition);
132
            } else {
133 95
                $class = $this->columnDefinition['type'];
134
            }
135
136 102
            if ($class === null || !is_callable([$class, 'factory'])) {
137 6
                $class = Type\Text::class;
138
            }
139
140 102
            $this->type = call_user_func([$class, 'factory'], $this->dbal, $this->columnDefinition);
141
        }
142
143 102
        return $this->type;
144
    }
145
}
146