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

AttributesRulesProvider::createAttributes()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
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
final class AttributesRulesProvider implements RulesProviderInterface
17
{
18
    /**
19
     * @var Generator|null
20
     */
21
    private Generator|null $rules = null;
22
23 13
    public function __construct(
24
        /**
25
         * @param class-string|object $class
26
         */
27
        private string|object $source,
28
        private int $propertyVisibility = ReflectionProperty::IS_PRIVATE | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PUBLIC
29
    ) {
30
    }
31
32
    /**
33
     * @return iterable
34
     * @throws ReflectionException
35
     */
36 13
    public function getRules(): iterable
37
    {
38 13
        if ($this->rules === null) {
39 13
            $this->rules = $this->parseRules();
40
        }
41
42 13
        yield from $this->rules;
43
    }
44
45
    /**
46
     * @return Generator
47
     * @throws ReflectionException
48
     */
49 13
    private function parseRules(): iterable
50
    {
51 13
        $reflection = is_object($this->source)
52 5
            ? new ReflectionObject($this->source)
53 8
            : new ReflectionClass($this->source);
54
55 13
        $reflectionProperties = $reflection->getProperties();
56 13
        if ($reflectionProperties === []) {
57
            return [];
58
        }
59 13
        foreach ($reflectionProperties as $property) {
60 13
            if (!$this->isUseProperty($property)) {
61 7
                continue;
62
            }
63
64 13
            $attributes = $property->getAttributes(RuleInterface::class, ReflectionAttribute::IS_INSTANCEOF);
65 13
            if ($attributes === []) {
66
                continue;
67
            }
68
69 13
            yield $property->getName() => $this->createAttributes($attributes);
70
        }
71
    }
72
73
    /**
74
     * @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...
75
     *
76
     * @return iterable
77
     */
78 13
    private function createAttributes(array $attributes): iterable
79
    {
80 13
        foreach ($attributes as $attribute) {
81 13
            yield $attribute->newInstance();
82
        }
83
    }
84
85 13
    private function isUseProperty(ReflectionProperty $property): bool
86
    {
87 13
        return ($property->isPublic() && ($this->propertyVisibility & ReflectionProperty::IS_PUBLIC))
88 12
            || ($property->isPrivate() && ($this->propertyVisibility & ReflectionProperty::IS_PRIVATE))
89 13
            || ($property->isProtected() && ($this->propertyVisibility & ReflectionProperty::IS_PROTECTED));
90
    }
91
}
92