Completed
Pull Request — master (#14)
by Pavel
03:32
created

EntityMetadata::mapIdentifier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Bankiru\Api\Doctrine\Mapping;
4
5
use Bankiru\Api\Doctrine\EntityRepository;
6
use Bankiru\Api\Doctrine\Exception\MappingException;
7
use Bankiru\Api\Doctrine\Rpc\Method\MethodProviderInterface;
8
use Doctrine\Common\Persistence\Mapping\ReflectionService;
9
use Doctrine\Instantiator\Instantiator;
10
use Doctrine\Instantiator\InstantiatorInterface;
11
12
class EntityMetadata implements ApiMetadata
13
{
14
    /**
15
     * The ReflectionProperty instances of the mapped class.
16
     *
17
     * @var \ReflectionProperty[]
18
     */
19
    public $reflFields = [];
20
    /** @var string */
21
    public $name;
22
    /** @var string */
23
    public $namespace;
24
    /** @var string */
25
    public $rootEntityName;
26
    /** @var string[] */
27
    public $identifier = [];
28
    /** @var array */
29
    public $fields = [];
30
    /** @var array */
31
    public $associations = [];
32
    /** @var string */
33
    public $repositoryClass = EntityRepository::class;
34
    /** @var \ReflectionClass */
35
    public $reflClass;
36
    /** @var MethodProviderInterface */
37
    public $methodProvider;
38
    /** @var string */
39
    public $clientName;
40
    /** @var string */
41
    public $apiName;
42
    /** @var string[] */
43
    public $apiFieldNames = [];
44
    /** @var string[] */
45
    public $fieldNames = [];
46
    /** @var bool */
47
    public $isMappedSuperclass = false;
48
    /** @var bool */
49
    public $containsForeignIdentifier;
50
    /** @var bool */
51
    public $isIdentifierComposite = false;
52
    /** @var int */
53
    public $generatorType = self::GENERATOR_TYPE_NATURAL;
54
    /** @var InstantiatorInterface */
55
    private $instantiator;
56
    /** @var  int */
57
    private $changeTrackingPolicy = self::CHANGETRACKING_DEFERRED_IMPLICIT;
58
59
    /**
60
     * Initializes a new ClassMetadata instance that will hold the object-relational mapping
61
     * metadata of the class with the given name.
62
     *
63
     * @param string $entityName The name of the entity class the new instance is used for.
64
     */
65 18
    public function __construct($entityName)
66
    {
67 18
        $this->name           = $entityName;
68 18
        $this->rootEntityName = $entityName;
69 18
    }
70
71
    /**
72
     * @return boolean
73
     */
74
    public function containsForeignIdentifier()
75
    {
76
        return $this->containsForeignIdentifier;
77
    }
78
79
    /** {@inheritdoc} */
80 7
    public function getReflectionProperties()
81
    {
82 7
        return $this->reflFields;
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88 16
    public function getReflectionProperty($name)
89
    {
90 16
        if (!array_key_exists($name, $this->reflFields)) {
91
            throw MappingException::noSuchProperty($name, $this->getName());
92
        }
93
94 16
        return $this->reflFields[$name];
95
    }
96
97
    /** {@inheritdoc} */
98 18
    public function getName()
99
    {
100 18
        return $this->name;
101
    }
102
103
    /** {@inheritdoc} */
104 18
    public function getMethodContainer()
105
    {
106 18
        return $this->methodProvider;
107
    }
108
109
    /** {@inheritdoc} */
110 12
    public function getRepositoryClass()
111
    {
112 12
        return $this->repositoryClass;
113
    }
114
115
    /** {@inheritdoc} */
116 2
    public function getIdentifier()
117
    {
118 2
        return $this->identifier;
119
    }
120
121 5
    public function setIdentifier($identifier)
122
    {
123 5
        $this->identifier            = $identifier;
124 5
        $this->isIdentifierComposite = (count($this->identifier) > 1);
125 5
    }
126
127
    /** {@inheritdoc} */
128 12
    public function getReflectionClass()
129
    {
130 12
        if (null === $this->reflClass) {
131
            $this->reflClass = new \ReflectionClass($this->getName());
132
        }
133
134 12
        return $this->reflClass;
135
    }
136
137
    /** {@inheritdoc} */
138 4
    public function isIdentifier($fieldName)
139
    {
140 4
        return in_array($fieldName, $this->identifier, true);
141
    }
142
143
    /** {@inheritdoc} */
144 2
    public function hasField($fieldName)
145
    {
146 2
        return in_array($fieldName, $this->getFieldNames(), true);
147
    }
148
149
    /** {@inheritdoc} */
150 12
    public function getFieldNames()
151
    {
152 12
        return array_keys($this->fields);
153
    }
154
155
    /** {@inheritdoc} */
156 17
    public function hasAssociation($fieldName)
157
    {
158 17
        return in_array($fieldName, $this->getAssociationNames(), true);
159
    }
160
161
    /** {@inheritdoc} */
162 17
    public function getAssociationNames()
163
    {
164 17
        return array_keys($this->associations);
165
    }
166
167
    /** {@inheritdoc} */
168 9
    public function isSingleValuedAssociation($fieldName)
169
    {
170 9
        return $this->hasAssociation($fieldName) && $this->associations[$fieldName]['type'] & self::TO_ONE;
171
    }
172
173
    /** {@inheritdoc} */
174 13
    public function isCollectionValuedAssociation($fieldName)
175
    {
176 13
        return $this->hasAssociation($fieldName) && $this->associations[$fieldName]['type'] & self::TO_MANY;
177
    }
178
179
    /** {@inheritdoc} */
180 16
    public function getIdentifierFieldNames()
181
    {
182 16
        return $this->identifier;
183
    }
184
185
    /** {@inheritdoc} */
186 17
    public function getTypeOfField($fieldName)
187
    {
188 17
        return $this->fields[$fieldName]['type'];
189
    }
190
191
    /** {@inheritdoc} */
192 9
    public function getAssociationTargetClass($assocName)
193
    {
194 9
        return $this->associations[$assocName]['target'];
195
    }
196
197
    /** {@inheritdoc} */
198
    public function isAssociationInverseSide($assocName)
199
    {
200
        $assoc = $this->associations[$assocName];
201
202
        return array_key_exists('mappedBy', $assoc);
203
    }
204
205
    /** {@inheritdoc} */
206
    public function getAssociationMappedByTargetField($assocName)
207
    {
208
        return $this->associations[$assocName]['mappedBy'];
209
    }
210
211
    /** {@inheritdoc} */
212 15
    public function getIdentifierValues($object)
213
    {
214 15
        if ($this->isIdentifierComposite) {
215 1
            $id = [];
216 1
            foreach ($this->identifier as $idField) {
217 1
                $value = $this->reflFields[$idField]->getValue($object);
218 1
                if ($value !== null) {
219 1
                    $id[$idField] = $value;
220 1
                }
221 1
            }
222
223 1
            return $id;
224
        }
225 14
        $id    = $this->identifier[0];
226 14
        $value = $this->reflFields[$id]->getValue($object);
227 14
        if (null === $value) {
228
            return [];
229
        }
230
231 14
        return [$id => $value];
232
    }
233
234
    /** {@inheritdoc} */
235 18
    public function wakeupReflection(ReflectionService $reflService)
236
    {
237
        // Restore ReflectionClass and properties
238 18
        $this->reflClass    = $reflService->getClass($this->name);
239 18
        $this->instantiator = $this->instantiator ?: new Instantiator();
240
241 18 View Code Duplication
        foreach ($this->fields as $field => $mapping) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
242 18
            $class                    = array_key_exists('declared', $mapping) ? $mapping['declared'] : $this->name;
243 18
            $this->reflFields[$field] = $reflService->getAccessibleProperty($class, $field);
244 18
        }
245
246 18 View Code Duplication
        foreach ($this->associations as $field => $mapping) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
247 14
            $class                    = array_key_exists('declared', $mapping) ? $mapping['declared'] : $this->name;
248 14
            $this->reflFields[$field] = $reflService->getAccessibleProperty($class, $field);
249 18
        }
250 18
    }
251
252
    /** {@inheritdoc} */
253 18
    public function initializeReflection(ReflectionService $reflService)
254
    {
255 18
        $this->reflClass = $reflService->getClass($this->name);
256 18
        $this->namespace = $reflService->getClassNamespace($this->name);
257 18
        if ($this->reflClass) {
258 18
            $this->name = $this->rootEntityName = $this->reflClass->getName();
0 ignored issues
show
Bug introduced by
Consider using $this->reflClass->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
259 18
        }
260 18
    }
261
262
    /** {@inheritdoc} */
263 17
    public function getApiName()
264
    {
265 17
        if (null === $this->apiName) {
266
            throw MappingException::noApiSpecified($this->getName());
267
        }
268
269 17
        return $this->apiName;
270
    }
271
272
    /** {@inheritdoc} */
273 18
    public function getClientName()
274
    {
275 18
        if (null === $this->clientName) {
276
            throw MappingException::noClientSpecified($this->getName());
277
        }
278
279 18
        return $this->clientName;
280
    }
281
282 18
    public function mapField(array $mapping)
283
    {
284 18
        $this->validateAndCompleteFieldMapping($mapping);
285 18
        $this->assertFieldNotMapped($mapping['field']);
286 18
        $this->fields[$mapping['field']] = $mapping;
287 18
    }
288
289
    /** {@inheritdoc} */
290 4
    public function getFieldMapping($fieldName)
291
    {
292 4
        if (!isset($this->fields[$fieldName])) {
293
            throw MappingException::unknownField($fieldName, $this->getName());
294
        }
295
296 4
        return $this->fields[$fieldName];
297
    }
298
299
    /** {@inheritdoc} */
300 13
    public function getAssociationMapping($fieldName)
301
    {
302 13
        if (!isset($this->associations[$fieldName])) {
303
            throw MappingException::unknownAssociation($fieldName, $this->getName());
304
        }
305
306 13
        return $this->associations[$fieldName];
307
    }
308
309 2
    public function setCustomRepositoryClass($customRepositoryClassName)
310
    {
311 2
        $this->repositoryClass = $customRepositoryClassName;
312 2
    }
313
314
    /**
315
     * @internal
316
     *
317
     * @param array $mapping
318
     *
319
     * @return void
320
     */
321 5
    public function addInheritedFieldMapping(array $mapping)
322
    {
323 5
        $this->fields[$mapping['field']]         = $mapping;
324 5
        $this->apiFieldNames[$mapping['field']]  = $mapping['api_field'];
325 5
        $this->fieldNames[$mapping['api_field']] = $mapping['field'];
326 5
    }
327
328
    /** {@inheritdoc} */
329
    public function getFieldName($apiFieldName)
330
    {
331
        return $this->fieldNames[$apiFieldName];
332
    }
333
334
    /** {@inheritdoc} */
335 17
    public function getApiFieldName($fieldName)
336
    {
337 17
        return $this->apiFieldNames[$fieldName];
338
    }
339
340
    public function hasApiField($apiFieldName)
341
    {
342
        return array_key_exists($apiFieldName, $this->fieldNames);
343
    }
344
345 14
    public function mapOneToMany(array $mapping)
346
    {
347 14
        $mapping = $this->validateAndCompleteOneToManyMapping($mapping);
348
349 14
        $this->storeMapping($mapping);
350 14
    }
351
352 14
    public function mapManyToOne(array $mapping)
353
    {
354 14
        $mapping = $this->validateAndCompleteOneToOneMapping($mapping);
355
356 14
        $this->storeMapping($mapping);
357 14
    }
358
359
    public function mapOneToOne(array $mapping)
360
    {
361
        $mapping = $this->validateAndCompleteOneToOneMapping($mapping);
362
363
        $this->storeMapping($mapping);
364
    }
365
366
    /** {@inheritdoc} */
367 11
    public function newInstance()
368
    {
369 11
        return $this->instantiator->instantiate($this->name);
370
    }
371
372 4
    public function isIdentifierComposite()
373
    {
374 4
        return $this->isIdentifierComposite;
375
    }
376
377
    /** {@inheritdoc} */
378
    public function getRootEntityName()
379
    {
380
        return $this->rootEntityName;
381
    }
382
383
    /**
384
     * Populates the entity identifier of an entity.
385
     *
386
     * @param object $entity
387
     * @param array  $id
388
     *
389
     * @return void
390
     */
391
    public function assignIdentifier($entity, array $id)
392
    {
393
        foreach ($id as $idField => $idValue) {
394
            $this->reflFields[$idField]->setValue($entity, $idValue);
395
        }
396
    }
397
398 5
    public function addInheritedAssociationMapping(array $mapping)
399
    {
400 5
        $this->associations[$mapping['field']]   = $mapping;
401 5
        $this->apiFieldNames[$mapping['field']]  = $mapping['api_field'];
402 5
        $this->fieldNames[$mapping['api_field']] = $mapping['field'];
403 5
    }
404
405
    /** {@inheritdoc} */
406 4
    public function getSubclasses()
407
    {
408
        //fixme
409 4
        return [];
410
    }
411
412
    /** {@inheritdoc} */
413 4
    public function getAssociationMappings()
414
    {
415 4
        return $this->associations;
416
    }
417
418 2
    public function isReadOnly()
419
    {
420 2
        return false;
421
    }
422
423
    /**
424
     * Sets the change tracking policy used by this class.
425
     *
426
     * @param integer $policy
427
     *
428
     * @return void
429
     */
430
    public function setChangeTrackingPolicy($policy)
431
    {
432
        $this->changeTrackingPolicy = $policy;
433
    }
434
435
    /**
436
     * Whether the change tracking policy of this class is "deferred explicit".
437
     *
438
     * @return boolean
439
     */
440
    public function isChangeTrackingDeferredExplicit()
441
    {
442
        return $this->changeTrackingPolicy == self::CHANGETRACKING_DEFERRED_EXPLICIT;
443
    }
444
445
    /**
446
     * Whether the change tracking policy of this class is "deferred implicit".
447
     *
448
     * @return boolean
449
     */
450 2
    public function isChangeTrackingDeferredImplicit()
451
    {
452 2
        return $this->changeTrackingPolicy == self::CHANGETRACKING_DEFERRED_IMPLICIT;
453
    }
454
455
    /**
456
     * Whether the change tracking policy of this class is "notify".
457
     *
458
     * @return boolean
459
     */
460
    public function isChangeTrackingNotify()
461
    {
462
        return $this->changeTrackingPolicy == self::CHANGETRACKING_NOTIFY;
463
    }
464
465 18
    public function mapIdentifier(array $mapping)
466
    {
467 18
        $this->setIdGeneratorType($mapping['generator']['strategy']);
468
469 18
        $this->mapField($mapping);
470 18
    }
471
472
    /**
473
     * Sets the type of Id generator to use for the mapped class.
474
     *
475
     * @param int $generatorType
476
     *
477
     * @return void
478
     */
479 18
    public function setIdGeneratorType($generatorType)
480
    {
481 18
        $this->generatorType = $generatorType;
482 18
    }
483
484 4
    public function isIdentifierNatural()
485
    {
486 4
        return $this->generatorType === self::GENERATOR_TYPE_NATURAL;
487
    }
488
489 4
    public function isIdentifierRemote()
490
    {
491 4
        return $this->generatorType === self::GENERATOR_TYPE_REMOTE;
492
    }
493
494
    /**
495
     * Validates & completes the basic mapping information that is common to all
496
     * association mappings (one-to-one, many-ot-one, one-to-many, many-to-many).
497
     *
498
     * @param array $mapping The mapping.
499
     *
500
     * @return array The updated mapping.
501
     *
502
     * @throws MappingException If something is wrong with the mapping.
503
     */
504 14
    protected function validateAndCompleteAssociationMapping(array $mapping)
505
    {
506 14
        if (!array_key_exists('api_field', $mapping)) {
507 14
            $mapping['api_field'] = $mapping['field'];
508 14
        }
509
510 14
        if (!isset($mapping['mappedBy'])) {
511 14
            $mapping['mappedBy'] = null;
512 14
        }
513
514 14
        if (!isset($mapping['inversedBy'])) {
515 14
            $mapping['inversedBy'] = null;
516 14
        }
517
518 14
        $mapping['isOwningSide'] = true; // assume owning side until we hit mappedBy
519
520
        // unset optional indexBy attribute if its empty
521 14
        if (!isset($mapping['indexBy']) || !$mapping['indexBy']) {
522 14
            unset($mapping['indexBy']);
523 14
        }
524
525
        // If targetEntity is unqualified, assume it is in the same namespace as
526
        // the sourceEntity.
527 14
        $mapping['source'] = $this->name;
528 14
        if (isset($mapping['target'])) {
529 14
            $mapping['target'] = ltrim($mapping['target'], '\\');
530 14
        }
531
532 14
        if (($mapping['type'] & self::MANY_TO_ONE) > 0 &&
533 14
            isset($mapping['orphanRemoval']) &&
534
            $mapping['orphanRemoval'] == true
535 14
        ) {
536
            throw new MappingException(
537
                sprintf('Illegal orphanRemoval %s for %s', $mapping['field'], $this->name)
538
            );
539
        }
540
541
        // Complete id mapping
542 14
        if (isset($mapping['id']) && $mapping['id'] === true) {
543 View Code Duplication
            if (isset($mapping['orphanRemoval']) && $mapping['orphanRemoval'] == true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
544
                throw new MappingException(
545
                    sprintf('Illegal orphanRemoval on identifier association %s for %s', $mapping['field'], $this->name)
546
                );
547
            }
548
549
            if (!in_array($mapping['field'], $this->identifier, true)) {
550
                $this->identifier[]              = $mapping['field'];
551
                $this->containsForeignIdentifier = true;
552
            }
553
554
            // Check for composite key
555
            if (!$this->isIdentifierComposite && count($this->identifier) > 1) {
556
                $this->isIdentifierComposite = true;
557
            }
558
        }
559
560
        // Mandatory and optional attributes for either side
561 14
        if (null !== $mapping['mappedBy']) {
562 14
            $mapping['isOwningSide'] = false;
563 14
        }
564
565 14 View Code Duplication
        if (isset($mapping['id']) && $mapping['id'] === true && $mapping['type'] & self::TO_MANY) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
566
            throw new MappingException(
567
                sprintf('Illegal toMany identifier association %s for %s', $mapping['field'], $this->name)
568
            );
569
        }
570
571
        // Fetch mode. Default fetch mode to LAZY, if not set.
572 14
        if (!isset($mapping['fetch'])) {
573 14
            $mapping['fetch'] = self::FETCH_LAZY;
574 14
        }
575
576
        // Cascades
577 14
        $cascades    = isset($mapping['cascade']) ? array_map('strtolower', $mapping['cascade']) : [];
578 14
        $allCascades = ['remove', 'persist', 'refresh', 'merge', 'detach'];
579 14
        if (in_array('all', $cascades, true)) {
580
            $cascades = $allCascades;
581 14
        } elseif (count($cascades) !== count(array_intersect($cascades, $allCascades))) {
582
            throw new MappingException('Invalid cascades: ' . implode(', ', $cascades));
583
        }
584 14
        $mapping['cascade']          = $cascades;
585 14
        $mapping['isCascadeRemove']  = in_array('remove', $cascades, true);
586 14
        $mapping['isCascadePersist'] = in_array('persist', $cascades, true);
587 14
        $mapping['isCascadeRefresh'] = in_array('refresh', $cascades, true);
588 14
        $mapping['isCascadeMerge']   = in_array('merge', $cascades, true);
589 14
        $mapping['isCascadeDetach']  = in_array('detach', $cascades, true);
590
591 14
        return $mapping;
592
    }
