Completed
Push — master ( 55daec...2d65d3 )
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 %
Metric Value
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
            'joinTable' => [
106
                'name' => sprintf('sylius_%s_association_%s', $subject, $subject),
107
                'joinColumns' => [[
108
                    'name' => 'association_id',
109
                    'referencedColumnName' => 'id',
110
                    'nullable' => false,
111
                    'unique' => false,
112
                    'onDelete' => 'CASCADE',
113
                ]],
114
                'inverseJoinColumns' => [[
115
                    'name' => $subject.'_id',
116
                    'referencedColumnName' => $associationEntityMetadata->fieldMappings['id']['columnName'],
117
                    'nullable' => false,
118
                    'unique' => false,
119
                    'onDelete' => 'CASCADE',
120
                ]],
121
            ],
122
        ];
123
    }
124
125
    /**
126
     * @param string $associationModel
127
     * @param ClassMetadata $associationMetadata
128
     *
129
     * @return array
130
     */
131
    private function createAssociationTypeMapping($associationModel, ClassMetadata $associationMetadata)
132
    {
133
        return [
134
            'fieldName' => 'type',
135
            'targetEntity' => $associationModel,
136
            'joinColumns' => [[
137
                'name' => 'association_type_id',
138
                'referencedColumnName' => $associationMetadata->fieldMappings['id']['columnName'],
139
                'nullable' => false,
140
                'onDelete' => 'CASCADE',
141
            ]],
142
        ];
143
    }
144
}
145