Test Failed
Push — develop ( b59003...d7f8a0 )
by Freddie
05:27 queued 10s
created

SchemaAttributeLogicValidation::hasFormat()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of FlexPHP.
4
 *
5
 * (c) Freddie Gar <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace FlexPHP\Schema\Validations;
11
12
use FlexPHP\Schema\Constants\Format;
13
use FlexPHP\Schema\Exception\InvalidSchemaAttributeException;
14
use FlexPHP\Schema\SchemaAttributeInterface;
15
16
class SchemaAttributeLogicValidation implements ValidationInterface
17
{
18
    /**
19
     * @var SchemaAttributeInterface
20
     */
21
    private $property;
22 134
23
    public function __construct(SchemaAttributeInterface $property)
24 134
    {
25 134
        $this->property = $property;
26
    }
27 134
28
    public function validate(): void
29 134
    {
30 21
        if (empty($this->property->constraints())) {
31
            return;
32
        }
33 115
34
        $name = 'Logic: [' . $this->property->name() . '] ';
35 115
36 20
        if ($this->property->isPk()) {
37 3
            if (!$this->property->isRequired()) {
38
                throw new InvalidSchemaAttributeException($name . 'Primary Key must be required.');
39
            }
40 17
41 2
            if ($this->property->isFk()) {
42
                throw new InvalidSchemaAttributeException($name . 'Primary Key cannot be Foreing Key too.');
43
            }
44 15
45 1
            if ($this->isInt() && !$this->property->isAi()) {
46
                throw new InvalidSchemaAttributeException($name . 'Primary Key numeric not autoincrement.');
47
            }
48 14
49 1
            if ($this->property->isAi() && $this->hasSizingConstraint()) {
50
                throw new InvalidSchemaAttributeException($name . 'Primary Key autoincrement cannot has sizing.');
51
            }
52
        }
53 108
54 10
        if ($this->property->isAi()) {
55 1
            if (!$this->property->isPk()) {
56
                throw new InvalidSchemaAttributeException($name . 'Autoincrement must be Primary Key too.');
57
            }
58 9
59 1
            if (!$this->isInt()) {
60
                throw new InvalidSchemaAttributeException($name . 'Autoincrement must be numeric.');
61
            }
62
        }
63 106
64 2
        if ($this->property->isBlameAt() && !$this->isDate()) {
65
            throw new InvalidSchemaAttributeException($name . 'Blame At property must be date datatype.');
66
        }
67 104
68 1
        if ($this->property->isCa() && $this->property->isUa()) {
69
            throw new InvalidSchemaAttributeException($name . 'Created and Updated At in same property is not valid.');
70
        }
71 103
72 4
        if ($this->property->isBlameBy() && !$this->isInt()) {
73
            throw new InvalidSchemaAttributeException($name . 'Blame By property must be integer datatype.');
74
        }
75 99
76 1
        if ($this->property->isCb() && $this->property->isUb()) {
77
            throw new InvalidSchemaAttributeException($name . 'Created and Updated By in same property is not valid.');
78
        }
79 98
80 10
        if ($this->isNumeric() && $this->hasLength()) {
81
            throw new InvalidSchemaAttributeException($name . 'Numeric properties use: min, max.');
82
        }
83 88
84 4
        if ($this->isString() && $this->hasSize()) {
85
            throw new InvalidSchemaAttributeException($name . 'String properties use: minlength, maxlength.');
86
        }
87 84
88 4
        if (($this->isDate() || $this->isBinary()) && $this->hasSizingConstraint()) {
89
            throw new InvalidSchemaAttributeException($name . 'Date, bool, blob properties not use min, max, etc');
90 80
        }
91
92 28
        if ($this->hasFormat()) {
93
            if ($this->isString()) {
94 28
                throw new InvalidSchemaAttributeException(\sprintf(
95
                    '%sString properties not allow format',
96
                    $name
97 87
                ));
98
            }
99 87
100
            if ($this->isBinary()) {
101
                throw new InvalidSchemaAttributeException(\sprintf(
102 98
                    '%sBinary (bool, blob) properties not allow format',
103
                    $name
104 98
                ));
105
            }
106
107 88
            if ($this->isArray()) {
108
                throw new InvalidSchemaAttributeException(\sprintf(
109 88
                    '%sArray (array, simple_array, json) properties not allow format',
110
                    $name
111
                ));
112 68
            }
113
114 68
            if ($this->isNumeric() && !$this->property->isFormat(Format::MONEY)) {
115
                throw new InvalidSchemaAttributeException(\sprintf(
116
                    '%sNumeric properties not allow format: %s',
117 70
                    $name,
118
                    $this->property->format()
119 70
                ));
120
            }
121
122 58
            if ($this->isDate() && $this->property->isFormat(Format::MONEY)) {
123
                throw new InvalidSchemaAttributeException(\sprintf(
124 58
                    '%sDate property not allow format: %s',
125
                    $name,
126
                    $this->property->format()
127 24
                ));
128
            }
129 24
        }
130
131
        if ($this->property->fchars() > 0 && !$this->property->isFk()) {
132 27
            throw new InvalidSchemaAttributeException(\sprintf(
133
                '%sOnly property with Foreing Key allow fchars option',
134 27
                $name,
135
            ));
136
        }
137
    }
138
139
    private function isInt(): bool
140
    {
141
        return \in_array($this->property->dataType(), ['smallint', 'integer', 'bigint']);
142
    }
143
144
    private function isDate(): bool
145
    {
146
        return \strpos($this->property->typeHint(), '\Date') !== false;
147
    }
148
149
    private function isArray(): bool
150
    {
151
        return \in_array($this->property->dataType(), ['array', 'simple_array', 'json']);
152
    }
153
154
    private function isNumeric(): bool
155
    {
156
        return \in_array($this->property->dataType(), ['smallint', 'integer', 'bigint', 'double', 'float']);
157
    }
158
159
    private function isString(): bool
160
    {
161
        return $this->property->dataType() !== 'bigint' && $this->property->typeHint() === 'string';
162
    }
163
164
    private function isBinary(): bool
165
    {
166
        return \in_array($this->property->dataType(), ['bool', 'boolean', 'blob']);
167
    }
168
169
    private function hasLength(): bool
170
    {
171
        return $this->property->minLength() !== null || $this->property->maxLength() !== null;
172
    }
173
174
    private function hasSize(): bool
175
    {
176
        return $this->property->min() !== null || $this->property->max() !== null;
177
    }
178
179
    private function hasCheck(): bool
180
    {
181
        return $this->property->minCheck() !== null || $this->property->maxCheck() !== null;
182
    }
183
184
    private function hasSizingConstraint(): bool
185
    {
186
        return $this->hasSize() || $this->hasLength() || $this->hasCheck();
187
    }
188
189
    private function hasFormat(): bool
190
    {
191
        return (bool)$this->property->format();
192
    }
193
}
194