diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php index 55fc340d8d2ee..4cd2f9029dd74 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php @@ -85,7 +85,8 @@ public function getEntitiesByIds($identifier, array $values) // Guess type $entity = current($qb->getRootEntities()); $metadata = $qb->getEntityManager()->getClassMetadata($entity); - if (in_array($metadata->getTypeOfField($identifier), array('integer', 'bigint', 'smallint'))) { + $identifierFieldType = $metadata->getTypeOfField($identifier); + if (in_array($identifierFieldType, array('integer', 'bigint', 'smallint'))) { $parameterType = Connection::PARAM_INT_ARRAY; // Filter out non-integer values (e.g. ""). If we don't, some @@ -93,6 +94,14 @@ public function getEntitiesByIds($identifier, array $values) $values = array_values(array_filter($values, function ($v) { return (string) $v === (string) (int) $v; })); + } elseif ('guid' === $identifierFieldType) { + $parameterType = Connection::PARAM_STR_ARRAY; + + // Filter out non-uuid values (e.g. "", 1, "asdf"). If we don't, some + // databases such as PostgreSQL fail. + $values = array_values(array_filter($values, function ($v) { + return (bool) preg_match('/^\{?[a-fA-F0-9]{8}-?[a-fA-F0-9]{4}-?[a-fA-F0-9]{4}-?[a-fA-F0-9]{4}-?[a-fA-F0-9]{12}\}?$/', $v); + })); } else { $parameterType = Connection::PARAM_STR_ARRAY; } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleGuidIdEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleGuidIdEntity.php new file mode 100644 index 0000000000000..a6ed1f9ab71be --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleGuidIdEntity.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; + +/** @Entity */ +class SingleGuidIdEntity +{ + /** @Id @Column(type="guid") */ + protected $id; + + /** @Column(type="string", nullable=true) */ + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } + + public function __toString() + { + return (string) $this->name; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php index 81b716ef38e2d..98d0e97ac2037 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php @@ -105,6 +105,35 @@ public function testFilterNonIntegerValues() $loader->getEntitiesByIds('id', array(1, '', 2, 3, 'foo')); } + public function testFilterNonGuidValues() + { + $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('f0b928bd-e471-4870-9f99-430a005e3897', 'e586ff90-222e-4a86-ac82-82627e84adfb'), Connection::PARAM_STR_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\SingleGuidIdEntity', 'e'); + + $loader = new ORMQueryBuilderLoader($qb); + $loader->getEntitiesByIds('id', array(1, '', 'f0b928bd-e471-4870-9f99-430a005e3897', 'g0b928bd-e471-4870-9f99-430a005e3897', 'e586ff90-222e-4a86-ac82-82627e84adfb', 'foo')); + } + public function testEmbeddedIdentifierName() { if (Version::compare('2.5.0') > 0) {