Completed
Push — 2.x ( dc834d...91b37b )
by
unknown
02:07
created

DoctrineORMMapper::addAssociation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 3
1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
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 Sonata\EasyExtendsBundle\Mapper;
13
14
use Doctrine\Common\EventSubscriber;
15
use Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs;
16
use Doctrine\Common\Persistence\ManagerRegistry;
17
use Doctrine\ORM\Mapping\ClassMetadataInfo;
18
19
class DoctrineORMMapper implements EventSubscriber
20
{
21
    /**
22
     * @var array
23
     */
24
    protected $associations;
25
26
    /**
27
     * @var array
28
     */
29
    protected $discriminators;
30
31
    /**
32
     * @var array
33
     */
34
    protected $discriminatorColumns;
35
36
    /**
37
     * @var array
38
     */
39
    protected $inheritanceTypes;
40
41
    /**
42
     * @var ManagerRegistry
43
     */
44
    protected $doctrine;
45
46
    /**
47
     * @var array
48
     */
49
    protected $indexes;
50
51
    /**
52
     * @var array
53
     */
54
    protected $uniques;
55
56
    /**
57
     * @param ManagerRegistry $doctrine
58
     * @param array           $associations
59
     * @param array           $indexes
60
     * @param array           $discriminators
61
     * @param array           $discriminatorColumns
62
     * @param array           $inheritanceTypes
63
     * @param array           $uniques
64
     */
65
    public function __construct(ManagerRegistry $doctrine, array $associations = array(), array $indexes = array(), array $discriminators = array(), array $discriminatorColumns = array(), array $inheritanceTypes = array(), array $uniques = array())
66
    {
67
        $this->doctrine = $doctrine;
68
        $this->associations = $associations;
69
        $this->indexes = $indexes;
70
        $this->uniques = $uniques;
71
        $this->discriminatorColumns = $discriminatorColumns;
72
        $this->discriminators = $discriminators;
73
        $this->inheritanceTypes = $inheritanceTypes;
74
    }
75
76
    /**
77
     * @return array
78
     */
79
    public function getSubscribedEvents()
80
    {
81
        return array(
82
            'loadClassMetadata',
83
        );
84
    }
85
86
    /**
87
     * @param string $class
88
     * @param string $field
89
     * @param array  $options
90
     */
91
    public function addAssociation($class, $field, array $options)
92
    {
93
        if (!isset($this->associations[$class])) {
94
            $this->associations[$class] = array();
95
        }
96
97
        $this->associations[$class][$field] = $options;
98
    }
99
100
    /**
101
     * Add a discriminator to a class.
102
     *
103
     * @param string $class              The Class
104
     * @param string $key                Key is the database value and values are the classes
105
     * @param string $discriminatorClass The mapped class
106
     */
107
    public function addDiscriminator($class, $key, $discriminatorClass)
108
    {
109
        if (!isset($this->discriminators[$class])) {
110
            $this->discriminators[$class] = array();
111
        }
112
113
        if (!isset($this->discriminators[$class][$key])) {
114
            $this->discriminators[$class][$key] = $discriminatorClass;
115
        }
116
    }
117
118
    /**
119
     * @param string $class
120
     * @param array  $columnDef
121
     */
122
    public function addDiscriminatorColumn($class, array $columnDef)
123
    {
124
        if (!isset($this->discriminatorColumns[$class])) {
125
            $this->discriminatorColumns[$class] = $columnDef;
126
        }
127
    }
128
129
    /**
130
     * @param string $class
131
     * @param string $type
132
     */
133
    public function addInheritanceType($class, $type)
134
    {
135
        if (!isset($this->inheritanceTypes[$class])) {
136
            $this->inheritanceTypes[$class] = $type;
137
        }
138
    }
139
140
    /**
141
     * @param string $class
142
     * @param string $name
143
     * @param array  $columns
144
     */
145
    public function addIndex($class, $name, array $columns)
146
    {
147
        if (!isset($this->indexes[$class])) {
148
            $this->indexes[$class] = array();
149
        }
150
151
        if (isset($this->indexes[$class][$name])) {
152
            return;
153
        }
154
155
        $this->indexes[$class][$name] = $columns;
156
    }
157
158
    /**
159
     * @param string $class
160
     * @param string $name
161
     * @param array  $columns
162
     */
163
    public function addUnique($class, $name, array $columns)
164
    {
165
        if (!isset($this->uniques[$class])) {
166
            $this->uniques[$class] = array();
167
        }
168
169
        if (isset($this->uniques[$class][$name])) {
170
            return;
171
        }
172
173
        $this->uniques[$class][$name] = $columns;
174
    }
175
176
    /**
177
     * @param $eventArgs
178
     */
179
    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
180
    {
181
        $metadata = $eventArgs->getClassMetadata();
182
183
        $this->loadAssociations($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...
184
        $this->loadIndexes($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...
185
        $this->loadUniques($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...
186
187
        $this->loadDiscriminatorColumns($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...
188
        $this->loadDiscriminators($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...
189
        $this->loadInheritanceTypes($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...
190
    }
191
192
    /**
193
     * @param ClassMetadataInfo $metadata
194
     *
195
     * @throws \RuntimeException
196
     */
197
    private function loadAssociations(ClassMetadataInfo $metadata)
198
    {
199
        if (!array_key_exists($metadata->name, $this->associations)) {
200
            return;
201
        }
202
203
        try {
204
            foreach ($this->associations[$metadata->name] as $type => $mappings) {
205
                foreach ($mappings as $mapping) {
206
207
                    // the association is already set, skip the native one
208
                    if ($metadata->hasAssociation($mapping['fieldName'])) {
209
                        continue;
210
                    }
211
212
                    call_user_func(array($metadata, $type), $mapping);
213
                }
214
            }
215
        } catch (\ReflectionException $e) {
216
            throw new \RuntimeException(sprintf('Error with class %s : %s', $metadata->name, $e->getMessage()), 404, $e);
217
        }
218
    }
219
220
    /**
221
     * @param ClassMetadataInfo $metadata
222
     *
223
     * @throws \RuntimeException
224
     */
225
    private function loadDiscriminatorColumns(ClassMetadataInfo $metadata)
226
    {
227
        if (!array_key_exists($metadata->name, $this->discriminatorColumns)) {
228
            return;
229
        }
230
231
        try {
232
            if (isset($this->discriminatorColumns[$metadata->name])) {
233
                $arrayDiscriminatorColumns = $this->discriminatorColumns[$metadata->name];
234
                if (isset($metadata->discriminatorColumn)) {
235
                    $arrayDiscriminatorColumns = array_merge($metadata->discriminatorColumn, $this->discriminatorColumns[$metadata->name]);
236
                }
237
                $metadata->setDiscriminatorColumn($arrayDiscriminatorColumns);
238
            }
239
        } catch (\ReflectionException $e) {
240
            throw new \RuntimeException(sprintf('Error with class %s : %s', $metadata->name, $e->getMessage()), 404, $e);
241
        }
242
    }
243
244
    /**
245
     * @param ClassMetadataInfo $metadata
246
     *
247
     * @throws \RuntimeException
248
     */
249
    private function loadInheritanceTypes(ClassMetadataInfo $metadata)
250
    {
251
        if (!array_key_exists($metadata->name, $this->inheritanceTypes)) {
252
            return;
253
        }
254
        try {
255
            if (isset($this->inheritanceTypes[$metadata->name])) {
256
                $metadata->setInheritanceType($this->inheritanceTypes[$metadata->name]);
257
            }
258
        } catch (\ReflectionException $e) {
259
            throw new \RuntimeException(sprintf('Error with class %s : %s', $metadata->name, $e->getMessage()), 404, $e);
260
        }
261
    }
262
263
    /**
264
     * @param ClassMetadataInfo $metadata
265
     *
266
     * @throws \RuntimeException
267
     */
268
    private function loadDiscriminators(ClassMetadataInfo $metadata)
269
    {
270
        if (!array_key_exists($metadata->name, $this->discriminators)) {
271
            return;
272
        }
273
274
        try {
275
            foreach ($this->discriminators[$metadata->name] as $key => $class) {
276
                if (in_array($key, $metadata->discriminatorMap)) {
277
                    continue;
278
                }
279
                $metadata->setDiscriminatorMap(array($key => $class));
280
            }
281
        } catch (\ReflectionException $e) {
282
            throw new \RuntimeException(sprintf('Error with class %s : %s', $metadata->name, $e->getMessage()), 404, $e);
283
        }
284
    }
285
286
    /**
287
     * @param ClassMetadataInfo $metadata
288
     */
289
    private function loadIndexes(ClassMetadataInfo $metadata)
290
    {
291
        if (!array_key_exists($metadata->name, $this->indexes)) {
292
            return;
293
        }
294
295
        foreach ($this->indexes[$metadata->name] as $name => $columns) {
296
            $metadata->table['indexes'][$name] = array('columns' => $columns);
297
        }
298
    }
299
300
    /**
301
     * @param ClassMetadataInfo $metadata
302
     */
303
    private function loadUniques(ClassMetadataInfo $metadata)
304
    {
305
        if (!array_key_exists($metadata->name, $this->uniques)) {
306
            return;
307
        }
308
309
        foreach ($this->uniques[$metadata->name] as $name => $columns) {
310
            $metadata->table['uniqueConstraints'][$name] = array('columns' => $columns);
311
        }
312
    }
313
}
314