Passed
Push — feature/initial-implementation ( 79751f...3b7c72 )
by Fike
01:53
created

Loader::__construct()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AmaTeam\ElasticSearch\Entity\Annotation;
6
7
use AmaTeam\ElasticSearch\API\Annotation\Document;
8
use AmaTeam\ElasticSearch\API\Annotation\Mapped;
9
use AmaTeam\ElasticSearch\API\Entity\EntityInterface;
10
use AmaTeam\ElasticSearch\API\Entity\LoaderInterface;
11
use AmaTeam\ElasticSearch\Entity\Annotation\Indexing\DocumentAnnotationListener;
12
use AmaTeam\ElasticSearch\Entity\Annotation\Listener\Mapping\Clazz\ClassParameterAnnotationListener;
13
use AmaTeam\ElasticSearch\Entity\Annotation\Listener\Mapping\Clazz\ClassTypeAnnotationListener;
14
use AmaTeam\ElasticSearch\Entity\Annotation\Listener\Mapping\Property\PropertyForcedViewsAnnotationListener;
15
use AmaTeam\ElasticSearch\Entity\Annotation\Listener\Mapping\Property\PropertyParameterAnnotationListener;
16
use AmaTeam\ElasticSearch\Entity\Annotation\Listener\Mapping\Property\PropertyTargetClassAnnotationListener;
17
use AmaTeam\ElasticSearch\Entity\Annotation\Listener\Mapping\Property\PropertyTypeAnnotationListener;
18
use AmaTeam\ElasticSearch\Entity\Entity;
19
use AmaTeam\ElasticSearch\Entity\Mapping\ClassMapping;
20
use Doctrine\Common\Annotations\AnnotationReader;
21
use ReflectionClass;
22
use ReflectionProperty;
23
24
class Loader implements LoaderInterface
25
{
26
    /**
27
     * @var AnnotationReader
28
     */
29
    private $annotationReader;
30
    /**
31
     * @var ClassAnnotationListenerInterface[]
32
     */
33
    private $classListeners = [];
34
    /**
35
     * @var PropertyAnnotationListenerInterface[]
36
     */
37
    private $propertyListeners = [];
38
39
    /**
40
     * @param AnnotationReader $annotationReader
41
     */
42
    public function __construct(AnnotationReader $annotationReader = null)
43
    {
44
        $this->annotationReader = $annotationReader ?: new AnnotationReader();
45
        $this->registerLoaders();
46
    }
47
48
    /**
49
     * @param string $className
50
     * @return bool
51
     */
52
    public function exists(string $className): bool
53
    {
54
        if (!class_exists($className)) {
55
            return false;
56
        }
57
        $reflection = new ReflectionClass($className);
58
        if ($this->annotationReader->getClassAnnotation($reflection, Mapped::class)) {
59
            return true;
60
        }
61
        return (bool) $this->annotationReader->getClassAnnotation($reflection, Document::class);
62
    }
63
64
    public function load(string $className): ?EntityInterface
65
    {
66
        if (!$this->exists($className)) {
67
            return null;
68
        }
69
        $entity = new Entity(new ClassMapping($className));
70
        $class = new ReflectionClass($className);
71
        foreach ($this->annotationReader->getClassAnnotations($class) as $annotation) {
72
            foreach ($this->classListeners as $listener) {
73
                $listener->accept($class, $entity, $annotation);
74
            }
75
        }
76
        foreach ($class->getProperties(~ReflectionProperty::IS_STATIC) as $property) {
77
            foreach ($this->annotationReader->getPropertyAnnotations($property) as $annotation) {
78
                foreach ($this->propertyListeners as $listener) {
79
                    $listener->accept($property, $entity, $annotation);
80
                }
81
            }
82
        }
83
        return $entity;
84
    }
85
86
    private function registerLoaders()
87
    {
88
        $this->classListeners = [
89
            new DocumentAnnotationListener(),
90
            new ClassParameterAnnotationListener(),
91
            new ClassTypeAnnotationListener(),
92
        ];
93
        $this->propertyListeners = [
94
            new PropertyTargetClassAnnotationListener(),
95
            new PropertyTypeAnnotationListener(),
96
            new PropertyParameterAnnotationListener(),
97
            new PropertyForcedViewsAnnotationListener(),
98
        ];
99
    }
100
}
101