Completed
Push — master ( 167738...fe3be6 )
by Paweł
58:17 queued 58:01
created

ORMMappedSuperClassSubscriber::hasRelation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
rs 9.4285
cc 1
eloc 7
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Bundle\ResourceBundle\EventListener;
13
14
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
15
use Doctrine\ORM\Events;
16
use Doctrine\ORM\Mapping\ClassMetadata;
17
use Doctrine\ORM\Mapping\ClassMetadataInfo;
18
19
/**
20
 * @author Ivan Molchanov <[email protected]>
21
 * @author Paweł Jędrzejewski <[email protected]>
22
 */
23
class ORMMappedSuperClassSubscriber extends AbstractDoctrineSubscriber
24
{
25
    /**
26
     * @return array
27
     */
28
    public function getSubscribedEvents()
29
    {
30
        return [
31
            Events::loadClassMetadata,
32
        ];
33
    }
34
35
    /**
36
     * @param LoadClassMetadataEventArgs $eventArgs
37
     */
38
    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
39
    {
40
        $metadata = $eventArgs->getClassMetadata();
41
        if (false === $this->isSyliusClass($metadata)) {
42
            return;
43
        }
44
45
        $this->convertToEntityIfNeeded($metadata);
0 ignored issues
show
Compatibility introduced by
$metadata of type object<Doctrine\Common\P...\Mapping\ClassMetadata> is not a sub-type of object<Doctrine\ORM\Mapping\ClassMetadataInfo>. It seems like you assume a concrete implementation of the interface Doctrine\Common\Persistence\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
46
47
        if (!$metadata->isMappedSuperclass) {
48
            $this->setAssociationMappings($metadata, $eventArgs->getEntityManager()->getConfiguration());
0 ignored issues
show
Compatibility introduced by
$metadata of type object<Doctrine\Common\P...\Mapping\ClassMetadata> is not a sub-type of object<Doctrine\ORM\Mapping\ClassMetadataInfo>. It seems like you assume a concrete implementation of the interface Doctrine\Common\Persistence\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
49
        } else {
50
            $this->unsetAssociationMappings($metadata);
0 ignored issues
show
Compatibility introduced by
$metadata of type object<Doctrine\Common\P...\Mapping\ClassMetadata> is not a sub-type of object<Doctrine\ORM\Mapping\ClassMetadataInfo>. It seems like you assume a concrete implementation of the interface Doctrine\Common\Persistence\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
51
        }
52
    }
53
54
    /**
55
     * @param ClassMetadataInfo $metadata
56
     */
57
    private function convertToEntityIfNeeded(ClassMetadataInfo $metadata)
58
    {
59
        foreach ($this->resourceRegistry->getAll() as $alias => $resourceMetadata) {
60
            if ($metadata->getName() !== $resourceMetadata->getClass('model')) {
61
                continue;
62
            }
63
64
            $metadata->isMappedSuperclass = false;
65
        }
66
    }
67
68
    /**
69
     * @param ClassMetadataInfo $metadata
70
     * @param $configuration
71
     */
72
    private function setAssociationMappings(ClassMetadataInfo $metadata, $configuration)
73
    {
74
        foreach (class_parents($metadata->getName()) as $parent) {
75
            $parentMetadata = new ClassMetadata(
76
                $parent,
77
                $configuration->getNamingStrategy()
78
            );
79
            if (in_array($parent, $configuration->getMetadataDriverImpl()->getAllClassNames())) {
80
                $configuration->getMetadataDriverImpl()->loadMetadataForClass($parent, $parentMetadata);
81
                if ($parentMetadata->isMappedSuperclass) {
82
                    foreach ($parentMetadata->getAssociationMappings() as $key => $value) {
83
                        if ($this->hasRelation($value['type'])) {
84
                            $metadata->associationMappings[$key] = $value;
85
                        }
86
                    }
87
                }
88
            }
89
        }
90
    }
91
92
    /**
93
     * @param ClassMetadataInfo $metadata
94
     */
95
    private function unsetAssociationMappings(ClassMetadataInfo $metadata)
96
    {
97
        foreach ($metadata->getAssociationMappings() as $key => $value) {
98
            if ($this->hasRelation($value['type'])) {
99
                unset($metadata->associationMappings[$key]);
100
            }
101
        }
102
    }
103
104
    /**
105
     * @param $type
106
     *
107
     * @return bool
108
     */
109
    private function hasRelation($type)
110
    {
111
        return in_array(
112
            $type,
113
            [
114
                ClassMetadataInfo::MANY_TO_MANY,
115
                ClassMetadataInfo::ONE_TO_MANY,
116
                ClassMetadataInfo::ONE_TO_ONE,
117
            ],
118
            true
119
        );
120
    }
121
}
122