Passed
Push — feature/initial-implementation ( 0c2c6c...79751f )
by Fike
01:54
created

Reader::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AmaTeam\ElasticSearch\Mapping\Annotation;
6
7
use AmaTeam\ElasticSearch\API\Annotation\Document;
8
use AmaTeam\ElasticSearch\Mapping\Annotation\Listener\ForcedViewListener;
9
use AmaTeam\ElasticSearch\Mapping\Annotation\Listener\ParameterListener;
10
use AmaTeam\ElasticSearch\Mapping\Annotation\Listener\TypeListener;
11
use AmaTeam\ElasticSearch\Mapping\Annotation\Property\Reader as PropertyReader;
12
use AmaTeam\ElasticSearch\Mapping\DocumentMapping;
13
use BadMethodCallException;
14
use Doctrine\Common\Annotations\AnnotationReader;
15
use ReflectionClass;
16
use ReflectionProperty;
17
18
class Reader
19
{
20
    /**
21
     * @var AnnotationReader
22
     */
23
    private $annotationReader;
24
    /**
25
     * @var PropertyReader
26
     */
27
    private $propertyReader;
28
    /**
29
     * @var AnnotationListenerInterface[]
30
     */
31
    private $listeners = [];
32
33
    /**
34
     * @param AnnotationReader $annotationReader
35
     * @param PropertyReader $propertyReader
36
     */
37
    public function __construct(AnnotationReader $annotationReader = null, PropertyReader $propertyReader = null)
38
    {
39
        $this->annotationReader = $annotationReader ?? new AnnotationReader();
40
        $this->propertyReader = $propertyReader ?? new PropertyReader($this->annotationReader);
41
        $this->registerListeners();
42
    }
43
44
    private function registerListeners()
45
    {
46
        $this->listeners = [
47
            new ForcedViewListener(),
48
            new ParameterListener(),
49
            new TypeListener(),
50
        ];
51
    }
52
53
    public function read(string $className): DocumentMapping
54
    {
55
        if (!class_exists($className)) {
56
            throw new BadMethodCallException("Class `$className` doesn't exist");
57
        }
58
        $reflection = new ReflectionClass($className);
59
        $descriptor = new DocumentMapping($reflection->getName());
60
        $annotations = $this->annotationReader->getClassAnnotations($reflection);
61
        foreach ($annotations as $annotation) {
62
            foreach ($this->listeners as $listener) {
63
                $listener->accept($reflection, $descriptor, $annotation);
64
            }
65
        }
66
        $properties = $reflection->getProperties(~ReflectionProperty::IS_STATIC);
67
        $descriptors = [];
68
        foreach ($properties as $property) {
69
            $descriptors[$property->getName()] = $this->propertyReader->read($property);
70
        }
71
        $descriptor->setProperties($descriptors);
72
        return $descriptor;
73
    }
74
75
    public function isDocumentClass(string $className): bool
76
    {
77
        if (!class_exists($className)) {
78
            return false;
79
        }
80
        $reflection = new ReflectionClass($className);
81
        return (bool) $this->annotationReader->getClassAnnotation($reflection, Document::class);
82
    }
83
}
84