Passed
Pull Request — master (#175)
by Alexander
02:36
created

Number::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 43
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 11
dl 0
loc 43
ccs 2
cts 2
cp 1
crap 1
rs 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use Attribute;
8
use Yiisoft\Strings\NumericHelper;
9
use Yiisoft\Validator\FormatterInterface;
10
use Yiisoft\Validator\Result;
11
use Yiisoft\Validator\Rule;
12
use Yiisoft\Validator\ValidationContext;
13
14
/**
15
 * NumberValidator validates that the attribute value is a number.
16
 *
17
 * The format of the number must match the regular expression specified in {@see Number::$integerPattern}
18
 * or {@see Number::$numberPattern}. Optionally, you may configure the {@see Number::min()} and {@see Number::max()}
19
 * to ensure the number is within certain range.
20
 */
21
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
22
final class Number extends Rule
23
{
24 39
    public function __construct(
25
        /**
26
         * @var bool whether the attribute value can only be an integer. Defaults to false.
27
         */
28
        private bool $asInteger = false,
29
        /**
30
         * @var float|int lower limit of the number. Defaults to null, meaning no lower limit.
31
         *
32
         * @see tooSmallMessage for the customized message used when the number is too small.
33
         */
34
        private $min = null,
35
        /**
36
         * @var float|int upper limit of the number. Defaults to null, meaning no upper limit.
37
         *
38
         * @see tooBigMessage for the customized message used when the number is too big.
39
         */
40
        private $max = null,
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 user-defined error message used when the value is bigger than {@link $max}.
47
         */
48
        private string $tooBigMessage = 'Value must be no greater than {max}.',
49
        /**
50
         * @var string the regular expression for matching integers.
51
         */
52
        private string $integerPattern = '/^\s*[+-]?\d+\s*$/',
53
        /**
54
         * @var string the regular expression for matching numbers. It defaults to a pattern
55
         * that matches floating numbers with optional exponential part (e.g. -1.23e-10).
56
         */
57
        private string $numberPattern = '/^\s*[-+]?\d*\.?\d+([eE][-+]?\d+)?\s*$/',
58
        ?FormatterInterface $formatter = null,
59
        bool $skipOnEmpty = false,
60
        bool $skipOnError = false,
61
        /**
62
         * @var callable|null
63
         */
64
        $when = null,
65
    ) {
66 39
        parent::__construct($formatter, $skipOnEmpty, $skipOnError, $when);
67
    }
68
69 39
    protected function validateValue($value, ?ValidationContext $context = null): Result
70
    {
71 39
        $result = new Result();
72
73 39
        if (is_bool($value) || !is_scalar($value)) {
74 5
            $result->addError($this->formatMessage($this->getNotANumberMessage(), ['value' => $value]));
75 5
            return $result;
76
        }
77
78 34
        $pattern = $this->asInteger ? $this->integerPattern : $this->numberPattern;
79
80 34
        if (!preg_match($pattern, NumericHelper::normalize($value))) {
81 9
            $result->addError($this->formatMessage($this->getNotANumberMessage(), ['value' => $value]));
82 31
        } elseif ($this->min !== null && $value < $this->min) {
83 14
            $result->addError($this->formatMessage($this->tooSmallMessage, ['min' => $this->min]));
84 25
        } elseif ($this->max !== null && $value > $this->max) {
85 9
            $result->addError($this->formatMessage($this->tooBigMessage, ['max' => $this->max]));
86
        }
87
88 34
        return $result;
89
    }
90
91 23
    private function getNotANumberMessage(): string
92
    {
93 23
        return $this->asInteger ? 'Value must be an integer.' : 'Value must be a number.';
94
    }
95
96 9
    public function getOptions(): array
97
    {
98 9
        return array_merge(
99 9
            parent::getOptions(),
100
            [
101 9
                'asInteger' => $this->asInteger,
102 9
                'min' => $this->min,
103 9
                'max' => $this->max,
104 9
                'notANumberMessage' => $this->formatMessage($this->getNotANumberMessage()),
105 9
                'tooSmallMessage' => $this->formatMessage($this->tooSmallMessage, ['min' => $this->min]),
106 9
                'tooBigMessage' => $this->formatMessage($this->tooBigMessage, ['max' => $this->max]),
107
            ],
108
        );
109
    }
110
}
111