Merge branch '2.3' into 2.6

* 2.3:
  [DoctrineBridge] Bypass the db when no valid identifier is provided in ORMQueryBuilderLoader
  [Form] Fixed: Filter non-integers when selecting entities by int ID
This commit is contained in:
Nicolas Grekas 2015-06-18 18:11:37 +02:00
commit 287db73898
2 changed files with 45 additions and 6 deletions

View File

@ -86,9 +86,18 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface
$metadata = $qb->getEntityManager()->getClassMetadata($entity); $metadata = $qb->getEntityManager()->getClassMetadata($entity);
if (in_array($metadata->getTypeOfField($identifier), array('integer', 'bigint', 'smallint'))) { if (in_array($metadata->getTypeOfField($identifier), array('integer', 'bigint', 'smallint'))) {
$parameterType = Connection::PARAM_INT_ARRAY; $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 { } else {
$parameterType = Connection::PARAM_STR_ARRAY; $parameterType = Connection::PARAM_STR_ARRAY;
} }
if (!$values) {
return array();
}
return $qb->andWhere($where) return $qb->andWhere($where)
->getQuery() ->getQuery()

View File

@ -15,7 +15,7 @@ use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader;
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
class ORMQueryBuilderLoaderTest extends DoctrineTestHelper class ORMQueryBuilderLoaderTest extends \PHPUnit_Framework_TestCase
{ {
/** /**
* @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
@ -27,6 +27,7 @@ class ORMQueryBuilderLoaderTest extends DoctrineTestHelper
/** /**
* @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
* @group legacy
*/ */
public function testClosureRequiresTheEntityManager() public function testClosureRequiresTheEntityManager()
{ {
@ -47,7 +48,7 @@ class ORMQueryBuilderLoaderTest extends DoctrineTestHelper
protected function checkIdentifierType($classname, $expectedType) protected function checkIdentifierType($classname, $expectedType)
{ {
$em = $this->createTestEntityManager(); $em = DoctrineTestHelper::createTestEntityManager();
$query = $this->getMockBuilder('QueryMock') $query = $this->getMockBuilder('QueryMock')
->setMethods(array('setParameter', 'getResult', 'getSql', '_doExecute')) ->setMethods(array('setParameter', 'getResult', 'getSql', '_doExecute'))
@ -55,8 +56,8 @@ class ORMQueryBuilderLoaderTest extends DoctrineTestHelper
$query->expects($this->once()) $query->expects($this->once())
->method('setParameter') ->method('setParameter')
->with('ORMQueryBuilderLoader_getEntitiesByIds_id', array(), $expectedType) ->with('ORMQueryBuilderLoader_getEntitiesByIds_id', array(1, 2), $expectedType)
->will($this->returnValue($query)); ->willReturn($query);
$qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder') $qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder')
->setConstructorArgs(array($em)) ->setConstructorArgs(array($em))
@ -65,12 +66,41 @@ class ORMQueryBuilderLoaderTest extends DoctrineTestHelper
$qb->expects($this->once()) $qb->expects($this->once())
->method('getQuery') ->method('getQuery')
->will($this->returnValue($query)); ->willReturn($query);
$qb->select('e') $qb->select('e')
->from($classname, 'e'); ->from($classname, 'e');
$loader = new ORMQueryBuilderLoader($qb); $loader = new ORMQueryBuilderLoader($qb);
$loader->getEntitiesByIds('id', array()); $loader->getEntitiesByIds('id', array(1, 2));
}
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'));
} }
} }