ValidationSet::rules()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace BrenoRoosevelt\Validation;
5
6
use BrenoRoosevelt\Validation\Rules\NotRequired;
7
use ReflectionAttribute;
8
use ReflectionClass;
9
use ReflectionException;
10
use ReflectionProperty;
11
12
/**
13
 * Composite
14
 */
15
final class ValidationSet implements Validation
16
{
17
    use GuardForValidation,
18
        MaybeBelongsToField;
19
20
    /** @var Validation[] */
21
    private array $rules;
22
23
    public static function new(): self
24
    {
25
        return new self;
26
    }
27
28
    public function add(Validation ...$rules): self
29
    {
30
        array_push($this->rules, ...$rules);
31
        return $this;
32
    }
33
34
    public function validate($input, array $context = []): ValidationResult|ValidationResultByField
35
    {
36
        $violations = $this->newEmptyValidationResult();
37
        foreach ($this->rules as $constraint) {
38
            $violations->error(...$constraint->validate($input, $context)->getErrors());
39
        }
40
41
        return $violations;
42
    }
43
44
    public function isRequired(): bool
45
    {
46
        foreach ($this->rules as $rule) {
47
            if ($rule instanceof NotRequired) {
48
                return false;
49
            }
50
        }
51
52
        return true;
53
    }
54
55
    public function notRequired(): self
56
    {
57
        if ($this->isRequired()) {
58
            $this->rules[] = new NotRequired;
59
        }
60
61
        return $this;
62
    }
63
64
    public function isEmpty(): bool
65
    {
66
        return empty($this->rules);
67
    }
68
69
    /**
70
     * @param string|object $objectOrClass
71
     * @return array
72
     * @throws ReflectionException
73
     */
74
    public static function fromProperties(string|object $objectOrClass): array
75
    {
76
        $ruleSets = [];
77
        foreach ((new ReflectionClass($objectOrClass))->getProperties() as $property) {
78
            $ruleSets[$property->getName()] = ValidationSet::fromReflectionProperty($property);
79
        }
80
81
        return array_filter($ruleSets, fn(ValidationSet $c) => !$c->isEmpty());
82
    }
83
84
    /**
85
     * @param string|object $objectOrClass
86
     * @param string $property
87
     * @return static
88
     * @throws ReflectionException
89
     */
90
    public static function fromProperty(string|object $objectOrClass, string $property): self
91
    {
92
        return self::fromReflectionProperty(new ReflectionProperty($objectOrClass, $property));
93
    }
94
95
    /**
96
     * @param ReflectionProperty $property
97
     * @return static
98
     */
99
    public static function fromReflectionProperty(ReflectionProperty $property): self
100
    {
101
        $ruleSet = new self;
102
        $ruleSet->rules = array_map(
103
            fn(ReflectionAttribute $attribute) => $attribute->newInstance(),
104
            $property->getAttributes(Validation::class, ReflectionAttribute::IS_INSTANCEOF)
105
        );
106
        $ruleSet->setField($property->getName());
107
        return $ruleSet;
108
    }
109
110
    /** @return Validation[] */
111
    public function rules(): array
112
    {
113
        return $this->rules;
114
    }
115
}
116