-
Notifications
You must be signed in to change notification settings - Fork 0
/
GetArgsListErrorsCapableTrait.php
139 lines (124 loc) · 4.82 KB
/
GetArgsListErrorsCapableTrait.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?php
namespace Dhii\Validation;
use InvalidArgumentException;
use OutOfRangeException;
use ReflectionParameter;
use Exception as RootException;
use Dhii\Util\String\StringableInterface as Stringable;
use ReflectionType;
use stdClass;
use Traversable;
/**
* Functionality for validating an args list.
*
* @since [*next-version*]
*/
trait GetArgsListErrorsCapableTrait
{
/**
* Produces a list of reasons why an args list is invalid against a spec.
*
* @since [*next-version*]
*
* @param array $args The list of arguments in order.
* @param array|Traversable|stdClass $spec The list of criteria.
*
* @throws OutOfRangeException If one of the criteria is invalid.
*
* @return string[]|Stringable[] The list of errors.
*/
protected function _getArgsListErrors($args, $spec)
{
$errors = [];
foreach ($spec as $_idx => $_param) {
if (!($_param instanceof ReflectionParameter)) {
throw $this->_createOutOfRangeException($this->__('Parameter #%1$d of the specification is invalid', [$_idx]), null, null, $_param);
}
$pos = $_param->getPosition(); // 0-based position index of the arg.
$isArgPresent = key_exists($pos, $args); // Whether this arg is specified
$isNullable = $_param->allowsNull(); // Whether null is allowed
// Is argument required but not present?
if (!$_param->isOptional() && !$isArgPresent) {
$errors[] = $this->__('Argument #%1$s is required', [$pos]);
continue;
}
$arg = $isArgPresent ? $args[$pos] : null; // The value of the arg
$isNullOk = $isNullable && $isArgPresent && is_null($arg); // Argument is present, is null, and this is allowed
if ($isNullOk) {
continue;
}
// Is argument of the right type?
// Type spec is not for all PHP versions
if (method_exists($_param, 'hasType') && $_param->hasType()) {
try {
$error = $this->_getValueTypeError($arg, $_param->getType());
} catch (InvalidArgumentException $e) {
throw $this->_createOutOfRangeException($this->__('Problem validating type of argument #%1$d against spec criterion #%1$d', [$pos, $_idx]), null, $e, $_param);
}
if (!is_null($error)) {
$errors[] = $this->__('Argument #%1$s is invalid: %2$s', [$pos, $this->_normalizeString($error)]);
}
}
}
return $errors;
}
/**
* Generates a list of reasons for a value failing validation against a type spec.
*
* @since [*next-version*]
*
* @param mixed $value The value being validated.
* @param ReflectionType $type A type criteria.
*
* @throws InvalidArgumentException If one of the criteria is invalid.
*
* @return string|Stringable|null The error, if value doesn't match the spec; `null` otherwise.
*/
abstract protected function _getValueTypeError($value, $type);
/**
* Normalizes a value to its string representation.
*
* The values that can be normalized are any scalar values, as well as
* {@see StringableInterface).
*
* @since [*next-version*]
*
* @param Stringable|string|int|float|bool $subject The value to normalize to string.
*
* @throws InvalidArgumentException If the value cannot be normalized.
*
* @return string The string that resulted from normalization.
*/
abstract protected function _normalizeString($subject);
/**
* Creates a new Out Of Range exception.
*
* @since [*next-version*]
*
* @param string|Stringable|int|float|bool|null $message The message, if any.
* @param int|float|string|Stringable|null $code The numeric error code, if any.
* @param RootException|null $previous The inner exception, if any.
* @param mixed|null $argument The value that is out of range, if any.
*
* @return OutOfRangeException The new exception.
*/
abstract protected function _createOutOfRangeException(
$message = null,
$code = null,
RootException $previous = null,
$argument = null
);
/**
* Translates a string, and replaces placeholders.
*
* @since [*next-version*]
* @see sprintf()
*
* @param string $string The format string to translate.
* @param array $args Placeholder values to replace in the string.
* @param mixed $context The context for translation.
*
* @return string The translated string.
*/
abstract protected function __($string, $args = [], $context = null);
}