593
594 14
    private function storeMapping(array $mapping)
595
    {
596 14
        $this->assertFieldNotMapped($mapping['field']);
597
598 14
        $this->apiFieldNames[$mapping['field']]  = $mapping['api_field'];
599 14
        $this->fieldNames[$mapping['api_field']] = $mapping['field'];
600 14
        $this->associations[$mapping['field']]   = $mapping;
601 14
    }
602
603 18
    private function validateAndCompleteFieldMapping(array &$mapping)
604
    {
605 18
        if (!array_key_exists('api_field', $mapping)) {
606 17
            $mapping['api_field'] = $mapping['field']; //todo: invent naming strategy
607 17
        }
608
609 18
        $this->apiFieldNames[$mapping['field']]  = $mapping['api_field'];
610 18
        $this->fieldNames[$mapping['api_field']] = $mapping['field'];
611
612
        // Complete id mapping
613 18
        if (isset($mapping['id']) && $mapping['id'] === true) {
614 18
            if (!in_array($mapping['field'], $this->identifier, true)) {
615 18
                $this->identifier[] = $mapping['field'];
616 18
            }
617
            // Check for composite key
618 18
            if (!$this->isIdentifierComposite && count($this->identifier) > 1) {
619 1
                $this->isIdentifierComposite = true;
620 1
            }
621 18
        }
622 18
    }
