Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

[WIP] DDC-1852 - Validating lifecycle callbacks in tools #361

Closed
wants to merge 8 commits into from

3 participants

Marco Pivetta Don't Add Me To Your Organization a.k.a The Travis Bot Benjamin Eberlei
Marco Pivetta
Collaborator

This feature simply adds validation for lifecycle callbacks.

This PR introduces some BC Breaks:

  1. Doctrine\ORM\Mapping\ClassMetadataInfo#validateLifecycleCallbacks() has been dropped
  2. Doctrine\ORM\Mapping\HasLifecycleCallbacks has been deprecated as it is not checked anymore. This makes the AnnotationDriver slower at first run, but I think this is where caching solves the problem correctly
  3. Mappings have to be validated via tools, as runtime validation is incomplete anyway. Runtime validation of lifecycle callbacks is dropped.

Build Status

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged 0cd962d into 9445502).

Marco Pivetta
Collaborator

Weird that the branch alone fails...

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged 403aae6 into 9445502).

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged a9922e4 into 9445502).

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged 33f832f into 9445502).

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged 49c94551 into 9445502).

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged a8e213bd into 7b75849).

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged c7d0a99 into 7b75849).

Marco Pivetta
Collaborator

@beberlei can't think of any other addition to this. See if you like this idea :)

Benjamin Eberlei beberlei commented on the diff June 18, 2012
lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
@@ -382,7 +382,6 @@ protected function validateRuntimeMetadata($class, $parent)
382 382
 
383 383
         $class->validateIdentifier();
384 384
         $class->validateAssocations();
385  
-        $class->validateLifecycleCallbacks($this->getReflectionService());
2
Benjamin Eberlei Owner
beberlei added a note June 18, 2012

Why remove this? I think it makes sense here.

Marco Pivetta Collaborator
Ocramius added a note June 18, 2012

Since validation has been moved to tools, this shouldn't be needed anymore here, plus it is a check that only worked on XML/YAML/PHP drivers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Marco Pivetta
Collaborator

As discussed on IRC, will (re-)add improved validation support in the ClassMetadataFactory :)

Benjamin Eberlei
Owner

Close then?

Marco Pivetta
Collaborator

Sorry, missed the message. Closing for now :)

Marco Pivetta Ocramius closed this July 04, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
10  UPGRADE_TO_2_3
@@ -24,4 +24,12 @@ Also, related functions were affected:
24 24
 * iterate($parameters, $hydrationMode) the argument $parameters can be either an key=>value array or an ArrayCollection instance
25 25
 * setParameters($parameters) the argument $parameters can be either an key=>value array or an ArrayCollection instance
26 26
 * getParameters() now returns ArrayCollection instead of array
27  
-* getParameter($key) now returns Parameter instance instead of parameter value
  27
+* getParameter($key) now returns Parameter instance instead of parameter value
  28
+
  29
+# Lifecycle Callbacks
  30
+
  31
+The `@HasLifecycleCallbacks` has been deprecated: you can now put the lifecycle annotations on your entities' public
  32
+methods without having to annotate the class itself. Also, the CLI tools can now detect invalid lifecycle callbacks.
  33
+
  34
+* Public method `Doctrine\ORM\Mapping\ClassMetadataInfo#validateLifecycleCallbacks` has been removed.
  35
+* Public static method `Doctrine\ORM\Mapping\MappingException#lifecycleCallbackMethodNotFound` has been removed.
1  lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
@@ -382,7 +382,6 @@ protected function validateRuntimeMetadata($class, $parent)
382 382
 
383 383
         $class->validateIdentifier();
384 384
         $class->validateAssocations();
385  
-        $class->validateLifecycleCallbacks($this->getReflectionService());
386 385
 
387 386
         // verify inheritance
388 387
         if (!$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
19  lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -902,23 +902,6 @@ public function validateAssocations()
902 902
     }
903 903
 
