Completed
Push — master ( 0729b3...dbaae6 )
by Kamil
18:26
created

LoadMetadataSubscriber::getSubscribedEvents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
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\AssociationBundle\EventListener;
13
14
use Doctrine\Common\EventSubscriber;
15
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
16
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
17
18
/**
19
 * @author Łukasz Chruściel <[email protected]>
20
 */
21
class LoadMetadataSubscriber implements EventSubscriber
22
{
23
    /**
24
     * @var array
25
     */
26
    protected $subjects;
27
28
    /**
29
     * @param array $subjects
30
     */
31
    public function __construct(array $subjects)
32
    {
33
        $this->subjects = $subjects;
34
    }
35
36
    /**
37
     * @return array
38
     */
39
    public function getSubscribedEvents()
40
    {
41
        return [
42
            'loadClassMetadata',
43
        ];
44
    }
45
46
    /**
47
     * @param LoadClassMetadataEventArgs $eventArgs
48
     */
49
    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
50
    {
51
        $metadata = $eventArgs->getClassMetadata();
52
        $metadataFactory = $eventArgs->getEntityManager()->getMetadataFactory();
53
54
        foreach ($this->subjects as $subject => $class) {
55
            if ($class['association']['classes']['model'] !== $metadata->getName()) {
56
                continue;
57
            }
58
59
            $associationEntity = $class['subject'];
60
            $associationEntityMetadata = $metadataFactory->getMetadataFor($associationEntity);
61
62
            $associationTypeModel = $class['association_type']['classes']['model'];
63
            $associationTypeMetadata = $metadataFactory->getMetadataFor($associationTypeModel);
64
65
            $metadata->mapManyToOne($this->createSubjectMapping($associationEntity, $subject, $associationEntityMetadata));
66
            $metadata->mapManyToMany($this->createAssociationMapping($associationEntity, $subject, $associationEntityMetadata));
67
            $metadata->mapManyToOne($this->createAssociationTypeMapping($associationTypeModel, $associationTypeMetadata));
68
        }
69
    }
70
71
    /**
72
     * @param string $associationEntity
73
     * @param string $subject
74
     * @param ClassMetadata $associationEntityMetadata
75
     *
76
     * @return array
77
     */
78
    private function createSubjectMapping($associationEntity, $subject, ClassMetadata $associationEntityMetadata)
79
    {
80
        return [
81
            'fieldName' => 'owner',
82
            'targetEntity' => $associationEntity,
83
            'inversedBy' => 'associations',
84
            'joinColumns' => [[
85
                'name' => $subject . '_id',
86
                'referencedColumnName' => $associationEntityMetadata->fieldMappings['id']['columnName'],
87
                'nullable' => false,
88
                'onDelete' => 'CASCADE',
89
            ]],
90
        ];
91
    }
92
93
    /**
94
     * @param string $associationEntity
95
     * @param string $subject
96
     * @param ClassMetadata $associationEntityMetadata
97
     *
98
     * @return array
99
     */
100
    private function createAssociationMapping($associationEntity, $subject, ClassMetadata $associationEntityMetadata)
101
    {
102
        return [
103
            'fieldName' => 'associatedObjects',
104
            'targetEntity' => $associationEntity,
105
            'joinColumns' => [[
106
                'name' => $subject . '_id',
107
                'referencedColumnName' => $associationEntityMetadata->fieldMappings['id']['columnName'],
108
                'nullable' => false,
109
                'onDelete' => 'CASCADE',
110
            ]],
111
        ];
112
    }
113
114
    /**
115
     * @param string $associationModel
116
     * @param ClassMetadata $associationMetadata
117
     *
118
     * @return array
119
     */
120
    private function createAssociationTypeMapping($associationModel, ClassMetadata $associationMetadata)
121
    {
122
        return [
123
            'fieldName' => 'type',
124
            'targetEntity' => $associationModel,
125
            'joinColumns' => [[
126
                'name' => 'association_type_id',
127
                'referencedColumnName' => $associationMetadata->fieldMappings['id']['columnName'],
128
                'nullable' => false,
129
                'onDelete' => 'CASCADE',
130
            ]],
131
        ];
132
    }
133
}
134