Failed Conditions
CANCELLED  
Pull Request — master (#7095)
by Benjamin
10:13
created

testFetchOverrideMapping()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Mapping;
6
7
use Doctrine\DBAL\Types\Type;
8
use Doctrine\ORM\Annotation as ORM;
9
use Doctrine\ORM\EntityManagerInterface;
10
use Doctrine\ORM\Events;
11
use Doctrine\ORM\Mapping;
12
use Doctrine\ORM\Mapping\ClassMetadata;
13
use Doctrine\ORM\Mapping\ClassMetadataFactory;
14
use Doctrine\ORM\Mapping\Factory\DefaultNamingStrategy;
15
use Doctrine\ORM\Mapping\Factory\UnderscoreNamingStrategy;
16
use Doctrine\ORM\Mapping\MappingException;
17
use Doctrine\ORM\Reflection\RuntimeReflectionService;
18
use Doctrine\Tests\Models\Cache\City;
19
use Doctrine\Tests\Models\CMS\CmsAddress;
20
use Doctrine\Tests\Models\CMS\CmsAddressListener;
21
use Doctrine\Tests\Models\CMS\CmsUser;
22
use Doctrine\Tests\Models\Company\CompanyContract;
23
use Doctrine\Tests\Models\Company\CompanyContractListener;
24
use Doctrine\Tests\Models\Company\CompanyFixContract;
25
use Doctrine\Tests\Models\Company\CompanyFlexContract;
26
use Doctrine\Tests\Models\Company\CompanyFlexUltraContract;
27
use Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener;
28
use Doctrine\Tests\Models\Company\CompanyPerson;
29
use Doctrine\Tests\Models\Quote;
30
use Doctrine\Tests\Models\DDC1476\DDC1476EntityWithDefaultFieldType;
31
use Doctrine\Tests\Models\DDC2825\ExplicitSchemaAndTable;
32
use Doctrine\Tests\Models\DDC2825\SchemaAndTableInTableName;
33
use Doctrine\Tests\Models\DDC3579\DDC3579Admin;
34
use Doctrine\Tests\Models\DDC5934\DDC5934Contract;
35
use Doctrine\Tests\Models\DDC869\DDC869ChequePayment;
36
use Doctrine\Tests\Models\DDC869\DDC869CreditCardPayment;
37
use Doctrine\Tests\Models\DDC869\DDC869PaymentRepository;
38
use Doctrine\Tests\Models\DDC889\DDC889Class;
39
use Doctrine\Tests\Models\DDC889\DDC889Entity;
40
use Doctrine\Tests\Models\DDC964\DDC964Admin;
41
use Doctrine\Tests\Models\DDC964\DDC964Guest;
42
use Doctrine\Tests\OrmTestCase;
43
44
abstract class AbstractMappingDriverTest extends OrmTestCase
45
{
46
    /**
47
     * @var Mapping\ClassMetadataBuildingContext
48
     */
49
    protected $metadataBuildingContext;
50
51
    public function setUp()
52
    {
53
        parent::setUp();
54
55
        $this->metadataBuildingContext = new Mapping\ClassMetadataBuildingContext(
56
            $this->createMock(ClassMetadataFactory::class),
57
            new RuntimeReflectionService()
58
        );
59
    }
60
61
    abstract protected function loadDriver();
62
63
    public function createClassMetadata($entityClassName)
64
    {
65
        $mappingDriver = $this->loadDriver();
66
67
        $class = new ClassMetadata($entityClassName, $this->metadataBuildingContext);
68
69
        $mappingDriver->loadMetadataForClass($entityClassName, $class, $this->metadataBuildingContext);
70
71
        return $class;
72
    }
73
74
    protected function createClassMetadataFactory(EntityManagerInterface $em = null) : ClassMetadataFactory
75
    {
76
        $driver     = $this->loadDriver();
77
        $em         = $em ?: $this->getTestEntityManager();
78
        $factory    = new ClassMetadataFactory();
79
80
        $em->getConfiguration()->setMetadataDriverImpl($driver);
81
        $factory->setEntityManager($em);
82
83
        return $factory;
84
    }
85
86
    /**
87
     * @param ClassMetadata $class
88
     */
89
    public function testEntityTableNameAndInheritance()
90
    {
91
        $class = $this->createClassMetadata(User::class);
92
93
        self::assertEquals('cms_users', $class->getTableName());
94
        self::assertEquals(Mapping\InheritanceType::NONE, $class->inheritanceType);
95
96
        return $class;
97
    }
98
99
    /**
100
     * @param ClassMetadata $class
101
     */
102
    public function testEntityIndexes()
103
    {
104
        $class = $this->createClassMetadata('Doctrine\Tests\ORM\Mapping\User');
105
106
        self::assertCount(2, $class->table->getIndexes());
107
        self::assertEquals(
108
            [
109
                'name_idx' => [
110
                    'name'    => 'name_idx',
111
                    'columns' => ['name'],
112
                    'unique'  => false,
113
                    'options' => [],
114
                    'flags'   => [],
115
                ],
116
                0 => [
117
                    'name'    => null,
118
                    'columns' => ['user_email'],
119
                    'unique'  => false,
120
                    'options' => [],
121
                    'flags'   => [],
122
                ]
123
            ],
124
            $class->table->getIndexes()
125
        );
126
127
        return $class;
128
    }
129
130
    public function testEntityIndexFlagsAndPartialIndexes()
131
    {
132
        $class = $this->createClassMetadata(Comment::class);
133
134
        self::assertEquals(
135
            [
136
                0 => [
137
                    'name'    => null,
138
                    'columns' => ['content'],
139
                    'unique'  => false,
140
                    'flags'   => ['fulltext'],
141
                    'options' => ['where' => 'content IS NOT NULL'],
142
                ]
143
            ],
144
            $class->table->getIndexes()
145
        );
146
    }
147
148
    /**
149
     * @depends testEntityTableNameAndInheritance
150
     * @param ClassMetadata $class
151
     */
152
    public function testEntityUniqueConstraints($class)
153
    {
154
        self::assertCount(1, $class->table->getUniqueConstraints());
155
        self::assertEquals(
156
            [
157
                'search_idx' => [
158
                    'name'    => 'search_idx',
159
                    'columns' => ['name', 'user_email'],
160
                    'options' => [],
161
                    'flags'   => [],
162
                ]
163
            ],
164
            $class->table->getUniqueConstraints()
165
        );
166
167
        return $class;
168
    }
169
170
    /**
171
     * @depends testEntityTableNameAndInheritance
172
     * @param ClassMetadata $class
173
     */
174
    public function testEntityOptions($class)
175
    {
176
        self::assertCount(2, $class->table->getOptions());
177
        self::assertEquals(
178
            [
179
                'foo' => 'bar',
180
                'baz' => ['key' => 'val']
181
            ],
182
            $class->table->getOptions()
183
        );
184
185
        return $class;
186
    }
187
188
    /**
189
     * @depends testEntityOptions
190
     * @param ClassMetadata $class
191
     */
192
    public function testEntitySequence($class)
193
    {
194
        self::assertInternalType(
195
            'array',
196
            $class->getProperty('id')->getValueGenerator()->getDefinition(),
0 ignored issues
show
Bug introduced by
The method getValueGenerator() does not exist on Doctrine\ORM\Mapping\Property. Did you maybe mean getValue()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

196
            $class->getProperty('id')->/** @scrutinizer ignore-call */ getValueGenerator()->getDefinition(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
197
            'No Sequence Definition set on this driver.'
198
        );
199
        self::assertEquals(
200
            [
201
                'sequenceName'   => 'tablename_seq',
202
                'allocationSize' => 100,
203
            ],
204
            $class->getProperty('id')->getValueGenerator()->getDefinition()
205
        );
206
    }
207
208
    public function testEntityCustomGenerator()
209
    {
210
        $class = $this->createClassMetadata(Animal::class);
211
212
        self::assertEquals(Mapping\GeneratorType::CUSTOM, $class->getProperty('id')->getValueGenerator()->getType(), "Generator Type");
213
        self::assertEquals(
214
            [
215
                'class'     => 'stdClass',
216
                'arguments' => [],
217
            ],
218
            $class->getProperty('id')->getValueGenerator()->getDefinition(),
219
            "Generator Definition"
220
        );
221
    }
222
223
224
    /**
225
     * @depends testEntityTableNameAndInheritance
226
     * @param ClassMetadata $class
227
     */
228
    public function testProperties($class)
229
    {
230
        self::assertCount(7, $class->getDeclaredPropertiesIterator());
0 ignored issues
show
Bug introduced by
$class->getDeclaredPropertiesIterator() of type Generator is incompatible with the type Countable|iterable expected by parameter $haystack of PHPUnit\Framework\Assert::assertCount(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

230
        self::assertCount(7, /** @scrutinizer ignore-type */ $class->getDeclaredPropertiesIterator());
Loading history...
231
232
        self::assertNotNull($class->getProperty('id'));
233
        self::assertNotNull($class->getProperty('name'));
234
        self::assertNotNull($class->getProperty('email'));
235
        self::assertNotNull($class->getProperty('version'));
236
        self::assertNotNull($class->getProperty('version'));
237
238
        return $class;
239
    }
240
241
    /**
242
     * @depends testProperties
243
     * @param ClassMetadata $class
244
     */
245
    public function testVersionProperty($class)
246
    {
247
        self::assertTrue($class->isVersioned());
248
        self::assertNotNull($class->versionProperty);
249
250
        $versionPropertyName = $class->versionProperty->getName();
0 ignored issues
show
Bug introduced by
The method getName() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

250
        /** @scrutinizer ignore-call */ 
251
        $versionPropertyName = $class->versionProperty->getName();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
251
252
        self::assertEquals("version", $versionPropertyName);
253
        self::assertNotNull($class->getProperty($versionPropertyName));
254
    }
255
256
    /**
257
     * @depends testEntityTableNameAndInheritance
258
     * @param ClassMetadata $class
259
     */
260
    public function testFieldMappingsColumnNames($class)
261
    {
262
        self::assertNotNull($class->getProperty('id'));
263
        self::assertNotNull($class->getProperty('name'));
264
        self::assertNotNull($class->getProperty('email'));
265
266
        self::assertEquals("id", $class->getProperty('id')->getColumnName());
0 ignored issues
show
Bug introduced by
The method getColumnName() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

266
        self::assertEquals("id", $class->getProperty('id')->/** @scrutinizer ignore-call */ getColumnName());
Loading history...
267
        self::assertEquals("name", $class->getProperty('name')->getColumnName());
268
        self::assertEquals("user_email", $class->getProperty('email')->getColumnName());
269
270
        return $class;
271
    }
272
273
    /**
274
     * @depends testEntityTableNameAndInheritance
275
     * @param ClassMetadata $class
276
     */
277
    public function testStringFieldMappings($class)
278
    {
279
        self::assertNotNull($class->getProperty('name'));
280
281
        $property = $class->getProperty('name');
282
283
        self::assertEquals('string', $property->getTypeName());
0 ignored issues
show
Bug introduced by
The method getTypeName() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

283
        self::assertEquals('string', $property->/** @scrutinizer ignore-call */ getTypeName());
Loading history...
284
        self::assertEquals(50, $property->getLength());
0 ignored issues
show
Bug introduced by
The method getLength() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

284
        self::assertEquals(50, $property->/** @scrutinizer ignore-call */ getLength());
Loading history...
285
        self::assertTrue($property->isNullable());
0 ignored issues
show
Bug introduced by
The method isNullable() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

285
        self::assertTrue($property->/** @scrutinizer ignore-call */ isNullable());
Loading history...
286
        self::assertTrue($property->isUnique());
0 ignored issues
show
Bug introduced by
The method isUnique() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

286
        self::assertTrue($property->/** @scrutinizer ignore-call */ isUnique());
Loading history...
287
288
        return $class;
289
    }
290
291
    /**
292
     * @depends testEntityTableNameAndInheritance
293
     *
294
     * @param ClassMetadata $class
295
     *
296
     * @return ClassMetadata
297
     */
298
    public function testFieldOptions(ClassMetadata $class)
299
    {
300
        self::assertNotNull($class->getProperty('name'));
301
302
        $property = $class->getProperty('name');
303
        $expected = ['foo' => 'bar', 'baz' => ['key' => 'val'], 'fixed' => false];
304
305
        self::assertEquals($expected, $property->getOptions());
0 ignored issues
show
Bug introduced by
The method getOptions() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

305
        self::assertEquals($expected, $property->/** @scrutinizer ignore-call */ getOptions());
Loading history...
306
307
        return $class;
308
    }
309
310
    /**
311
     * @depends testEntityTableNameAndInheritance
312
     * @param ClassMetadata $class
313
     */
314
    public function testIdFieldOptions($class)
315
    {
316
        self::assertNotNull($class->getProperty('id'));
317
318
        $property = $class->getProperty('id');
319
        $expected = ['foo' => 'bar', 'unsigned' => false];
320
321
        self::assertEquals($expected, $property->getOptions());
322
323
        return $class;
324
    }
325
326
    /**
327
     * @depends testProperties
328
     * @param ClassMetadata $class
329
     */
330
    public function testIdentifier($class)
331
    {
332
        self::assertNotNull($class->getProperty('id'));
333
334
        $property = $class->getProperty('id');
335
336
        self::assertEquals('integer', $property->getTypeName());
337
        self::assertEquals(['id'], $class->identifier);
338
        self::assertEquals(Mapping\GeneratorType::AUTO, $property->getValueGenerator()->getType(), "ID-Generator is not GeneratorType::AUTO");
339
340
        return $class;
341
    }
342
343
    /**
344
     * @group #6129
345
     *
346
     * @return ClassMetadata
347
     */
348
    public function testBooleanValuesForOptionIsSetCorrectly()
349
    {
350
        $class = $this->createClassMetadata(User::class);
351
352
        $idOptions = $class->getProperty('id')->getOptions();
353
        $nameOptions = $class->getProperty('name')->getOptions();
354
355
        self::assertInternalType('bool', $idOptions['unsigned']);
356
        self::assertFalse($idOptions['unsigned']);
357
        self::assertInternalType('bool', $nameOptions['fixed']);
358
        self::assertFalse($nameOptions['fixed']);
359
360
        return $class;
361
    }
362
363
    public function testOneToOneUnidirectional() : void
364
    {
365
        // One to One owning
366
        $fullAddressClass = $this->createClassMetadata(Quote\FullAddress::class);
367
        $cityAssociation  = $fullAddressClass->getProperty('city');
368
369
        self::assertInstanceOf(Mapping\OneToOneAssociationMetadata::class, $cityAssociation);
370
        self::assertTrue($cityAssociation->isOwningSide());
0 ignored issues
show
Bug introduced by
The method isOwningSide() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

370
        self::assertTrue($cityAssociation->/** @scrutinizer ignore-call */ isOwningSide());
Loading history...
371
    }
372
373
    public function testOneToOneBidirectional() : void
374
    {
375
        // One to One owning / One To One inverse
376
        $addressClass    = $this->createClassMetadata(Quote\Address::class);
377
        $userAssociation = $addressClass->getProperty('user');
378
379
        self::assertInstanceOf(Mapping\OneToOneAssociationMetadata::class, $userAssociation);
380
        self::assertTrue($userAssociation->isOwningSide());
381
382
        $userClass          = $this->createClassMetadata(Quote\User::class);
383
        $addressAssociation = $userClass->getProperty('address');
384
385
        self::assertInstanceOf(Mapping\OneToOneAssociationMetadata::class, $addressAssociation);
386
        self::assertFalse($addressAssociation->isOwningSide());
387
    }
388
389
    public function testManyToOneUnidirectional() : void
390
    {
391
        // Many to One owning
392
        $groupClass       = $this->createClassMetadata(Quote\Group::class);
393
        $groupAssociation = $groupClass->getProperty('parent');
394
395
        self::assertInstanceOf(Mapping\ManyToOneAssociationMetadata::class, $groupAssociation);
396
        self::assertTrue($groupAssociation->isOwningSide());
397
    }
398
399
    public function testManyToOneBidirectional() : void
400
    {
401
        // Many To One owning / One To Many inverse
402
        $phoneClass      = $this->createClassMetadata(Quote\Phone::class);
403
        $userAssociation = $phoneClass->getProperty('user');
404
405
        self::assertInstanceOf(Mapping\ManyToOneAssociationMetadata::class, $userAssociation);
406
        self::assertTrue($userAssociation->isOwningSide());
407
408
        $userClass        = $this->createClassMetadata(Quote\User::class);
409
        $phoneAssociation = $userClass->getProperty('phones');
410
411
        self::assertInstanceOf(Mapping\OneToManyAssociationMetadata::class, $phoneAssociation);
412
        self::assertFalse($phoneAssociation->isOwningSide());
413
    }
414
415
    public function testManyToManyBidirectional() : void
416
    {
417
        // Many to Many owning / Many to Many inverse
418
        $userClass        = $this->createClassMetadata(Quote\User::class);
419
        $groupAssociation = $userClass->getProperty('groups');
420
421
        self::assertInstanceOf(Mapping\ManyToManyAssociationMetadata::class, $groupAssociation);
422
        self::assertTrue($groupAssociation->isOwningSide());
423
424
        $groupClass      = $this->createClassMetadata(Quote\Group::class);
425
        $userAssociation = $groupClass->getProperty('users');
426
427
        self::assertInstanceOf(Mapping\ManyToManyAssociationMetadata::class, $userAssociation);
428
        self::assertFalse($userAssociation->isOwningSide());
429
    }
430
431
    /**
432
     * @depends testProperties
433
     * @param ClassMetadata $class
434
     */
435
    public function testOwningOneToOneAssociation($class)
436
    {
437
        self::assertArrayHasKey('address', iterator_to_array($class->getDeclaredPropertiesIterator()));
438
439
        $association = $class->getProperty('address');
440
441
        self::assertTrue($association->isOwningSide());
442
        self::assertEquals('user', $association->getInversedBy());
0 ignored issues
show
Bug introduced by
The method getInversedBy() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

442
        self::assertEquals('user', $association->/** @scrutinizer ignore-call */ getInversedBy());
Loading history...
443
        // Check cascading
444
        self::assertEquals(['remove'], $association->getCascade());
0 ignored issues
show
Bug introduced by
The method getCascade() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

444
        self::assertEquals(['remove'], $association->/** @scrutinizer ignore-call */ getCascade());
Loading history...
445
446
        return $class;
447
    }
448
449
    /**
450
     * @depends testOwningOneToOneAssociation
451
     * @param ClassMetadata $class
452
     */
453
    public function testInverseOneToManyAssociation($class)
454
    {
455
        self::assertArrayHasKey('phonenumbers', iterator_to_array($class->getDeclaredPropertiesIterator()));
456
457
        $association = $class->getProperty('phonenumbers');
458
459
        self::assertFalse($association->isOwningSide());
460
        self::assertTrue($association->isOrphanRemoval());
0 ignored issues
show
Bug introduced by
The method isOrphanRemoval() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

460
        self::assertTrue($association->/** @scrutinizer ignore-call */ isOrphanRemoval());
Loading history...
461
462
        // Check cascading
463
        self::assertEquals(['persist', 'remove'], $association->getCascade());
464
465
        // Test Order By
466
        self::assertEquals(['number' => 'ASC'], $association->getOrderBy());
0 ignored issues
show
Bug introduced by
The method getOrderBy() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\ToManyAssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

466
        self::assertEquals(['number' => 'ASC'], $association->/** @scrutinizer ignore-call */ getOrderBy());
Loading history...
467
468
        return $class;
469
    }
470
471
    /**
472
     * @depends testInverseOneToManyAssociation
473
     * @param ClassMetadata $class
474
     */
475
    public function testManyToManyAssociationWithCascadeAll($class)
476
    {
477
        self::assertArrayHasKey('groups', iterator_to_array($class->getDeclaredPropertiesIterator()));
478
479
        $association = $class->getProperty('groups');
480
481
        self::assertTrue($association->isOwningSide());
482
483
        // Make sure that cascade-all works as expected
484
        self::assertEquals(['remove', 'persist', 'refresh'], $association->getCascade());
485
486
        // Test Order By
487
        self::assertEquals([], $association->getOrderBy());
488
489
        return $class;
490
    }
491
492
    /**
493
     * @depends testManyToManyAssociationWithCascadeAll
494
     * @param ClassMetadata $class
495
     */
496
    public function testLifecycleCallbacks($class)
497
    {
498
        self::assertCount(2, $class->lifecycleCallbacks);
499
        self::assertEquals($class->lifecycleCallbacks['prePersist'][0], 'doStuffOnPrePersist');
500
        self::assertEquals($class->lifecycleCallbacks['postPersist'][0], 'doStuffOnPostPersist');
501
502
        return $class;
503
    }
504
505
    /**
506
     * @depends testManyToManyAssociationWithCascadeAll
507
     * @param ClassMetadata $class
508
     */
509
    public function testLifecycleCallbacksSupportMultipleMethodNames($class)
510
    {
511
        self::assertCount(2, $class->lifecycleCallbacks['prePersist']);
512
        self::assertEquals($class->lifecycleCallbacks['prePersist'][1], 'doOtherStuffOnPrePersistToo');
513
514
        return $class;
515
    }
516
517
    /**
518
     * @depends testLifecycleCallbacksSupportMultipleMethodNames
519
     * @param ClassMetadata $class
520
     */
521
    public function testJoinColumnUniqueAndNullable($class)
522
    {
523
        // Non-Nullability of Join Column
524
        $association = $class->getProperty('groups');
525
        $joinTable   = $association->getJoinTable();
0 ignored issues
show
Bug introduced by
The method getJoinTable() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\ManyToManyAssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

525
        /** @scrutinizer ignore-call */ 
526
        $joinTable   = $association->getJoinTable();
Loading history...
526
        $joinColumns = $joinTable->getJoinColumns();
527
        $joinColumn  = reset($joinColumns);
528
529
        self::assertFalse($joinColumn->isNullable());
530
        self::assertFalse($joinColumn->isUnique());
531
532
        return $class;
533
    }
534
535
    /**
536
     * @depends testJoinColumnUniqueAndNullable
537
     * @param ClassMetadata $class
538
     */
539
    public function testColumnDefinition($class)
540
    {
541
        self::assertNotNull($class->getProperty('email'));
542
543
        $property           = $class->getProperty('email');
544
        $association        = $class->getProperty('groups');
545
        $joinTable          = $association->getJoinTable();
546
        $inverseJoinColumns = $joinTable->getInverseJoinColumns();
547
        $inverseJoinColumn  = reset($inverseJoinColumns);
548
549
        self::assertEquals("CHAR(32) NOT NULL", $property->getColumnDefinition());
0 ignored issues
show
Bug introduced by
The method getColumnDefinition() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

549
        self::assertEquals("CHAR(32) NOT NULL", $property->/** @scrutinizer ignore-call */ getColumnDefinition());
Loading history...
550
        self::assertEquals("INT NULL", $inverseJoinColumn->getColumnDefinition());
551
552
        return $class;
553
    }
554
555
    /**
556
     * @depends testColumnDefinition
557
     * @param ClassMetadata $class
558
     */
559
    public function testJoinColumnOnDelete($class)
560
    {
561
        $association = $class->getProperty('address');
562
        $joinColumns = $association->getJoinColumns();
0 ignored issues
show
Bug introduced by
The method getJoinColumns() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\ToOneAssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

562
        /** @scrutinizer ignore-call */ 
563
        $joinColumns = $association->getJoinColumns();
Loading history...
563
        $joinColumn  = reset($joinColumns);
564
565
        self::assertEquals('CASCADE', $joinColumn->getOnDelete());
566
567
        return $class;
568
    }
569
570
    /**
571
     * @group DDC-514
572
     */
573
    public function testDiscriminatorColumnDefaults()
574
    {
575
        if (strpos(get_class($this), 'PHPMappingDriver') !== false) {
576
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
577
        }
578
579
        $class = $this->createClassMetadata(Animal::class);
580
581
        self::assertNotNull($class->discriminatorColumn);
582
583
        $discrColumn = $class->discriminatorColumn;
584
585
        self::assertEquals('Animal', $discrColumn->getTableName());
586
        self::assertEquals('discr', $discrColumn->getColumnName());
587
        self::assertEquals('string', $discrColumn->getTypeName());
588
        self::assertEquals(32, $discrColumn->getLength());
589
        self::assertNull($discrColumn->getColumnDefinition());
590
    }
591
592
    /**
593
     * @group DDC-869
594
     */
595
    public function testMappedSuperclassWithRepository()
596
    {
597
        $em      = $this->getTestEntityManager();
598
        $factory = $this->createClassMetadataFactory($em);
599
        $class   = $factory->getMetadataFor(DDC869CreditCardPayment::class);
600
601
        self::assertNotNull($class->getProperty('id'));
602
        self::assertNotNull($class->getProperty('value'));
603
        self::assertNotNull($class->getProperty('creditCardNumber'));
604
        self::assertEquals($class->getCustomRepositoryClassName(), DDC869PaymentRepository::class);
605
        self::assertInstanceOf(DDC869PaymentRepository::class, $em->getRepository(DDC869CreditCardPayment::class));
606
        self::assertTrue($em->getRepository(DDC869ChequePayment::class)->isTrue());
607
608
        $class = $factory->getMetadataFor(DDC869ChequePayment::class);
609
610
        self::assertNotNull($class->getProperty('id'));
611
        self::assertNotNull($class->getProperty('value'));
612
        self::assertNotNull($class->getProperty('serialNumber'));
613
        self::assertEquals($class->getCustomRepositoryClassName(), DDC869PaymentRepository::class);
614
        self::assertInstanceOf(DDC869PaymentRepository::class, $em->getRepository(DDC869ChequePayment::class));
615
        self::assertTrue($em->getRepository(DDC869ChequePayment::class)->isTrue());
616
    }
617
618
    /**
619
     * @group DDC-1476
620
     */
621
    public function testDefaultFieldType()
622
    {
623
        $factory = $this->createClassMetadataFactory();
624
        $class   = $factory->getMetadataFor(DDC1476EntityWithDefaultFieldType::class);
625
626
        self::assertNotNull($class->getProperty('id'));
627
        self::assertNotNull($class->getProperty('name'));
628
629
        $idProperty = $class->getProperty('id');
630
        $nameProperty = $class->getProperty('name');
631
632
        self::assertInstanceOf(Mapping\FieldMetadata::class, $idProperty);
633
        self::assertInstanceOf(Mapping\FieldMetadata::class, $nameProperty);
634
635
        self::assertEquals('string', $idProperty->getTypeName());
636
        self::assertEquals('string', $nameProperty->getTypeName());
637
638
        self::assertEquals('id', $idProperty->getName());
639
        self::assertEquals('name', $nameProperty->getName());
640
641
        self::assertEquals('id', $idProperty->getColumnName());
642
        self::assertEquals('name', $nameProperty->getColumnName());
643
644
        self::assertFalse($idProperty->hasValueGenerator());
0 ignored issues
show
Bug introduced by
The method hasValueGenerator() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

644
        self::assertFalse($idProperty->/** @scrutinizer ignore-call */ hasValueGenerator());
Loading history...
645
    }
646
647
    /**
648
     * @group DDC-1170
649
     */
650
    public function testIdentifierColumnDefinition()
651
    {
652
        $class = $this->createClassMetadata(DDC1170Entity::class);
653
654
        self::assertNotNull($class->getProperty('id'));
655
        self::assertNotNull($class->getProperty('value'));
656
657
        self::assertEquals("INT unsigned NOT NULL", $class->getProperty('id')->getColumnDefinition());
658
        self::assertEquals("VARCHAR(255) NOT NULL", $class->getProperty('value')->getColumnDefinition());
659
    }
660
661
    /**
662
     * @group DDC-559
663
     */
664
    public function testNamingStrategy()
665
    {
666
        $em      = $this->getTestEntityManager();
667
        $factory = $this->createClassMetadataFactory($em);
668
669
        self::assertInstanceOf(DefaultNamingStrategy::class, $em->getConfiguration()->getNamingStrategy());
670
        $em->getConfiguration()->setNamingStrategy(new UnderscoreNamingStrategy(CASE_UPPER));
671
        self::assertInstanceOf(UnderscoreNamingStrategy::class, $em->getConfiguration()->getNamingStrategy());
672
673
        $class        = $factory->getMetadataFor(DDC1476EntityWithDefaultFieldType::class);
674
        $idProperty   = $class->getProperty('id');
675
        $nameProperty = $class->getProperty('name');
676
677
        self::assertEquals('ID', $idProperty->getColumnName());
678
        self::assertEquals('NAME', $nameProperty->getColumnName());
679
        self::assertEquals('DDC1476ENTITY_WITH_DEFAULT_FIELD_TYPE', $class->table->getName());
680
    }
681
682
    /**
683
     * @group DDC-807
684
     * @group DDC-553
685
     */
686
    public function testDiscriminatorColumnDefinition()
687
    {
688
        $class = $this->createClassMetadata(DDC807Entity::class);
689
690
        self::assertNotNull($class->discriminatorColumn);
691
692
        $discrColumn = $class->discriminatorColumn;
693
694
        self::assertEquals('dtype', $discrColumn->getColumnName());
695
        self::assertEquals("ENUM('ONE','TWO')", $discrColumn->getColumnDefinition());
696
    }
697
698
    /**
699
     * @group DDC-889
700
     */
701
    public function testInvalidEntityOrMappedSuperClassShouldMentionParentClasses()
702
    {
703
        $this->expectException(MappingException::class);
704
        $this->expectExceptionMessage('Class "Doctrine\Tests\Models\DDC889\DDC889Class" sub class of "Doctrine\Tests\Models\DDC889\DDC889SuperClass" is not a valid entity or mapped super class.');
705
706
        $this->createClassMetadata(DDC889Class::class);
707
    }
708
709
    /**
710
     * @group DDC-889
711
     */
712
    public function testIdentifierRequiredShouldMentionParentClasses()
713
    {
714
        $factory = $this->createClassMetadataFactory();
715
716
        $this->expectException(MappingException::class);
717
        $this->expectExceptionMessage('No identifier/primary key specified for Entity "Doctrine\Tests\Models\DDC889\DDC889Entity" sub class of "Doctrine\Tests\Models\DDC889\DDC889SuperClass". Every Entity must have an identifier/primary key.');
718
719
        $factory->getMetadataFor(DDC889Entity::class);
720
    }
721
722
    /*
723
     * @group DDC-964
724
     */
725
    public function testAssociationOverridesMapping()
726
    {
727
        $factory        = $this->createClassMetadataFactory();
728
        $adminMetadata  = $factory->getMetadataFor(DDC964Admin::class);
729
        $guestMetadata  = $factory->getMetadataFor(DDC964Guest::class);
730
731
        // assert groups association mappings
732
        self::assertArrayHasKey('groups', iterator_to_array($guestMetadata->getDeclaredPropertiesIterator()));
733
        self::assertArrayHasKey('groups', iterator_to_array($adminMetadata->getDeclaredPropertiesIterator()));
734
735
        $guestGroups = $guestMetadata->getProperty('groups');
736
        $adminGroups = $adminMetadata->getProperty('groups');
737
738
        // assert not override attributes
739
        self::assertEquals($guestGroups->getName(), $adminGroups->getName());
740
        self::assertEquals(get_class($guestGroups), get_class($adminGroups));
741
        self::assertEquals($guestGroups->getMappedBy(), $adminGroups->getMappedBy());
0 ignored issues
show
Bug introduced by
The method getMappedBy() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

741
        self::assertEquals($guestGroups->/** @scrutinizer ignore-call */ getMappedBy(), $adminGroups->getMappedBy());
Loading history...
742
        self::assertEquals($guestGroups->getInversedBy(), $adminGroups->getInversedBy());
743
        self::assertEquals($guestGroups->isOwningSide(), $adminGroups->isOwningSide());
744
        self::assertEquals($guestGroups->getFetchMode(), $adminGroups->getFetchMode());
0 ignored issues
show
Bug introduced by
The method getFetchMode() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

744
        self::assertEquals($guestGroups->/** @scrutinizer ignore-call */ getFetchMode(), $adminGroups->getFetchMode());
Loading history...
745
        self::assertEquals($guestGroups->getCascade(), $adminGroups->getCascade());
746
747
        // assert not override attributes
748
        $guestGroupsJoinTable          = $guestGroups->getJoinTable();
749
        $guestGroupsJoinColumns        = $guestGroupsJoinTable->getJoinColumns();
750
        $guestGroupsJoinColumn         = reset($guestGroupsJoinColumns);
751
        $guestGroupsInverseJoinColumns = $guestGroupsJoinTable->getInverseJoinColumns();
752
        $guestGroupsInverseJoinColumn  = reset($guestGroupsInverseJoinColumns);
753
754
        self::assertEquals('ddc964_users_groups', $guestGroupsJoinTable->getName());
755
        self::assertEquals('user_id', $guestGroupsJoinColumn->getColumnName());
756
        self::assertEquals('group_id', $guestGroupsInverseJoinColumn->getColumnName());
757
758
        $adminGroupsJoinTable          = $adminGroups->getJoinTable();
759
        $adminGroupsJoinColumns        = $adminGroupsJoinTable->getJoinColumns();
760
        $adminGroupsJoinColumn         = reset($adminGroupsJoinColumns);
761
        $adminGroupsInverseJoinColumns = $adminGroupsJoinTable->getInverseJoinColumns();
762
        $adminGroupsInverseJoinColumn  = reset($adminGroupsInverseJoinColumns);
763
764
        self::assertEquals('ddc964_users_admingroups', $adminGroupsJoinTable->getName());
765
        self::assertEquals('adminuser_id', $adminGroupsJoinColumn->getColumnName());
766
        self::assertEquals('admingroup_id', $adminGroupsInverseJoinColumn->getColumnName());
767
768
        // assert address association mappings
769
        self::assertArrayHasKey('address', iterator_to_array($guestMetadata->getDeclaredPropertiesIterator()));
770
        self::assertArrayHasKey('address', iterator_to_array($adminMetadata->getDeclaredPropertiesIterator()));
771
772
        $guestAddress = $guestMetadata->getProperty('address');
773
        $adminAddress = $adminMetadata->getProperty('address');
774
775
        // assert not override attributes
776
        self::assertEquals($guestAddress->getName(), $adminAddress->getName());
777
        self::assertEquals(get_class($guestAddress), get_class($adminAddress));
778
        self::assertEquals($guestAddress->getMappedBy(), $adminAddress->getMappedBy());
779
        self::assertEquals($guestAddress->getInversedBy(), $adminAddress->getInversedBy());
780
        self::assertEquals($guestAddress->isOwningSide(), $adminAddress->isOwningSide());
781
        self::assertEquals($guestAddress->getFetchMode(), $adminAddress->getFetchMode());
782
        self::assertEquals($guestAddress->getCascade(), $adminAddress->getCascade());
783
784
        // assert override
785
        $guestAddressJoinColumns = $guestAddress->getJoinColumns();
786
        $guestAddressJoinColumn  = reset($guestAddressJoinColumns);
787
788
        self::assertEquals('address_id', $guestAddressJoinColumn->getColumnName());
789
790
        $adminAddressJoinColumns = $adminAddress->getJoinColumns();
791
        $adminAddressJoinColumn  = reset($adminAddressJoinColumns);
792
793
        self::assertEquals('adminaddress_id', $adminAddressJoinColumn->getColumnName());
794
    }
795
796
    /*
797
     * @group DDC-3579
798
     */
799
    public function testInversedByOverrideMapping()
800
    {
801
        $factory        = $this->createClassMetadataFactory();
802
        $adminMetadata  = $factory->getMetadataFor(DDC3579Admin::class);
803
804
        // assert groups association mappings
805
        self::assertArrayHasKey('groups', iterator_to_array($adminMetadata->getDeclaredPropertiesIterator()));
806
807
        $adminGroups = $adminMetadata->getProperty('groups');
808
809
        // assert override
810
        self::assertEquals('admins', $adminGroups->getInversedBy());
811
    }
812
813
    /**
814
     * @group DDC-5934
815
     */
816
    public function testFetchOverrideMapping()
817
    {
818
        // check override metadata
819
        $contractMetadata = $this->createClassMetadataFactory()->getMetadataFor(DDC5934Contract::class);
820
821
        self::assertArrayHasKey('members', iterator_to_array($contractMetadata->getDeclaredPropertiesIterator()));
822
823
        $contractMembers = $contractMetadata->getProperty('members');
824
825
        self::assertSame(Mapping\FetchMode::EXTRA_LAZY, $contractMembers->getFetchMode());
826
    }
827
828
    /**
829
     * @group DDC-964
830
     */
831
    public function testAttributeOverridesMapping()
832
    {
833
        $factory       = $this->createClassMetadataFactory();
834
        $adminMetadata = $factory->getMetadataFor(DDC964Admin::class);
835
836
        self::assertEquals(
837
            [
838
                'user_id' => 'id',
839
                'user_name' => 'name',
840
                'adminaddress_id' => 'address',
841
            ],
842
            $adminMetadata->fieldNames
843
        );
844
845
        self::assertNotNull($adminMetadata->getProperty('id'));
846
847
        $idProperty = $adminMetadata->getProperty('id');
848
849
        self::assertTrue($idProperty->isPrimaryKey());
850
        self::assertEquals('id', $idProperty->getName());
851
        self::assertEquals('user_id', $idProperty->getColumnName());
852
853
        self::assertNotNull($adminMetadata->getProperty('name'));
854
855
        $nameProperty = $adminMetadata->getProperty('name');
856
857
        self::assertEquals('name', $nameProperty->getName());
858
        self::assertEquals('user_name', $nameProperty->getColumnName());
859
        self::assertEquals(250, $nameProperty->getLength());
860
        self::assertTrue($nameProperty->isNullable());
861
        self::assertFalse($nameProperty->isUnique());
862
863
        $guestMetadata = $factory->getMetadataFor(DDC964Guest::class);
864
865
        self::assertEquals(
866
            [
867
                'guest_id' => 'id',
868
                'guest_name' => 'name',
869
                'address_id' => 'address',
870
            ],
871
            $guestMetadata->fieldNames
872
        );
873
874
        self::assertNotNull($guestMetadata->getProperty('id'));
875
876
        $idProperty = $guestMetadata->getProperty('id');
877
878
        self::assertTrue($idProperty->isPrimaryKey());
879
        self::assertEquals('id', $idProperty->getName());
880
        self::assertEquals('guest_id', $idProperty->getColumnName());
881
882
        self::assertNotNull($guestMetadata->getProperty('name'));
883
884
        $nameProperty = $guestMetadata->getProperty('name');
885
886
        self::assertEquals('name', $nameProperty->getName());
887
        self::assertEquals('guest_name', $nameProperty->getColumnName());
888
        self::assertEquals(240, $nameProperty->getLength());
889
        self::assertFalse($nameProperty->isNullable());
890
        self::assertTrue($nameProperty->isUnique());
891
    }
892
893
    /**
894
     * @group DDC-1955
895
     */
896
    public function testEntityListeners()
897
    {
898
        $factory    = $this->createClassMetadataFactory();
899
        $superClass = $factory->getMetadataFor(CompanyContract::class);
900
        $flexClass  = $factory->getMetadataFor(CompanyFixContract::class);
901
        $fixClass   = $factory->getMetadataFor(CompanyFlexContract::class);
902
903
        self::assertArrayHasKey(Events::prePersist, $superClass->entityListeners);
904
        self::assertArrayHasKey(Events::postPersist, $superClass->entityListeners);
905
906
        self::assertCount(1, $superClass->entityListeners[Events::prePersist]);
907
        self::assertCount(1, $superClass->entityListeners[Events::postPersist]);
908
909
        $postPersist = $superClass->entityListeners[Events::postPersist][0];
910
        $prePersist  = $superClass->entityListeners[Events::prePersist][0];
911
912
        self::assertEquals(CompanyContractListener::class, $postPersist['class']);
913
        self::assertEquals(CompanyContractListener::class, $prePersist['class']);
914
        self::assertEquals('postPersistHandler', $postPersist['method']);
915
        self::assertEquals('prePersistHandler', $prePersist['method']);
916
917
        //Inherited listeners
918
        self::assertEquals($fixClass->entityListeners, $superClass->entityListeners);
919
        self::assertEquals($flexClass->entityListeners, $superClass->entityListeners);
920
    }
921
922
    /**
923
     * @group DDC-1955
924
     */
925
    public function testEntityListenersOverride()
926
    {
927
        $factory    = $this->createClassMetadataFactory();
928
        $ultraClass = $factory->getMetadataFor(CompanyFlexUltraContract::class);
929
930
        //overridden listeners
931
        self::assertArrayHasKey(Events::postPersist, $ultraClass->entityListeners);
932
        self::assertArrayHasKey(Events::prePersist, $ultraClass->entityListeners);
933
934
        self::assertCount(1, $ultraClass->entityListeners[Events::postPersist]);
935
        self::assertCount(3, $ultraClass->entityListeners[Events::prePersist]);
936
937
        $postPersist = $ultraClass->entityListeners[Events::postPersist][0];
938
        $prePersist  = $ultraClass->entityListeners[Events::prePersist][0];
939
940
        self::assertEquals(CompanyContractListener::class, $postPersist['class']);
941
        self::assertEquals(CompanyContractListener::class, $prePersist['class']);
942
        self::assertEquals('postPersistHandler', $postPersist['method']);
943
        self::assertEquals('prePersistHandler', $prePersist['method']);
944
945
        $prePersist = $ultraClass->entityListeners[Events::prePersist][1];
946
        self::assertEquals(CompanyFlexUltraContractListener::class, $prePersist['class']);
947
        self::assertEquals('prePersistHandler1', $prePersist['method']);
948
949
        $prePersist = $ultraClass->entityListeners[Events::prePersist][2];
950
        self::assertEquals(CompanyFlexUltraContractListener::class, $prePersist['class']);
951
        self::assertEquals('prePersistHandler2', $prePersist['method']);
952
    }
953
954
955
    /**
956
     * @group DDC-1955
957
     */
958
    public function testEntityListenersNamingConvention()
959
    {
960
        $factory  = $this->createClassMetadataFactory();
961
        $metadata = $factory->getMetadataFor(CmsAddress::class);
962
963
        self::assertArrayHasKey(Events::postPersist, $metadata->entityListeners);
964
        self::assertArrayHasKey(Events::prePersist, $metadata->entityListeners);
965
        self::assertArrayHasKey(Events::postUpdate, $metadata->entityListeners);
966
        self::assertArrayHasKey(Events::preUpdate, $metadata->entityListeners);
967
        self::assertArrayHasKey(Events::postRemove, $metadata->entityListeners);
968
        self::assertArrayHasKey(Events::preRemove, $metadata->entityListeners);
969
        self::assertArrayHasKey(Events::postLoad, $metadata->entityListeners);
970
        self::assertArrayHasKey(Events::preFlush, $metadata->entityListeners);
971
972
        self::assertCount(1, $metadata->entityListeners[Events::postPersist]);
973
        self::assertCount(1, $metadata->entityListeners[Events::prePersist]);
974
        self::assertCount(1, $metadata->entityListeners[Events::postUpdate]);
975
        self::assertCount(1, $metadata->entityListeners[Events::preUpdate]);
976
        self::assertCount(1, $metadata->entityListeners[Events::postRemove]);
977
        self::assertCount(1, $metadata->entityListeners[Events::preRemove]);
978
        self::assertCount(1, $metadata->entityListeners[Events::postLoad]);
979
        self::assertCount(1, $metadata->entityListeners[Events::preFlush]);
980
981
        $postPersist = $metadata->entityListeners[Events::postPersist][0];
982
        $prePersist  = $metadata->entityListeners[Events::prePersist][0];
983
        $postUpdate  = $metadata->entityListeners[Events::postUpdate][0];
984
        $preUpdate   = $metadata->entityListeners[Events::preUpdate][0];
985
        $postRemove  = $metadata->entityListeners[Events::postRemove][0];
986
        $preRemove   = $metadata->entityListeners[Events::preRemove][0];
987
        $postLoad    = $metadata->entityListeners[Events::postLoad][0];
988
        $preFlush    = $metadata->entityListeners[Events::preFlush][0];
989
990
        self::assertEquals(CmsAddressListener::class, $postPersist['class']);
991
        self::assertEquals(CmsAddressListener::class, $prePersist['class']);
992
        self::assertEquals(CmsAddressListener::class, $postUpdate['class']);
993
        self::assertEquals(CmsAddressListener::class, $preUpdate['class']);
994
        self::assertEquals(CmsAddressListener::class, $postRemove['class']);
995
        self::assertEquals(CmsAddressListener::class, $preRemove['class']);
996
        self::assertEquals(CmsAddressListener::class, $postLoad['class']);
997
        self::assertEquals(CmsAddressListener::class, $preFlush['class']);
998
999
        self::assertEquals(Events::postPersist, $postPersist['method']);
1000
        self::assertEquals(Events::prePersist, $prePersist['method']);
1001
        self::assertEquals(Events::postUpdate, $postUpdate['method']);
1002
        self::assertEquals(Events::preUpdate, $preUpdate['method']);
1003
        self::assertEquals(Events::postRemove, $postRemove['method']);
1004
        self::assertEquals(Events::preRemove, $preRemove['method']);
1005
        self::assertEquals(Events::postLoad, $postLoad['method']);
1006
        self::assertEquals(Events::preFlush, $preFlush['method']);
1007
    }
1008
1009
    /**
1010
     * @group DDC-2183
1011
     */
1012
    public function testSecondLevelCacheMapping()
1013
    {
1014
        $factory = $this->createClassMetadataFactory();
1015
        $class   = $factory->getMetadataFor(City::class);
1016
1017
        self::assertNotNull($class->getCache());
1018
        self::assertEquals(Mapping\CacheUsage::READ_ONLY, $class->getCache()->getUsage());
1019
        self::assertEquals('doctrine_tests_models_cache_city', $class->getCache()->getRegion());
1020
1021
        self::assertArrayHasKey('state', iterator_to_array($class->getDeclaredPropertiesIterator()));
1022
1023
        $stateAssociation = $class->getProperty('state');
1024
1025
        self::assertNotNull($stateAssociation->getCache());
0 ignored issues
show
Bug introduced by
The method getCache() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata or Doctrine\ORM\Mapping\EmbeddedClassMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1025
        self::assertNotNull($stateAssociation->/** @scrutinizer ignore-call */ getCache());
Loading history...
1026
        self::assertEquals(Mapping\CacheUsage::READ_ONLY, $stateAssociation->getCache()->getUsage());
1027
        self::assertEquals('doctrine_tests_models_cache_city__state', $stateAssociation->getCache()->getRegion());
1028
1029
        self::assertArrayHasKey('attractions', iterator_to_array($class->getDeclaredPropertiesIterator()));
1030
1031
        $attractionsAssociation = $class->getProperty('attractions');
1032
1033
        self::assertNotNull($attractionsAssociation->getCache());
1034
        self::assertEquals(Mapping\CacheUsage::READ_ONLY, $attractionsAssociation->getCache()->getUsage());
1035
        self::assertEquals('doctrine_tests_models_cache_city__attractions', $attractionsAssociation->getCache()->getRegion());
1036
    }
1037
1038
    /**
1039
     * @group DDC-2825
1040
     * @group 881
1041
     */
1042
    public function testSchemaDefinitionViaExplicitTableSchemaAnnotationProperty()
1043
    {
1044
        $factory  = $this->createClassMetadataFactory();
1045
        $metadata = $factory->getMetadataFor(ExplicitSchemaAndTable::class);
1046
1047
        self::assertSame('explicit_schema', $metadata->getSchemaName());
1048
        self::assertSame('explicit_table', $metadata->getTableName());
1049
    }
1050
1051
    /**
1052
     * @group DDC-2825
1053
     * @group 881
1054
     */
1055
    public function testSchemaDefinitionViaSchemaDefinedInTableNameInTableAnnotationProperty()
1056
    {
1057
        $factory  = $this->createClassMetadataFactory();
1058
        $metadata = $factory->getMetadataFor(SchemaAndTableInTableName::class);
1059
1060
        self::assertSame('implicit_schema', $metadata->getSchemaName());
1061
        self::assertSame('implicit_table', $metadata->getTableName());
1062
    }
1063
1064
    /**
1065
     * @group DDC-514
1066
     * @group DDC-1015
1067
     */
1068
    public function testDiscriminatorColumnDefaultLength()
1069
    {
1070
        if (strpos(get_class($this), 'PHPMappingDriver') !== false) {
1071
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
1072
        }
1073
1074
        $class = $this->createClassMetadata(SingleTableEntityNoDiscriminatorColumnMapping::class);
1075
1076
        self::assertEquals(255, $class->discriminatorColumn->getLength());
1077
1078
        $class = $this->createClassMetadata(SingleTableEntityIncompleteDiscriminatorColumnMapping::class);
1079
1080
        self::assertEquals(255, $class->discriminatorColumn->getLength());
1081
    }
1082
1083
    /**
1084
     * @group DDC-514
1085
     * @group DDC-1015
1086
     */
1087
    public function testDiscriminatorColumnDefaultType()
1088
    {
1089
        if (strpos(get_class($this), 'PHPMappingDriver') !== false) {
1090
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
1091
        }
1092
1093
        $class = $this->createClassMetadata(SingleTableEntityNoDiscriminatorColumnMapping::class);
1094
1095
        self::assertEquals('string', $class->discriminatorColumn->getTypeName());
1096
1097
        $class = $this->createClassMetadata(SingleTableEntityIncompleteDiscriminatorColumnMapping::class);
1098
1099
        self::assertEquals('string', $class->discriminatorColumn->getTypeName());
1100
    }
1101
1102
    /**
1103
     * @group DDC-514
1104
     * @group DDC-1015
1105
     */
1106
    public function testDiscriminatorColumnDefaultName()
1107
    {
1108
        if (strpos(get_class($this), 'PHPMappingDriver') !== false) {
1109
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
1110
        }
1111
1112
        $class = $this->createClassMetadata(SingleTableEntityNoDiscriminatorColumnMapping::class);
1113
1114
        self::assertEquals('dtype', $class->discriminatorColumn->getColumnName());
1115
1116
        $class = $this->createClassMetadata(SingleTableEntityIncompleteDiscriminatorColumnMapping::class);
1117
1118
        self::assertEquals('dtype', $class->discriminatorColumn->getColumnName());
1119
    }
1120
}
1121
1122
/**
1123
 * @ORM\Entity
1124
 * @ORM\HasLifecycleCallbacks
1125
 * @ORM\Table(
1126
 *  name="cms_users",
1127
 *  uniqueConstraints={@ORM\UniqueConstraint(name="search_idx", columns={"name", "user_email"})},
1128
 *  indexes={@ORM\Index(name="name_idx", columns={"name"}), @ORM\Index(columns={"user_email"})},
1129
 *  options={"foo": "bar", "baz": {"key": "val"}}
1130
 * )
1131
 */
1132
class User
1133
{
1134
    /**
1135
     * @ORM\Id
1136
     * @ORM\Column(type="integer", options={"foo": "bar", "unsigned": false})
1137
     * @ORM\GeneratedValue(strategy="AUTO")
1138
     * @ORM\SequenceGenerator(sequenceName="tablename_seq", allocationSize=100)
1139
     */
1140
    public $id;
1141
1142
    /**
1143
     * @ORM\Column(length=50, nullable=true, unique=true, options={"foo": "bar", "baz": {"key": "val"}, "fixed": false})
1144
     */
1145
    public $name;
1146
1147
    /**
1148
     * @ORM\Column(name="user_email", columnDefinition="CHAR(32) NOT NULL")
1149
     */
1150
    public $email;
1151
1152
    /**
1153
     * @ORM\OneToOne(targetEntity=Address::class, cascade={"remove"}, inversedBy="user")
1154
     * @ORM\JoinColumn(onDelete="CASCADE")
1155
     */
1156
    public $address;
1157
1158
    /**
1159
     * @ORM\OneToMany(targetEntity=Phonenumber::class, mappedBy="user", cascade={"persist"}, orphanRemoval=true)
1160
     * @ORM\OrderBy({"number"="ASC"})
1161
     */
1162
    public $phonenumbers;
1163
1164
    /**
1165
     * @ORM\ManyToMany(targetEntity=Group::class, cascade={"all"})
1166
     * @ORM\JoinTable(name="cms_user_groups",
1167
     *    joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false, unique=false)},
1168
     *    inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id", columnDefinition="INT NULL")}
1169
     * )
1170
     */
1171
    public $groups;
1172
1173
    /**
1174
     * @ORM\Column(type="integer")
1175
     * @ORM\Version
1176
     */
1177
    public $version;
1178
1179
1180
    /**
1181
     * @ORM\PrePersist
1182
     */
1183
    public function doStuffOnPrePersist()
1184
    {
1185
    }
1186
1187
    /**
1188
     * @ORM\PrePersist
1189
     */
1190
    public function doOtherStuffOnPrePersistToo()
1191
    {
1192
    }
1193
1194
    /**
1195
     * @ORM\PostPersist
1196
     */
1197
    public function doStuffOnPostPersist()
1198
    {
1199
    }
1200
1201
    public static function loadMetadata(ClassMetadata $metadata)
1202
    {
1203
        $tableMetadata = new Mapping\TableMetadata();
1204
1205
        $tableMetadata->setName('cms_users');
1206
        $tableMetadata->addIndex(
1207
            [
1208
                'name'    => 'name_idx',
1209
                'columns' => ['name'],
1210
                'unique'  => false,
1211
                'options' => [],
1212
                'flags'   => [],
1213
            ]
1214
        );
1215
1216
        $tableMetadata->addIndex(
1217
            [
1218
                'name'    => null,
1219
                'columns' => ['user_email'],
1220
                'unique'  => false,
1221
                'options' => [],
1222
                'flags'   => [],
1223
            ]
1224
        );
1225
1226
        $tableMetadata->addUniqueConstraint(
1227
            [
1228
                'name'    => 'search_idx',
1229
                'columns' => ['name', 'user_email'],
1230
                'options' => [],
1231
                'flags'   => [],
1232
            ]
1233
        );
1234
        $tableMetadata->addOption('foo', 'bar');
1235
        $tableMetadata->addOption('baz', ['key' => 'val']);
1236
1237
        $metadata->setTable($tableMetadata);
1238
        $metadata->setInheritanceType(Mapping\InheritanceType::NONE);
0 ignored issues
show
Bug introduced by
Doctrine\ORM\Mapping\InheritanceType::NONE of type string is incompatible with the type integer expected by parameter $type of Doctrine\ORM\Mapping\Cla...a::setInheritanceType(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1238
        $metadata->setInheritanceType(/** @scrutinizer ignore-type */ Mapping\InheritanceType::NONE);
Loading history...
1239
        $metadata->setChangeTrackingPolicy(Mapping\ChangeTrackingPolicy::DEFERRED_IMPLICIT);
1240
1241
        $metadata->addLifecycleCallback('doStuffOnPrePersist', 'prePersist');
1242
        $metadata->addLifecycleCallback('doOtherStuffOnPrePersistToo', 'prePersist');
1243
        $metadata->addLifecycleCallback('doStuffOnPostPersist', 'postPersist');
1244
1245
        $metadata->setGeneratorDefinition(
0 ignored issues
show
Bug introduced by
The method setGeneratorDefinition() does not exist on Doctrine\ORM\Mapping\ClassMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1245
        $metadata->/** @scrutinizer ignore-call */ 
1246
                   setGeneratorDefinition(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1246
            [
1247
                'sequenceName'   => 'tablename_seq',
1248
                'allocationSize' => 100,
1249
            ]
1250
        );
1251
1252
        $fieldMetadata = new Mapping\FieldMetadata('id');
1253
        $fieldMetadata->setType(Type::getType('integer'));
1254
        $fieldMetadata->setPrimaryKey(true);
1255
        $fieldMetadata->setOptions(['foo' => 'bar', 'unsigned' => false]);
1256
1257
        $metadata->addProperty($fieldMetadata);
1258
1259
        $fieldMetadata = new Mapping\FieldMetadata('name');
1260
        $fieldMetadata->setType(Type::getType('string'));
1261
        $fieldMetadata->setLength(50);
1262
        $fieldMetadata->setNullable(true);
1263
        $fieldMetadata->setUnique(true);
1264
        $fieldMetadata->setOptions(
1265
            [
1266
                'foo' => 'bar',
1267
                'baz' => [
1268
                    'key' => 'val',
1269
                ],
1270
                'fixed' => false,
1271
            ]
1272
        );
1273
1274
        $metadata->addProperty($fieldMetadata);
1275
1276
        $fieldMetadata = new Mapping\FieldMetadata('email');
1277
1278
        $fieldMetadata->setType(Type::getType('string'));
1279
        $fieldMetadata->setColumnName('user_email');
1280
        $fieldMetadata->setColumnDefinition('CHAR(32) NOT NULL');
1281
1282
        $metadata->addProperty($fieldMetadata);
1283
1284
        $fieldMetadata = new Mapping\VersionFieldMetadata('version');
1285
1286
        $fieldMetadata->setType(Type::getType('integer'));
1287
1288
        $metadata->addProperty($fieldMetadata);
1289
        $metadata->setIdGeneratorType(Mapping\GeneratorType::AUTO);
0 ignored issues
show
Bug introduced by
The method setIdGeneratorType() does not exist on Doctrine\ORM\Mapping\ClassMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1289
        $metadata->/** @scrutinizer ignore-call */ 
1290
                   setIdGeneratorType(Mapping\GeneratorType::AUTO);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1290
1291
        $joinColumns = [];
1292
1293
        $joinColumn = new Mapping\JoinColumnMetadata();
1294
1295
        $joinColumn->setColumnName('address_id');
1296
        $joinColumn->setReferencedColumnName('id');
1297
        $joinColumn->setOnDelete('CASCADE');
1298
1299
        $joinColumns[] = $joinColumn;
1300
1301
        $association = new Mapping\OneToOneAssociationMetadata('address');
1302
1303
        $association->setJoinColumns($joinColumns);
1304
        $association->setTargetEntity(Address::class);
1305
        $association->setInversedBy('user');
1306
        $association->setCascade(['remove']);
1307
        $association->setOrphanRemoval(false);
1308
1309
        $metadata->addProperty($association);
1310
1311
        $association = new Mapping\OneToManyAssociationMetadata('phonenumbers');
1312
1313
        $association->setTargetEntity(Phonenumber::class);
1314
        $association->setMappedBy('user');
1315
        $association->setCascade(['persist']);
1316
        $association->setOrderBy(['number' => 'ASC']);
1317
        $association->setOrphanRemoval(true);
1318
1319
        $metadata->addProperty($association);
1320
1321
        $joinTable = new Mapping\JoinTableMetadata();
1322
        $joinTable->setName('cms_users_groups');
1323
1324
        $joinColumn = new Mapping\JoinColumnMetadata();
1325
1326
        $joinColumn->setColumnName('user_id');
1327
        $joinColumn->setReferencedColumnName('id');
1328
        $joinColumn->setNullable(false);
1329
        $joinColumn->setUnique(false);
1330
1331
        $joinTable->addJoinColumn($joinColumn);
1332
1333
        $joinColumn = new Mapping\JoinColumnMetadata();
1334
1335
        $joinColumn->setColumnName('group_id');
1336
        $joinColumn->setReferencedColumnName('id');
1337
        $joinColumn->setColumnDefinition('INT NULL');
1338
1339
        $joinTable->addInverseJoinColumn($joinColumn);
1340
1341
        $association = new Mapping\ManyToManyAssociationMetadata('groups');
1342
1343
        $association->setJoinTable($joinTable);
1344
        $association->setTargetEntity(Group::class);
1345
        $association->setCascade(['remove', 'persist', 'refresh']);
1346
1347
        $metadata->addProperty($association);
1348
    }
1349
}
1350
1351
/**
1352
 * @ORM\Entity
1353
 * @ORM\InheritanceType("SINGLE_TABLE")
1354
 * @ORM\DiscriminatorMap({"cat" = Cat::class, "dog" = Dog::class})
1355
 * @ORM\DiscriminatorColumn(name="discr", length=32, type="string")
1356
 */
1357
abstract class Animal
1358
{
1359
    /**
1360
     * @ORM\Id @ORM\Column(type="string") @ORM\GeneratedValue(strategy="CUSTOM")
1361
     * @ORM\CustomIdGenerator(class=stdClass::class)
1362
     */
1363
    public $id;
1364
}
1365
1366
/** @ORM\Entity */
1367
class Cat extends Animal
1368
{
1369
}
1370
1371
/** @ORM\Entity */
1372
class Dog extends Animal
1373
{
1374
}
1375
1376
/**
1377
 * @ORM\Entity
1378
 */
1379
class DDC1170Entity
1380
{
1381
    /**
1382
     * @param string $value
1383
     */
1384
    public function __construct($value = null)
1385
    {
1386
        $this->value = $value;
1387
    }
1388
1389
    /**
1390
     * @ORM\Id
1391
     * @ORM\GeneratedValue(strategy="NONE")
1392
     * @ORM\Column(type="integer", columnDefinition = "INT unsigned NOT NULL")
1393
     */
1394
    private $id;
1395
1396
    /**
1397
     * @ORM\Column(columnDefinition = "VARCHAR(255) NOT NULL")
1398
     */
1399
    private $value;
1400
1401
    /**
1402
     * @return int
1403
     */
1404
    public function getId()
1405
    {
1406
        return $this->id;
1407
    }
1408
1409
    /**
1410
     * @return string
1411
     */
1412
    public function getValue()
1413
    {
1414
        return $this->value;
1415
    }
1416
}
1417
1418
/**
1419
 * @ORM\Entity
1420
 * @ORM\InheritanceType("SINGLE_TABLE")
1421
 * @ORM\DiscriminatorMap({"ONE" = DDC807SubClasse1::class, "TWO" = DDC807SubClasse2::class})
1422
 * @ORM\DiscriminatorColumn(name = "dtype", columnDefinition="ENUM('ONE','TWO')")
1423
 */
1424
class DDC807Entity
1425
{
1426
    /**
1427
     * @ORM\Id
1428
     * @ORM\Column(type="integer")
1429
     * @ORM\GeneratedValue(strategy="NONE")
1430
     */
1431
    public $id;
1432
}
1433
1434
class DDC807SubClasse1 {}
1435
class DDC807SubClasse2 {}
1436
1437
class Address {}
1438
class Phonenumber {}
1439
class Group {}
1440
1441
/**
1442
 * @ORM\Entity
1443
 * @ORM\Table(indexes={@ORM\Index(columns={"content"}, flags={"fulltext"}, options={"where": "content IS NOT NULL"})})
1444
 */
1445
class Comment
1446
{
1447
    /**
1448
     * @ORM\Column(type="text")
1449
     */
1450
    private $content;
0 ignored issues
show
introduced by
The private property $content is not used, and could be removed.
Loading history...
1451
}
1452
1453
/**
1454
 * @ORM\Entity
1455
 * @ORM\InheritanceType("SINGLE_TABLE")
1456
 * @ORM\DiscriminatorMap({
1457
 *     "ONE" = Doctrine\Tests\ORM\Mapping\SingleTableEntityNoDiscriminatorColumnMappingSub1::class,
1458
 *     "TWO" = Doctrine\Tests\ORM\Mapping\SingleTableEntityNoDiscriminatorColumnMappingSub2::class
1459
 * })
1460
 */
1461
class SingleTableEntityNoDiscriminatorColumnMapping
1462
{
1463
    /**
1464
     * @ORM\Id
1465
     * @ORM\Column(type="integer")
1466
     * @ORM\GeneratedValue(strategy="NONE")
1467
     */
1468
    public $id;
1469
}
1470
1471
/**
1472
 * @ORM\Entity
1473
 */
1474
class SingleTableEntityNoDiscriminatorColumnMappingSub1 extends SingleTableEntityNoDiscriminatorColumnMapping {}
1475
1476
/**
1477
 * @ORM\Entity
1478
 */
1479
class SingleTableEntityNoDiscriminatorColumnMappingSub2 extends SingleTableEntityNoDiscriminatorColumnMapping {}
1480
1481
/**
1482
 * @ORM\Entity
1483
 * @ORM\InheritanceType("SINGLE_TABLE")
1484
 * @ORM\DiscriminatorMap({
1485
 *     "ONE" = Doctrine\Tests\ORM\Mapping\SingleTableEntityIncompleteDiscriminatorColumnMappingSub1::class,
1486
 *     "TWO" = Doctrine\Tests\ORM\Mapping\SingleTableEntityIncompleteDiscriminatorColumnMappingSub2::class
1487
 * })
1488
 * @ORM\DiscriminatorColumn(name="dtype")
1489
 */
1490
class SingleTableEntityIncompleteDiscriminatorColumnMapping
1491
{
1492
    /**
1493
     * @ORM\Id
1494
     * @ORM\Column(type="integer")
1495
     * @ORM\GeneratedValue(strategy="NONE")
1496
     */
1497
    public $id;
1498
}
1499
1500
class SingleTableEntityIncompleteDiscriminatorColumnMappingSub1
1501
    extends SingleTableEntityIncompleteDiscriminatorColumnMapping {}
0 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
1502
1503
class SingleTableEntityIncompleteDiscriminatorColumnMappingSub2
1504
    extends SingleTableEntityIncompleteDiscriminatorColumnMapping {}
0 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
1505