Passed
Push — dev ( 40f0b5...3a2e98 )
by Fike
02:50
created

Loader::exists()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AmaTeam\ElasticSearch\Entity\Annotation;
6
7
use AmaTeam\ElasticSearch\API\Annotation\Embeddable;
8
use AmaTeam\ElasticSearch\API\Entity\Descriptor;
9
use AmaTeam\ElasticSearch\API\Entity\DescriptorInterface;
10
use AmaTeam\ElasticSearch\API\Indexing;
11
use AmaTeam\ElasticSearch\API\Entity\Mapping\Structure\Mapping;
12
use AmaTeam\ElasticSearch\API\Entity\Descriptor\LoaderInterface;
13
use AmaTeam\ElasticSearch\Utility\Classes;
14
use Doctrine\Common\Annotations\AnnotationReader;
15
use ReflectionClass;
16
use ReflectionProperty;
17
18
class Loader implements LoaderInterface
19
{
20
    /**
21
     * @var AnnotationReader
22
     */
23
    private $annotationReader;
24
    /**
25
     * @var StructureAnnotationListenerInterface[]
26
     */
27
    private $classListeners = [];
28
    /**
29
     * @var PropertyAnnotationListenerInterface[]
30
     */
31
    private $propertyListeners = [];
32
33
    /**
34
     * @param AnnotationReader $annotationReader
35
     */
36
    public function __construct(AnnotationReader $annotationReader = null)
37
    {
38
        $this->annotationReader = $annotationReader ?: new AnnotationReader();
39
        $this->registerLoaders();
40
    }
41
42
    /**
43
     * @param string $className
44
     * @return bool
45
     */
46
    public function exists(string $className): bool
47
    {
48
        if (!class_exists($className)) {
49
            return false;
50
        }
51
        $reflection = new ReflectionClass($className);
52
        return (bool) $this->annotationReader->getClassAnnotation($reflection, Embeddable::class);
53
    }
54
55
    public function load(string $className): ?DescriptorInterface
56
    {
57
        $className = Classes::normalizeAbsoluteName($className);
58
        if (!$this->exists($className)) {
59
            return null;
60
        }
61
        $descriptor = new Descriptor($className, new Mapping(), new Indexing());
62
        $reflection = new ReflectionClass($className);
63
        foreach ($this->annotationReader->getClassAnnotations($reflection) as $annotation) {
64
            foreach ($this->classListeners as $listener) {
65
                $listener->accept($reflection, $descriptor, $annotation);
66
            }
67
        }
68
        foreach ($reflection->getProperties(~ReflectionProperty::IS_STATIC) as $property) {
69
            if ($property->getDeclaringClass()->getName() !== $reflection->getName()) {
70
                continue;
71
            }
72
            foreach ($this->annotationReader->getPropertyAnnotations($property) as $annotation) {
73
                foreach ($this->propertyListeners as $listener) {
74
                    $listener->accept($property, $descriptor, $annotation);
75
                }
76
            }
77
        }
78
        return $descriptor;
79
    }
80
81
    private function registerLoaders()
82
    {
83
        $this->classListeners = ListenerProvider::getClassListeners();
84
        $this->propertyListeners = ListenerProvider::getPropertyListeners();
85
    }
86
}
87