1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* tubee.io |
7
|
|
|
* |
8
|
|
|
* @copyright Copryright (c) 2017-2019 gyselroth GmbH (https://gyselroth.com) |
9
|
|
|
* @license GPL-3.0 https://opensource.org/licenses/GPL-3.0 |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Tubee\AttributeMap; |
13
|
|
|
|
14
|
|
|
use InvalidArgumentException; |
15
|
|
|
|
16
|
|
|
class Validator |
17
|
|
|
{ |
18
|
|
|
/** |
19
|
|
|
* Validate resource. |
20
|
|
|
*/ |
21
|
7 |
View Code Duplication |
public static function validate(array $resource): array |
|
|
|
|
22
|
|
|
{ |
23
|
7 |
|
foreach ($resource as $attribute => $definition) { |
24
|
7 |
|
if (!is_array($definition)) { |
25
|
1 |
|
throw new InvalidArgumentException('map attribute '.$attribute.' definition must be an array'); |
26
|
|
|
} |
27
|
|
|
|
28
|
6 |
|
$resource[$attribute] = self::validateAttribute($definition); |
29
|
|
|
} |
30
|
|
|
|
31
|
1 |
|
return $resource; |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Validate attribute. |
36
|
|
|
*/ |
37
|
6 |
|
protected static function validateAttribute(array $schema): array |
38
|
|
|
{ |
39
|
|
|
$defaults = [ |
40
|
6 |
|
'ensure' => AttributeMapInterface::ENSURE_LAST, |
41
|
|
|
'value' => null, |
42
|
|
|
'type' => null, |
43
|
|
|
'name' => null, |
44
|
|
|
'from' => null, |
45
|
|
|
'script' => null, |
46
|
|
|
'unwind' => null, |
47
|
|
|
'rewrite' => [], |
48
|
|
|
'require_regex' => null, |
49
|
|
|
'required' => false, |
50
|
|
|
'map' => null, |
51
|
|
|
]; |
52
|
|
|
|
53
|
6 |
|
if (!isset($schema['name'])) { |
54
|
1 |
|
throw new InvalidArgumentException('attribute name is required'); |
55
|
|
|
} |
56
|
|
|
|
57
|
5 |
|
$name = $schema['name']; |
58
|
|
|
|
59
|
5 |
|
foreach ($schema as $option => &$definition) { |
60
|
5 |
|
if (is_null($definition)) { |
61
|
1 |
|
continue; |
62
|
|
|
} |
63
|
|
|
|
64
|
5 |
|
switch ($option) { |
65
|
5 |
|
case 'ensure': |
66
|
1 |
|
if (!in_array($definition, AttributeMapInterface::VALID_ENSURES)) { |
67
|
1 |
|
throw new InvalidArgumentException('map.ensure as string must be provided (one of exists,last,merge,absent)'); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
break; |
71
|
5 |
|
case 'type': |
72
|
2 |
|
if (!in_array($definition, AttributeMapInterface::VALID_TYPES)) { |
73
|
1 |
|
throw new InvalidArgumentException('map attribute '.$name.' has an invalid attribute type '.$definition.', only '.implode(',', AttributeMapInterface::VALID_TYPES).' are supported'); |
74
|
|
|
} |
75
|
|
|
|
76
|
1 |
|
break; |
77
|
5 |
|
case 'unwind': |
78
|
|
|
break; |
79
|
5 |
|
case 'rewrite': |
80
|
|
|
if (!is_array($definition)) { |
81
|
|
|
throw new InvalidArgumentException('attribute '.$option.' must be an array'); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
$definition = self::validateRewriteRules($definition); |
85
|
|
|
|
86
|
|
|
break; |
87
|
5 |
|
case 'value': |
88
|
|
|
break; |
89
|
5 |
|
case 'name': |
90
|
3 |
|
case 'from': |
91
|
3 |
|
case 'script': |
92
|
3 |
View Code Duplication |
case 'require_regex': |
|
|
|
|
93
|
5 |
|
if (!is_string($definition)) { |
94
|
|
|
throw new InvalidArgumentException('map attribute '.$name.' has an invalid option '.$option.', value must be of type string'); |
95
|
|
|
} |
96
|
|
|
|
97
|
5 |
|
break; |
98
|
3 |
View Code Duplication |
case 'required': |
|
|
|
|
99
|
1 |
|
if (!is_bool($definition)) { |
100
|
|
|
throw new InvalidArgumentException('map attribute '.$name.' has an invalid option '.$option.', value must be of type boolean'); |
101
|
|
|
} |
102
|
|
|
|
103
|
1 |
|
break; |
104
|
2 |
|
case 'map': |
105
|
|
|
/*if (!is_array($definition['map'])) { |
106
|
|
|
throw new InvalidArgumentException('map attribute '.$name.' has an invalid option '.$option.', value must be of type array'); |
107
|
|
|
}*/ |
108
|
|
|
|
109
|
|
|
if (!isset($definition['collection'])) { |
110
|
|
|
throw new InvalidArgumentException('mapping for attribute '.$name.' requires map.collection'); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
if (!isset($definition['to'])) { |
114
|
|
|
throw new InvalidArgumentException('mapping for attribute '.$name.' requires map.to'); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
break; |
118
|
|
|
default: |
119
|
5 |
|
throw new InvalidArgumentException('map attribute '.$name.' has an invalid option '.$option); |
120
|
|
|
} |
121
|
|
|
} |
122
|
|
|
|
123
|
1 |
|
return array_replace_recursive($defaults, $schema); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Validate rewrite rules. |
128
|
|
|
*/ |
129
|
|
|
protected static function validateRewriteRules(array $rules): array |
130
|
|
|
{ |
131
|
|
|
$defaults = [ |
132
|
|
|
'from' => null, |
133
|
|
|
'to' => null, |
134
|
|
|
'match' => null, |
135
|
|
|
]; |
136
|
|
|
|
137
|
|
|
foreach ($rules as &$rule) { |
138
|
|
|
$rule = array_merge($defaults, $rule); |
139
|
|
|
|
140
|
|
|
foreach ($rule as $key => $value) { |
141
|
|
|
if (is_null($value)) { |
142
|
|
|
continue; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
switch ($key) { |
146
|
|
|
case 'from': |
147
|
|
|
case 'to': |
148
|
|
|
case 'match': |
149
|
|
|
if (!is_string($value)) { |
150
|
|
|
throw new InvalidArgumentException('rewrite option '.$key.' must be a string'); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
break; |
154
|
|
|
default: |
155
|
|
|
throw new InvalidArgumentException('Invalid option rewrite.'.$key.' provided'); |
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
return $rules; |
161
|
|
|
} |
162
|
|
|
} |
163
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.