623
624
    /**
625
     * @param string $fieldName
626
     *
627
     * @throws MappingException
628
     */
629 18
    private function assertFieldNotMapped($fieldName)
630
    {
631 18
        if (array_key_exists($fieldName, $this->fields) ||
632 18
            array_key_exists($fieldName, $this->associations) ||
633 18
            array_key_exists($fieldName, $this->identifier)
634 18
        ) {
635
            throw new MappingException('Field already mapped');
636
        }
637 18
    }
638
639
    /**
640
     * @param array $mapping
641
     *
642
     * @return array
643
     * @throws MappingException
644
     * @throws \InvalidArgumentException
645
     */
646 14
    private function validateAndCompleteOneToManyMapping(array $mapping)
647
    {
648 14
        $mapping = $this->validateAndCompleteAssociationMapping($mapping);
649
650
        // OneToMany-side MUST be inverse (must have mappedBy)
651 14
        if (!isset($mapping['mappedBy'])) {
652
            throw new MappingException(
653
                sprintf('Many to many requires mapped by: %s', $mapping['field'])
654
            );
655
        }
656 14
        $mapping['orphanRemoval']   = isset($mapping['orphanRemoval']) && $mapping['orphanRemoval'];
657 14
        $mapping['isCascadeRemove'] = $mapping['orphanRemoval'] || $mapping['isCascadeRemove'];
658 14
        $this->assertMappingOrderBy($mapping);
659
660 14
        return $mapping;
661
    }
