Passed
Push — master ( 2b6758...acf834 )
by Aleksei
06:59
created

Number::tooBigMessage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use Yiisoft\Strings\NumericHelper;
8
use Yiisoft\Validator\DataSetInterface;
9
use Yiisoft\Validator\Result;
10
use Yiisoft\Validator\Rule;
11
12
/**
13
 * NumberValidator validates that the attribute value is a number.
14
 *
15
 * The format of the number must match the regular expression specified in [[integerPattern]] or [[numberPattern]].
16
 * Optionally, you may configure the [[max]] and [[min]] properties to ensure the number
17
 * is within certain range.
18
 */
19
class Number extends Rule
20
{
21
    /**
22
     * @var bool whether the attribute value can only be an integer. Defaults to false.
23
     */
24
    private bool $asInteger = false;
25
    /**
26
     * @var float|int upper limit of the number. Defaults to null, meaning no upper limit.
27
     *
28
     * @see tooBigMessage for the customized message used when the number is too big.
29
     */
30
    private $max;
31
    /**
32
     * @var float|int lower limit of the number. Defaults to null, meaning no lower limit.
33
     *
34
     * @see tooSmallMessage for the customized message used when the number is too small.
35
     */
36
    private $min;
37
    /**
38
     * @var string user-defined error message used when the value is bigger than {@link $max}.
39
     */
40
    private string $tooBigMessage = 'Value must be no greater than {max}.';
41
    /**
42
     * @var string user-defined error message used when the value is smaller than {@link $min}.
43
     */
44
    private string $tooSmallMessage = 'Value must be no less than {min}.';
45
    /**
46
     * @var string the regular expression for matching integers.
47
     */
48
    private string $integerPattern = '/^\s*[+-]?\d+\s*$/';
49
    /**
50
     * @var string the regular expression for matching numbers. It defaults to a pattern
51
     * that matches floating numbers with optional exponential part (e.g. -1.23e-10).
52
     */
53
    private string $numberPattern = '/^\s*[-+]?\d*\.?\d+([eE][-+]?\d+)?\s*$/';
54
55 31
    protected function validateValue($value, DataSetInterface $dataSet = null): Result
56
    {
57 31
        $result = new Result();
58
59 31
        if (!is_scalar($value)) {
60 4
            $result->addError($this->translateMessage($this->getNotANumberMessage(), ['value' => $value]));
61 4
            return $result;
62
        }
63
64 27
        $pattern = $this->asInteger ? $this->integerPattern : $this->numberPattern;
65
66 27
        if (!preg_match($pattern, NumericHelper::normalize($value))) {
67 9
            $result->addError($this->translateMessage($this->getNotANumberMessage(), ['value' => $value]));
68 24
        } elseif ($this->min !== null && $value < $this->min) {
69 10
            $result->addError($this->translateMessage($this->tooSmallMessage, ['min' => $this->min]));
70 20
        } elseif ($this->max !== null && $value > $this->max) {
71 7
            $result->addError($this->translateMessage($this->tooBigMessage, ['max' => $this->max]));
72
        }
73
74 27
        return $result;
75
    }
76
77 11
    public function integer(): self
78
    {
79 11
        $new = clone $this;
80 11
        $new->asInteger = true;
81 11
        return $new;
82
    }
83
84 15
    public function min($value): self
85
    {
86 15
        $new = clone $this;
87 15
        $new->min = $value;
88 15
        return $new;
89
    }
90
91 14
    public function max($value): self
92
    {
93 14
        $new = clone $this;
94 14
        $new->max = $value;
95 14
        return $new;
96
    }
97
98 1
    public function tooSmallMessage(string $message): self
99
    {
100 1
        $new = clone $this;
101 1
        $new->tooSmallMessage = $message;
102 1
        return $new;
103
    }
104
105
    public function tooBigMessage(string $message): self
106
    {
107
        $new = clone $this;
108
        $new->tooBigMessage = $message;
109
        return $new;
110
    }
111
112 21
    private function getNotANumberMessage(): string
113
    {
114 21
        if ($this->asInteger === true) {
115 9
            return 'Value must be an integer.';
116
        }
117 13
        return 'Value must be a number.';
118
    }
119
120 8
    public function getOptions(): array
121
    {
122 8
        return array_merge(
123 8
            parent::getOptions(),
124
            [
125 8
                'notANumberMessage' => $this->translateMessage($this->getNotANumberMessage()),
126 8
                'asInteger' => $this->asInteger,
127 8
                'min' => $this->min,
128 8
                'tooSmallMessage' => $this->translateMessage($this->tooSmallMessage, ['min' => $this->min]),
129 8
                'max' => $this->max,
130 8
                'tooBigMessage' => $this->translateMessage($this->tooBigMessage, ['max' => $this->max]),
131
            ],
132
        );
133
    }
134
}
135