diff --git a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php index b2c6b9f5e..f8b7607ca 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php @@ -244,10 +244,14 @@ abstract class AbstractHydrator } if (isset($cache[$key]['isNewObjectParameter'])) { + $class = $cache[$key]['class']; $argIndex = $cache[$key]['argIndex']; $objIndex = $cache[$key]['objIndex']; - $rowData['newObjects'][$objIndex]['class'] = $cache[$key]['class']; - $rowData['newObjects'][$objIndex]['args'][$argIndex] = $cache[$key]['fieldName']; + $value = $cache[$key]['type'] + ->convertToPHPValue($value, $this->_platform); + + $rowData['newObjects'][$objIndex]['class'] = $class; + $rowData['newObjects'][$objIndex]['args'][$argIndex] = $value; } if (isset($cache[$key]['isScalar'])) { diff --git a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php index 7ab624ec0..e311507db 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php @@ -389,8 +389,8 @@ class ObjectHydrator extends AbstractHydrator } $indexExists = isset($this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]]); - $index = $indexExists ? $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] : false; - $indexIsValid = $index !== false ? isset($reflFieldValue[$index]) : false; + $argIndex = $indexExists ? $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] : false; + $indexIsValid = $argIndex !== false ? isset($reflFieldValue[$argIndex]) : false; if ( ! $indexExists || ! $indexIsValid) { if (isset($this->_existingCollections[$collKey])) { @@ -417,7 +417,7 @@ class ObjectHydrator extends AbstractHydrator } } else { // Update result pointer - $this->_resultPointers[$dqlAlias] = $reflFieldValue[$index]; + $this->_resultPointers[$dqlAlias] = $reflFieldValue[$argIndex]; } } else if ( ! $reflFieldValue) { $reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias); @@ -517,9 +517,9 @@ class ObjectHydrator extends AbstractHydrator } else { // Update result pointer - $index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]]; - $this->_resultPointers[$dqlAlias] = $result[$index]; - $resultKey = $index; + $argIndex = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]]; + $this->_resultPointers[$dqlAlias] = $result[$argIndex]; + $resultKey = $argIndex; /*if ($this->_rsm->isMixed) { $result[] = $result[$index]; ++$this->_resultCounter; @@ -549,13 +549,19 @@ class ObjectHydrator extends AbstractHydrator $resultKey = $this->_resultCounter - 1; } - foreach ($newObjects as $newObject) { - $args = array(); + $count = count($newObjects); + + foreach ($newObjects as $objIndex => $newObject) { $class = $newObject['class']; - foreach ($newObject['args'] as $index => $name) { - $args[$index] = $result[$resultKey][$name]; + $args = $newObject['args']; + $obj = $class->newInstanceArgs($args); + + if ($count === 1) { + $result[$resultKey] = $obj; + continue; } - $result[$resultKey] = $class->newInstanceArgs($args); + + $result[$resultKey][$objIndex] = $obj; } } diff --git a/tests/Doctrine/Tests/ORM/Functional/NewOperatorTest.php b/tests/Doctrine/Tests/ORM/Functional/NewOperatorTest.php index 1b85b485b..e83130e28 100644 --- a/tests/Doctrine/Tests/ORM/Functional/NewOperatorTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/NewOperatorTest.php @@ -398,4 +398,56 @@ class NewOperatorTest extends \Doctrine\Tests\OrmFunctionalTestCase $result[2]->phonenumbers ); } + + public function testShouldSupportMultipleNewOperators() + { + $dql = " + SELECT + new Doctrine\Tests\Models\CMS\CmsUserDTO( + u.name, + e.email + ), + new Doctrine\Tests\Models\CMS\CmsAddressDTO( + a.country, + a.city + ) + FROM + Doctrine\Tests\Models\CMS\CmsUser u + JOIN + u.email e + JOIN + u.address a + ORDER BY + u.name"; + + $query = $this->_em->createQuery($dql); + $result = $query->getResult(); + + $this->assertCount(3, $result); + + $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUserDTO', $result[0][0]); + $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUserDTO', $result[1][0]); + $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUserDTO', $result[2][0]); + + $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsAddressDTO', $result[0][1]); + $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsAddressDTO', $result[1][1]); + $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsAddressDTO', $result[2][1]); + + $this->assertEquals($this->fixtures[0]->name, $result[0][0]->name); + $this->assertEquals($this->fixtures[1]->name, $result[1][0]->name); + $this->assertEquals($this->fixtures[2]->name, $result[2][0]->name); + + $this->assertEquals($this->fixtures[0]->email->email, $result[0][0]->email); + $this->assertEquals($this->fixtures[1]->email->email, $result[1][0]->email); + $this->assertEquals($this->fixtures[2]->email->email, $result[2][0]->email); + + + $this->assertEquals($this->fixtures[0]->address->city, $result[0][1]->city); + $this->assertEquals($this->fixtures[1]->address->city, $result[1][1]->city); + $this->assertEquals($this->fixtures[2]->address->city, $result[2][1]->city); + + $this->assertEquals($this->fixtures[0]->address->country, $result[0][1]->country); + $this->assertEquals($this->fixtures[1]->address->country, $result[1][1]->country); + $this->assertEquals($this->fixtures[2]->address->country, $result[2][1]->country); + } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index 573621d25..351615f42 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -1561,24 +1561,30 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase public function testSupportsNewOperator() { $this->assertSqlGeneration( - 'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a', - 'SELECT c0_.name AS sclr0, c1_.email AS sclr1, c2_.city AS sclr2 FROM cms_users c0_ INNER JOIN cms_emails c1_ ON c0_.email_id = c1_.id INNER JOIN cms_addresses c2_ ON c0_.id = c2_.user_id' + "SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a", + "SELECT c0_.name AS sclr0, c1_.email AS sclr1, c2_.city AS sclr2 FROM cms_users c0_ INNER JOIN cms_emails c1_ ON c0_.email_id = c1_.id INNER JOIN cms_addresses c2_ ON c0_.id = c2_.user_id" ); $this->assertSqlGeneration( - 'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.id + u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a', + "SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.id + u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a", "SELECT c0_.name AS sclr0, c1_.email AS sclr1, c2_.id + c0_.id AS sclr2 FROM cms_users c0_ INNER JOIN cms_emails c1_ ON c0_.email_id = c1_.id INNER JOIN cms_addresses c2_ ON c0_.id = c2_.user_id" ); $this->assertSqlGeneration( - 'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city, COUNT(p)) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a JOIN u.phonenumbers p', - 'SELECT c0_.name AS sclr0, c1_.email AS sclr1, c2_.city AS sclr2, COUNT(c3_.phonenumber) AS sclr3 FROM cms_users c0_ INNER JOIN cms_emails c1_ ON c0_.email_id = c1_.id INNER JOIN cms_addresses c2_ ON c0_.id = c2_.user_id INNER JOIN cms_phonenumbers c3_ ON c0_.id = c3_.user_id' + "SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city, COUNT(p)) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a JOIN u.phonenumbers p", + "SELECT c0_.name AS sclr0, c1_.email AS sclr1, c2_.city AS sclr2, COUNT(c3_.phonenumber) AS sclr3 FROM cms_users c0_ INNER JOIN cms_emails c1_ ON c0_.email_id = c1_.id INNER JOIN cms_addresses c2_ ON c0_.id = c2_.user_id INNER JOIN cms_phonenumbers c3_ ON c0_.id = c3_.user_id" ); $this->assertSqlGeneration( - 'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city, COUNT(p) + u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a JOIN u.phonenumbers p', - 'SELECT c0_.name AS sclr0, c1_.email AS sclr1, c2_.city AS sclr2, COUNT(c3_.phonenumber) + c0_.id AS sclr3 FROM cms_users c0_ INNER JOIN cms_emails c1_ ON c0_.email_id = c1_.id INNER JOIN cms_addresses c2_ ON c0_.id = c2_.user_id INNER JOIN cms_phonenumbers c3_ ON c0_.id = c3_.user_id' + "SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city, COUNT(p) + u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a JOIN u.phonenumbers p", + "SELECT c0_.name AS sclr0, c1_.email AS sclr1, c2_.city AS sclr2, COUNT(c3_.phonenumber) + c0_.id AS sclr3 FROM cms_users c0_ INNER JOIN cms_emails c1_ ON c0_.email_id = c1_.id INNER JOIN cms_addresses c2_ ON c0_.id = c2_.user_id INNER JOIN cms_phonenumbers c3_ ON c0_.id = c3_.user_id" ); + + $this->assertSqlGeneration( + "SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(a.id, a.country, a.city), new Doctrine\Tests\Models\CMS\CmsAddressDTO(u.name, e.email) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a ORDER BY u.name", + "SELECT c0_.id AS sclr0, c0_.country AS sclr1, c0_.city AS sclr2, c1_.name AS sclr3, c2_.email AS sclr4 FROM cms_users c1_ INNER JOIN cms_emails c2_ ON c1_.email_id = c2_.id INNER JOIN cms_addresses c0_ ON c1_.id = c0_.user_id ORDER BY c1_.name ASC" + ); + } public function testCustomTypeValueSql()