diff --git a/lib/FSi/DoctrineExtensions/Uploadable/UploadableListener.php b/lib/FSi/DoctrineExtensions/Uploadable/UploadableListener.php index 39287bf..03c9ccc 100644 --- a/lib/FSi/DoctrineExtensions/Uploadable/UploadableListener.php +++ b/lib/FSi/DoctrineExtensions/Uploadable/UploadableListener.php @@ -469,19 +469,20 @@ protected function getPropertyObserver(ObjectManager $objectManager) protected function validateExtendedMetadata(ClassMetadata $baseClassMetadata, ClassMetadataInterface $extendedClassMetadata) { foreach ($extendedClassMetadata->getUploadableProperties() as $field => $options) { + $className = $baseClassMetadata->getName(); if (empty($options['targetField'])) { throw new MappingException(sprintf( 'Mapping "Uploadable" in property "%s" of class "%s" does not have required "targetField" attribute, or attribute is empty.', $field, - $baseClassMetadata->name + $className )); } - if (!property_exists($baseClassMetadata->name, $options['targetField'])) { + if (!$this->propertyExistsInClassTree($className, $options['targetField'])) { throw new MappingException(sprintf( 'Mapping "Uploadable" in property "%s" of class "%s" has "targetField" set to "%s", which doesn\'t exist.', $field, - $baseClassMetadata->name, + $className, $options['targetField'] )); } @@ -490,7 +491,7 @@ protected function validateExtendedMetadata(ClassMetadata $baseClassMetadata, Cl throw new MappingException(sprintf( 'Mapping "Uploadable" in property "%s" of class "%s" have "targetField" that points at already mapped field ("%s").', $field, - $baseClassMetadata->name, + $className, $options['targetField'] )); } @@ -499,7 +500,7 @@ protected function validateExtendedMetadata(ClassMetadata $baseClassMetadata, Cl throw new MappingException(sprintf( 'Property "%s" of class "%s" have mapping "Uploadable" but isn\'t mapped as Doctrine\'s column.', $field, - $baseClassMetadata->name, + $className, $options['targetField'] )); } @@ -508,7 +509,7 @@ protected function validateExtendedMetadata(ClassMetadata $baseClassMetadata, Cl throw new MappingException(sprintf( 'Property "%s" of class "%s" have mapping "Uploadable" with key length is not a number.', $field, - $baseClassMetadata->name, + $className, $options['targetField'] )); } @@ -517,7 +518,7 @@ protected function validateExtendedMetadata(ClassMetadata $baseClassMetadata, Cl throw new MappingException(sprintf( 'Property "%s" of class "%s" have mapping "Uploadable" with key length less than 1.', $field, - $baseClassMetadata->name, + $className, $options['targetField'] )); } @@ -526,7 +527,7 @@ protected function validateExtendedMetadata(ClassMetadata $baseClassMetadata, Cl throw new MappingException(sprintf( 'Mapping "Uploadable" in property "%s" of class "%s" does have keymaker that isn\'t instance of expected FSi\\DoctrineExtensions\\Uploadable\\Keymaker\\KeymakerInterface ("%s" given).', $field, - $baseClassMetadata->name, + $className, is_object($options['keymaker']) ? get_class($options['keymaker']) : gettype($options['keymaker']) )); } @@ -622,4 +623,23 @@ private function generateNewKey(KeymakerInterface $keymaker, $object, $property, return $newKey; } + + /** + * @param string $class + * @param string $property + * @return boolean + */ + private function propertyExistsInClassTree($class, $property) + { + if (property_exists($class, $property)) { + return true; + } + + $parentClass = get_parent_class($class); + if ($parentClass !== false) { + return $this->propertyExistsInClassTree($parentClass, $property); + } + + return false; + } } diff --git a/tests/FSi/DoctrineExtensions/Tests/Uploadable/Fixture/Inheritance/Employee.php b/tests/FSi/DoctrineExtensions/Tests/Uploadable/Fixture/Inheritance/Employee.php new file mode 100644 index 0000000..8ca34d4 --- /dev/null +++ b/tests/FSi/DoctrineExtensions/Tests/Uploadable/Fixture/Inheritance/Employee.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FSi\DoctrineExtensions\Tests\Uploadable\Fixture\Inheritance; + +use Doctrine\ORM\Mapping as ORM; + +/** + * @ORM\Entity + */ +class Employee extends Person +{ +} diff --git a/tests/FSi/DoctrineExtensions/Tests/Uploadable/Fixture/Inheritance/Person.php b/tests/FSi/DoctrineExtensions/Tests/Uploadable/Fixture/Inheritance/Person.php new file mode 100644 index 0000000..fe14ab8 --- /dev/null +++ b/tests/FSi/DoctrineExtensions/Tests/Uploadable/Fixture/Inheritance/Person.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FSi\DoctrineExtensions\Tests\Uploadable\Fixture\Inheritance; + +use Doctrine\ORM\Mapping as ORM; +use FSi\DoctrineExtensions\Uploadable\File; +use FSi\DoctrineExtensions\Uploadable\Mapping\Annotation as FSi; +use SplFileInfo; + +/** + * @ORM\Entity + * @ORM\InheritanceType("SINGLE_TABLE") + * @ORM\DiscriminatorColumn(name="discr", type="string") + * @ORM\DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) + */ +class Person +{ + /** + * @var integer + * + * @ORM\Column(name="id", type="integer") + * @ORM\Id + * @ORM\GeneratedValue(strategy="AUTO") + */ + private $id; + + /** + * @ORM\Column(nullable=true) + * @FSi\Uploadable(targetField="file") + */ + private $filePath; + + /** + * @var File|SplFileInfo + */ + private $file; + + public function getId() + { + return $this->id; + } + + public function getFilePath() + { + return $this->filePath; + } + + public function setFilePath($filePath) + { + $this->filePath = $filePath; + } + + public function getFile() + { + return $this->file; + } + + public function setFile($file) + { + $this->file = $file; + } +} diff --git a/tests/FSi/DoctrineExtensions/Tests/Uploadable/InheritanceTest.php b/tests/FSi/DoctrineExtensions/Tests/Uploadable/InheritanceTest.php index d84f3d4..e320f5d 100644 --- a/tests/FSi/DoctrineExtensions/Tests/Uploadable/InheritanceTest.php +++ b/tests/FSi/DoctrineExtensions/Tests/Uploadable/InheritanceTest.php @@ -10,6 +10,7 @@ namespace FSi\DoctrineExtensions\Tests\Uploadable; use FSi\DoctrineExtensions\Tests\Tool\BaseORMTest; +use FSi\DoctrineExtensions\Tests\Uploadable\Fixture\Inheritance\Employee; use FSi\DoctrineExtensions\Tests\Uploadable\Fixture\Inheritance\Event; use FSi\DoctrineExtensions\Tests\Uploadable\Fixture\Inheritance\Promotion; @@ -19,6 +20,8 @@ class InheritanceTest extends BaseORMTest const EXCERPT_PAGE = 'FSi\\DoctrineExtensions\\Tests\\Uploadable\\Fixture\\Inheritance\\ExcerptContentPage'; const EVENT_PAGE = 'FSi\\DoctrineExtensions\\Tests\\Uploadable\\Fixture\\Inheritance\\Event'; const PROMOTION_PAGE = 'FSi\\DoctrineExtensions\\Tests\\Uploadable\\Fixture\\Inheritance\\Promotion'; + const PERSON = 'FSi\\DoctrineExtensions\\Tests\\Uploadable\\Fixture\\Inheritance\\Person'; + const EMPLOYEE = 'FSi\\DoctrineExtensions\\Tests\\Uploadable\\Fixture\\Inheritance\\Employee'; const TEST_FILE1 = '/FSi/DoctrineExtensions/Tests/Uploadable/Fixture/penguins.jpg'; const TEST_FILE2 = '/FSi/DoctrineExtensions/Tests/Uploadable/Fixture/lighthouse.jpg'; @@ -63,6 +66,20 @@ public function testUploadablePropertyInLeafClassInInheritanceTree() $this->assertNotNull($promotion->getIntroImage()); } + public function testUploadablePropertyInSingleTableInInheritance() + { + $employee = new Employee(); + $employee->setFile(new \SplFileInfo(TESTS_PATH . self::TEST_FILE1)); + + $this->_em->persist($employee); + $this->_em->flush(); + $this->_em->clear(); + + $employee = $this->_em->find(self::EMPLOYEE, $employee->getId()); + + $this->assertNotNull($employee->getFile()); + } + protected function tearDown() { Utils::deleteRecursive(FILESYSTEM1); @@ -78,7 +95,9 @@ protected function getUsedEntityFixtures() self::PAGE, self::EXCERPT_PAGE, self::EVENT_PAGE, - self::PROMOTION_PAGE + self::PROMOTION_PAGE, + self::PERSON, + self::EMPLOYEE ]; } }