904 904
     /**
905  
-     * Validate lifecycle callbacks
906  
-     *
907  
-     * @param ReflectionService $reflService
908  
-     * @return void
909  
-     */
910  
-    public function validateLifecycleCallbacks($reflService)
911  
-    {
912  
-        foreach ($this->lifecycleCallbacks as $event => $callbacks) {
913  
-            foreach ($callbacks as $callbackFuncName) {
914  
-                if ( ! $reflService->hasPublicMethod($this->name, $callbackFuncName)) {
915  
-                    throw MappingException::lifecycleCallbackMethodNotFound($this->name, $callbackFuncName);
916  
-                }
917  
-            }
918  
-        }
919  
-    }
920  
-
921  
-    /**
922 905
      * Gets the ReflectionClass instance of the mapped class.
923 906
      *
924 907
      * @return ReflectionClass
@@ -1831,7 +1814,7 @@ public function setAssociationOverride($fieldName, array $overrideMapping)
1831 1814
         $mapping['sourceToTargetKeyColumns']    = null;
1832 1815
         $mapping['relationToSourceKeyColumns']  = null;
1833 1816
         $mapping['relationToTargetKeyColumns']  = null;
1834  
-        
  1817
+
1835 1818
         switch ($mapping['type']) {
1836 1819
             case self::ONE_TO_ONE:
1837 1820
                 $mapping = $this->_validateAndCompleteOneToOneMapping($mapping);
67  lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
@@ -532,50 +532,47 @@ public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
532 532
             }
533 533
         }
534 534
 
535  
-        // Evaluate @HasLifecycleCallbacks annotation
536  
-        if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) {
537  
-            foreach ($class->getMethods() as $method) {
538  
-                // filter for the declaring class only, callbacks from parents will already be registered.
539  
-                if ($method->isPublic() && $method->getDeclaringClass()->getName() == $class->name) {
540  
-                    $annotations = $this->_reader->getMethodAnnotations($method);
541  
-
542  
-                    if ($annotations && is_numeric(key($annotations))) {
543  
-                        foreach ($annotations as $annot) {
544  
-                            $annotations[get_class($annot)] = $annot;
545  
-                        }
  535
+        foreach ($class->getMethods() as $method) {
  536
+            // filter for the declaring class only, callbacks from parents will already be registered.
  537
+            if ($method->getDeclaringClass()->getName() == $class->name) {
  538
+                $annotations = $this->_reader->getMethodAnnotations($method);
  539
+
  540
+                if ($annotations && is_numeric(key($annotations))) {
  541
+                    foreach ($annotations as $annot) {
  542
+                        $annotations[get_class($annot)] = $annot;
546 543
                     }
  544
+                }
547 545
 
548  
-                    if (isset($annotations['Doctrine\ORM\Mapping\PrePersist'])) {
549  
-                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::prePersist);
550  
-                    }
  546
+                if (isset($annotations['Doctrine\ORM\Mapping\PrePersist'])) {
  547
+                    $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::prePersist);
  548
+                }
551 549
 
552  
-                    if (isset($annotations['Doctrine\ORM\Mapping\PostPersist'])) {
553  
-                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postPersist);
554  
-                    }
  550
+                if (isset($annotations['Doctrine\ORM\Mapping\PostPersist'])) {
  551
+                    $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postPersist);
  552
+                }
555 553
 
556  
-                    if (isset($annotations['Doctrine\ORM\Mapping\PreUpdate'])) {
557  
-                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preUpdate);
558  
-                    }
  554
+                if (isset($annotations['Doctrine\ORM\Mapping\PreUpdate'])) {
  555
+                    $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preUpdate);
  556
+                }
559 557
 
560  
-                    if (isset($annotations['Doctrine\ORM\Mapping\PostUpdate'])) {
561  
-                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postUpdate);
562  
-                    }
  558
+                if (isset($annotations['Doctrine\ORM\Mapping\PostUpdate'])) {
  559
+                    $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postUpdate);
  560
+                }
563 561
 
564  
-                    if (isset($annotations['Doctrine\ORM\Mapping\PreRemove'])) {
565  
-                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preRemove);
566  
-                    }
  562
+                if (isset($annotations['Doctrine\ORM\Mapping\PreRemove'])) {
  563
+                    $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preRemove);
  564
+                }
567 565
 
568  
-                    if (isset($annotations['Doctrine\ORM\Mapping\PostRemove'])) {
569  
-                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postRemove);
570  
-                    }
  566
+                if (isset($annotations['Doctrine\ORM\Mapping\PostRemove'])) {
  567
+                    $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postRemove);
  568
+                }
571 569
 
572  
-                    if (isset($annotations['Doctrine\ORM\Mapping\PostLoad'])) {
573  
-                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad);
574  
-                    }
  570
+                if (isset($annotations['Doctrine\ORM\Mapping\PostLoad'])) {
  571
+                    $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad);
  572
+                }
575 573
 
576  
-                    if (isset($annotations['Doctrine\ORM\Mapping\PreFlush'])) {
577  
-                        $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preFlush);
578  
-                    }
  574
+                if (isset($annotations['Doctrine\ORM\Mapping\PreFlush'])) {
  575
+                    $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preFlush);
579 576
                 }
580 577
             }
581 578
         }
1  lib/Doctrine/ORM/Mapping/HasLifecycleCallbacks.php
@@ -20,6 +20,7 @@
20 20
 namespace Doctrine\ORM\Mapping;
21 21
 
22 22
 /**
  23
+ * @deprecated This annotation is currently unused and will probably removed with future releases
23 24
  * @Annotation
24 25
  * @Target("CLASS")
25 26
  */
