Passed
Push — develop ( babbbc...8dad66 )
by Freddie
05:46
created

SchemaAttribute::dataType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
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;
11
12
use FlexPHP\Schema\Constants\Keyword;
13
use FlexPHP\Schema\Constants\Rule;
14
use FlexPHP\Schema\Validations\SchemaAttributeValidation;
15
16
final class SchemaAttribute implements SchemaAttributeInterface
17
{
18
    /**
19
     * @var string
20
     */
21
    private $name;
22
23
    /**
24
     * @var string
25
     */
26
    private $dataType;
27
28
    /**
29
     * @var array<string, mixed>
30
     */
31
    private $constraints = [];
32
33
    /**
34
     * @param mixed $constraints
35
     */
36 54
    public function __construct(string $name, string $dataType, $constraints = null)
37
    {
38 54
        $this->setName($name);
39 54
        $this->setDataType($dataType);
40 54
        $this->setConstraints($constraints);
41
42 54
        $this->validate();
43 51
    }
44
45 54
    public function name(): string
46
    {
47 54
        return $this->name;
48
    }
49
50 54
    public function dataType(): string
51
    {
52 54
        return $this->dataType;
53
    }
54
55 54
    public function constraints(): array
56
    {
57 54
        return $this->constraints;
58
    }
59
60 6
    public function type(): ?string
61
    {
62 6
        return $this->constraints[Rule::TYPE] ?? null;
63
    }
64
65 11
    public function isRequired(): bool
66
    {
67 11
        return (bool)($this->constraints[Rule::REQUIRED] ?? null);
68
    }
69
70 10
    public function minLength(): ?int
71
    {
72 10
        return $this->constraints[Rule::MINLENGTH] ?? null;
73
    }
74
75 10
    public function maxLength(): ?int
76
    {
77 10
        return $this->constraints[Rule::MAXLENGTH] ?? null;
78
    }
79
80 10
    public function minCheck(): ?int
81
    {
82 10
        return $this->constraints[Rule::MINCHECK] ?? null;
83
    }
84
85 10
    public function maxCheck(): ?int
86
    {
87 10
        return $this->constraints[Rule::MAXCHECK] ?? null;
88
    }
89
90 8
    public function min(): ?int
91
    {
92 8
        return $this->constraints[Rule::MIN] ?? null;
93
    }
94
95 8
    public function max(): ?int
96
    {
97 8
        return $this->constraints[Rule::MAX] ?? null;
98
    }
99
100 6
    public function equalTo(): ?string
101
    {
102 6
        return $this->constraints[Rule::EQUALTO] ?? null;
103
    }
104
105 54
    public function properties(): array
106
    {
107
        return [
108 54
            Keyword::NAME => $this->name(),
109 54
            Keyword::DATATYPE => $this->dataType(),
110 54
            Keyword::CONSTRAINTS => $this->constraints(),
111
        ];
112
    }
113
114 54
    private function validate(): void
115
    {
116 54
        (new SchemaAttributeValidation($this->properties()))->validate();
117 51
    }
118
119 54
    private function setName(string $name): void
120
    {
121 54
        $this->name = $name;
122 54
    }
123
124 54
    private function setDataType(string $dataType): void
125
    {
126 54
        $this->dataType = $dataType;
127 54
    }
128
129
    /**
130
     * @param mixed $constraints
131
     */
132 54
    private function setConstraints($constraints): void
133
    {
134 54
        if (!empty($constraints)) {
135 39
            if (\is_string($constraints)) {
136 18
                $this->setConstraintsFromString($constraints);
137
            } else {
138 21
                $this->setConstraintsFromArray($constraints);
139
            }
140
        }
141 54
    }
142
143 18
    private function setConstraintsFromString(string $constraints): void
144
    {
145 18
        $this->setConstraintsFromArray($this->getConstraintsFromString($constraints));
146 18
    }
147
148 39
    private function setConstraintsFromArray(array $constraints): void
149
    {
150 39
        $this->constraints = $this->getConstraintsCast($constraints);
151 39
    }
152
153 18
    private function getConstraintsFromString(string $constraints): array
154
    {
155 18
        $_constraints = \explode('|', $constraints);
156
157
        /** @var mixed $_constraint */
158 18
        foreach ($_constraints as $index => $_constraint) {
159 18
            $_rule = \explode(':', $_constraint);
160
161 18
            if (\count($_rule) === 2) {
162 17
                [$_name, $_options] = $_rule;
163
164 17
                if (\strpos($_options, ',') !== false) { // Range
165 2
                    [$min, $max] = \explode(',', $_options);
166 2
                    $_options = \compact('min', 'max');
167 15
                } elseif (\preg_match('/^false$/i', $_options)) { // False as string
168 4
                    $_options = false;
169 14
                } elseif (\preg_match('/^true$/i', $_options)) { // True as string
170 5
                    $_options = true;
171
                }
172
173 17
                $_constraints[$_name] = $_options;
174
            } else {
175 5
                $_constraints[$_rule[0]] = true;
176
            }
177
178 18
            unset($_constraints[$index]);
179
        }
180
181 18
        return $_constraints;
182
    }
183
184 39
    private function getConstraintsCast(array $constraints): array
185
    {
186 39
        foreach ($constraints as $name => $value) {
187 39
            if (\is_int($name)) {
188 3
                $constraints[$value] = true;
189 3
                unset($constraints[$name]);
190 38
            } elseif ($name === 'check' || $name === 'length') {
191 4
                $constraints['min' . $name] = (int)$value['min'];
192 4
                $constraints['max' . $name] = (int)$value['max'];
193 4
                unset($constraints[$name]);
194
            } else {
195 39
                $constraints[$name] = \is_numeric($value) ? (int)$value : $value;
196
            }
197
        }
198
199 39
        return $constraints;
200
    }
201
}
202