diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index 51d6dbf05..b61a2557b 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -19,6 +19,7 @@ namespace Doctrine\ORM; +use Doctrine\ORM\Mapping\MappingException; use Exception; use Doctrine\Common\EventManager; use Doctrine\DBAL\Connection; @@ -539,10 +540,22 @@ use Doctrine\Common\Util\ClassUtils; * @param string|null $entityName if given, only entities of this type will get detached * * @return void + * + * @throws ORMInvalidArgumentException if a non-null non-string value is given + * @throws \Doctrine\Common\Persistence\Mapping\MappingException if a $entityName is given, but that entity is not + * found in the mappings */ public function clear($entityName = null) { - $this->unitOfWork->clear($entityName); + if (null !== $entityName && ! is_string($entityName)) { + throw ORMInvalidArgumentException::invalidEntityName($entityName); + } + + $this->unitOfWork->clear( + null === $entityName + ? null + : $this->metadataFactory->getMetadataFor($entityName)->getName() + ); } /** diff --git a/lib/Doctrine/ORM/ORMException.php b/lib/Doctrine/ORM/ORMException.php index 919789d92..039ef2eaa 100644 --- a/lib/Doctrine/ORM/ORMException.php +++ b/lib/Doctrine/ORM/ORMException.php @@ -101,7 +101,7 @@ class ORMException extends Exception return new self("Unrecognized field: $field"); } - /** + /** * * @param string $class * @param string $association diff --git a/lib/Doctrine/ORM/ORMInvalidArgumentException.php b/lib/Doctrine/ORM/ORMInvalidArgumentException.php index 81466a0fe..accf1cc15 100644 --- a/lib/Doctrine/ORM/ORMInvalidArgumentException.php +++ b/lib/Doctrine/ORM/ORMInvalidArgumentException.php @@ -210,6 +210,18 @@ class ORMInvalidArgumentException extends \InvalidArgumentException )); } + /** + * Used when a given entityName hasn't the good type + * + * @param mixed $entityName The given entity (which shouldn't be a string) + * + * @return self + */ + public static function invalidEntityName($entityName) + { + return new self(sprintf('Entity name must be a string, %s given', gettype($entityName))); + } + /** * Helper method to show an object as string. * diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index fbbab7b6a..368fdfd63 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -2360,6 +2360,8 @@ class UnitOfWork implements PropertyChangedListener * @param string|null $entityName if given, only entities of this type will get detached. * * @return void + * + * @throws ORMInvalidArgumentException if an invalid entity name is given */ public function clear($entityName = null) { diff --git a/tests/Doctrine/Tests/ORM/EntityManagerTest.php b/tests/Doctrine/Tests/ORM/EntityManagerTest.php index d0cf2bcbb..954a3f2f0 100644 --- a/tests/Doctrine/Tests/ORM/EntityManagerTest.php +++ b/tests/Doctrine/Tests/ORM/EntityManagerTest.php @@ -3,15 +3,20 @@ namespace Doctrine\Tests\ORM; use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; +use Doctrine\Common\Persistence\Mapping\MappingException; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManager; use Doctrine\ORM\ORMException; use Doctrine\ORM\ORMInvalidArgumentException; use Doctrine\ORM\Query\ResultSetMapping; +use Doctrine\Tests\Models\GeoNames\Country; use Doctrine\Tests\OrmTestCase; class EntityManagerTest extends OrmTestCase { + /** + * @var EntityManager + */ private $_em; function setUp() @@ -69,7 +74,7 @@ class EntityManagerTest extends OrmTestCase } /** - * @covers Doctrine\ORM\EntityManager::createNamedNativeQuery + * @covers \Doctrine\ORM\EntityManager::createNamedNativeQuery */ public function testCreateNamedNativeQuery() { @@ -217,4 +222,60 @@ class EntityManagerTest extends OrmTestCase $config->setMetadataDriverImpl($this->createMock(MappingDriver::class)); EntityManager::create(1, $config); } + + /** + * @group 6017 + */ + public function testClearManagerWithObject() + { + $entity = new Country(456, 'United Kingdom'); + + $this->expectException(ORMInvalidArgumentException::class); + + $this->_em->clear($entity); + } + + /** + * @group 6017 + */ + public function testClearManagerWithUnknownEntityName() + { + $this->expectException(MappingException::class); + + $this->_em->clear(uniqid('nonExisting', true)); + } + + /** + * @group 6017 + */ + public function testClearManagerWithProxyClassName() + { + $proxy = $this->_em->getReference(Country::class, ['id' => rand(457, 100000)]); + + $entity = new Country(456, 'United Kingdom'); + + $this->_em->persist($entity); + + $this->assertTrue($this->_em->contains($entity)); + + $this->_em->clear(get_class($proxy)); + + $this->assertFalse($this->_em->contains($entity)); + } + + /** + * @group 6017 + */ + public function testClearManagerWithNullValue() + { + $entity = new Country(456, 'United Kingdom'); + + $this->_em->persist($entity); + + $this->assertTrue($this->_em->contains($entity)); + + $this->_em->clear(null); + + $this->assertFalse($this->_em->contains($entity)); + } } diff --git a/tests/Doctrine/Tests/ORM/ORMInvalidArgumentExceptionTest.php b/tests/Doctrine/Tests/ORM/ORMInvalidArgumentExceptionTest.php new file mode 100644 index 000000000..81f22e2b7 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/ORMInvalidArgumentExceptionTest.php @@ -0,0 +1,60 @@ +getMessage()); + } + + /** + * @return string[][] + */ + public function invalidEntityNames() + { + return [ + [null, 'Entity name must be a string, NULL given'], + [true, 'Entity name must be a string, boolean given'], + [123, 'Entity name must be a string, integer given'], + [123.45, 'Entity name must be a string, double given'], + [new \stdClass(), 'Entity name must be a string, object given'], + ]; + } +} diff --git a/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php b/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php index 0ff2572b9..5a32d2882 100644 --- a/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php +++ b/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php @@ -4,10 +4,12 @@ namespace Doctrine\Tests\ORM; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\NotifyPropertyChanged; +use Doctrine\Common\Persistence\Mapping\MappingException; use Doctrine\Common\PropertyChangedListener; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\ORMInvalidArgumentException; use Doctrine\ORM\UnitOfWork; +use Doctrine\ORM\ORMException; use Doctrine\Tests\Mocks\ConnectionMock; use Doctrine\Tests\Mocks\DriverMock; use Doctrine\Tests\Mocks\EntityManagerMock;