Passed
Pull Request — master (#490)
by Alexander
02:37
created

Number::isIntegerOnly()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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