7  lib/Doctrine/ORM/Mapping/MappingException.php
@@ -144,7 +144,7 @@ public static function missingResultSetMappingFieldName($entity, $resultName)
144 144
     {
145 145
         return new self('Result set mapping named "'.$resultName.'" in "'.$entity.' requires a field name.');
146 146
     }
147  
-    
  147
+
148 148
     public static function nameIsMandatoryForSqlResultSetMapping($className)
149 149
     {
150 150
         return new self("Result set mapping name on entity class '$className' is not defined.");
@@ -413,11 +413,6 @@ public static function mappedClassNotPartOfDiscriminatorMap($className, $rootCla
413 413
         );
414 414
     }
415 415
 
416  
-    public static function lifecycleCallbackMethodNotFound($className, $methodName)
417  
-    {
418  
-        return new self("Entity '" . $className . "' has no method '" . $methodName . "' to be registered as lifecycle callback.");
419  
-    }
420  
-
421 416
     public static function invalidFetchMode($className, $annotation)
422 417
     {
423 418
         return new self("Entity '" . $className . "' has a mapping with invalid fetch mode '" . $annotation . "'");
10  lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -37,7 +37,7 @@
37 37
  *     $generator->setUpdateEntityIfExists(true);
38 38
  *     $generator->generate($classes, '/path/to/generate/entities');
39 39
  *
40  
- * 
  40
+ *
41 41
  * @link    www.doctrine-project.org
42 42
  * @since   2.0
43 43
  * @author  Benjamin Eberlei <kontakt@beberlei.de>
@@ -679,10 +679,6 @@ private function generateEntityDocBlock(ClassMetadataInfo $metadata)
679 679
             if ($metadata->customRepositoryClassName) {
680 680
                 $lines[count($lines) - 1] .= '(repositoryClass="' . $metadata->customRepositoryClassName . '")';
681 681
             }
682  
-
683  
-            if (isset($metadata->lifecycleCallbacks) && $metadata->lifecycleCallbacks) {
684  
-                $lines[] = ' * @' . $this->annotationsPrefix . 'HasLifecycleCallbacks';
685  
-            }
686 682
         }
