Passed
Pull Request — master (#222)
by Rustam
02:28
created

CompareTo::getMessage()   B

Complexity

Conditions 10
Paths 10

Size

Total Lines 23
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 10.0145

Importance

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