Test Failed
Pull Request — master (#222)
by Rustam
02:30
created

CompareTo::compareValues()   B

Complexity

Conditions 10
Paths 18

Size

Total Lines 28
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 10.1953

Importance

Changes 0
Metric Value
cc 10
eloc 25
nc 18
nop 4
dl 0
loc 28
ccs 21
cts 24
cp 0.875
crap 10.1953
rs 7.6666
c 0
b 0
f 0

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
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use Attribute;
8
use Closure;
9
use InvalidArgumentException;
10
use JetBrains\PhpStorm\ArrayShape;
11
use RuntimeException;
12
use Yiisoft\Validator\Rule\Trait\RuleNameTrait;
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_TRAIT, expecting T_STRING or '{' on line 12 at column 27
Loading history...
13
use Yiisoft\Validator\Rule\Trait\HandlerClassNameTrait;
14
use Yiisoft\Validator\ParametrizedRuleInterface;
15
16
/**
17
 * Compares the specified value with another value.
18
 *
19
 * The value being compared with a constant {@see CompareTo::$compareValue}, which is set
20
 * in the constructor.
21
 *
22
 * It supports different comparison operators, specified
23
 * via the {@see CompareTo::$operator}.
24
 *
25
 * The default comparison function is based on string values, which means the values
26
 * are compared byte by byte. When comparing numbers, make sure to change {@see CompareTo::$type} to
27
 * {@see CompareTo::TYPE_NUMBER} to enable numeric comparison.
28
 */
29
#[Attribute(Attribute::TARGET_PROPERTY)]
30
final class CompareTo implements ParametrizedRuleInterface
31
{
32
    use HandlerClassNameTrait;
33
    use RuleNameTrait;
34
35
    /**
36
     * Constant for specifying the comparison as string values.
37
     * No conversion will be done before comparison.
38
     *
39
     * @see $type
40
     */
41
    public const TYPE_STRING = 'string';
42
    /**
43
     * Constant for specifying the comparison as numeric values.
44
     * String values will be converted into numbers before comparison.
45
     *
46
     * @see $type
47
     */
48
    public const TYPE_NUMBER = 'number';
49
    private array $validOperators = [
50
        '==' => 1,
51
        '===' => 1,
52
        '!=' => 1,
53
        '!==' => 1,
54
        '>' => 1,
55
        '>=' => 1,
56 30
        '<' => 1,
57
        '<=' => 1,
58
    ];
59
60
    public function __construct(
61
        /**
62
         * @var mixed the constant value to be compared with.
63
         */
64
        private $compareValue,
65
        /**
66
         * @var string|null user-defined error message
67
         */
68
        private ?string $message = null,
69
        /**
70
         * @var string the type of the values being compared.
71
         */
72
        private string $type = self::TYPE_STRING,
73
        /**
74
         * @var string the operator for comparison. The following operators are supported:
75
         *
76
         * - `==`: check if two values are equal. The comparison is done is non-strict mode.
77
         * - `===`: check if two values are equal. The comparison is done is strict mode.
78
         * - `!=`: check if two values are NOT equal. The comparison is done is non-strict mode.
79
         * - `!==`: check if two values are NOT equal. The comparison is done is strict mode.
80
         * - `>`: check if value being validated is greater than the value being compared with.
81
         * - `>=`: check if value being validated is greater than or equal to the value being compared with.
82
         * - `<`: check if value being validated is less than the value being compared with.
83
         * - `<=`: check if value being validated is less than or equal to the value being compared with.
84
         *
85
         * When you want to compare numbers, make sure to also chabge @see CompareTo::$type} to
86
         * {@see CompareTo::TYPE_NUMBER}.
87
         */
88
        private string $operator = '==',
89
        private bool $skipOnEmpty = false,
90 30
        private bool $skipOnError = false,
91
        private ?Closure $when = null,
92 30
    ) {
93
        if (!isset($this->validOperators[$operator])) {
94
            throw new InvalidArgumentException("Operator \"$operator\" is not supported.");
95
        }
96
    }
97 21
98
    /**
99 21
     * @return mixed
100 1
     */
101
    public function getCompareValue(): mixed
102
    {
103 20
        return $this->compareValue;
104 20
    }
105 15
106 6
    /**
107 14
     * @return string
108 11
     */
109 7
    public function getType(): string
110 7
    {
111 2
        return $this->type;
112 5
    }
113 2
114 3
    /**
115 2
     * @return string
116 1
     */
117 1
    public function getOperator(): string
118
    {
119
        return $this->operator;
120
    }
121
122
    /**
123 29
     * @return bool
124
     */
125 29
    public function isSkipOnEmpty(): bool
126
    {
127 29
        return $this->skipOnEmpty;
128 14
    }
129 14
130
    /**
131
     * @return bool
132 29
     */
133
    public function isSkipOnError(): bool
134
    {
135
        return $this->skipOnError;
136
    }
137
138
    /**
139
     * @return Closure|null
140
     */
141
    public function getWhen(): ?Closure
142
    {
143
        return $this->when;
144
    }
145 29
146
    public function getMessage(): string
147 29
    {
148
        return $this->message ?? match ($this->operator) {
149
            '==', '===' => 'Value must be equal to "{value}".',
150
                '!=', '!==' => 'Value must not be equal to "{value}".',
151 29
                '>' => 'Value must be greater than "{value}".',
152 29
                '>=' => 'Value must be greater than or equal to "{value}".',
153
                '<' => 'Value must be less than "{value}".',
154 29
                '<=' => 'Value must be less than or equal to "{value}".',
155 29
                default => throw new RuntimeException("Unknown operator: {$this->operator}"),
156 4
        };
157 25
    }
158 4
159 21
    #[ArrayShape([
160 5
        'compareValue' => '',
161 16
        'message' => 'array',
162 4
        'type' => 'string',
163 12
        'operator' => 'string',
164 3
        'skipOnEmpty' => 'bool',
165 9
        'skipOnError' => 'bool',
166 3
    ])]
167 6
    public function getOptions(): array
168 3
    {
169 3
        return [
170 3
            'compareValue' => $this->compareValue,
171
            'message' => [
172
                'message' => $this->getMessage(),
173
                'parameters' => ['value' => $this->compareValue],
174
            ],
175
            'type' => $this->type,
176 7
            'operator' => $this->operator,
177
            'skipOnEmpty' => $this->skipOnEmpty,
178 7
            'skipOnError' => $this->skipOnError,
179 7
        ];
180 7
    }
181
}
182