1
|
|
|
<?php |
2
|
|
|
namespace Agavi\Validator; |
3
|
|
|
|
4
|
|
|
// +---------------------------------------------------------------------------+ |
5
|
|
|
// | This file is part of the Agavi package. | |
6
|
|
|
// | Copyright (c) 2005-2011 the Agavi Project. | |
7
|
|
|
// | | |
8
|
|
|
// | For the full copyright and license information, please view the LICENSE | |
9
|
|
|
// | file that was distributed with this source code. You can also view the | |
10
|
|
|
// | LICENSE file online at http://www.agavi.org/LICENSE.txt | |
11
|
|
|
// | vi: set noexpandtab: | |
12
|
|
|
// | Local Variables: | |
13
|
|
|
// | indent-tabs-mode: t | |
14
|
|
|
// | End: | |
15
|
|
|
// +---------------------------------------------------------------------------+ |
16
|
|
|
use Agavi\Core\Context; |
17
|
|
|
use Agavi\Exception\ConfigurationException; |
18
|
|
|
use Agavi\Request\RequestDataHolder; |
19
|
|
|
use Agavi\Util\ArrayPathDefinition; |
20
|
|
|
use Agavi\Util\ParameterHolder; |
21
|
|
|
use Agavi\Util\VirtualArrayPath; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* AgaviValidationManager provides management for request parameters and their |
25
|
|
|
* associated validators. |
26
|
|
|
* |
27
|
|
|
* @package agavi |
28
|
|
|
* @subpackage validator |
29
|
|
|
* |
30
|
|
|
* @author Uwe Mesecke <[email protected]> |
31
|
|
|
* @copyright Authors |
32
|
|
|
* @copyright The Agavi Project |
33
|
|
|
* |
34
|
|
|
* @since 0.11.0 |
35
|
|
|
* |
36
|
|
|
* @version $Id$ |
37
|
|
|
*/ |
38
|
|
|
class ValidationManager extends ParameterHolder implements ValidatorContainerInterface |
39
|
|
|
{ |
40
|
|
|
/** |
41
|
|
|
* @var DependencyManager The dependency manager. |
42
|
|
|
*/ |
43
|
|
|
protected $dependencyManager = null; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @var array An array of child validators. |
47
|
|
|
*/ |
48
|
|
|
protected $children = array(); |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @var Context The context instance. |
52
|
|
|
*/ |
53
|
|
|
protected $context = null; |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* @var ValidationReport The report container storing the validation results. |
57
|
|
|
*/ |
58
|
|
|
protected $report = null; |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* All request variables are always available. |
62
|
|
|
*/ |
63
|
|
|
const MODE_RELAXED = 'relaxed'; |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* All request variables are available when no validation defined else only |
67
|
|
|
* validated request variables are available. |
68
|
|
|
*/ |
69
|
|
|
const MODE_CONDITIONAL = 'conditional'; |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Only validated request variables are available. |
73
|
|
|
*/ |
74
|
|
|
const MODE_STRICT = 'strict'; |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* initializes the validator manager. |
78
|
|
|
* |
79
|
|
|
* @param Context $context The context instance. |
80
|
|
|
* @param array $parameters The initialization parameters. |
81
|
|
|
* |
82
|
|
|
* @author Uwe Mesecke <[email protected]> |
83
|
|
|
* @since 0.11.0 |
84
|
|
|
*/ |
85
|
|
|
public function initialize(Context $context, array $parameters = array()) |
86
|
|
|
{ |
87
|
|
|
if (isset($parameters['mode'])) { |
88
|
|
|
if (!in_array($parameters['mode'], array(self::MODE_RELAXED, self::MODE_CONDITIONAL, self::MODE_STRICT))) { |
89
|
|
|
throw new ConfigurationException('Invalid validation mode "' . $parameters['mode'] . '" specified'); |
90
|
|
|
} |
91
|
|
|
} else { |
92
|
|
|
$parameters['mode'] = self::MODE_STRICT; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
$this->context = $context; |
96
|
|
|
$this->setParameters($parameters); |
97
|
|
|
|
98
|
|
|
$this->dependencyManager = new DependencyManager(); |
99
|
|
|
$this->report = new ValidationReport(); |
100
|
|
|
$this->children = array(); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Retrieve the current application context. |
105
|
|
|
* |
106
|
|
|
* @return Context The current Context instance. |
107
|
|
|
* |
108
|
|
|
* @author Uwe Mesecke <[email protected]> |
109
|
|
|
* @since 0.11.0 |
110
|
|
|
*/ |
111
|
|
|
final public function getContext() |
112
|
|
|
{ |
113
|
|
|
return $this->context; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Retrieve the validation result report container of the last validation run. |
118
|
|
|
* |
119
|
|
|
* @return ValidationReport The result report container. |
120
|
|
|
* |
121
|
|
|
* @author Dominik del Bondio <[email protected]> |
122
|
|
|
* @since 1.0.0 |
123
|
|
|
*/ |
124
|
|
|
public function getReport() |
125
|
|
|
{ |
126
|
|
|
return $this->report; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Creates a new validator instance. |
131
|
|
|
* |
132
|
|
|
* @param string $class The name of the class implementing the validator. |
133
|
|
|
* @param array $arguments The argument names. |
134
|
|
|
* @param array $errors The error messages. |
135
|
|
|
* @param array $parameters The validator parameters. |
136
|
|
|
* @param ValidatorContainerInterface $parent The parent (will use the validation |
137
|
|
|
* manager if null is given) |
138
|
|
|
* @return Validator |
139
|
|
|
* |
140
|
|
|
* @author Dominik del Bondio <[email protected]> |
141
|
|
|
* @since 0.11.0 |
142
|
|
|
*/ |
143
|
|
|
public function createValidator($class, array $arguments, array $errors = array(), $parameters = array(), ValidatorContainerInterface $parent = null) |
144
|
|
|
{ |
145
|
|
|
if ($parent === null) { |
146
|
|
|
$parent = $this; |
147
|
|
|
} |
148
|
|
|
/** @var Validator $obj */ |
149
|
|
|
$obj = new $class; |
150
|
|
|
$obj->initialize($this->getContext(), $parameters, $arguments, $errors); |
151
|
|
|
$parent->addChild($obj); |
152
|
|
|
|
153
|
|
|
return $obj; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* Clears the validation manager for reuse |
158
|
|
|
* |
159
|
|
|
* clears the validator manager by resetting the dependency and error |
160
|
|
|
* manager and removing all validators after calling their shutdown |
161
|
|
|
* method so they can do a save shutdown. |
162
|
|
|
* |
163
|
|
|
* @author Uwe Mesecke <[email protected]> |
164
|
|
|
* @since 0.11.0 |
165
|
|
|
*/ |
166
|
|
|
public function clear() |
167
|
|
|
{ |
168
|
|
|
$this->dependencyManager->clear(); |
169
|
|
|
|
170
|
|
|
$this->report = new ValidationReport(); |
171
|
|
|
|
172
|
|
|
/** @var Validator $child */ |
173
|
|
|
foreach ($this->children as $child) { |
174
|
|
|
$child->shutdown(); |
175
|
|
|
} |
176
|
|
|
$this->children = array(); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* Adds a new child validator. |
181
|
|
|
* |
182
|
|
|
* @param Validator $validator The new child validator. |
183
|
|
|
* |
184
|
|
|
* @author Uwe Mesecke <[email protected]> |
185
|
|
|
* @since 0.11.0 |
186
|
|
|
*/ |
187
|
|
View Code Duplication |
public function addChild(Validator $validator) |
|
|
|
|
188
|
|
|
{ |
189
|
|
|
$name = $validator->getName(); |
190
|
|
|
if (isset($this->children[$name])) { |
191
|
|
|
throw new \InvalidArgumentException('A validator with the name "' . $name . '" already exists'); |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
$this->children[$name] = $validator; |
195
|
|
|
$validator->setParentContainer($this); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
/** |
199
|
|
|
* Returns a named child validator. |
200
|
|
|
* |
201
|
|
|
* @param string $name The child validator name. |
202
|
|
|
* |
203
|
|
|
* @return Validator |
204
|
|
|
* @author Dominik del Bondio <[email protected]> |
205
|
|
|
* @since 0.11.0 |
206
|
|
|
*/ |
207
|
|
View Code Duplication |
public function getChild($name) |
|
|
|
|
208
|
|
|
{ |
209
|
|
|
if (!isset($this->children[$name])) { |
210
|
|
|
throw new \InvalidArgumentException('A validator with the name "' . $name . '" does not exist'); |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
return $this->children[$name]; |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
/** |
217
|
|
|
* Returns all child validators. |
218
|
|
|
* |
219
|
|
|
* @return Validator[] An array of Validator instances. |
220
|
|
|
* |
221
|
|
|
* @author Dominik del Bondio <[email protected]> |
222
|
|
|
* @since 0.11.0 |
223
|
|
|
*/ |
224
|
|
|
public function getChilds() |
225
|
|
|
{ |
226
|
|
|
return $this->children; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* Returns the dependency manager. |
231
|
|
|
* |
232
|
|
|
* @return DependencyManager The dependency manager instance. |
233
|
|
|
* |
234
|
|
|
* @author Uwe Mesecke <[email protected]> |
235
|
|
|
* @since 0.11.0 |
236
|
|
|
*/ |
237
|
|
|
public function getDependencyManager() |
238
|
|
|
{ |
239
|
|
|
return $this->dependencyManager; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* Gets the base path of the validator. |
244
|
|
|
* |
245
|
|
|
* @return VirtualArrayPath The base path. |
246
|
|
|
* |
247
|
|
|
* @author Uwe Mesecke <[email protected]> |
248
|
|
|
* @since 0.11.0 |
249
|
|
|
*/ |
250
|
|
|
public function getBase() |
251
|
|
|
{ |
252
|
|
|
return new VirtualArrayPath($this->getParameter('base', '')); |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
/** |
256
|
|
|
* Starts the validation process. |
257
|
|
|
* |
258
|
|
|
* @param RequestDataHolder $parameters The data which should be validated. |
259
|
|
|
* |
260
|
|
|
* @return bool true, if validation succeeded. |
261
|
|
|
* |
262
|
|
|
* @author Uwe Mesecke <[email protected]> |
263
|
|
|
* @since 0.11.0 |
264
|
|
|
*/ |
265
|
|
|
public function execute(RequestDataHolder $parameters) |
266
|
|
|
{ |
267
|
|
|
$success = true; |
268
|
|
|
$this->report = new ValidationReport(); |
269
|
|
|
$result = Validator::SUCCESS; |
270
|
|
|
|
271
|
|
|
$req = $this->context->getRequest(); |
272
|
|
|
|
273
|
|
|
$executedValidators = 0; |
274
|
|
|
/** @var Validator $validator */ |
275
|
|
|
foreach ($this->children as $validator) { |
276
|
|
|
++$executedValidators; |
277
|
|
|
|
278
|
|
|
$validatorResult = $validator->execute($parameters); |
279
|
|
|
$result = max($result, $validatorResult); |
280
|
|
|
|
281
|
|
|
switch ($validatorResult) { |
282
|
|
|
case Validator::SUCCESS: |
283
|
|
|
continue 2; |
284
|
|
|
case Validator::INFO: |
285
|
|
|
continue 2; |
286
|
|
|
case Validator::SILENT: |
287
|
|
|
continue 2; |
288
|
|
|
case Validator::NOTICE: |
289
|
|
|
continue 2; |
290
|
|
|
case Validator::ERROR: |
291
|
|
|
$success = false; |
292
|
|
|
continue 2; |
293
|
|
|
case Validator::CRITICAL: |
294
|
|
|
$success = false; |
295
|
|
|
break 2; |
296
|
|
|
} |
297
|
|
|
} |
298
|
|
|
$this->report->setResult($result); |
299
|
|
|
$this->report->setDependTokens($this->getDependencyManager()->getDependTokens()); |
300
|
|
|
|
301
|
|
|
$ma = $req->getParameter('module_accessor'); |
302
|
|
|
$aa = $req->getParameter('controller_accessor'); |
303
|
|
|
$umap = $req->getParameter('use_module_controller_parameters'); |
304
|
|
|
|
305
|
|
|
$mode = $this->getParameter('mode'); |
306
|
|
|
|
307
|
|
|
if ($executedValidators == 0 && $mode == self::MODE_STRICT) { |
308
|
|
|
// strict mode and no validators executed -> clear the parameters |
309
|
|
|
if ($umap) { |
310
|
|
|
$maParam = $parameters->getParameter($ma); |
311
|
|
|
$aaParam = $parameters->getParameter($aa); |
312
|
|
|
} |
313
|
|
|
$parameters->clearAll(); |
314
|
|
|
if ($umap) { |
315
|
|
|
if ($maParam) { |
316
|
|
|
$parameters->setParameter($ma, $maParam); |
|
|
|
|
317
|
|
|
} |
318
|
|
|
if ($aaParam) { |
319
|
|
|
$parameters->setParameter($aa, $aaParam); |
|
|
|
|
320
|
|
|
} |
321
|
|
|
} |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
if ($mode == self::MODE_STRICT || ($executedValidators > 0 && $mode == self::MODE_CONDITIONAL)) { |
325
|
|
|
// first, we explicitly unset failed arguments |
326
|
|
|
// the primary purpose of this is to make sure that arrays that failed validation themselves (e.g. due to array length validation, or due to use of operator validators with an argument base) are removed |
327
|
|
|
// that's of course only necessary if validation failed |
328
|
|
|
$failedArguments = $this->report->getFailedArguments(); |
329
|
|
|
|
330
|
|
|
/** @var ValidationArgument $argument */ |
331
|
|
|
foreach ($failedArguments as $argument) { |
332
|
|
|
$parameters->remove($argument->getSource(), $argument->getName()); |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
// next, we remove all arguments from the request data that are not in the list of succeeded arguments |
336
|
|
|
// this will also remove any arguments that didn't have validation rules defined |
337
|
|
|
$succeededArguments = $this->report->getSucceededArguments(); |
338
|
|
|
foreach ($parameters->getSourceNames() as $source) { |
339
|
|
|
$sourceItems = $parameters->getAll($source); |
340
|
|
|
foreach (ArrayPathDefinition::getFlatKeyNames($sourceItems) as $name) { |
341
|
|
|
if (!isset($succeededArguments[$source . '/' . $name]) && (!$umap || ($source != RequestDataHolder::SOURCE_PARAMETERS || ($name != $ma && $name != $aa)))) { |
342
|
|
|
$parameters->remove($source, $name); |
343
|
|
|
} |
344
|
|
|
} |
345
|
|
|
} |
346
|
|
|
} |
347
|
|
|
|
348
|
|
|
return $success; |
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
/** |
352
|
|
|
* Shuts the validation system down. |
353
|
|
|
* |
354
|
|
|
* @author Uwe Mesecke <[email protected]> |
355
|
|
|
* @since 0.11.0 |
356
|
|
|
*/ |
357
|
|
|
public function shutdown() |
358
|
|
|
{ |
359
|
|
|
/** @var Validator $child */ |
360
|
|
|
foreach ($this->children as $child) { |
361
|
|
|
$child->shutdown(); |
362
|
|
|
} |
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
/** |
366
|
|
|
* Registers multiple validators. |
367
|
|
|
* |
368
|
|
|
* @param Validator[] $validators An array of validators. |
369
|
|
|
* |
370
|
|
|
* @author Uwe Mesecke <[email protected]> |
371
|
|
|
* @since 0.11.0 |
372
|
|
|
*/ |
373
|
|
|
public function registerValidators(array $validators) |
374
|
|
|
{ |
375
|
|
|
foreach ($validators as $validator) { |
376
|
|
|
$this->addChild($validator); |
377
|
|
|
} |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
/** |
381
|
|
|
* Adds an incident to the validation result. This will automatically adjust |
382
|
|
|
* the field result table (which is required because one can still manually |
383
|
|
|
* add errors either via AgaviRequest::addError or by directly using this |
384
|
|
|
* method) |
385
|
|
|
* |
386
|
|
|
* @param ValidationIncident $incident The incident. |
387
|
|
|
* |
388
|
|
|
* @author Dominik del Bondio <[email protected]> |
389
|
|
|
* @since 0.11.0 |
390
|
|
|
*/ |
391
|
|
|
public function addIncident(ValidationIncident $incident) |
392
|
|
|
{ |
393
|
|
|
return $this->report->addIncident($incident); |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
|
397
|
|
|
///////////////////////////////////////////////////////////////////////////// |
398
|
|
|
////////////////////////////// Deprecated Parts ///////////////////////////// |
399
|
|
|
///////////////////////////////////////////////////////////////////////////// |
400
|
|
|
|
401
|
|
|
|
402
|
|
|
/** |
403
|
|
|
* Returns the final validation result. |
404
|
|
|
* |
405
|
|
|
* @return int The result of the validation process. |
406
|
|
|
* |
407
|
|
|
* @author Dominik del Bondio <[email protected]> |
408
|
|
|
* @since 0.11.0 |
409
|
|
|
* |
410
|
|
|
* @deprecated 1.0.0 |
411
|
|
|
*/ |
412
|
|
|
public function getResult() |
413
|
|
|
{ |
414
|
|
|
$result = $this->report->getResult(); |
415
|
|
|
|
416
|
|
|
if (null === $result) { |
417
|
|
|
$result = Validator::NOT_PROCESSED; |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
return $result; |
421
|
|
|
} |
422
|
|
|
|
423
|
|
|
/** |
424
|
|
|
* Adds a validation result for a given field. |
425
|
|
|
* |
426
|
|
|
* @param Validator $validator The validator. |
427
|
|
|
* @param string $fieldname The name of the field which has been validated. |
428
|
|
|
* @param int $result The result of the validation. |
429
|
|
|
* |
430
|
|
|
* @author Dominik del Bondio <[email protected]> |
431
|
|
|
* @since 0.11.0 |
432
|
|
|
* |
433
|
|
|
* @deprecated 1.0.0 |
434
|
|
|
*/ |
435
|
|
|
public function addFieldResult($validator, $fieldname, $result) |
436
|
|
|
{ |
437
|
|
|
$argument = new ValidationArgument($fieldname); |
438
|
|
|
return $this->report->addArgumentResult($argument, $result, $validator); |
439
|
|
|
} |
440
|
|
|
|
441
|
|
|
/** |
442
|
|
|
* Adds a intermediate result of an validator for the given argument |
443
|
|
|
* |
444
|
|
|
* @param ValidationArgument $argument The argument |
445
|
|
|
* @param int $result The arguments result. |
446
|
|
|
* @param Validator $validator The validator (if the error was caused |
447
|
|
|
* inside a validator). |
448
|
|
|
* |
449
|
|
|
* @author Dominik del Bondio <[email protected]> |
450
|
|
|
* @since 1.0.0 |
451
|
|
|
*/ |
452
|
|
|
public function addArgumentResult(ValidationArgument $argument, $result, $validator = null) |
453
|
|
|
{ |
454
|
|
|
return $this->report->addArgumentResult($argument, $result, $validator); |
455
|
|
|
} |
456
|
|
|
|
457
|
|
|
/** |
458
|
|
|
* Will return the highest error code for a field. This can be optionally |
459
|
|
|
* limited to the highest error code of an validator. If the field was not |
460
|
|
|
* "touched" by a validator null is returned. |
461
|
|
|
* |
462
|
|
|
* @param string $fieldname The name of the field. |
463
|
|
|
* @param string $validatorName The Validator name |
464
|
|
|
* |
465
|
|
|
* @return int The error code. |
466
|
|
|
* |
467
|
|
|
* @author Dominik del Bondio <[email protected]> |
468
|
|
|
* @since 0.11.0 |
469
|
|
|
* |
470
|
|
|
* @deprecated 1.0.0 |
471
|
|
|
*/ |
472
|
|
|
public function getFieldErrorCode($fieldname, $validatorName = null) |
473
|
|
|
{ |
474
|
|
|
return $this->report->getAuthoritativeArgumentSeverity(new ValidationArgument($fieldname), $validatorName); |
475
|
|
|
} |
476
|
|
|
|
477
|
|
|
/** |
478
|
|
|
* Checks whether a field has failed in any validator. |
479
|
|
|
* |
480
|
|
|
* @param string $fieldname The name of the field. |
481
|
|
|
* |
482
|
|
|
* @return bool Whether the field has failed. |
483
|
|
|
* |
484
|
|
|
* @author Dominik del Bondio <[email protected]> |
485
|
|
|
* @since 0.11.0 |
486
|
|
|
* |
487
|
|
|
* @deprecated 1.0.0 |
488
|
|
|
*/ |
489
|
|
|
public function isFieldFailed($fieldname) |
490
|
|
|
{ |
491
|
|
|
return $this->report->isArgumentFailed(new ValidationArgument($fieldname)); |
492
|
|
|
} |
493
|
|
|
|
494
|
|
|
/** |
495
|
|
|
* Checks whether a field has been processed by a validator (this includes |
496
|
|
|
* fields which were skipped because their value was not set and the validator |
497
|
|
|
* was not required) |
498
|
|
|
* |
499
|
|
|
* @param string $fieldname The name of the field. |
500
|
|
|
* |
501
|
|
|
* @return bool Whether the field was validated. |
502
|
|
|
* |
503
|
|
|
* @author Dominik del Bondio <[email protected]> |
504
|
|
|
* @since 0.11.0 |
505
|
|
|
* |
506
|
|
|
* @deprecated 1.0.0 |
507
|
|
|
*/ |
508
|
|
|
public function isFieldValidated($fieldname) |
509
|
|
|
{ |
510
|
|
|
return $this->report->isArgumentValidated(new ValidationArgument($fieldname)); |
511
|
|
|
} |
512
|
|
|
|
513
|
|
|
/** |
514
|
|
|
* Returns all fields which succeeded in the validation. Includes fields which |
515
|
|
|
* were not processed (happens when the field is "not set" and the validator |
516
|
|
|
* is not required) |
517
|
|
|
* |
518
|
|
|
* @param string $source The source for which the fields should be returned. |
519
|
|
|
* |
520
|
|
|
* @return array An array of field names. |
521
|
|
|
* |
522
|
|
|
* @author Dominik del Bondio <[email protected]> |
523
|
|
|
* @since 0.11.0 |
524
|
|
|
* |
525
|
|
|
* @deprecated 1.0.0 |
526
|
|
|
*/ |
527
|
|
|
public function getSucceededFields($source) |
528
|
|
|
{ |
529
|
|
|
$names = array(); |
530
|
|
|
$arguments = $this->report->getSucceededArguments($source); |
531
|
|
|
foreach ($arguments as $argument) { |
532
|
|
|
$names[] = $argument->getName(); |
533
|
|
|
} |
534
|
|
|
|
535
|
|
|
return $names; |
536
|
|
|
} |
537
|
|
|
|
538
|
|
|
/** |
539
|
|
|
* Checks if any incidents occurred Returns all fields which succeeded in the |
540
|
|
|
* validation. Includes fields which were not processed (happens when the |
541
|
|
|
* field is "not set" and the validator is not required) |
542
|
|
|
* |
543
|
|
|
* @param int $minSeverity The minimum severity which shall be checked for. |
544
|
|
|
* |
545
|
|
|
* @return bool The result. |
546
|
|
|
* |
547
|
|
|
* @author Dominik del Bondio <[email protected]> |
548
|
|
|
* @since 0.11.0 |
549
|
|
|
* |
550
|
|
|
* @deprecated 1.0.0 |
551
|
|
|
*/ |
552
|
|
|
public function hasIncidents($minSeverity = null) |
553
|
|
|
{ |
554
|
|
|
return count($this->getIncidents($minSeverity)) > 0; |
|
|
|
|
555
|
|
|
} |
556
|
|
|
|
557
|
|
|
/** |
558
|
|
|
* Returns all incidents which happened during the execution of the validation. |
559
|
|
|
* |
560
|
|
|
* @param int $minSeverity The minimum severity a returned incident needs to have. |
561
|
|
|
* |
562
|
|
|
* @return ValidationIncident[] The incidents. |
563
|
|
|
* |
564
|
|
|
* @author Dominik del Bondio <[email protected]> |
565
|
|
|
* @since 0.11.0 |
566
|
|
|
* |
567
|
|
|
* @deprecated 1.0.0 |
568
|
|
|
*/ |
569
|
|
|
public function getIncidents($minSeverity = null) |
570
|
|
|
{ |
571
|
|
|
$incidents = array(); |
572
|
|
|
if ($minSeverity === null) { |
573
|
|
|
return $this->report->getIncidents(); |
574
|
|
|
} else { |
575
|
|
|
foreach ($this->report->getIncidents() as $incident) { |
576
|
|
|
if ($incident->getSeverity() >= $minSeverity) { |
577
|
|
|
$incidents[] = $incident; |
578
|
|
|
} |
579
|
|
|
} |
580
|
|
|
} |
581
|
|
|
return $incidents; |
582
|
|
|
} |
583
|
|
|
|
584
|
|
|
/** |
585
|
|
|
* Returns all incidents of a given validator. |
586
|
|
|
* |
587
|
|
|
* @param string $validatorName The name of the validator. |
588
|
|
|
* @param int $minSeverity The minimum severity a returned incident needs to have. |
589
|
|
|
* |
590
|
|
|
* @return ValidationIncident[] The incidents. |
591
|
|
|
* |
592
|
|
|
* @author Dominik del Bondio <[email protected]> |
593
|
|
|
* @since 0.11.0 |
594
|
|
|
* |
595
|
|
|
* @deprecated 1.0.0 |
596
|
|
|
*/ |
597
|
|
View Code Duplication |
public function getValidatorIncidents($validatorName, $minSeverity = null) |
|
|
|
|
598
|
|
|
{ |
599
|
|
|
$incidents = $this->report->byValidator($validatorName)->getIncidents(); |
600
|
|
|
|
601
|
|
|
if ($minSeverity === null) { |
602
|
|
|
return $incidents; |
603
|
|
|
} else { |
604
|
|
|
$matchingIncidents = array(); |
605
|
|
|
foreach ($incidents as $incident) { |
606
|
|
|
if ($incident->getSeverity() >= $minSeverity) { |
607
|
|
|
$matchingIncidents[] = $incident; |
608
|
|
|
} |
609
|
|
|
} |
610
|
|
|
return $matchingIncidents; |
611
|
|
|
} |
612
|
|
|
} |
613
|
|
|
/** |
614
|
|
|
* Returns all incidents of a given field. |
615
|
|
|
* |
616
|
|
|
* @param string $fieldname The name of the field. |
617
|
|
|
* @param int $minSeverity The minimum severity a returned incident needs to have. |
618
|
|
|
* |
619
|
|
|
* @return ValidationIncident[] The incidents. |
620
|
|
|
* |
621
|
|
|
* @author Dominik del Bondio <[email protected]> |
622
|
|
|
* @since 0.11.0 |
623
|
|
|
* |
624
|
|
|
* @deprecated 1.0.0 |
625
|
|
|
*/ |
626
|
|
View Code Duplication |
public function getFieldIncidents($fieldname, $minSeverity = null) |
|
|
|
|
627
|
|
|
{ |
628
|
|
|
$incidents = $this->report->byArgument($fieldname)->getIncidents(); |
629
|
|
|
|
630
|
|
|
if ($minSeverity === null) { |
631
|
|
|
return $incidents; |
632
|
|
|
} else { |
633
|
|
|
$matchingIncidents = array(); |
634
|
|
|
foreach ($incidents as $incident) { |
635
|
|
|
if ($incident->getSeverity() >= $minSeverity) { |
636
|
|
|
$matchingIncidents[] = $incident; |
637
|
|
|
} |
638
|
|
|
} |
639
|
|
|
return $matchingIncidents; |
640
|
|
|
} |
641
|
|
|
} |
642
|
|
|
|
643
|
|
|
/** |
644
|
|
|
* Returns all errors of a given field. |
645
|
|
|
* |
646
|
|
|
* @param string $fieldname The name of the field. |
647
|
|
|
* @param int $minSeverity The minimum severity a returned incident of the error |
648
|
|
|
* needs to have. |
649
|
|
|
* |
650
|
|
|
* @return ValidationError[] The errors. |
651
|
|
|
* |
652
|
|
|
* @author Dominik del Bondio <[email protected]> |
653
|
|
|
* @since 0.11.0 |
654
|
|
|
* |
655
|
|
|
* @deprecated 1.0.0 |
656
|
|
|
*/ |
657
|
|
|
public function getFieldErrors($fieldname, $minSeverity = null) |
658
|
|
|
{ |
659
|
|
|
$incidents = $this->getFieldIncidents($fieldname, $minSeverity); |
|
|
|
|
660
|
|
|
$errors = array(); |
661
|
|
|
foreach ($incidents as $incident) { |
662
|
|
|
$errors = array_merge($errors, $incident->getErrors()); |
663
|
|
|
} |
664
|
|
|
return $errors; |
665
|
|
|
} |
666
|
|
|
|
667
|
|
|
/** |
668
|
|
|
* Returns all errors of a given field in a given validator. |
669
|
|
|
* |
670
|
|
|
* @param string $validatorName The name of the field. |
671
|
|
|
* @param int $minSeverity The minimum severity a returned incident of the error |
672
|
|
|
* needs to have. |
673
|
|
|
* |
674
|
|
|
* @return ValidationIncident[] The incidents. |
675
|
|
|
* |
676
|
|
|
* @author Dominik del Bondio <[email protected]> |
677
|
|
|
* @since 0.11.0 |
678
|
|
|
* |
679
|
|
|
* @deprecated 1.0.0 |
680
|
|
|
*/ |
681
|
|
|
public function getValidatorFieldErrors($validatorName, $fieldname, $minSeverity = null) |
682
|
|
|
{ |
683
|
|
|
$incidents = $this->getFieldIncidents($fieldname, $minSeverity); |
|
|
|
|
684
|
|
|
$matchingIncidents = array(); |
685
|
|
|
foreach ($incidents as $incident) { |
686
|
|
|
$validator = $incident->getValidator(); |
687
|
|
|
if ($validator && $validator->getName() == $validatorName) { |
688
|
|
|
$matchingIncidents[] = $incident; |
689
|
|
|
} |
690
|
|
|
} |
691
|
|
|
return $matchingIncidents; |
692
|
|
|
} |
693
|
|
|
|
694
|
|
|
/** |
695
|
|
|
* Returns all failed fields (this are all fields including those with |
696
|
|
|
* severity none and notice). |
697
|
|
|
* |
698
|
|
|
* @return array The names of the fields. |
699
|
|
|
* @param int $minSeverity The minimum severity a field needs to have. |
700
|
|
|
* |
701
|
|
|
* @author Dominik del Bondio <[email protected]> |
702
|
|
|
* @since 0.11.0 |
703
|
|
|
* |
704
|
|
|
* @deprecated 1.0.0 |
705
|
|
|
*/ |
706
|
|
|
public function getFailedFields($minSeverity = null) |
707
|
|
|
{ |
708
|
|
|
$fields = array(); |
709
|
|
|
foreach ($this->getIncidents($minSeverity) as $incident) { |
|
|
|
|
710
|
|
|
$fields = array_merge($fields, $incident->getFields()); |
|
|
|
|
711
|
|
|
} |
712
|
|
|
|
713
|
|
|
return array_values(array_unique($fields)); |
714
|
|
|
} |
715
|
|
|
|
716
|
|
|
/** |
717
|
|
|
* Retrieve an error message. |
718
|
|
|
* |
719
|
|
|
* @param string $name An error name. |
720
|
|
|
* |
721
|
|
|
* @return string The error message. |
722
|
|
|
* |
723
|
|
|
* @author Sean Kerr <[email protected]> |
724
|
|
|
* @author Dominik del Bondio <[email protected]> |
725
|
|
|
* @since 0.9.0 |
726
|
|
|
* |
727
|
|
|
* @deprecated 1.0.0 |
728
|
|
|
*/ |
729
|
|
|
public function getError($name) |
730
|
|
|
{ |
731
|
|
|
$incidents = $this->getFieldIncidents($name, Validator::NOTICE); |
|
|
|
|
732
|
|
|
|
733
|
|
|
if (count($incidents) == 0) { |
734
|
|
|
return null; |
735
|
|
|
} |
736
|
|
|
|
737
|
|
|
$errors = $incidents[0]->getErrors(); |
738
|
|
|
return $errors[0]->getMessage(); |
739
|
|
|
} |
740
|
|
|
|
741
|
|
|
/** |
742
|
|
|
* Retrieve an array of error names. |
743
|
|
|
* |
744
|
|
|
* @return array An indexed array of error names. |
745
|
|
|
* |
746
|
|
|
* @author Sean Kerr <[email protected]> |
747
|
|
|
* @author Dominik del Bondio <[email protected]> |
748
|
|
|
* @since 0.9.0 |
749
|
|
|
* |
750
|
|
|
* @deprecated 1.0.0 |
751
|
|
|
*/ |
752
|
|
|
public function getErrorNames() |
753
|
|
|
{ |
754
|
|
|
return $this->getFailedFields(); |
|
|
|
|
755
|
|
|
} |
756
|
|
|
|
757
|
|
|
/** |
758
|
|
|
* Retrieve an array of errors. |
759
|
|
|
* |
760
|
|
|
* @param string $name An optional error name. |
761
|
|
|
* |
762
|
|
|
* @return array An associative array of errors(if no name was given) as |
763
|
|
|
* an array with the error messages (key 'messages') and |
764
|
|
|
* the validators (key 'validators') which failed. |
765
|
|
|
* |
766
|
|
|
* @author Sean Kerr <[email protected]> |
767
|
|
|
* @author Dominik del Bondio <[email protected]> |
768
|
|
|
* @since 0.9.0 |
769
|
|
|
* |
770
|
|
|
* @deprecated 1.0.0 |
771
|
|
|
*/ |
772
|
|
|
public function getErrors($name = null) |
773
|
|
|
{ |
774
|
|
|
$errors = array(); |
775
|
|
|
|
776
|
|
|
foreach ($this->getIncidents(Validator::NOTICE) as $incident) { |
|
|
|
|
777
|
|
|
$validator = $incident->getValidator(); |
778
|
|
|
foreach ($incident->getErrors() as $error) { |
779
|
|
|
$msg = $error->getMessage(); |
780
|
|
|
foreach ($error->getFields() as $field) { |
781
|
|
|
if (!isset($errors[$field])) { |
782
|
|
|
$errors[$field] = array('messages' => array(), 'validators' => array()); |
783
|
|
|
} |
784
|
|
|
$errors[$field]['messages'][] = $msg; |
785
|
|
|
if ($validator) { |
786
|
|
|
$errors[$field]['validators'][] = $validator->getName(); |
787
|
|
|
} |
788
|
|
|
} |
789
|
|
|
} |
790
|
|
|
} |
791
|
|
|
|
792
|
|
|
if ($name === null) { |
793
|
|
|
return $errors; |
794
|
|
|
} else { |
795
|
|
|
return isset($errors[$name]) ? $errors[$name] : null; |
796
|
|
|
} |
797
|
|
|
} |
798
|
|
|
|
799
|
|
|
/** |
800
|
|
|
* Retrieve an array of error Messages. |
801
|
|
|
* |
802
|
|
|
* @param string $name An optional error name. |
803
|
|
|
* |
804
|
|
|
* @return array An indexed array of error messages (if a name was given) |
805
|
|
|
* or an indexed array in this format: |
806
|
|
|
* array('message' => string, 'errors' => array(string)) |
807
|
|
|
* |
808
|
|
|
* @author Dominik del Bondio <[email protected]> |
809
|
|
|
* @since 0.11.0 |
810
|
|
|
* |
811
|
|
|
* @deprecated 1.0.0 |
812
|
|
|
*/ |
813
|
|
|
public function getErrorMessages($name = null) |
814
|
|
|
{ |
815
|
|
|
|
816
|
|
|
if ($name !== null) { |
817
|
|
|
$incidents = $this->getFieldIncidents($name, Validator::NOTICE); |
|
|
|
|
818
|
|
|
$msgs = array(); |
819
|
|
|
foreach ($incidents as $incident) { |
820
|
|
|
foreach ($incident->getErrors() as $error) { |
821
|
|
|
$msgs[] = $error->getMessage(); |
822
|
|
|
} |
823
|
|
|
} |
824
|
|
|
return $msgs; |
825
|
|
|
} else { |
826
|
|
|
$incidents = $this->getIncidents(Validator::NOTICE); |
|
|
|
|
827
|
|
|
$msgs = array(); |
828
|
|
|
foreach ($incidents as $incident) { |
829
|
|
|
foreach ($incident->getErrors() as $error) { |
830
|
|
|
$msgs[] = array('message' => $error->getMessage(), 'errors' => $error->getFields()); |
831
|
|
|
} |
832
|
|
|
} |
833
|
|
|
return $msgs; |
834
|
|
|
} |
835
|
|
|
} |
836
|
|
|
|
837
|
|
|
/** |
838
|
|
|
* Indicates whether or not a field has an error. |
839
|
|
|
* |
840
|
|
|
* @param string $name A field name. |
841
|
|
|
* |
842
|
|
|
* @return bool true, if the field has an error, false otherwise. |
843
|
|
|
* |
844
|
|
|
* @author Sean Kerr <[email protected]> |
845
|
|
|
* @author Dominik del Bondio <[email protected]> |
846
|
|
|
* @author David Zülke <[email protected]> |
847
|
|
|
* @since 0.9.0 |
848
|
|
|
* |
849
|
|
|
* @deprecated 1.0.0 |
850
|
|
|
*/ |
851
|
|
|
public function hasError($name) |
852
|
|
|
{ |
853
|
|
|
$ec = $this->getFieldErrorCode($name); |
|
|
|
|
854
|
|
|
// greater than or equal to notice cause that's when we need to show an error (this is different to hasErrors() behavior due to legacy) |
855
|
|
|
return ($ec >= Validator::NOTICE); |
856
|
|
|
} |
857
|
|
|
|
858
|
|
|
/** |
859
|
|
|
* Indicates whether or not any errors exist. |
860
|
|
|
* |
861
|
|
|
* @return bool true, if any error exist, otherwise false. |
862
|
|
|
* |
863
|
|
|
* @author Sean Kerr <[email protected]> |
864
|
|
|
* @author Dominik del Bondio <[email protected]> |
865
|
|
|
* @since 0.9.0 |
866
|
|
|
* |
867
|
|
|
* @deprecated 1.0.0 |
868
|
|
|
*/ |
869
|
|
|
public function hasErrors() |
870
|
|
|
{ |
871
|
|
|
// anything above notice. just notice means validation didn't fail, although a notice is considered an error itself. but notices only "show up" if other validators with higher severity (error, fatal) failed |
872
|
|
|
return $this->getResult() > Validator::NOTICE; |
|
|
|
|
873
|
|
|
} |
874
|
|
|
|
875
|
|
|
/** |
876
|
|
|
* Set an error. |
877
|
|
|
* |
878
|
|
|
* @param string $name An error name. |
879
|
|
|
* @param string $message An error message. |
880
|
|
|
* |
881
|
|
|
* @author Dominik del Bondio <[email protected]> |
882
|
|
|
* @since 0.9.0 |
883
|
|
|
* |
884
|
|
|
* @deprecated 1.0.0 |
885
|
|
|
*/ |
886
|
|
|
public function setError($name, $message) |
887
|
|
|
{ |
888
|
|
|
$name = new ValidationArgument($name); |
889
|
|
|
$incident = new ValidationIncident(null, Validator::ERROR); |
|
|
|
|
890
|
|
|
$incident->addError(new ValidationError($message, null, array($name))); |
891
|
|
|
$this->addIncident($incident); |
892
|
|
|
} |
893
|
|
|
|
894
|
|
|
/** |
895
|
|
|
* Set an array of errors |
896
|
|
|
* |
897
|
|
|
* If an existing error name matches any of the keys in the supplied |
898
|
|
|
* array, the associated message will be appended to the messages array. |
899
|
|
|
* |
900
|
|
|
* @param array $errors An associative array of errors and their associated |
901
|
|
|
* messages. |
902
|
|
|
* |
903
|
|
|
* @author Dominik del Bondio <[email protected]> |
904
|
|
|
* @since 0.9.0 |
905
|
|
|
* |
906
|
|
|
* @deprecated 1.0.0 |
907
|
|
|
*/ |
908
|
|
|
public function setErrors(array $errors) |
909
|
|
|
{ |
910
|
|
|
$incident = new ValidationIncident(null, Validator::ERROR); |
|
|
|
|
911
|
|
|
foreach ($errors as $name => $error) { |
912
|
|
|
$name = new ValidationArgument($name); |
913
|
|
|
$incident->addError(new ValidationError($error, null, array($name))); |
914
|
|
|
} |
915
|
|
|
|
916
|
|
|
$this->addIncident($incident); |
917
|
|
|
} |
918
|
|
|
} |
919
|
|
|
|
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.