662
663
    /**
664
     * @param array $mapping
665
     *
666
     * @throws \InvalidArgumentException
667
     */
668 14
    private function assertMappingOrderBy(array $mapping)
669
    {
670 14
        if (array_key_exists('orderBy', $mapping) && !is_array($mapping['orderBy'])) {
671
            throw new \InvalidArgumentException(
672
                "'orderBy' is expected to be an array, not " . gettype($mapping['orderBy'])
673
            );
674
        }
675 14
    }
676
677
    /**
678
     * @param array $mapping
679
     *
680
     * @return array
681
     */
682 14
    private function validateAndCompleteOneToOneMapping(array $mapping)
683
    {
684 14
        $mapping = $this->validateAndCompleteAssociationMapping($mapping);
685
686 14
        $mapping['orphanRemoval']   = isset($mapping['orphanRemoval']) && $mapping['orphanRemoval'];
687 14
        $mapping['isCascadeRemove'] = $mapping['orphanRemoval'] || $mapping['isCascadeRemove'];
688 14
        if ($mapping['orphanRemoval']) {
689
            unset($mapping['unique']);
690
        }
691
692 14
        return $mapping;
693
    }
694
695
    /**
696
     * Populates the entity identifier of an entity.
697
     *
698
     * @param object $entity
699
     * @param array  $id
700
     *
701
     * @return void
702
     *
703
     * @todo Rename to assignIdentifier()
704
     */
705
    public function setIdentifierValues($entity, array $id)
706
    {
707
        foreach ($id as $idField => $idValue) {
708
            $this->reflFields[$idField]->setValue($entity, $idValue);
709
        }
710
    }
711
}
712