1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Doctrine\Tests\ORM\Tools\Export; |
4
|
|
|
|
5
|
|
|
use Doctrine\Common\EventManager; |
6
|
|
|
use Doctrine\Common\Persistence\Mapping\Driver\PHPDriver; |
7
|
|
|
use Doctrine\ORM\Configuration; |
8
|
|
|
use Doctrine\ORM\Events; |
9
|
|
|
use Doctrine\ORM\Mapping\ClassMetadata; |
10
|
|
|
use Doctrine\ORM\Mapping\ClassMetadataFactory; |
11
|
|
|
use Doctrine\ORM\Mapping\ClassMetadataInfo; |
12
|
|
|
use Doctrine\ORM\Mapping\Driver\AnnotationDriver; |
13
|
|
|
use Doctrine\ORM\Mapping\Driver\XmlDriver; |
14
|
|
|
use Doctrine\ORM\Mapping\Driver\YamlDriver; |
15
|
|
|
use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory; |
16
|
|
|
use Doctrine\ORM\Tools\EntityGenerator; |
17
|
|
|
use Doctrine\ORM\Tools\Export\ClassMetadataExporter; |
18
|
|
|
use Doctrine\Tests\Mocks\ConnectionMock; |
19
|
|
|
use Doctrine\Tests\Mocks\DriverMock; |
20
|
|
|
use Doctrine\Tests\Mocks\EntityManagerMock; |
21
|
|
|
use Doctrine\Tests\OrmTestCase; |
22
|
|
|
use Symfony\Component\Yaml\Parser; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Test case for ClassMetadataExporter |
26
|
|
|
* |
27
|
|
|
* @author Jonathan H. Wage <[email protected]> |
28
|
|
|
* @author Roman Borschel <[email protected] |
29
|
|
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
30
|
|
|
* @link http://www.phpdoctrine.org |
31
|
|
|
* @since 2.0 |
32
|
|
|
* @version $Revision$ |
33
|
|
|
*/ |
34
|
|
|
abstract class AbstractClassMetadataExporterTest extends OrmTestCase |
35
|
|
|
{ |
36
|
|
|
protected $_extension; |
37
|
|
|
|
38
|
|
|
abstract protected function _getType(); |
39
|
|
|
|
40
|
|
View Code Duplication |
protected function _createEntityManager($metadataDriver) |
41
|
|
|
{ |
42
|
|
|
$driverMock = new DriverMock(); |
43
|
|
|
$config = new Configuration(); |
44
|
|
|
$config->setProxyDir(__DIR__ . '/../../Proxies'); |
45
|
|
|
$config->setProxyNamespace('Doctrine\Tests\Proxies'); |
46
|
|
|
$eventManager = new EventManager(); |
47
|
|
|
$conn = new ConnectionMock([], $driverMock, $config, $eventManager); |
48
|
|
|
$config->setMetadataDriverImpl($metadataDriver); |
49
|
|
|
|
50
|
|
|
return EntityManagerMock::create($conn, $config, $eventManager); |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
protected function _createMetadataDriver($type, $path) |
54
|
|
|
{ |
55
|
|
|
$mappingDriver = [ |
56
|
|
|
'php' => PHPDriver::class, |
57
|
|
|
'annotation' => AnnotationDriver::class, |
58
|
|
|
'xml' => XmlDriver::class, |
59
|
|
|
'yaml' => YamlDriver::class, |
60
|
|
|
]; |
61
|
|
|
|
62
|
|
|
$this->assertArrayHasKey($type, $mappingDriver, "There is no metadata driver for the type '" . $type . "'."); |
63
|
|
|
|
64
|
|
|
$class = $mappingDriver[$type]; |
65
|
|
|
$driver = ($type === 'annotation') |
66
|
|
|
? $this->createAnnotationDriver([$path]) |
67
|
|
|
: new $class($path); |
68
|
|
|
|
69
|
|
|
return $driver; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
protected function _createClassMetadataFactory($em, $type) |
73
|
|
|
{ |
74
|
|
|
$factory = ($type === 'annotation') |
75
|
|
|
? new ClassMetadataFactory() |
76
|
|
|
: new DisconnectedClassMetadataFactory(); |
77
|
|
|
|
78
|
|
|
$factory->setEntityManager($em); |
79
|
|
|
|
80
|
|
|
return $factory; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
public function testExportDirectoryAndFilesAreCreated() |
84
|
|
|
{ |
85
|
|
|
$this->_deleteDirectory(__DIR__ . '/export/'.$this->_getType()); |
86
|
|
|
|
87
|
|
|
$type = $this->_getType(); |
88
|
|
|
$metadataDriver = $this->_createMetadataDriver($type, __DIR__ . '/' . $type); |
89
|
|
|
$em = $this->_createEntityManager($metadataDriver); |
90
|
|
|
$cmf = $this->_createClassMetadataFactory($em, $type); |
91
|
|
|
$metadata = $cmf->getAllMetadata(); |
92
|
|
|
|
93
|
|
|
$metadata[0]->name = ExportedUser::class; |
94
|
|
|
|
95
|
|
|
$this->assertEquals(ExportedUser::class, $metadata[0]->name); |
96
|
|
|
|
97
|
|
|
$type = $this->_getType(); |
98
|
|
|
$cme = new ClassMetadataExporter(); |
99
|
|
|
$exporter = $cme->getExporter($type, __DIR__ . '/export/' . $type); |
100
|
|
|
|
101
|
|
|
if ($type === 'annotation') { |
102
|
|
|
$entityGenerator = new EntityGenerator(); |
103
|
|
|
|
104
|
|
|
$entityGenerator->setAnnotationPrefix(""); |
105
|
|
|
$exporter->setEntityGenerator($entityGenerator); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
$this->_extension = $exporter->getExtension(); |
109
|
|
|
|
110
|
|
|
$exporter->setMetadata($metadata); |
111
|
|
|
$exporter->export(); |
112
|
|
|
|
113
|
|
|
if ($type == 'annotation') { |
114
|
|
|
$this->assertTrue(file_exists(__DIR__ . '/export/' . $type . '/'.str_replace('\\', '/', ExportedUser::class).$this->_extension)); |
115
|
|
|
} else { |
116
|
|
|
$this->assertTrue(file_exists(__DIR__ . '/export/' . $type . '/Doctrine.Tests.ORM.Tools.Export.ExportedUser'.$this->_extension)); |
117
|
|
|
} |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* @depends testExportDirectoryAndFilesAreCreated |
122
|
|
|
*/ |
123
|
|
|
public function testExportedMetadataCanBeReadBackIn() |
124
|
|
|
{ |
125
|
|
|
$type = $this->_getType(); |
126
|
|
|
|
127
|
|
|
$metadataDriver = $this->_createMetadataDriver($type, __DIR__ . '/export/' . $type); |
128
|
|
|
$em = $this->_createEntityManager($metadataDriver); |
129
|
|
|
$cmf = $this->_createClassMetadataFactory($em, $type); |
130
|
|
|
$metadata = $cmf->getAllMetadata(); |
131
|
|
|
|
132
|
|
|
$this->assertEquals(1, count($metadata)); |
133
|
|
|
|
134
|
|
|
$class = current($metadata); |
135
|
|
|
|
136
|
|
|
$this->assertEquals(ExportedUser::class, $class->name); |
137
|
|
|
|
138
|
|
|
return $class; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* @depends testExportedMetadataCanBeReadBackIn |
143
|
|
|
* @param ClassMetadataInfo $class |
144
|
|
|
*/ |
145
|
|
|
public function testTableIsExported($class) |
146
|
|
|
{ |
147
|
|
|
$this->assertEquals('cms_users', $class->table['name']); |
148
|
|
|
$this->assertEquals( |
149
|
|
|
['engine' => 'MyISAM', 'foo' => ['bar' => 'baz']], |
150
|
|
|
$class->table['options']); |
151
|
|
|
|
152
|
|
|
return $class; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* @depends testTableIsExported |
157
|
|
|
* @param ClassMetadataInfo $class |
158
|
|
|
*/ |
159
|
|
|
public function testTypeIsExported($class) |
160
|
|
|
{ |
161
|
|
|
$this->assertFalse($class->isMappedSuperclass); |
162
|
|
|
|
163
|
|
|
return $class; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* @depends testTypeIsExported |
168
|
|
|
* @param ClassMetadataInfo $class |
169
|
|
|
*/ |
170
|
|
|
public function testIdentifierIsExported($class) |
171
|
|
|
{ |
172
|
|
|
$this->assertEquals(ClassMetadataInfo::GENERATOR_TYPE_IDENTITY, $class->generatorType, "Generator Type wrong"); |
173
|
|
|
$this->assertEquals(['id'], $class->identifier); |
174
|
|
|
$this->assertTrue(isset($class->fieldMappings['id']['id']) && $class->fieldMappings['id']['id'] === true); |
175
|
|
|
|
176
|
|
|
return $class; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @depends testIdentifierIsExported |
181
|
|
|
* @param ClassMetadataInfo $class |
182
|
|
|
*/ |
183
|
|
|
public function testFieldsAreExported($class) |
184
|
|
|
{ |
185
|
|
|
$this->assertTrue(isset($class->fieldMappings['id']['id']) && $class->fieldMappings['id']['id'] === true); |
186
|
|
|
$this->assertEquals('id', $class->fieldMappings['id']['fieldName']); |
187
|
|
|
$this->assertEquals('integer', $class->fieldMappings['id']['type']); |
188
|
|
|
$this->assertEquals('id', $class->fieldMappings['id']['columnName']); |
189
|
|
|
|
190
|
|
|
$this->assertEquals('name', $class->fieldMappings['name']['fieldName']); |
191
|
|
|
$this->assertEquals('string', $class->fieldMappings['name']['type']); |
192
|
|
|
$this->assertEquals(50, $class->fieldMappings['name']['length']); |
193
|
|
|
$this->assertEquals('name', $class->fieldMappings['name']['columnName']); |
194
|
|
|
|
195
|
|
|
$this->assertEquals('email', $class->fieldMappings['email']['fieldName']); |
196
|
|
|
$this->assertEquals('string', $class->fieldMappings['email']['type']); |
197
|
|
|
$this->assertEquals('user_email', $class->fieldMappings['email']['columnName']); |
198
|
|
|
$this->assertEquals('CHAR(32) NOT NULL', $class->fieldMappings['email']['columnDefinition']); |
199
|
|
|
|
200
|
|
|
$this->assertEquals(true, $class->fieldMappings['age']['options']['unsigned']); |
201
|
|
|
|
202
|
|
|
return $class; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* @depends testExportDirectoryAndFilesAreCreated |
207
|
|
|
*/ |
208
|
|
|
public function testFieldsAreProperlySerialized() |
209
|
|
|
{ |
210
|
|
|
$type = $this->_getType(); |
211
|
|
|
|
212
|
|
|
if ($type == 'xml') { |
213
|
|
|
$xml = simplexml_load_file(__DIR__ . '/export/'.$type.'/Doctrine.Tests.ORM.Tools.Export.ExportedUser.dcm.xml'); |
214
|
|
|
|
215
|
|
|
$xml->registerXPathNamespace("d", "http://doctrine-project.org/schemas/orm/doctrine-mapping"); |
216
|
|
|
$nodes = $xml->xpath("/d:doctrine-mapping/d:entity/d:field[@name='name' and @type='string' and @nullable='true']"); |
217
|
|
|
$this->assertEquals(1, count($nodes)); |
218
|
|
|
|
219
|
|
|
$nodes = $xml->xpath("/d:doctrine-mapping/d:entity/d:field[@name='name' and @type='string' and @unique='true']"); |
220
|
|
|
$this->assertEquals(1, count($nodes)); |
221
|
|
|
} else { |
222
|
|
|
$this->markTestSkipped('Test not available for '.$type.' driver'); |
223
|
|
|
} |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* @depends testFieldsAreExported |
228
|
|
|
* @param ClassMetadataInfo $class |
229
|
|
|
*/ |
230
|
|
|
public function testOneToOneAssociationsAreExported($class) |
231
|
|
|
{ |
232
|
|
|
$this->assertTrue(isset($class->associationMappings['address'])); |
233
|
|
|
$this->assertEquals(Address::class, $class->associationMappings['address']['targetEntity']); |
234
|
|
|
$this->assertEquals('address_id', $class->associationMappings['address']['joinColumns'][0]['name']); |
235
|
|
|
$this->assertEquals('id', $class->associationMappings['address']['joinColumns'][0]['referencedColumnName']); |
236
|
|
|
$this->assertEquals('CASCADE', $class->associationMappings['address']['joinColumns'][0]['onDelete']); |
237
|
|
|
|
238
|
|
|
$this->assertTrue($class->associationMappings['address']['isCascadeRemove']); |
239
|
|
|
$this->assertTrue($class->associationMappings['address']['isCascadePersist']); |
240
|
|
|
$this->assertFalse($class->associationMappings['address']['isCascadeRefresh']); |
241
|
|
|
$this->assertFalse($class->associationMappings['address']['isCascadeMerge']); |
242
|
|
|
$this->assertFalse($class->associationMappings['address']['isCascadeDetach']); |
243
|
|
|
$this->assertTrue($class->associationMappings['address']['orphanRemoval']); |
244
|
|
|
$this->assertEquals(ClassMetadataInfo::FETCH_EAGER, $class->associationMappings['address']['fetch']); |
245
|
|
|
|
246
|
|
|
return $class; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
/** |
250
|
|
|
* @depends testFieldsAreExported |
251
|
|
|
*/ |
252
|
|
|
public function testManyToOneAssociationsAreExported($class) |
253
|
|
|
{ |
254
|
|
|
$this->assertTrue(isset($class->associationMappings['mainGroup'])); |
255
|
|
|
$this->assertEquals(Group::class, $class->associationMappings['mainGroup']['targetEntity']); |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
/** |
259
|
|
|
* @depends testOneToOneAssociationsAreExported |
260
|
|
|
* @param ClassMetadataInfo $class |
261
|
|
|
*/ |
262
|
|
|
public function testOneToManyAssociationsAreExported($class) |
263
|
|
|
{ |
264
|
|
|
$this->assertTrue(isset($class->associationMappings['phonenumbers'])); |
265
|
|
|
$this->assertEquals(Phonenumber::class, $class->associationMappings['phonenumbers']['targetEntity']); |
266
|
|
|
$this->assertEquals('user', $class->associationMappings['phonenumbers']['mappedBy']); |
267
|
|
|
$this->assertEquals(['number' => 'ASC'], $class->associationMappings['phonenumbers']['orderBy']); |
268
|
|
|
|
269
|
|
|
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadeRemove']); |
270
|
|
|
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadePersist']); |
271
|
|
|
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeRefresh']); |
272
|
|
|
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadeMerge']); |
273
|
|
|
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeDetach']); |
274
|
|
|
$this->assertTrue($class->associationMappings['phonenumbers']['orphanRemoval']); |
275
|
|
|
$this->assertEquals(ClassMetadataInfo::FETCH_LAZY, $class->associationMappings['phonenumbers']['fetch']); |
276
|
|
|
|
277
|
|
|
return $class; |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* @depends testOneToManyAssociationsAreExported |
282
|
|
|
* @param ClassMetadataInfo $metadata |
|
|
|
|
283
|
|
|
*/ |
284
|
|
|
public function testManyToManyAssociationsAreExported($class) |
285
|
|
|
{ |
286
|
|
|
$this->assertTrue(isset($class->associationMappings['groups'])); |
287
|
|
|
$this->assertEquals(Group::class, $class->associationMappings['groups']['targetEntity']); |
288
|
|
|
$this->assertEquals('cms_users_groups', $class->associationMappings['groups']['joinTable']['name']); |
289
|
|
|
|
290
|
|
|
$this->assertEquals('user_id', $class->associationMappings['groups']['joinTable']['joinColumns'][0]['name']); |
291
|
|
|
$this->assertEquals('id', $class->associationMappings['groups']['joinTable']['joinColumns'][0]['referencedColumnName']); |
292
|
|
|
|
293
|
|
|
$this->assertEquals('group_id', $class->associationMappings['groups']['joinTable']['inverseJoinColumns'][0]['name']); |
294
|
|
|
$this->assertEquals('id', $class->associationMappings['groups']['joinTable']['inverseJoinColumns'][0]['referencedColumnName']); |
295
|
|
|
$this->assertEquals('INT NULL', $class->associationMappings['groups']['joinTable']['inverseJoinColumns'][0]['columnDefinition']); |
296
|
|
|
|
297
|
|
|
$this->assertTrue($class->associationMappings['groups']['isCascadeRemove']); |
298
|
|
|
$this->assertTrue($class->associationMappings['groups']['isCascadePersist']); |
299
|
|
|
$this->assertTrue($class->associationMappings['groups']['isCascadeRefresh']); |
300
|
|
|
$this->assertTrue($class->associationMappings['groups']['isCascadeMerge']); |
301
|
|
|
$this->assertTrue($class->associationMappings['groups']['isCascadeDetach']); |
302
|
|
|
$this->assertEquals(ClassMetadataInfo::FETCH_EXTRA_LAZY, $class->associationMappings['groups']['fetch']); |
303
|
|
|
|
304
|
|
|
return $class; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
/** |
308
|
|
|
* @depends testManyToManyAssociationsAreExported |
309
|
|
|
* @param ClassMetadataInfo $class |
310
|
|
|
*/ |
311
|
|
|
public function testLifecycleCallbacksAreExported($class) |
312
|
|
|
{ |
313
|
|
|
$this->assertTrue(isset($class->lifecycleCallbacks['prePersist'])); |
314
|
|
|
$this->assertEquals(2, count($class->lifecycleCallbacks['prePersist'])); |
315
|
|
|
$this->assertEquals('doStuffOnPrePersist', $class->lifecycleCallbacks['prePersist'][0]); |
316
|
|
|
$this->assertEquals('doOtherStuffOnPrePersistToo', $class->lifecycleCallbacks['prePersist'][1]); |
317
|
|
|
|
318
|
|
|
$this->assertTrue(isset($class->lifecycleCallbacks['postPersist'])); |
319
|
|
|
$this->assertEquals(1, count($class->lifecycleCallbacks['postPersist'])); |
320
|
|
|
$this->assertEquals('doStuffOnPostPersist', $class->lifecycleCallbacks['postPersist'][0]); |
321
|
|
|
|
322
|
|
|
return $class; |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
/** |
326
|
|
|
* @depends testLifecycleCallbacksAreExported |
327
|
|
|
* @param ClassMetadataInfo $class |
328
|
|
|
*/ |
329
|
|
|
public function testCascadeIsExported($class) |
330
|
|
|
{ |
331
|
|
|
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadePersist']); |
332
|
|
|
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadeMerge']); |
333
|
|
|
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadeRemove']); |
334
|
|
|
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeRefresh']); |
335
|
|
|
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeDetach']); |
336
|
|
|
$this->assertTrue($class->associationMappings['phonenumbers']['orphanRemoval']); |
337
|
|
|
|
338
|
|
|
return $class; |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
/** |
342
|
|
|
* @depends testCascadeIsExported |
343
|
|
|
* @param ClassMetadataInfo $class |
344
|
|
|
*/ |
345
|
|
|
public function testInversedByIsExported($class) |
346
|
|
|
{ |
347
|
|
|
$this->assertEquals('user', $class->associationMappings['address']['inversedBy']); |
348
|
|
|
} |
349
|
|
|
/** |
350
|
|
|
* @depends testExportDirectoryAndFilesAreCreated |
351
|
|
|
*/ |
352
|
|
|
public function testCascadeAllCollapsed() |
353
|
|
|
{ |
354
|
|
|
$type = $this->_getType(); |
355
|
|
|
|
356
|
|
|
if ($type == 'xml') { |
357
|
|
|
$xml = simplexml_load_file(__DIR__ . '/export/'.$type.'/Doctrine.Tests.ORM.Tools.Export.ExportedUser.dcm.xml'); |
358
|
|
|
|
359
|
|
|
$xml->registerXPathNamespace("d", "http://doctrine-project.org/schemas/orm/doctrine-mapping"); |
360
|
|
|
$nodes = $xml->xpath("/d:doctrine-mapping/d:entity/d:one-to-many[@field='interests']/d:cascade/d:*"); |
361
|
|
|
$this->assertEquals(1, count($nodes)); |
362
|
|
|
|
363
|
|
|
$this->assertEquals('cascade-all', $nodes[0]->getName()); |
364
|
|
|
} else if ($type == 'yaml') { |
365
|
|
|
$yaml = new Parser(); |
366
|
|
|
$value = $yaml->parse(file_get_contents(__DIR__ . '/export/'.$type.'/Doctrine.Tests.ORM.Tools.Export.ExportedUser.dcm.yml')); |
367
|
|
|
|
368
|
|
|
$this->assertTrue(isset($value[ExportedUser::class]['oneToMany']['interests']['cascade'])); |
369
|
|
|
$this->assertEquals(1, count($value[ExportedUser::class]['oneToMany']['interests']['cascade'])); |
370
|
|
|
$this->assertEquals('all', $value[ExportedUser::class]['oneToMany']['interests']['cascade'][0]); |
371
|
|
|
} else { |
372
|
|
|
$this->markTestSkipped('Test not available for '.$type.' driver'); |
373
|
|
|
} |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
/** |
377
|
|
|
* @depends testExportedMetadataCanBeReadBackIn |
378
|
|
|
* |
379
|
|
|
* @param ClassMetadata $class |
380
|
|
|
*/ |
381
|
|
|
public function testEntityListenersAreExported($class) |
382
|
|
|
{ |
383
|
|
|
$this->assertNotEmpty($class->entityListeners); |
384
|
|
|
$this->assertCount(2, $class->entityListeners[Events::prePersist]); |
385
|
|
|
$this->assertCount(2, $class->entityListeners[Events::postPersist]); |
386
|
|
|
$this->assertEquals(UserListener::class, $class->entityListeners[Events::prePersist][0]['class']); |
387
|
|
|
$this->assertEquals('customPrePersist', $class->entityListeners[Events::prePersist][0]['method']); |
388
|
|
|
$this->assertEquals(GroupListener::class, $class->entityListeners[Events::prePersist][1]['class']); |
389
|
|
|
$this->assertEquals('prePersist', $class->entityListeners[Events::prePersist][1]['method']); |
390
|
|
|
$this->assertEquals(UserListener::class, $class->entityListeners[Events::postPersist][0]['class']); |
391
|
|
|
$this->assertEquals('customPostPersist', $class->entityListeners[Events::postPersist][0]['method']); |
392
|
|
|
$this->assertEquals(AddressListener::class, $class->entityListeners[Events::postPersist][1]['class']); |
393
|
|
|
$this->assertEquals('customPostPersist', $class->entityListeners[Events::postPersist][1]['method']); |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
public function __destruct() |
397
|
|
|
{ |
398
|
|
|
# $this->_deleteDirectory(__DIR__ . '/export/'.$this->_getType()); |
|
|
|
|
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
protected function _deleteDirectory($path) |
402
|
|
|
{ |
403
|
|
|
if (is_file($path)) { |
404
|
|
|
return unlink($path); |
405
|
|
|
} else if (is_dir($path)) { |
406
|
|
|
$files = glob(rtrim($path,'/').'/*'); |
407
|
|
|
|
408
|
|
|
if (is_array($files)) { |
409
|
|
|
foreach ($files as $file){ |
410
|
|
|
$this->_deleteDirectory($file); |
411
|
|
|
} |
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
return rmdir($path); |
415
|
|
|
} |
416
|
|
|
} |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
class Address |
420
|
|
|
{ |
421
|
|
|
|
422
|
|
|
} |
423
|
|
|
class Phonenumber |
424
|
|
|
{ |
425
|
|
|
|
426
|
|
|
} |
427
|
|
|
class Group |
428
|
|
|
{ |
429
|
|
|
|
430
|
|
|
} |
431
|
|
|
class UserListener |
432
|
|
|
{ |
433
|
|
|
/** |
434
|
|
|
* @\Doctrine\ORM\Mapping\PrePersist |
435
|
|
|
*/ |
436
|
|
|
public function customPrePersist(): void {} |
437
|
|
|
/** |
438
|
|
|
* @\Doctrine\ORM\Mapping\PostPersist |
439
|
|
|
*/ |
440
|
|
|
public function customPostPersist(): void {} |
441
|
|
|
} |
442
|
|
|
class GroupListener |
443
|
|
|
{ |
444
|
|
|
/** |
445
|
|
|
* @\Doctrine\ORM\Mapping\PrePersist |
446
|
|
|
*/ |
447
|
|
|
public function prePersist(): void {} |
448
|
|
|
} |
449
|
|
|
class AddressListener |
450
|
|
|
{ |
451
|
|
|
/** |
452
|
|
|
* @\Doctrine\ORM\Mapping\PostPersist |
453
|
|
|
*/ |
454
|
|
|
public function customPostPersist(): void {} |
455
|
|
|
} |
456
|
|
|
|
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italy
is not defined by the methodfinale(...)
.The most likely cause is that the parameter was removed, but the annotation was not.