LoadClassMetadataListener::getSubscribedEvents()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
ccs 0
cts 2
cp 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * @author KonstantinKuklin <[email protected]>
5
 */
6
7
namespace KonstantinKuklin\DoctrineCompressedFields\EventListener;
8
9
use Doctrine\Common\Annotations\AnnotationReader;
10
use Doctrine\Common\Annotations\AnnotationRegistry;
11
use Doctrine\Common\Annotations\CachedReader;
12
use Doctrine\Common\Annotations\DocParser;
13
use Doctrine\Common\Cache\VoidCache;
14
use Doctrine\Common\EventSubscriber;
15
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
16
use Doctrine\ORM\Events;
17
use KonstantinKuklin\DoctrineCompressedFields\Annotation\Hub;
18
use KonstantinKuklin\DoctrineCompressedFields\Annotation\Mask;
19
use KonstantinKuklin\DoctrineCompressedFields\BitNormalizer;
20
use KonstantinKuklin\DoctrineCompressedFields\MetadataLayer;
21
22
class LoadClassMetadataListener implements EventSubscriber
23
{
24
    /**
25
     * @var AnnotationReader
26
     */
27
    private static $defaultAnnotationReader;
28
29
    public function __construct()
30
    {
31
        $this->initDefaultAnnotationReader();
32
    }
33
34
    /**
35
     * Create default annotation reader for extension
36
     *
37
     * @throws \RuntimeException
38
     */
39
    private function initDefaultAnnotationReader()
40
    {
41
        if (null !== self::$defaultAnnotationReader) {
42
            return;
43
        }
44
45
        $docParser = new DocParser();
46
        $docParser->setImports([
47
            'Bits' => 'KonstantinKuklin\\DoctrineCompressedFields\\Annotation',
48
        ]);
49
        $docParser->setIgnoreNotImportedAnnotations(true);
50
51
        $reader = new AnnotationReader($docParser);
52
53
        AnnotationRegistry::registerFile(__DIR__ . '/../Annotation/Hub.php');
0 ignored issues
show
Deprecated Code introduced by
The method Doctrine\Common\Annotati...egistry::registerFile() has been deprecated with message: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists')

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
54
        AnnotationRegistry::registerFile(__DIR__ . '/../Annotation/Mask.php');
0 ignored issues
show
Deprecated Code introduced by
The method Doctrine\Common\Annotati...egistry::registerFile() has been deprecated with message: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists')

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
55
        $reader = new CachedReader($reader, new VoidCache());
56
57
        self::$defaultAnnotationReader = $reader;
0 ignored issues
show
Documentation Bug introduced by
It seems like $reader of type object<Doctrine\Common\Annotations\CachedReader> is incompatible with the declared type object<Doctrine\Common\A...tions\AnnotationReader> of property $defaultAnnotationReader.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function getSubscribedEvents()
64
    {
65
        return [
66
            Events::loadClassMetadata,
67
        ];
68
    }
69
70
    /**
71
     * @param LoadClassMetadataEventArgs $eventArgs
72
     *
73
     * @throws \Doctrine\ORM\ORMException
74
     */
75 8
    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
76
    {
77 8
        $classMetadata = $eventArgs->getClassMetadata();
78 8
        if (MetadataLayer::isAlreadyProcessed($classMetadata)) {
79
            // we can skip it
80
            return;
81
        }
82
83 8
        $fieldNames = array_flip($classMetadata->getFieldNames());
84 8
        $reflectionClass = $classMetadata->getReflectionClass();
85
86 8
        foreach ($reflectionClass->getProperties() as $reflectionProperty) {
87 8
            if (isset($fieldNames[$reflectionProperty->getName()])) {
88 8
                $this->loadHubProperty($reflectionProperty, $classMetadata);
89
            } else {
90 8
                $this->loadMaskProperty($reflectionProperty, $classMetadata);
91
            }
92
        }
93 8
    }
94
95
    /**
96
     * @param \ReflectionProperty                                $reflectionProperty
97
     * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $classMetadata
98
     *
99
     * @throws \Exception
100
     */
101 8
    private function loadMaskProperty($reflectionProperty, $classMetadata)
102
    {
103
        /** @var Mask $maskAnnotation */
104 8
        $maskAnnotation = self::$defaultAnnotationReader->getPropertyAnnotation(
105 8
            $reflectionProperty,
106 8
            Mask::class
107
        );
108
109 8
        if (!$maskAnnotation) {
110
            return;
111
        }
112
113
        // normalize bit list
114 8
        $maskAnnotation->bits = BitNormalizer::getNormalized(
0 ignored issues
show
Documentation Bug introduced by
It seems like \KonstantinKuklin\Doctri...($maskAnnotation->bits) of type array<integer,integer> is incompatible with the declared type array<integer,string> of property $bits.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
115 8
            $maskAnnotation->bits
116
        );
117
118 8
        MetadataLayer::setMask($classMetadata, $maskAnnotation, $reflectionProperty);
119 8
    }
120
121
    /**
122
     * @param \ReflectionProperty                                $reflectionProperty
123
     * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $classMetadata
124
     */
125 8
    private function loadHubProperty($reflectionProperty, $classMetadata)
126
    {
127 8
        $hubAnnotation = self::$defaultAnnotationReader->getPropertyAnnotation(
128 8
            $reflectionProperty,
129 8
            Hub::class
130
        );
131
132 8
        if (!$hubAnnotation) {
133 8
            return;
134
        }
135
136 8
        MetadataLayer::setHub($classMetadata, $hubAnnotation, $reflectionProperty);
137 8
    }
138
}
139