Passed
Pull Request — master (#222)
by Alexander
05:06 queued 02:29
created

CompareToValidator   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Test Coverage

Coverage 89.66%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 32
c 1
b 0
f 0
dl 0
loc 66
ccs 26
cts 29
cp 0.8966
rs 10
wmc 12

2 Methods

Rating   Name   Duplication   Size   Complexity  
A validate() 0 9 2
B compareValues() 0 28 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule\CompareTo;
6
7
use Yiisoft\Validator\Result;
8
use Yiisoft\Validator\Rule\RuleValidatorInterface;
9
use Yiisoft\Validator\ValidationContext;
10
use Yiisoft\Validator\ValidatorInterface;
11
12
/**
13
 * Compares the specified value with another value.
14
 *
15
 * The value being compared with a constant {@see CompareTo::$compareValue}, which is set
16
 * in the constructor.
17
 *
18
 * It supports different comparison operators, specified
19
 * via the {@see CompareTo::$operator}.
20
 *
21
 * The default comparison function is based on string values, which means the values
22
 * are compared byte by byte. When comparing numbers, make sure to change {@see CompareTo::$type} to
23
 * {@see CompareTo::TYPE_NUMBER} to enable numeric comparison.
24
 */
25
final class CompareToValidator implements RuleValidatorInterface
26
{
27
    /**
28
     * Constant for specifying the comparison as string values.
29
     * No conversion will be done before comparison.
30
     *
31
     * @see $type
32
     */
33
    public const TYPE_STRING = 'string';
34
    /**
35
     * Constant for specifying the comparison as numeric values.
36
     * String values will be converted into numbers before comparison.
37
     *
38
     * @see $type
39
     */
40
    public const TYPE_NUMBER = 'number';
41
42 30
    public function validate(mixed $value, object $rule, ValidatorInterface $validator, ?ValidationContext $context = null): Result
43
    {
44 30
        $result = new Result();
45
46 30
        if (!$this->compareValues($rule->operator, $rule->type, $value, $rule->compareValue)) {
47 15
            $result->addError($rule->getMessage(), ['value' => $rule->compareValue]);
48
        }
49
50 30
        return $result;
51
    }
52
53
    /**
54
     * Compares two values with the specified operator.
55
     *
56
     * @param string $operator the comparison operator
57
     * @param string $type the type of the values being compared
58
     * @param mixed $value the value being compared
59
     * @param mixed $compareValue another value being compared
60
     *
61
     * @return bool whether the comparison using the specified operator is true.
62
     */
63 30
    private function compareValues(string $operator, string $type, $value, $compareValue): bool
64
    {
65 30
        if ($type === self::TYPE_NUMBER) {
66
            $value = (float) $value;
67
            $compareValue = (float)$compareValue;
68
        } else {
69 30
            $value = (string) $value;
70 30
            $compareValue = (string) $compareValue;
71
        }
72 30
        switch ($operator) {
73 30
            case '==':
74 5
                return $value == $compareValue;
75 25
            case '===':
76 4
                return $value === $compareValue;
77 21
            case '!=':
78 5
                return $value != $compareValue;
79 16
            case '!==':
80 4
                return $value !== $compareValue;
81 12
            case '>':
82 3
                return $value > $compareValue;
83 9
            case '>=':
84 3
                return $value >= $compareValue;
85 6
            case '<':
86 3
                return $value < $compareValue;
87 3
            case '<=':
88 3
                return $value <= $compareValue;
89
            default:
90
                return false;
91
        }
92
    }
93
}
94