Passed
Push — master ( 8f8432...bddb5e )
by Bukashk0zzz
03:15
created

Filter   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 29
c 4
b 0
f 0
dl 0
loc 73
rs 10
wmc 12

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A filterEntity() 0 28 6
A getAttributes() 0 22 5
1
<?php declare(strict_types = 1);
2
3
namespace Bukashk0zzz\FilterBundle\Service;
4
5
use Bukashk0zzz\FilterBundle\Annotation\FilterAnnotation;
6
use Doctrine\Common\Annotations\Reader;
7
use Doctrine\Common\Util\ClassUtils;
8
use Laminas\Filter\FilterChain;
9
use ReflectionProperty;
10
11
/**
12
 * Class Filter.
13
 */
14
class Filter
15
{
16
    /**
17
     * @var Reader Cached annotation reader
18
     */
19
    protected $annotationReader;
20
21
    /**
22
     * Filter constructor.
23
     */
24
    public function __construct(Reader $annotationReader)
25
    {
26
        $this->annotationReader = $annotationReader;
27
    }
28
29
    public function filterEntity(mixed $object): void
30
    {
31
        if ($object === null) {
32
            return;
33
        }
34
35
        $reflectionClass = ClassUtils::newReflectionClass($object::class);
36
37
        foreach ($reflectionClass->getProperties() as $property) {
38
            $attributes = $this->getAttributes($property);
39
40
            if (empty($attributes)) {
41
                continue;
42
            }
43
44
            $property->setAccessible(true);
45
            $value = $property->getValue($object);
46
47
            if (empty($value)) {
48
                continue;
49
            }
50
51
            $filter = new FilterChain();
52
            foreach ($attributes as $attribute) {
53
                $filter->attachByName($attribute->getFilter(), $attribute->getOptions());
54
            }
55
56
            $property->setValue($object, $filter->filter($value));
57
        }
58
    }
59
60
    /**
61
     * Get Annotations of PHP Attributes.
62
     *
63
     * @return array<FilterAnnotation>
64
     */
65
    private function getAttributes(ReflectionProperty $property): array
66
    {
67
        $annotations = $this->annotationReader->getPropertyAnnotations($property);
68
69
        $attributes = [];
70
        foreach ($annotations as $annotation) {
71
            if ($annotation instanceof FilterAnnotation) {
72
                $attributes[] = $annotation;
73
            }
74
        }
75
76
        // If we get an empty array with the annotations, we try PHP Attributes
77
        if (empty($attributes)) {
78
            $attrs = $property->getAttributes(FilterAnnotation::class);
79
80
            $attributes = [];
81
            foreach ($attrs as $attr) {
82
                $attributes[] = $attr->newInstance();
83
            }
84
        }
85
86
        return $attributes;
87
    }
88
}
89