Passed
Pull Request — master (#248)
by Rustam
03:00
created

LessThanHandler::validate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
c 1
b 0
f 0
dl 0
loc 24
ccs 14
cts 14
cp 1
rs 9.7998
cc 3
nc 3
nop 3
crap 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use Yiisoft\Validator\Exception\UnexpectedRuleException;
8
use Yiisoft\Validator\Formatter;
9
use Yiisoft\Validator\FormatterInterface;
10
use Yiisoft\Validator\Result;
11
use Yiisoft\Validator\ValidationContext;
12
13
/**
14
 * Validates if the specified value is less than another value or attribute.
15
 *
16
 * The value being validated with {@see LessThan::$targetValue} or {@see LessThan::$targetAttribute}, which
17
 * is set in the constructor.
18
 *
19
 * The default validation function is based on string values, which means the values
20
 * are compared byte by byte. When validating numbers, make sure to change {@see LessThan::$type} to
21
 * {@see LessThan::TYPE_NUMBER} to enable numeric validation.
22
 */
23
final class LessThanHandler implements RuleHandlerInterface
24
{
25
    private FormatterInterface $formatter;
26
27 8
    public function __construct(?FormatterInterface $formatter = null)
28
    {
29 8
        $this->formatter = $formatter ?? new Formatter();
30
    }
31
32 8
    public function validate(mixed $value, object $rule, ?ValidationContext $context = null): Result
33
    {
34 8
        if (!$rule instanceof LessThan) {
35 1
            throw new UnexpectedRuleException(LessThan::class, $rule);
36
        }
37
38 7
        $result = new Result();
39 7
        $targetValue = $rule->getTargetValue() ?? $context?->getDataSet()?->getAttributeValue($rule->getTargetAttribute());
0 ignored issues
show
Bug introduced by
It seems like $rule->getTargetAttribute() can also be of type null; however, parameter $attribute of Yiisoft\Validator\DataSe...ce::getAttributeValue() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

39
        $targetValue = $rule->getTargetValue() ?? $context?->getDataSet()?->getAttributeValue(/** @scrutinizer ignore-type */ $rule->getTargetAttribute());
Loading history...
40
41 7
        if (!$this->isLessThan($value, $targetValue, $rule->getType())) {
42 4
            $formattedMessage = $this->formatter->format(
43 4
                $rule->getMessage(),
44
                [
45 4
                    'attribute' => $context?->getAttribute(),
46 4
                    'targetAttribute' => $rule->getTargetValue(),
47 4
                    'targetValue' => $rule->getTargetValue(),
48 4
                    'targetValueOrAttribute' => $rule->getTargetValue() ?? $rule->getTargetAttribute(),
49
                    'value' => $value,
50
                ]
51
            );
52 4
            $result->addError($formattedMessage);
53
        }
54
55 7
        return $result;
56
    }
57
58 7
    private function isLessThan(mixed $value, mixed $targetValue, string $type): bool
59
    {
60 7
        if ($type === LessThan::TYPE_NUMBER) {
61
            $value = (float)$value;
62
            $targetValue = (float)$targetValue;
63
        } else {
64 7
            $value = (string)$value;
65 7
            $targetValue = (string)$targetValue;
66
        }
67
68 7
        return $value < $targetValue;
69
    }
70
}
71