Completed
Push — master ( 821934...7a99c7 )
by Vincent
08:31 queued 45s
created

ConstraintValueValidator::hasConstraints()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Bdf\Form\Validator;
4
5
use Bdf\Form\ElementInterface;
6
use Bdf\Form\Error\FormError;
7
use Exception;
8
use Symfony\Component\Validator\Constraint;
9
10
/**
11
 * Value validator using symfony constraint
12
 * The element will be used as "root" context object on the symfony validator
13
 *
14
 * @template T
15
 * @implements ValueValidatorInterface<T>
16
 */
17
final class ConstraintValueValidator implements ValueValidatorInterface
18
{
19
    /**
20
     * @var self
21
     */
22
    private static $emptyInstance;
23
24
    /**
25
     * @var Constraint[]
26
     */
27
    private $constraints;
28
29
    /**
30
     * @var TransformerExceptionConstraint
31
     */
32
    private $transformerExceptionConstraint;
33
34
35
    /**
36
     * ConstraintValueValidator constructor.
37
     *
38
     * @param Constraint[] $constraints
39
     * @param TransformerExceptionConstraint|null $transformerExceptionConstraint
40
     */
41 417
    public function __construct(array $constraints = [], ?TransformerExceptionConstraint $transformerExceptionConstraint = null)
42
    {
43 417
        $this->constraints = $constraints;
44 417
        $this->transformerExceptionConstraint = $transformerExceptionConstraint ?? new TransformerExceptionConstraint();
45 417
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 399
    public function validate($value, ElementInterface $element): FormError
51
    {
52 399
        if (!$this->constraints) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->constraints of type Symfony\Component\Validator\Constraint[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
53 205
            return FormError::null();
54
        }
55
56 224
        $root = $element->root();
57 224
        $groups = $root->constraintGroups();
58
59
        /** @psalm-suppress TooManyArguments */
60 224
        $context = $root->getValidator()->startContext($element);
0 ignored issues
show
Unused Code introduced by
The call to Symfony\Component\Valida...terface::startContext() has too many arguments starting with $element. ( Ignorable by Annotation )

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

60
        $context = $root->getValidator()->/** @scrutinizer ignore-call */ startContext($element);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
61
62 224
        foreach ($this->constraints as $constraint) {
63 224
            $errors = $context->validate($value, $constraint, $groups)->getViolations();
64
65 224
            if ($errors->has(0)) {
66 188
                return FormError::violation($errors->get(0));
67
            }
68
        }
69
70 115
        return FormError::null();
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76 38
    public function onTransformerException(Exception $exception, $value, ElementInterface $element): FormError
77
    {
78 38
        if ($this->transformerExceptionConstraint->ignoreException) {
79 17
            return FormError::null();
80
        }
81
82
        /** @psalm-suppress TooManyArguments */
83 22
        $errors = $element->root()
84 22
            ->getValidator()
85 22
            ->startContext($element)
0 ignored issues
show
Unused Code introduced by
The call to Symfony\Component\Valida...terface::startContext() has too many arguments starting with $element. ( Ignorable by Annotation )

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

85
            ->/** @scrutinizer ignore-call */ startContext($element)

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
86 22
            ->validate($value, $this->transformerExceptionConstraint->withException($exception))
87 22
            ->getViolations()
88
        ;
89
90 22
        if ($errors->has(0)) {
91 22
            return FormError::violation($errors->get(0));
92
        }
93
94 1
        return FormError::null();
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100 46
    public function constraints(): array
101
    {
102 46
        return $this->constraints;
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108 54
    public function hasConstraints(): bool
109
    {
110 54
        return !empty($this->constraints);
111
    }
112
113
    /**
114
     * Get the empty value validator instance
115
     *
116
     * @return ConstraintValueValidator<mixed>
117
     */
118 329
    public static function empty(): self
119
    {
120 329
        if (self::$emptyInstance) {
121 329
            return self::$emptyInstance;
122
        }
123
124 1
        return self::$emptyInstance = new self();
125
    }
126
}
127