Passed
Pull Request — master (#222)
by Dmitriy
02:26
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
c 0
b 0
f 0
nc 10
nop 0
dl 0
loc 23
ccs 18
cts 19
cp 0.9474
crap 10.0145
rs 7.6666

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\CompareTo;
6
7
use Attribute;
8
use Closure;
9
use InvalidArgumentException;
10
use RuntimeException;
11
use Yiisoft\Validator\Rule\RuleNameTrait;
12
use Yiisoft\Validator\Rule\HandlerClassNameTrait;
13
use Yiisoft\Validator\RuleInterface;
14
15
/**
16
 * Compares the specified value with another value.
17
 *
18
 * The value being compared with a constant {@see CompareTo::$compareValue}, which is set
19
 * in the constructor.
20
 *
21
 * It supports different comparison operators, specified
22
 * via the {@see CompareTo::$operator}.
23
 *
24
 * The default comparison function is based on string values, which means the values
25
 * are compared byte by byte. When comparing numbers, make sure to change {@see CompareTo::$type} to
26
 * {@see CompareTo::TYPE_NUMBER} to enable numeric comparison.
27
 */
28
#[Attribute(Attribute::TARGET_PROPERTY)]
29
final class CompareTo implements RuleInterface
30
{
31
    use HandlerClassNameTrait;
32
    use RuleNameTrait;
33
34
    /**
35
     * Constant for specifying the comparison as string values.
36
     * No conversion will be done before comparison.
37
     *
38
     * @see $type
39
     */
40
    public const TYPE_STRING = 'string';
41
    /**
42
     * Constant for specifying the comparison as numeric values.
43
     * String values will be converted into numbers before comparison.
44
     *
45
     * @see $type
46
     */
47
    public const TYPE_NUMBER = 'number';
48
    private array $validOperators = [
49
        '==' => 1,
50
        '===' => 1,
51
        '!=' => 1,
52
        '!==' => 1,
53
        '>' => 1,
54
        '>=' => 1,
55
        '<' => 1,
56
        '<=' => 1,
57
    ];
58
59 1
    public function __construct(
60
        /**
61
         * @var mixed the constant value to be compared with.
62
         */
63
        public          $compareValue,
64
        /**
65
         * @var string|null user-defined error message
66
         */
67
        public ?string $message = null,
68
        /**
69
         * @var string the type of the values being compared.
70
         */
71
        public string $type = self::TYPE_STRING,
72
        /**
73
         * @var string the operator for comparison. The following operators are supported:
74
         *
75
         * - `==`: check if two values are equal. The comparison is done is non-strict mode.
76
         * - `===`: check if two values are equal. The comparison is done is strict mode.
77
         * - `!=`: check if two values are NOT equal. The comparison is done is non-strict mode.
78
         * - `!==`: check if two values are NOT equal. The comparison is done is strict mode.
79
         * - `>`: check if value being validated is greater than the value being compared with.
80
         * - `>=`: check if value being validated is greater than or equal to the value being compared with.
81
         * - `<`: check if value being validated is less than the value being compared with.
82
         * - `<=`: check if value being validated is less than or equal to the value being compared with.
83
         *
84
         * When you want to compare numbers, make sure to also chabge @see CompareTo::$type} to
85
         * {@see CompareTo::TYPE_NUMBER}.
86
         */
87
        public string $operator = '==',
88
        public bool $skipOnEmpty = false,
89
        public bool $skipOnError = false,
90
        public ?Closure $when = null,
91
    ) {
92 1
        if (!isset($this->validOperators[$operator])) {
93
            throw new InvalidArgumentException("Operator \"$operator\" is not supported.");
94
        }
95
    }
96
97 22
    public function getMessage(): string
98
    {
99 22
        if ($this->message !== null) {
100 2
            return $this->message;
101
        }
102
103 20
        switch ($this->operator) {
104 20
            case '==':
105 15
            case '===':
106 6
                return 'Value must be equal to "{value}".';
107 14
            case '!=':
108 11
            case '!==':
109 7
                return 'Value must not be equal to "{value}".';
110 7
            case '>':
111 2
                return 'Value must be greater than "{value}".';
112 5
            case '>=':
113 2
                return 'Value must be greater than or equal to "{value}".';
114 3
            case '<':
115 2
                return 'Value must be less than "{value}".';
116 1
            case '<=':
117 1
                return 'Value must be less than or equal to "{value}".';
118
            default:
119
                throw new RuntimeException("Unknown operator: {$this->operator}");
120
        }
121
    }
122
123 7
    public function getOptions(): array
124
    {
125
        return [
126 7
            'compareValue' => $this->compareValue,
127
            'message' => [
128 7
                'message' => $this->getMessage(),
129 7
                'parameters' => ['value' => $this->compareValue],
130
            ],
131 7
            'type' => $this->type,
132 7
            'operator' => $this->operator,
133 7
            'skipOnEmpty' => $this->skipOnEmpty,
134 7
            'skipOnError' => $this->skipOnError,
135
        ];
136
    }
137
}
138