diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 796b941b4..cef558496 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -274,6 +274,9 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface $class->setDiscriminatorMap($parent->discriminatorMap); $class->setLifecycleCallbacks($parent->lifecycleCallbacks); $class->setChangeTrackingPolicy($parent->changeTrackingPolicy); + if ($parent->isMappedSuperclass) { + $class->setCustomRepositoryClass($parent->customRepositoryClassName); + } } // Invoke driver diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index ee7db54ac..36e3dcb01 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -147,12 +147,15 @@ class AnnotationDriver implements Driver // Evaluate Entity annotation if (isset($classAnnotations['Doctrine\ORM\Mapping\Entity'])) { $entityAnnot = $classAnnotations['Doctrine\ORM\Mapping\Entity']; - $metadata->setCustomRepositoryClass($entityAnnot->repositoryClass); - + if ($entityAnnot->repositoryClass !== null) { + $metadata->setCustomRepositoryClass($entityAnnot->repositoryClass); + } if ($entityAnnot->readOnly) { $metadata->markReadOnly(); } } else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) { + $mappedSuperclassAnnot = $classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass']; + $metadata->setCustomRepositoryClass($mappedSuperclassAnnot->repositoryClass); $metadata->isMappedSuperclass = true; } else { throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className); diff --git a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php index e6a674b38..6e5b36a45 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php +++ b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php @@ -36,7 +36,9 @@ final class Entity extends Annotation { * @Annotation * @Target("CLASS") */ -final class MappedSuperclass extends Annotation {} +final class MappedSuperclass extends Annotation { + public $repositoryClass; +} /** * @Annotation diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index 20631d63c..b676ca8da 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -52,13 +52,16 @@ class XmlDriver extends AbstractFileDriver $xmlRoot = $this->getElement($className); if ($xmlRoot->getName() == 'entity') { - $metadata->setCustomRepositoryClass( - isset($xmlRoot['repository-class']) ? (string)$xmlRoot['repository-class'] : null - ); + if (isset($xmlRoot['repository-class'])) { + $metadata->setCustomRepositoryClass((string)$xmlRoot['repository-class']); + } if (isset($xmlRoot['read-only']) && $xmlRoot['read-only'] == "true") { $metadata->markReadOnly(); } } else if ($xmlRoot->getName() == 'mapped-superclass') { + $metadata->setCustomRepositoryClass( + isset($xmlRoot['repository-class']) ? (string)$xmlRoot['repository-class'] : null + ); $metadata->isMappedSuperclass = true; } else { throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className); diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php index a47d56fa1..a2c5402b6 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -46,13 +46,16 @@ class YamlDriver extends AbstractFileDriver $element = $this->getElement($className); if ($element['type'] == 'entity') { - $metadata->setCustomRepositoryClass( - isset($element['repositoryClass']) ? $element['repositoryClass'] : null - ); + if (isset($element['repositoryClass'])) { + $metadata->setCustomRepositoryClass($element['repositoryClass']); + } if (isset($element['readOnly']) && $element['readOnly'] == true) { $metadata->markReadOnly(); } } else if ($element['type'] == 'mappedSuperclass') { + $metadata->setCustomRepositoryClass( + isset($element['repositoryClass']) ? $element['repositoryClass'] : null + ); $metadata->isMappedSuperclass = true; } else { throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className); diff --git a/tests/Doctrine/Tests/Models/DDC869/DDC869ChequePayment.php b/tests/Doctrine/Tests/Models/DDC869/DDC869ChequePayment.php new file mode 100644 index 000000000..46cceb4c7 --- /dev/null +++ b/tests/Doctrine/Tests/Models/DDC869/DDC869ChequePayment.php @@ -0,0 +1,40 @@ +. + */ + +namespace Doctrine\Tests\Models\DDC869; + +/** + * @Entity + */ +class DDC869ChequePayment extends DDC869Payment +{ + + /** @column(type="string") */ + protected $serialNumber; + + public static function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata) + { + $metadata->mapField(array( + 'fieldName' => 'serialNumber', + 'type' => 'string', + )); + } + +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/DDC869/DDC869CreditCardPayment.php b/tests/Doctrine/Tests/Models/DDC869/DDC869CreditCardPayment.php new file mode 100644 index 000000000..b446e059a --- /dev/null +++ b/tests/Doctrine/Tests/Models/DDC869/DDC869CreditCardPayment.php @@ -0,0 +1,40 @@ +. + */ + +namespace Doctrine\Tests\Models\DDC869; + +/** + * @Entity + */ +class DDC869CreditCardPayment extends DDC869Payment +{ + + /** @column(type="string") */ + protected $creditCardNumber; + + public static function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata) + { + $metadata->mapField(array( + 'fieldName' => 'creditCardNumber', + 'type' => 'string', + )); + } + +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/DDC869/DDC869Payment.php b/tests/Doctrine/Tests/Models/DDC869/DDC869Payment.php new file mode 100644 index 000000000..c3c365715 --- /dev/null +++ b/tests/Doctrine/Tests/Models/DDC869/DDC869Payment.php @@ -0,0 +1,57 @@ +. + */ + +namespace Doctrine\Tests\Models\DDC869; + +/** + * @MappedSuperclass(repositoryClass = "Doctrine\Tests\Models\DDC869\DDC869PaymentRepository") + */ +class DDC869Payment +{ + + /** + * @Id + * @Column(type="integer") + * @GeneratedValue + */ + protected $id; + + /** @column(type="float") */ + protected $value; + + + public static function loadMetadata(\Doctrine\ORM\Mapping\ClassMetadataInfo $metadata) + { + $metadata->mapField(array( + 'id' => true, + 'fieldName' => 'id', + 'type' => 'integer', + 'columnName' => 'id', + )); + $metadata->mapField(array( + 'fieldName' => 'value', + 'type' => 'float', + )); + $metadata->isMappedSuperclass = true; + $metadata->setCustomRepositoryClass("Doctrine\Tests\Models\DDC869\DDC869PaymentRepository"); + $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadataInfo::GENERATOR_TYPE_AUTO); + } + +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/DDC869/DDC869PaymentRepository.php b/tests/Doctrine/Tests/Models/DDC869/DDC869PaymentRepository.php new file mode 100644 index 000000000..d9018266a --- /dev/null +++ b/tests/Doctrine/Tests/Models/DDC869/DDC869PaymentRepository.php @@ -0,0 +1,37 @@ +. + */ + +namespace Doctrine\Tests\Models\DDC869; + +use Doctrine\ORM\EntityRepository; + +class DDC869PaymentRepository extends EntityRepository +{ + + /** + * Very complex method + * + * @return bool + */ + public function isTrue() + { + return true; + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 74e7764a9..98c43a5b9 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -291,6 +291,42 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $class->discriminatorColumn ); } + + /** + * @group DDC-869 + */ + public function testMappedSuperclassWithRepository() + { + $driver = $this->_loadDriver(); + $em = $this->_getTestEntityManager(); + $factory = new \Doctrine\ORM\Mapping\ClassMetadataFactory(); + + $em->getConfiguration()->setMetadataDriverImpl($driver); + $factory->setEntityManager($em); + + + $class = $factory->getMetadataFor('Doctrine\Tests\Models\DDC869\DDC869CreditCardPayment'); + + $this->assertTrue(isset($class->fieldMappings['id'])); + $this->assertTrue(isset($class->fieldMappings['value'])); + $this->assertTrue(isset($class->fieldMappings['creditCardNumber'])); + $this->assertEquals($class->customRepositoryClassName, "Doctrine\Tests\Models\DDC869\DDC869PaymentRepository"); + $this->assertInstanceOf("Doctrine\Tests\Models\DDC869\DDC869PaymentRepository", + $em->getRepository("Doctrine\Tests\Models\DDC869\DDC869CreditCardPayment")); + $this->assertTrue($em->getRepository("Doctrine\Tests\Models\DDC869\DDC869ChequePayment")->isTrue()); + + + + $class = $factory->getMetadataFor('Doctrine\Tests\Models\DDC869\DDC869ChequePayment'); + + $this->assertTrue(isset($class->fieldMappings['id'])); + $this->assertTrue(isset($class->fieldMappings['value'])); + $this->assertTrue(isset($class->fieldMappings['serialNumber'])); + $this->assertEquals($class->customRepositoryClassName, "Doctrine\Tests\Models\DDC869\DDC869PaymentRepository"); + $this->assertInstanceOf("Doctrine\Tests\Models\DDC869\DDC869PaymentRepository", + $em->getRepository("Doctrine\Tests\Models\DDC869\DDC869ChequePayment")); + $this->assertTrue($em->getRepository("Doctrine\Tests\Models\DDC869\DDC869ChequePayment")->isTrue()); + } } /** diff --git a/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php b/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php index d5aac63f9..7d31b8586 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php @@ -52,6 +52,35 @@ class BasicInheritanceMappingTest extends \Doctrine\Tests\OrmTestCase $this->assertTrue(isset($class->associationMappings['mappedRelated1'])); } + + /** + * @group DDC-869 + */ + public function testGetMetadataForSubclassWithMappedSuperclassWhithRepository() + { + $class = $this->_factory->getMetadataFor('Doctrine\Tests\Models\DDC869\DDC869CreditCardPayment'); + + $this->assertTrue(isset($class->fieldMappings['id'])); + $this->assertTrue(isset($class->fieldMappings['value'])); + $this->assertTrue(isset($class->fieldMappings['creditCardNumber'])); + $this->assertEquals($class->customRepositoryClassName, "Doctrine\Tests\Models\DDC869\DDC869PaymentRepository"); + + + $class = $this->_factory->getMetadataFor('Doctrine\Tests\Models\DDC869\DDC869ChequePayment'); + + $this->assertTrue(isset($class->fieldMappings['id'])); + $this->assertTrue(isset($class->fieldMappings['value'])); + $this->assertTrue(isset($class->fieldMappings['serialNumber'])); + $this->assertEquals($class->customRepositoryClassName, "Doctrine\Tests\Models\DDC869\DDC869PaymentRepository"); + + + // override repositoryClass + $class = $this->_factory->getMetadataFor('Doctrine\Tests\ORM\Mapping\SubclassWithRepository'); + + $this->assertTrue(isset($class->fieldMappings['id'])); + $this->assertTrue(isset($class->fieldMappings['value'])); + $this->assertEquals($class->customRepositoryClassName, "Doctrine\ORM\EntityRepository"); + } /** * @group DDC-388 @@ -277,4 +306,12 @@ abstract class MediumSuperclassBase extends SuperclassBase class MediumSuperclassEntity extends MediumSuperclassBase { +} + +/** + * @Entity(repositoryClass = "Doctrine\ORM\EntityRepository") + */ +class SubclassWithRepository extends \Doctrine\Tests\Models\DDC869\DDC869Payment +{ + } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.php new file mode 100644 index 000000000..ad8b86d9e --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.php @@ -0,0 +1,5 @@ +mapField(array( + 'fieldName' => 'serialNumber', + 'type' => 'string', +)); \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.php new file mode 100644 index 000000000..1318333a8 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.php @@ -0,0 +1,5 @@ +mapField(array( + 'fieldName' => 'creditCardNumber', + 'type' => 'string', +)); \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869Payment.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869Payment.php new file mode 100644 index 000000000..1d1f551ba --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869Payment.php @@ -0,0 +1,17 @@ +mapField(array( + 'id' => true, + 'fieldName' => 'id', + 'type' => 'integer', + 'columnName' => 'id', +)); +$metadata->mapField(array( + 'fieldName' => 'value', + 'type' => 'float', + )); +$metadata->isMappedSuperclass = true; +$metadata->setCustomRepositoryClass("Doctrine\Tests\Models\DDC869\DDC869PaymentRepository"); +$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO); \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.xml new file mode 100644 index 000000000..05e2540ef --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.xml new file mode 100644 index 000000000..daf01f034 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.xml new file mode 100644 index 000000000..be9f760b9 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.yml new file mode 100644 index 000000000..94f269817 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.yml @@ -0,0 +1,5 @@ +Doctrine\Tests\Models\DDC869\DDC869ChequePayment: + type: entity + fields: + serialNumber: + type: string \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.yml new file mode 100644 index 000000000..153a99fa7 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.yml @@ -0,0 +1,5 @@ +Doctrine\Tests\Models\DDC869\DDC869CreditCardPayment: + type: entity + fields: + creditCardNumber: + type: string \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.yml new file mode 100644 index 000000000..b776664e1 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.yml @@ -0,0 +1,12 @@ +Doctrine\Tests\Models\DDC869\DDC869Payment: + type: mappedSuperclass + repositoryClass : Doctrine\Tests\Models\DDC869\DDC869PaymentRepository + id: + id: + type: integer + unsigned: true + generator: + strategy: AUTO + fields: + value: + type: float \ No newline at end of file