Passed
Push — master ( ad4b0f...2b9312 )
by Alexander
02:17
created

NumberValidator::validateAttribute()   C

Complexity

Conditions 12
Paths 65

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 0
cts 20
cp 0
rs 5.2987
c 0
b 0
f 0
cc 12
eloc 14
nc 65
nop 2
crap 156

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Horat1us\Yii\Validators;
4
5
use Yii;
6
use yii\helpers\StringHelper;
7
use yii\validators\Validator;
8
9
/**
10
 * NumberValidator validates that the attribute value is a number.
11
 *
12
 * The format of the number must match the regular expression specified in [[integerPattern]] or [[numberPattern]].
13
 * Optionally, you may configure the [[max]] and [[min]] properties to ensure the number
14
 * is within certain range.
15
 *
16
 * Difference from original yii2 number validator is possibility to set min and max as callables
17
 *
18
 * @author Alexander Letnikow <[email protected]>
19
 * @since 2.0
20
 */
21
class NumberValidator extends Validator
22
{
23
    /**
24
     * @var bool whether the attribute value can only be an integer. Defaults to false.
25
     */
26
    public $integerOnly = false;
27
    /**
28
     * @var int|float|callable upper limit of the number. Defaults to null, meaning no upper limit.
29
     * @see tooBig for the customized message used when the number is too big.
30
     */
31
    public $max;
32
    /**
33
     * @var int|float|callable lower limit of the number. Defaults to null, meaning no lower limit.
34
     * @see tooSmall for the customized message used when the number is too small.
35
     */
36
    public $min;
37
    /**
38
     * @var string user-defined error message used when the value is bigger than [[max]].
39
     */
40
    public $tooBig;
41
    /**
42
     * @var string user-defined error message used when the value is smaller than [[min]].
43
     */
44
    public $tooSmall;
45
    /**
46
     * @var string the regular expression for matching integers.
47
     */
48
    public $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
    public $numberPattern = '/^\s*[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\s*$/';
54
55
56
    /**
57
     * @inheritdoc
58
     */
59
    public function init()
60
    {
61
        parent::init();
62
        if ($this->message === null) {
63
            $this->message = $this->integerOnly ? Yii::t('yii', '{attribute} must be an integer.')
64
                : Yii::t('yii', '{attribute} must be a number.');
65
        }
66
        if ($this->min !== null && $this->tooSmall === null) {
67
            $this->tooSmall = Yii::t('yii', '{attribute} must be no less than {min}.');
68
        }
69
        if ($this->max !== null && $this->tooBig === null) {
70
            $this->tooBig = Yii::t('yii', '{attribute} must be no greater than {max}.');
71
        }
72
    }
73
74
    /**
75
     * @inheritdoc
76
     */
77
    public function validateAttribute($model, $attribute)
78
    {
79
        $value = $model->$attribute;
80
        if (is_array($value) || (is_object($value) && !method_exists($value, '__toString'))) {
81
            $this->addError($model, $attribute, $this->message);
82
            return;
83
        }
84
        $pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern;
85
86
        if (!preg_match($pattern, StringHelper::normalizeNumber($value))) {
87
            $this->addError($model, $attribute, $this->message);
88
        }
89
90
        $min = is_callable($this->min) ? call_user_func($this->min) : $this->min;
91
        if ($min !== null && $value < $min) {
92
            $this->addError($model, $attribute, $this->tooSmall, ['min' => $min]);
93
        }
94
95
        $max = is_callable($this->max) ? call_user_func($this->max) : $this->max;
96
        if ($max !== null && $value > $max) {
97
            $this->addError($model, $attribute, $this->tooBig, ['max' => $max]);
98
        }
99
    }
100
101
    /**
102
     * @inheritdoc
103
     */
104
    protected function validateValue($value)
105
    {
106
        if (is_array($value) || is_object($value)) {
107
            return [Yii::t('yii', '{attribute} is invalid.'), []];
108
        }
109
        $pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern;
110
        if (!preg_match($pattern, StringHelper::normalizeNumber($value))) {
111
            return [$this->message, []];
112
        } elseif (
113
            $this->min !== null
114
            && $value < ($min = (is_callable($this->min) ? call_user_func($this->min) : $this->min))
115
        ) {
116
            return [$this->tooSmall, ['min' => $min]];
117
        } elseif (
118
            $this->max !== null
119
            && $value > ($max = (is_callable($this->max) ? call_user_func($this->max) : $this->max))
120
        ) {
121
            return [$this->tooBig, ['max' => $max]];
122
        }
123
124
        return null;
125
    }
126
}
127