Passed
Pull Request — master (#265)
by Dmitriy
02:37
created

AttributesRulesProvider::parseRules()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5.1158

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 11
c 3
b 0
f 0
dl 0
loc 17
ccs 10
cts 12
cp 0.8333
rs 9.6111
cc 5
nc 8
nop 0
crap 5.1158
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\RulesProvider;
6
7
use Generator;
8
use ReflectionAttribute;
9
use ReflectionClass;
10
use ReflectionException;
11
use ReflectionObject;
12
use ReflectionProperty;
13
use Yiisoft\Validator\RuleInterface;
14
use Yiisoft\Validator\RulesProviderInterface;
15
16
use function is_object;
17
18
final class AttributesRulesProvider implements RulesProviderInterface
19
{
20
    private Generator|iterable|null $rules = null;
21
22 14
    public function __construct(
23
        /**
24
         * @param class-string|object $class
25
         */
26
        private string|object $source,
27
        private int $propertyVisibility = ReflectionProperty::IS_PRIVATE | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PUBLIC
28
    ) {
29
    }
30
31
    /**
32
     * @throws ReflectionException
33
     *
34
     * @return iterable
35
     */
36 14
    public function getRules(): iterable
37
    {
38 14
        if ($this->rules === null) {
39 14
            $this->rules = $this->parseRules();
40
        }
41
42 14
        yield from $this->rules;
43
    }
44
45
    /**
46
     * @throws ReflectionException
47
     *
48
     * @return Generator
49
     */
50 14
    private function parseRules(): iterable
51
    {
52 14
        $reflection = is_object($this->source)
53 5
            ? new ReflectionObject($this->source)
54 9
            : new ReflectionClass($this->source);
55
56 14
        $reflectionProperties = $reflection->getProperties($this->propertyVisibility);
57 14
        if ($reflectionProperties === []) {
58
            return [];
59
        }
60 14
        foreach ($reflectionProperties as $property) {
61 14
            $attributes = $property->getAttributes(RuleInterface::class, ReflectionAttribute::IS_INSTANCEOF);
62 14
            if ($attributes === []) {
63
                continue;
64
            }
65
66 14
            yield $property->getName() => $this->createAttributes($attributes);
67
        }
68
    }
69
70
    /**
71
     * @param array<array-key, ReflectionAttribute<RuleInterface>> $attributes
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array-key, Reflect...tribute<RuleInterface>> at position 2 could not be parsed: Unknown type name 'array-key' at position 2 in array<array-key, ReflectionAttribute<RuleInterface>>.
Loading history...
72
     *
73
     * @return iterable
74
     */
75 14
    private function createAttributes(array $attributes): iterable
76
    {
77 14
        foreach ($attributes as $attribute) {
78 14
            yield $attribute->newInstance();
79
        }
80
    }
81
}
82