Passed
Pull Request — master (#490)
by Alexander
03:05 queued 39s
created

Number::getOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 20
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 26
cc 1
ccs 0
cts 0
cp 0
crap 2
rs 9.6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use Attribute;
8
use Closure;
9
use Yiisoft\Validator\Rule\Trait\SkipOnEmptyTrait;
10
use Yiisoft\Validator\Rule\Trait\SkipOnErrorTrait;
11
use Yiisoft\Validator\Rule\Trait\WhenTrait;
12
use Yiisoft\Validator\RuleWithOptionsInterface;
13
use Yiisoft\Validator\SkipOnEmptyInterface;
14
use Yiisoft\Validator\SkipOnErrorInterface;
15
use Yiisoft\Validator\WhenInterface;
16
17
/**
18
 * Defines validation options to check that the value is a number.
19
 *
20
 * The format of the number must match the regular expression specified in {@see Number::$integerPattern}
21
 * or {@see Number::$numberPattern}. Optionally, you may configure the {@see Number::min()} and {@see Number::max()}
22
 * to ensure the number is within certain range.
23
 *
24
 * @see NumberHandler
25
 *
26
 * @psalm-import-type WhenType from WhenInterface
27
 */
28
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
29
final class Number implements RuleWithOptionsInterface, SkipOnErrorInterface, WhenInterface, SkipOnEmptyInterface
30
{
31
    use SkipOnEmptyTrait;
32 36
    use SkipOnErrorTrait;
33
    use WhenTrait;
34
35
    /**
36
     * @param bool $integerOnly Whether the value can only be an integer. Defaults to `false`.
37
     * @param float|int|null $min Lower limit of the number. Defaults to `null`, meaning no lower limit.
38
     * See {@see $tooSmallMessage} for the customized message used when the number is too small.
39
     * @param float|int|null $max Upper limit of the number. Defaults to `null`, meaning no upper limit.
40
     * See {@see $tooBigMessage} for the customized message used when the number is too big.
41
     * @param string $incorrectInputMessage Error message used when the value is not numeric.
42
     *
43
     * You may use the following placeholders in the message:
44
     *
45
     * - `{attribute}`: the translated label of the attribute being validated.
46
     * - `{type}`: the type of the value being validated.
47
     * @param string $tooSmallMessage Error message used when the value is smaller than {@link $min}.
48
     *
49
     * You may use the following placeholders in the message:
50
     *
51
     * - `{attribute}`: the translated label of the attribute being validated.
52
     * - `{min}`: minimum value.
53
     * - `{value}`: actual value.
54
     * @param string $tooBigMessage Error message used when the value is bigger than {@link $max}.
55
     *
56
     * You may use the following placeholders in the message:
57
     *
58
     * - `{attribute}`: the translated label of the attribute being validated.
59
     * - `{max}`: maximum value.
60
     * - `{value}`: actual value.
61
     * @param string $integerPattern The regular expression for matching integers.
62
     * @param string $numberPattern The regular expression for matching numbers. It defaults to a pattern
63
     * that matches floating numbers with optional exponential part (e.g. -1.23e-10).
64
     * @param bool|callable|null $skipOnEmpty Whether to skip this rule if the value validated is empty.
65
     * See {@see SkipOnEmptyInterface}.
66
     * @param bool $skipOnError Whether to skip this rule if any of the previous rules gave an error.
67
     * See {@see SkipOnErrorInterface}.
68
     * @param Closure|null $when A callable to define a condition for applying the rule.
69
     * See {@see WhenInterface}.
70
     * @psalm-param WhenType $when
71
     */
72
    public function __construct(
73
        private bool $integerOnly = false,
74
        private float|int|null $min = null,
75
        private float|int|null $max = null,
76
        private string $incorrectInputMessage = 'The allowed types are integer, float and string.',
77
        private string $tooSmallMessage = 'Value must be no less than {min}.',
78
        private string $tooBigMessage = 'Value must be no greater than {max}.',
79
        private string $integerPattern = '/^\s*[+-]?\d+\s*$/',
80 10
        private string $numberPattern = '/^\s*[-+]?\d*\.?\d+([eE][-+]?\d+)?\s*$/',
81
        private mixed $skipOnEmpty = null,
82 10
        private bool $skipOnError = false,
83
        private Closure|null $when = null,
84
    ) {
85 106
    }
86
87 106
    public function getName(): string
88
    {
89
        return 'number';
90 83
    }
91
92 83
    /**
93
     * Whether the value can only be an integer.
94
     *
95 57
     * @return bool Whether the value can only be an integer. Defaults to `false`.
96
     *
97 57
     * @see $integerOnly
98
     */
99
    public function isIntegerOnly(): bool
100 14
    {
101
        return $this->integerOnly;
102 14
    }
103
104
    /**
105 39
     * Get lower limit of the number. `null` means no lower limit.
106
     *
107 39
     * @return float|int|null Lower limit of the number.
108
     *
109
     * @see $min
110 20
     */
111
    public function getMin(): float|int|null
112 20
    {
113
        return $this->min;
114
    }
115 42
116
    /**
117 42
     * Get upper limit of the number. `null` means no upper limit.
118
     *
119
     * @return float|int|null Upper limit of the number.
120 64
     *
121
     * @see $max
122 64
     */
123
    public function getMax(): float|int|null
124
    {
125 37
        return $this->max;
126
    }
127 37
128
    /**
129
     * Get error message used when the value is not numeric.
130 14
     *
131
     * @return string Error message.
132
     *
133 14
     * @see $incorrectInputMessage
134 14
     */
135 14
    public function getIncorrectInputMessage(): string
136
    {
137 14
        return $this->incorrectInputMessage;
138
    }
139
140
    /**
141 14
     * Get error message used when the value is smaller than {@link $min}.
142
     *
143
     * @return string Error message.
144
     *
145 14
     * @see $tooSmallMessage
146 14
     */
147
    public function getTooSmallMessage(): string
148
    {
149 14
        return $this->tooSmallMessage;
150 14
    }
151
152 14
    /**
153 14
     * Get error message used when the value is bigger than {@link $max}.
154 14
     *
155 14
     * @return string Error message.
156
     *
157
     * @see $tooBigMessage
158
     */
159 120
    public function getTooBigMessage(): string
160
    {
161 120
        return $this->tooBigMessage;
162
    }
163
164
    /**
165
     * Get the regular expression for matching integers.
166
     *
167
     * @return string The regular expression.
168
     *
169
     * @see $integerPattern
170
     */
171
    public function getIntegerPattern(): string
172
    {
173
        return $this->integerPattern;
174
    }
175
176
    /**
177
     * The regular expression for matching numbers.
178
     *
179
     * @return string The regular expression.
180
     *
181
     * @see $numberPattern
182
     */
183
    public function getNumberPattern(): string
184
    {
185
        return $this->numberPattern;
186
    }
187
188
    /**
189
     * Get error message used when value type does not match.
190
     *
191
     * @return string Error message.
192
     */
193
    public function getNotNumberMessage(): string
194
    {
195
        return $this->integerOnly ? 'Value must be an integer.' : 'Value must be a number.';
196
    }
197
198
    public function getOptions(): array
199
    {
200
        return [
201
            'asInteger' => $this->integerOnly,
202
            'min' => $this->min,
203
            'max' => $this->max,
204
            'incorrectInputMessage' => [
205
                'template' => $this->incorrectInputMessage,
206
                'parameters' => [],
207
            ],
208
            'notNumberMessage' => [
209
                'template' => $this->getNotNumberMessage(),
210
                'parameters' => [],
211
            ],
212
            'tooSmallMessage' => [
213
                'template' => $this->tooSmallMessage,
214
                'parameters' => ['min' => $this->min],
215
            ],
216
            'tooBigMessage' => [
217
                'template' => $this->tooBigMessage,
218
                'parameters' => ['max' => $this->max],
219
            ],
220
            'skipOnEmpty' => $this->getSkipOnEmptyOption(),
221
            'skipOnError' => $this->skipOnError,
222
            'integerPattern' => $this->integerPattern,
223
            'numberPattern' => $this->numberPattern,
224
        ];
225
    }
226
227
    public function getHandler(): string
228
    {
229
        return NumberHandler::class;
230
    }
231
}
232