From c5e858af60f491b8eb630ddd9afee6b28a9dc352 Mon Sep 17 00:00:00 2001 From: Paul Ferrett Date: Fri, 22 Jan 2016 17:38:41 +0800 Subject: [PATCH 1/3] [Form] Filter non-uuids when selecting entities by guid ID --- .../Form/ChoiceList/ORMQueryBuilderLoader.php | 11 +++++- .../Tests/Fixtures/SingleGuidIdEntity.php | 37 +++++++++++++++++++ .../ChoiceList/ORMQueryBuilderLoaderTest.php | 29 +++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleGuidIdEntity.php diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php index 55fc340d8d2e..b729e0186ab6 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 (in_array($identifierFieldType, array('guid'))) { + $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 000000000000..a6ed1f9ab71b --- /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 81b716ef38e2..5b606d6e8ad4 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) { From 47bf91e9f3e2280ae152e6b54ac9e32d0919e536 Mon Sep 17 00:00:00 2001 From: Paul Ferrett Date: Fri, 22 Jan 2016 21:15:15 +0800 Subject: [PATCH 2/3] Coding style fixes. --- .../Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php | 2 +- .../Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php index b729e0186ab6..fdb2acb5e94e 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php @@ -100,7 +100,7 @@ public function getEntitiesByIds($identifier, array $values) // 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); + 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/Form/ChoiceList/ORMQueryBuilderLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php index 5b606d6e8ad4..98d0e97ac203 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php @@ -115,7 +115,7 @@ public function testFilterNonGuidValues() $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) + ->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') From 6acd1e5c6c5cd8a5699a63b02977795255314572 Mon Sep 17 00:00:00 2001 From: Paul Ferrett Date: Sat, 23 Jan 2016 07:57:09 +0800 Subject: [PATCH 3/3] Use a straight comparison rather than in_array check for single value. --- .../Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php index fdb2acb5e94e..4cd2f9029dd7 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php @@ -94,7 +94,7 @@ public function getEntitiesByIds($identifier, array $values) $values = array_values(array_filter($values, function ($v) { return (string) $v === (string) (int) $v; })); - } elseif (in_array($identifierFieldType, array('guid'))) { + } elseif ('guid' === $identifierFieldType) { $parameterType = Connection::PARAM_STR_ARRAY; // Filter out non-uuid values (e.g. "", 1, "asdf"). If we don't, some