1 | <?php |
||
14 | class Validation |
||
15 | { |
||
16 | /** |
||
17 | * Validators. |
||
18 | * |
||
19 | * @var array |
||
20 | */ |
||
21 | protected $validators = []; |
||
22 | |||
23 | /** |
||
24 | * Options. |
||
25 | * |
||
26 | * @var array |
||
27 | */ |
||
28 | protected $options = []; |
||
29 | |||
30 | /** |
||
31 | * The translator to use for the exception message. |
||
32 | * |
||
33 | * @var array |
||
34 | */ |
||
35 | protected $translator = null; |
||
36 | |||
37 | /** |
||
38 | * Errors from the validation. |
||
39 | * |
||
40 | * @var array |
||
41 | */ |
||
42 | protected $errors = []; |
||
43 | |||
44 | /** |
||
45 | * The 'errors' attribute name. |
||
46 | * |
||
47 | * @var string |
||
48 | */ |
||
49 | protected $errors_name = 'errors'; |
||
50 | |||
51 | /** |
||
52 | * The 'has_error' attribute name. |
||
53 | * |
||
54 | * @var string |
||
55 | */ |
||
56 | protected $has_errors_name = 'has_errors'; |
||
57 | |||
58 | /** |
||
59 | * The 'validators' attribute name. |
||
60 | * |
||
61 | * @var string |
||
62 | */ |
||
63 | protected $validators_name = 'validators'; |
||
64 | |||
65 | /** |
||
66 | * The 'translator' attribute name. |
||
67 | * |
||
68 | * @var string |
||
69 | */ |
||
70 | protected $translator_name = 'translator'; |
||
71 | |||
72 | /** |
||
73 | * Create new Validator service provider. |
||
74 | * |
||
75 | * @param null|array|ArrayAccess $validators |
||
76 | * @param null|array $translator |
||
77 | * @param []|array $options |
||
|
|||
78 | */ |
||
79 | 2 | public function __construct($validators = null, $translator = null, $options = []) |
|
80 | { |
||
81 | // Set the validators |
||
82 | 2 | if (is_array($validators) || $validators instanceof \ArrayAccess) { |
|
83 | 2 | $this->validators = $validators; |
|
84 | } elseif (is_null($validators)) { |
||
85 | $this->validators = []; |
||
86 | } |
||
87 | 2 | $this->translator = $translator; |
|
88 | 2 | $this->options = array_merge($this->options, $options); |
|
89 | 2 | } |
|
90 | |||
91 | /** |
||
92 | * Validation middleware invokable class. |
||
93 | * |
||
94 | * @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request |
||
95 | * @param \Psr\Http\Server\RequestHandlerInterface $response PSR7 response |
||
96 | * |
||
97 | * @return \Psr\Http\Message\ResponseInterface |
||
98 | */ |
||
99 | 2 | public function __invoke(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface |
|
100 | { |
||
101 | 2 | $this->errors = []; |
|
102 | 2 | $params = $request->getParsedBody(); |
|
103 | |||
104 | 2 | $routeContext = RouteContext::fromRequest($request); |
|
105 | 2 | $route = $routeContext->getRoute(); |
|
106 | 2 | $arguments = $route->getArguments(); |
|
107 | |||
108 | 2 | $queryParams = $request->getQueryParams(); |
|
109 | |||
110 | 2 | $params = array_merge((array) $arguments, (array) $params, (array) $queryParams); |
|
111 | |||
112 | 2 | $this->validate($params, $this->validators); |
|
113 | |||
114 | 2 | $request = $request->withAttribute($this->errors_name, $this->getErrors()); |
|
115 | 2 | $request = $request->withAttribute($this->has_errors_name, $this->hasErrors()); |
|
116 | 2 | $request = $request->withAttribute($this->validators_name, $this->getValidators()); |
|
117 | 2 | $request = $request->withAttribute($this->translator_name, $this->getTranslator()); |
|
118 | |||
119 | 2 | return $handler->handle($request); |
|
120 | } |
||
121 | |||
122 | /** |
||
123 | * Validate the parameters by the given params, validators and actual keys. |
||
124 | * This method populates the $errors attribute. |
||
125 | * |
||
126 | * @param array $params The array of parameters. |
||
127 | * @param array $validators The array of validators. |
||
128 | * @param array $actualKeys An array that will save all the keys of the tree to retrieve the correct value. |
||
129 | */ |
||
130 | 2 | private function validate($params = [], $validators = [], $actualKeys = []) |
|
131 | { |
||
132 | //Validate every parameters in the validators array |
||
133 | 2 | foreach ($validators as $key => $validator) { |
|
134 | 2 | $actualKeys[] = $key; |
|
135 | 2 | $param = $this->getNestedParam($params, $actualKeys); |
|
136 | 2 | if (is_array($validator)) { |
|
137 | $this->validate($params, $validator, $actualKeys); |
||
138 | } else { |
||
139 | try { |
||
140 | 2 | $validator->assert($param); |
|
141 | 2 | } catch (NestedValidationException $exception) { |
|
142 | 2 | if ($this->translator) { |
|
143 | 1 | $this->translator = $exception->getMessages($this->translator); |
|
144 | } |
||
145 | 2 | $this->errors[implode('.', $actualKeys)] = $exception->getMessages(); |
|
146 | } |
||
147 | } |
||
148 | |||
149 | //Remove the key added in this foreach |
||
150 | 2 | array_pop($actualKeys); |
|
151 | } |
||
152 | 2 | } |
|
153 | |||
154 | /** |
||
155 | * Get the nested parameter value. |
||
156 | * |
||
157 | * @param array $params An array that represents the values of the parameters. |
||
158 | * @param array $keys An array that represents the tree of keys to use. |
||
159 | * |
||
160 | * @return mixed The nested parameter value by the given params and tree of keys. |
||
161 | */ |
||
162 | 2 | private function getNestedParam($params = [], $keys = []) |
|
163 | { |
||
164 | 2 | if (empty($keys)) { |
|
165 | 2 | return $params; |
|
166 | } else { |
||
167 | 2 | $firstKey = array_shift($keys); |
|
168 | 2 | if ($this->isArrayLike($params) && array_key_exists($firstKey, $params)) { |
|
169 | 2 | $params = (array) $params; |
|
170 | 2 | $paramValue = $params[$firstKey]; |
|
171 | |||
172 | 2 | return $this->getNestedParam($paramValue, $keys); |
|
173 | } else { |
||
174 | return; |
||
175 | } |
||
176 | } |
||
177 | } |
||
178 | |||
179 | /** |
||
180 | * Check if the given $params is an array like variable. |
||
181 | * |
||
182 | * @param array $params The variable to check. |
||
183 | * |
||
184 | * @return bool Returns true if the given $params parameter is array like. |
||
185 | */ |
||
186 | 2 | private function isArrayLike($params) |
|
190 | |||
191 | /** |
||
192 | * Check if there are any errors. |
||
193 | * |
||
194 | * @return bool |
||
195 | */ |
||
196 | 2 | public function hasErrors() |
|
200 | |||
201 | /** |
||
202 | * Get errors. |
||
203 | * |
||
204 | * @return array The errors array. |
||
205 | */ |
||
206 | 2 | public function getErrors() |
|
210 | |||
211 | /** |
||
212 | * Get validators. |
||
213 | * |
||
214 | * @return array The validators array. |
||
215 | */ |
||
216 | 2 | public function getValidators() |
|
220 | |||
221 | /** |
||
222 | * Set validators. |
||
223 | * |
||
224 | * @param array $validators The validators array. |
||
225 | */ |
||
226 | 1 | public function setValidators($validators) |
|
230 | |||
231 | /** |
||
232 | * Get translator. |
||
233 | * |
||
234 | * @return callable The translator. |
||
235 | */ |
||
236 | 2 | public function getTranslator() |
|
240 | |||
241 | /** |
||
242 | * Set translator. |
||
243 | * |
||
244 | * @param callable $translator The translator. |
||
245 | */ |
||
246 | 1 | public function setTranslator($translator) |
|
250 | } |
||
251 |
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.