687 683
 
688 684
         $lines[] = ' */';
@@ -975,10 +971,10 @@ private function generateAssociationMappingPropertyDocBlock(array $associationMa
975 971
 
976 972
         if ($this->generateAnnotations) {
977 973
             $lines[] = $this->spaces . ' *';
978  
-            
  974
+
979 975
             if (isset($associationMapping['id']) && $associationMapping['id']) {
980 976
                 $lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . 'Id';
981  
-            
  977
+
982 978
                 if ($generatorType = $this->getIdGeneratorTypeString($metadata->generatorType)) {
983 979
                     $lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . 'GeneratedValue(strategy="' . $generatorType . '")';
984 980
                 }
16  lib/Doctrine/ORM/Tools/SchemaValidator.php
@@ -249,6 +249,22 @@ public function validateClass(ClassMetadataInfo $class)
249 249
             }
250 250
         }
251 251
 
  252
+        foreach ($class->lifecycleCallbacks as $name => $callbacks) {
  253
+            foreach ($callbacks as $callback) {
  254
+                if (!$class->reflClass->hasMethod($callback)) {
  255
+                    $ce[] = "A lifecycle callback for event '" . $name . "' is defined on non-existing method ".
  256
+                        " '" . $class->name . "#" . $callback . "'.";
  257
+                    continue;
  258
+                }
  259
+
  260
+                $method = $class->reflClass->getMethod($callback);
  261
+                if (!$method->isPublic()) {
  262
+                    $ce[] = "A lifecycle callback for event '" . $name . "' is defined on " . ($method->isProtected() ? 'protected' : 'private')
  263
+                        . " method '" . $class->name . "#" . $callback . "'. Only public methods can be used as callbacks.";
  264
+                }
  265
+            }
  266
+        }
  267
+
252 268
         return $ce;
253 269
     }
254 270
 
5  tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php
@@ -184,7 +184,7 @@ public function testLifecycleListener_ChangeUpdateChangeSet()
184 184
     }
185 185
 }
186 186
 
187  
-/** @Entity @HasLifecycleCallbacks */
  187
+/** @Entity */
188 188
 class LifecycleCallbackTestUser {
189 189
     /** @Id @Column(type="integer") @GeneratedValue */
190 190
     private $id;
@@ -203,7 +203,6 @@ public function testCallback() {$this->value = 'Hello World';}
203 203
 
204 204
 /**
205 205
  * @Entity
206  
- * @HasLifecycleCallbacks
207 206
  * @Table(name="lc_cb_test_entity")
208 207
  */
209 208
 class LifecycleCallbackTestEntity
@@ -288,7 +287,7 @@ public function __construct()
288 287
     }
289 288
 }
290 289
 
291  
-/** @MappedSuperclass @HasLifecycleCallbacks */
  290
+/** @MappedSuperclass */
292 291
 class LifecycleCallbackParentEntity {
293 292
     /** @PrePersist */
294 293
     function doStuff() {
6  tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1655Test.php
@@ -89,7 +89,6 @@ public function testPostLoadInheritanceChild()
89 89
  *    "foo" = "DDC1655Foo",
90 90
  *    "bar" = "DDC1655Bar"
91 91
  * })
92  
- * @HasLifecycleCallbacks
93 92
  */
94 93
 class DDC1655Foo
95 94
 {
@@ -112,10 +111,7 @@ public function postLoad()
112 111
     }
113 112
 }
114 113
 
115  
-/**
116  
- * @Entity
117  
- * @HasLifecycleCallbacks
118  
- */
  114
+/** @Entity */
119 115
 class DDC1655Bar extends DDC1655Foo
