From 45579fd7cd792eca9e4fdc90b34dd18523441137 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Thu, 11 Jun 2015 17:49:33 +0200 Subject: [PATCH] [Form] Fixed: Filter non-integers when selecting entities by int ID --- .../Form/ChoiceList/ORMQueryBuilderLoader.php | 6 +++ .../ChoiceList/ORMQueryBuilderLoaderTest.php | 38 +++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php index 872e77affe..60aece4400 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php @@ -86,6 +86,12 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface $metadata = $qb->getEntityManager()->getClassMetadata($entity); if (in_array($metadata->getTypeOfField($identifier), array('integer', 'bigint', 'smallint'))) { $parameterType = Connection::PARAM_INT_ARRAY; + + // Filter out non-integer values (e.g. ""). If we don't, some + // databases such as PostgreSQL fail. + $values = array_values(array_filter($values, function ($v) { + return (string) $v === (string) (int) $v; + })); } else { $parameterType = Connection::PARAM_STR_ARRAY; } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php index bbad668250..7b68fda055 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php @@ -15,7 +15,7 @@ use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader; use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; use Doctrine\DBAL\Connection; -class ORMQueryBuilderLoaderTest extends DoctrineTestHelper +class ORMQueryBuilderLoaderTest extends \PHPUnit_Framework_TestCase { /** * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException @@ -27,6 +27,7 @@ class ORMQueryBuilderLoaderTest extends DoctrineTestHelper /** * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException + * @group legacy */ public function testClosureRequiresTheEntityManager() { @@ -47,7 +48,7 @@ class ORMQueryBuilderLoaderTest extends DoctrineTestHelper protected function checkIdentifierType($classname, $expectedType) { - $em = $this->createTestEntityManager(); + $em = DoctrineTestHelper::createTestEntityManager(); $query = $this->getMockBuilder('QueryMock') ->setMethods(array('setParameter', 'getResult', 'getSql', '_doExecute')) @@ -56,7 +57,7 @@ class ORMQueryBuilderLoaderTest extends DoctrineTestHelper $query->expects($this->once()) ->method('setParameter') ->with('ORMQueryBuilderLoader_getEntitiesByIds_id', array(), $expectedType) - ->will($this->returnValue($query)); + ->willReturn($query); $qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder') ->setConstructorArgs(array($em)) @@ -65,7 +66,7 @@ class ORMQueryBuilderLoaderTest extends DoctrineTestHelper $qb->expects($this->once()) ->method('getQuery') - ->will($this->returnValue($query)); + ->willReturn($query); $qb->select('e') ->from($classname, 'e'); @@ -73,4 +74,33 @@ class ORMQueryBuilderLoaderTest extends DoctrineTestHelper $loader = new ORMQueryBuilderLoader($qb); $loader->getEntitiesByIds('id', array()); } + + public function testFilterNonIntegerValues() + { + $em = DoctrineTestHelper::createTestEntityManager(); + + $query = $this->getMockBuilder('QueryMock') + ->setMethods(array('setParameter', 'getResult', 'getSql', '_doExecute')) + ->getMock(); + + $query->expects($this->once()) + ->method('setParameter') + ->with('ORMQueryBuilderLoader_getEntitiesByIds_id', array(1, 2, 3), Connection::PARAM_INT_ARRAY) + ->willReturn($query); + + $qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder') + ->setConstructorArgs(array($em)) + ->setMethods(array('getQuery')) + ->getMock(); + + $qb->expects($this->once()) + ->method('getQuery') + ->willReturn($query); + + $qb->select('e') + ->from('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity', 'e'); + + $loader = new ORMQueryBuilderLoader($qb); + $loader->getEntitiesByIds('id', array(1, '', 2, 3, 'foo')); + } }