Completed
Pull Request — 2.x (#97)
by Christian
02:46 queued 26s
created

DoctrineORMMapper::loadOverrides()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 18
rs 8.8571
cc 5
eloc 10
nc 8
nop 1
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
     * @var array
58
     */
59
    protected $overrides;
60
61
    /**
62
     * @param ManagerRegistry $doctrine
63
     * @param array           $associations
64
     * @param array           $indexes
65
     * @param array           $discriminators
66
     * @param array           $discriminatorColumns
67
     * @param array           $inheritanceTypes
68
     * @param array           $uniques
69
     * @param array           $overrides
70
     */
71
    public function __construct(ManagerRegistry $doctrine, array $associations = array(), array $indexes = array(), array $discriminators = array(), array $discriminatorColumns = array(), array $inheritanceTypes = array(), array $uniques = array(), array $overrides = array())
0 ignored issues
show
Unused Code introduced by
The parameter $overrides is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
72
    {
73
        $this->doctrine = $doctrine;
74
        $this->associations = $associations;
75
        $this->indexes = $indexes;
76
        $this->uniques = $uniques;
77
        $this->discriminatorColumns = $discriminatorColumns;
78
        $this->discriminators = $discriminators;
79
        $this->inheritanceTypes = $inheritanceTypes;
80
    }
81
82
    /**
83
     * @return array
84
     */
85
    public function getSubscribedEvents()
86
    {
87
        return array(
88
            'loadClassMetadata',
89
        );
90
    }
91
92
    /**
93
     * @param string $class
94
     * @param string $field
95
     * @param array  $options
96
     */
97
    public function addAssociation($class, $field, array $options)
98
    {
99
        if (!isset($this->associations[$class])) {
100
            $this->associations[$class] = array();
101
        }
102
103
        $this->associations[$class][$field] = $options;
104
    }
105
106
    /**
107
     * Add a discriminator to a class.
108
     *
109
     * @param string $class              The Class
110
     * @param string $key                Key is the database value and values are the classes
111
     * @param string $discriminatorClass The mapped class
112
     */
113
    public function addDiscriminator($class, $key, $discriminatorClass)
114
    {
115
        if (!isset($this->discriminators[$class])) {
116
            $this->discriminators[$class] = array();
117
        }
118
119
        if (!isset($this->discriminators[$class][$key])) {
120
            $this->discriminators[$class][$key] = $discriminatorClass;
121
        }
122
    }
123
124
    /**
125
     * @param string $class
126
     * @param array  $columnDef
127
     */
128
    public function addDiscriminatorColumn($class, array $columnDef)
129
    {
130
        if (!isset($this->discriminatorColumns[$class])) {
131
            $this->discriminatorColumns[$class] = $columnDef;
132
        }
133
    }
134
135
    /**
136
     * @param string $class
137
     * @param string $type
138
     */
139
    public function addInheritanceType($class, $type)
140
    {
141
        if (!isset($this->inheritanceTypes[$class])) {
142
            $this->inheritanceTypes[$class] = $type;
143
        }
144
    }
145
146
    /**
147
     * @param string $class
148
     * @param string $name
149
     * @param array  $columns
150
     */
151
    public function addIndex($class, $name, array $columns)
152
    {
153
        if (!isset($this->indexes[$class])) {
154
            $this->indexes[$class] = array();
155
        }
156
157
        if (isset($this->indexes[$class][$name])) {
158
            return;
159
        }
160
161
        $this->indexes[$class][$name] = $columns;
162
    }
163
164
    /**
165
     * @param string $class
166
     * @param string $name
167
     * @param array  $columns
168
     */
169
    public function addUnique($class, $name, array $columns)
170
    {
171
        if (!isset($this->uniques[$class])) {
172
            $this->uniques[$class] = array();
173
        }
174
175
        if (isset($this->uniques[$class][$name])) {
176
            return;
177
        }
178
179
        $this->uniques[$class][$name] = $columns;
180
    }
181
182
    /**
183
     * Adds new ORM override.
184
     *
185
     * @param string $class
186
     * @param string $type
187
     * @param array  $options
188
     */
189
    final public function addOverride($class, $type, array $options)
190
    {
191
        if (!isset($this->overrides[$class])) {
192
            $this->overrides[$class] = array();
193
        }
194
195
        $this->overrides[$class][$type] = $options;
196
    }
197
198
    /**
199
     * @param $eventArgs
200
     */
201
    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
202
    {
203
        $metadata = $eventArgs->getClassMetadata();
204
205
        $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...
206
        $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...
207
        $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...
208
209
        $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...
210
        $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...
211
        $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...
212
        $this->loadOverrides($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...
213
    }
214
215
    /**
216
     * @param ClassMetadataInfo $metadata
217
     *
218
     * @throws \RuntimeException
219
     */
220
    private function loadAssociations(ClassMetadataInfo $metadata)
221
    {
222
        if (!array_key_exists($metadata->name, $this->associations)) {
223
            return;
224
        }
225
226
        try {
227
            foreach ($this->associations[$metadata->name] as $type => $mappings) {
228
                foreach ($mappings as $mapping) {
229
230
                    // the association is already set, skip the native one
231
                    if ($metadata->hasAssociation($mapping['fieldName'])) {
232
                        continue;
233
                    }
234
235
                    call_user_func(array($metadata, $type), $mapping);
236
                }
237
            }
238
        } catch (\ReflectionException $e) {
239
            throw new \RuntimeException(sprintf('Error with class %s : %s', $metadata->name, $e->getMessage()), 404, $e);
240
        }
241
    }
242
243
    /**
244
     * @param ClassMetadataInfo $metadata
245
     *
246
     * @throws \RuntimeException
247
     */
248
    private function loadDiscriminatorColumns(ClassMetadataInfo $metadata)
249
    {
250
        if (!array_key_exists($metadata->name, $this->discriminatorColumns)) {
251
            return;
252
        }
253
254
        try {
255
            if (isset($this->discriminatorColumns[$metadata->name])) {
256
                $arrayDiscriminatorColumns = $this->discriminatorColumns[$metadata->name];
257
                if (isset($metadata->discriminatorColumn)) {
258
                    $arrayDiscriminatorColumns = array_merge($metadata->discriminatorColumn, $this->discriminatorColumns[$metadata->name]);
259
                }
260
                $metadata->setDiscriminatorColumn($arrayDiscriminatorColumns);
261
            }
262
        } catch (\ReflectionException $e) {
263
            throw new \RuntimeException(sprintf('Error with class %s : %s', $metadata->name, $e->getMessage()), 404, $e);
264
        }
265
    }
266
267
    /**
268
     * @param ClassMetadataInfo $metadata
269
     *
270
     * @throws \RuntimeException
271
     */
272
    private function loadInheritanceTypes(ClassMetadataInfo $metadata)
273
    {
274
        if (!array_key_exists($metadata->name, $this->inheritanceTypes)) {
275
            return;
276
        }
277
        try {
278
            if (isset($this->inheritanceTypes[$metadata->name])) {
279
                $metadata->setInheritanceType($this->inheritanceTypes[$metadata->name]);
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
     * @throws \RuntimeException
290
     */
291
    private function loadDiscriminators(ClassMetadataInfo $metadata)
292
    {
293
        if (!array_key_exists($metadata->name, $this->discriminators)) {
294
            return;
295
        }
296
297
        try {
298
            foreach ($this->discriminators[$metadata->name] as $key => $class) {
299
                if (in_array($key, $metadata->discriminatorMap)) {
300
                    continue;
301
                }
302
                $metadata->setDiscriminatorMap(array($key => $class));
303
            }
304
        } catch (\ReflectionException $e) {
305
            throw new \RuntimeException(sprintf('Error with class %s : %s', $metadata->name, $e->getMessage()), 404, $e);
306
        }
307
    }
308
309
    /**
310
     * @param ClassMetadataInfo $metadata
311
     */
312
    private function loadIndexes(ClassMetadataInfo $metadata)
313
    {
314
        if (!array_key_exists($metadata->name, $this->indexes)) {
315
            return;
316
        }
317
318
        foreach ($this->indexes[$metadata->name] as $name => $columns) {
319
            $metadata->table['indexes'][$name] = array('columns' => $columns);
320
        }
321
    }
322
323
    /**
324
     * @param ClassMetadataInfo $metadata
325
     */
326
    private function loadUniques(ClassMetadataInfo $metadata)
327
    {
328
        if (!array_key_exists($metadata->name, $this->uniques)) {
329
            return;
330
        }
331
332
        foreach ($this->uniques[$metadata->name] as $name => $columns) {
333
            $metadata->table['uniqueConstraints'][$name] = array('columns' => $columns);
334
        }
335
    }
336
337
    /**
338
     * @param ClassMetadataInfo $metadata
339
     *
340
     * @throws \RuntimeException
341
     */
342
    private function loadOverrides(ClassMetadataInfo $metadata)
343
    {
344
        if (!array_key_exists($metadata->name, $this->overrides)) {
345
            return;
346
        }
347
348
        try {
349
            foreach ($this->overrides[$metadata->name] as $type => $overrides) {
350
                foreach ($overrides as $override) {
351
                    call_user_func(array($metadata, $type), $override['fieldName'], $override);
352
                }
353
            }
354
        } catch (\ReflectionException $e) {
355
            throw new \RuntimeException(
356
                sprintf('Error with class %s : %s', $metadata->name, $e->getMessage()), 404, $e
357
            );
358
        }
359
    }
360
}
361