120 116
 {
121 117
     public $subLoaded;
1  tests/Doctrine/Tests/ORM/Functional/Ticket/DDC345Test.php
@@ -103,7 +103,6 @@ public function __construct()
103 103
 
104 104
 /**
105 105
  * @Entity
106  
- * @HasLifecycleCallbacks
107 106
  * @Table(name="ddc345_memberships", uniqueConstraints={
108 107
  *      @UniqueConstraint(name="ddc345_memship_fks", columns={"user_id","group_id"})
109 108
  * })
1  tests/Doctrine/Tests/ORM/Functional/Ticket/DDC448Test.php
@@ -53,7 +53,6 @@ class DDC448MainTable
53 53
 /**
54 54
  * @Entity
55 55
  * @Table(name="connectedClass")
56  
- * @HasLifecycleCallbacks
57 56
  */
58 57
 class DDC448ConnectedClass
59 58
 {
15  tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php
@@ -481,7 +481,7 @@ public function testIdentifierRequiredShouldMentionParentClasses()
481 481
     {
482 482
 
483 483
         $factory = $this->createClassMetadataFactory();
484  
-        
  484
+
485 485
         $factory->getMetadataFor('Doctrine\Tests\Models\DDC889\DDC889Entity');
486 486
     }
487 487
 
@@ -490,7 +490,7 @@ public function testIdentifierRequiredShouldMentionParentClasses()
490 490
      */
491 491
     public function testNamedNativeQuery()
492 492
     {
493  
-        
  493
+
494 494
         $class = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
495 495
 
496 496
         //named native query
@@ -519,7 +519,7 @@ public function testNamedNativeQuery()
519 519
         $this->assertArrayHasKey('mapping-count', $class->sqlResultSetMappings);
520 520
         $this->assertArrayHasKey('mapping-find-all', $class->sqlResultSetMappings);
521 521
         $this->assertArrayHasKey('mapping-without-fields', $class->sqlResultSetMappings);
522  
-        
  522
+
523 523
         $findAllMapping = $class->getSqlResultSetMapping('mapping-find-all');
524 524
         $this->assertEquals('mapping-find-all', $findAllMapping['name']);
525 525
         $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddress', $findAllMapping['entities'][0]['entityClass']);
@@ -531,7 +531,7 @@ public function testNamedNativeQuery()
531 531
         $this->assertEquals('mapping-without-fields', $withoutFieldsMapping['name']);
532 532
         $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddress', $withoutFieldsMapping['entities'][0]['entityClass']);
533 533
         $this->assertEquals(array(), $withoutFieldsMapping['entities'][0]['fields']);
534  
-        
  534
+
535 535
         $countMapping = $class->getSqlResultSetMapping('mapping-count');
536 536
         $this->assertEquals('mapping-count', $countMapping['name']);
537 537
         $this->assertEquals(array('name'=>'count'), $countMapping['columns'][0]);
@@ -619,7 +619,7 @@ public function testAssociationOverridesMapping()
619 619
         $adminMetadata  = $factory->getMetadataFor('Doctrine\Tests\Models\DDC964\DDC964Admin');
620 620
         $guestMetadata  = $factory->getMetadataFor('Doctrine\Tests\Models\DDC964\DDC964Guest');
621 621
 
622  
-        
  622
+
623 623
         // assert groups association mappings
624 624
         $this->assertArrayHasKey('groups', $guestMetadata->associationMappings);
625 625
         $this->assertArrayHasKey('groups', $adminMetadata->associationMappings);
@@ -678,7 +678,7 @@ public function testAssociationOverridesMapping()
678 678
         $this->assertEquals($guestAddress['isCascadeRefresh'], $adminAddress['isCascadeRefresh']);
679 679
         $this->assertEquals($guestAddress['isCascadeMerge'], $adminAddress['isCascadeMerge']);
680 680
         $this->assertEquals($guestAddress['isCascadeDetach'], $adminAddress['isCascadeDetach']);
681  
-        
  681
+
682 682
         // assert override
683 683
         $this->assertEquals('address_id', $guestAddress['joinColumns'][0]['name']);
684 684
         $this->assertEquals(array('address_id'=>'id'), $guestAddress['sourceToTargetKeyColumns']);
@@ -735,7 +735,6 @@ public function testAttributeOverridesMapping()
735 735
 
736 736
 /**
737 737
  * @Entity
738  
- * @HasLifecycleCallbacks
739 738
  * @Table(
740 739
  *  name="cms_users",
741 740
  *  uniqueConstraints={@UniqueConstraint(name="search_idx", columns={"name", "user_email"})},
@@ -1037,7 +1036,7 @@ class DDC807Entity
1037 1036
      * @GeneratedValue(strategy="NONE")
1038 1037
      **/
1039 1038
    public $id;
1040  
-   
  1039
+
1041 1040
    public static function loadMetadata(ClassMetadataInfo $metadata)
1042 1041
     {
1043 1042
          $metadata->mapField(array(
6  tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php
@@ -262,7 +262,6 @@ class MappedSuperClassInheritence
262 262
  * @Entity
263 263
  * @InheritanceType("JOINED")
264 264
  * @DiscriminatorMap({"parent" = "AnnotationParent", "child" = "AnnotationChild"})
265  
- * @HasLifecycleCallbacks
266 265
  */
267 266
 class AnnotationParent
268 267
 {
@@ -288,10 +287,7 @@ public function preUpdate()
288 287
     }
289 288
 }
290 289
 
291  
-/**
292  
- * @Entity
293  
- * @HasLifecycleCallbacks
294  
- */
  290
+/** @Entity */
295 291
 class AnnotationChild extends AnnotationParent
296 292
 {
297 293
 
19  tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
@@ -340,7 +340,7 @@ public function testUnderscoreNamingStrategyDefaults()
340 340
             'fieldName'     => 'user',
341 341
             'targetEntity'  => 'CmsUser'
342 342
         ));
343  
-        
  343
+
344 344
         $this->assertEquals(array('USER_ID'=>'ID'), $oneToOneMetadata->associationMappings['user']['sourceToTargetKeyColumns']);
345 345
         $this->assertEquals(array('USER_ID'=>'USER_ID'), $oneToOneMetadata->associationMappings['user']['joinColumnFieldNames']);
346 346
         $this->assertEquals(array('ID'=>'USER_ID'), $oneToOneMetadata->associationMappings['user']['targetToSourceKeyColumns']);
@@ -348,7 +348,7 @@ public function testUnderscoreNamingStrategyDefaults()
348 348
         $this->assertEquals('USER_ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['name']);
349 349
         $this->assertEquals('ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['referencedColumnName']);
350 350
 
351  
-        
  351
+
352 352
         $this->assertEquals('CMS_ADDRESS_CMS_USER', $manyToManyMetadata->associationMappings['user']['joinTable']['name']);
353 353
 
354 354
         $this->assertEquals(array('CMS_ADDRESS_ID','CMS_USER_ID'), $manyToManyMetadata->associationMappings['user']['joinTableColumns']);
@@ -770,7 +770,7 @@ public function testNamingCollisionSqlResultSetMappingShouldThrowException()
770 770
     {
771 771
         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
772 772
         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
773  
-        
  773
+
774 774
         $cm->addSqlResultSetMapping(array(
775 775
             'name'      => 'find-all',
776 776
             'entities'  => array(
@@ -803,19 +803,6 @@ public function testClassCaseSensitivity()
803 803
     }
804 804
 
805 805
     /**
806  
-     * @group DDC-659
807  
-     */
808  
-    public function testLifecycleCallbackNotFound()
809  
-    {
810  
-        $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
811  
-        $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
812  
-        $cm->addLifecycleCallback('notfound', 'postLoad');
813  
-
814  
-        $this->setExpectedException("Doctrine\ORM\Mapping\MappingException", "Entity 'Doctrine\Tests\Models\CMS\CmsUser' has no method 'notfound' to be registered as lifecycle callback.");
815  
-        $cm->validateLifecycleCallbacks(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
816  
-    }
817  
-
818  
-    /**
819 806
      * @group ImproveErrorMessages
820 807
      */
821 808
     public function testTargetEntityNotFound()
1  tests/Doctrine/Tests/ORM/Tools/Export/annotation/Doctrine.Tests.ORM.Tools.Export.User.php
@@ -4,7 +4,6 @@
4 4
 
5 5
 /**
6 6
  * @Entity
7  
- * @HasLifecycleCallbacks
8 7
  * @Table(name="cms_users")
9 8
  */
10 9
 class User
44  tests/Doctrine/Tests/ORM/Tools/SchemaValidatorTest.php
@@ -9,7 +9,7 @@
9 9
 class SchemaValidatorTest extends \Doctrine\Tests\OrmTestCase
10 10
 {
11 11
     /**
12  
-     * @var EntityManager
  12
+     * @var \Doctrine\ORM\EntityManager
13 13
      */
14 14
     private $em = null;
15 15
 
@@ -136,6 +136,31 @@ public function testInvalidTripleAssociationAsKeyMapping()
136 136
             "The referenced column name 'id' has to be a primary key column on the target entity class 'Doctrine\Tests\ORM\Tools\DDC1649Two'."
137 137
         ), $ce);
138 138
     }
  139
+
  140
+    /**
  141
+     * @group DDC-1852
  142
+     */
  143
+    public function testInvalidLifecycleCallbacks()
  144
+    {
  145
+        $nonPublicCallbacks = $this->em->getClassMetadata(__NAMESPACE__ . '\DDC1852InvalidLifecycleCallbacks');
  146
+
  147
+        $nonPublicCallbacks->lifecycleCallbacks[\Doctrine\ORM\Events::prePersist][] = 'someNonExistingMethod';
  148
+        $ce = $this->validator->validateClass($nonPublicCallbacks);
  149
+
  150
+        $this->assertEquals(
  151
+            array(
  152
+                "A lifecycle callback for event 'prePersist' is defined on private method '"
  153
+                    . __NAMESPACE__ . "\DDC1852InvalidLifecycleCallbacks#somePrivateMethod'."
  154
+                    . " Only public methods can be used as callbacks.",
  155
+                "A lifecycle callback for event 'prePersist' is defined on protected method '"
  156
+                    . __NAMESPACE__ . "\DDC1852InvalidLifecycleCallbacks#someProtectedMethod'."
  157
+                    . " Only public methods can be used as callbacks.",
  158
+                "A lifecycle callback for event 'prePersist' is defined on non-existing method  '"
  159
+                    . __NAMESPACE__ . "\DDC1852InvalidLifecycleCallbacks#someNonExistingMethod'.",
  160
+            ),
  161
+            $ce
  162
+        );
  163
+    }
139 164
 }
140 165
 
141 166
 /**
@@ -204,7 +229,7 @@ class DDC1587ValidEntity1
204 229
     private $name;
205 230
 
206 231
     /**
207  
-     * @var Identifier
  232
+     * @var DDC1587ValidEntity2
208 233
      *
209 234
      * @OneToOne(targetEntity="DDC1587ValidEntity2", cascade={"all"}, mappedBy="agent")
210 235
      * @JoinColumn(name="pk", referencedColumnName="pk_agent")
@@ -265,3 +290,18 @@ class DDC1649Three
265 290
     private $two;
266 291
 }
267 292
 
  293
+/**
  294
+ * @Entity
  295
+ */
  296
+class DDC1852InvalidLifecycleCallbacks
  297
+{
  298
+    /** @Id @Column */
  299
+    private $id;
  300
+
  301
+    /** @PrePersist */
  302
+    private function somePrivateMethod() {}
  303
+
  304
+    /** @PrePersist */
  305
+    protected function someProtectedMethod() {}
  306
+}
  307
+
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.