From 5680775591c213e1d2a7e5030adfdbea30a20cb2 Mon Sep 17 00:00:00 2001 From: eltharin Date: Wed, 5 Feb 2025 15:25:09 +0100 Subject: [PATCH] add order for args for nested dtos --- src/Internal/Hydration/AbstractHydrator.php | 2 + .../Tests/ORM/Functional/NewOperatorTest.php | 74 +++++++++++++++++-- 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/Internal/Hydration/AbstractHydrator.php b/src/Internal/Hydration/AbstractHydrator.php index 0a44d3a02b5..a2538f97a5d 100644 --- a/src/Internal/Hydration/AbstractHydrator.php +++ b/src/Internal/Hydration/AbstractHydrator.php @@ -24,6 +24,7 @@ use function end; use function in_array; use function is_array; +use function ksort; /** * Base class for all hydrators. A hydrator is a class that provides some form @@ -350,6 +351,7 @@ protected function gatherRowData(array $data, array &$id, array &$nonemptyCompon } foreach ($rowData['newObjects'] as $objIndex => $newObject) { + ksort($newObject['args']); $obj = $newObject['class']->newInstanceArgs($newObject['args']); $rowData['newObjects'][$objIndex]['obj'] = $obj; diff --git a/tests/Tests/ORM/Functional/NewOperatorTest.php b/tests/Tests/ORM/Functional/NewOperatorTest.php index 2394b6fd880..fdb6e854f1b 100644 --- a/tests/Tests/ORM/Functional/NewOperatorTest.php +++ b/tests/Tests/ORM/Functional/NewOperatorTest.php @@ -1030,12 +1030,7 @@ public function testShouldSupportNestedNewOperators(): void new CmsAddressDTO( a.country, a.city, - a.zip, - new CmsAddressDTO( - a.country, - a.city, - a.zip - ) + a.zip ) ) as user, u.status, @@ -1087,6 +1082,73 @@ public function testShouldSupportNestedNewOperators(): void self::assertSame($this->fixtures[2]->username, $result[2]['cmsUserUsername']); } + public function testShouldSupportNestedNewOperatorsWithDtoFirst(): void + { + $dql = ' + SELECT + new CmsUserDTO( + u.name, + e.email, + new CmsAddressDTO( + a.country, + a.city, + a.zip + ), + 555812452 + ) as user, + u.status, + u.username as cmsUserUsername + FROM + Doctrine\Tests\Models\CMS\CmsUser u + JOIN + u.email e + JOIN + u.address a + ORDER BY + u.name'; + + $query = $this->getEntityManager()->createQuery($dql); + $result = $query->getResult(); + + self::assertCount(3, $result); + + self::assertInstanceOf(CmsUserDTO::class, $result[0]['user']); + self::assertInstanceOf(CmsUserDTO::class, $result[1]['user']); + self::assertInstanceOf(CmsUserDTO::class, $result[2]['user']); + + self::assertInstanceOf(CmsAddressDTO::class, $result[0]['user']->address); + self::assertInstanceOf(CmsAddressDTO::class, $result[1]['user']->address); + self::assertInstanceOf(CmsAddressDTO::class, $result[2]['user']->address); + + self::assertSame($this->fixtures[0]->name, $result[0]['user']->name); + self::assertSame($this->fixtures[1]->name, $result[1]['user']->name); + self::assertSame($this->fixtures[2]->name, $result[2]['user']->name); + + self::assertSame($this->fixtures[0]->email->email, $result[0]['user']->email); + self::assertSame($this->fixtures[1]->email->email, $result[1]['user']->email); + self::assertSame($this->fixtures[2]->email->email, $result[2]['user']->email); + + self::assertSame($this->fixtures[0]->address->city, $result[0]['user']->address->city); + self::assertSame($this->fixtures[1]->address->city, $result[1]['user']->address->city); + self::assertSame($this->fixtures[2]->address->city, $result[2]['user']->address->city); + + self::assertSame($this->fixtures[0]->address->country, $result[0]['user']->address->country); + self::assertSame($this->fixtures[1]->address->country, $result[1]['user']->address->country); + self::assertSame($this->fixtures[2]->address->country, $result[2]['user']->address->country); + + self::assertSame(555812452, $result[0]['user']->phonenumbers); + self::assertSame(555812452, $result[1]['user']->phonenumbers); + self::assertSame(555812452, $result[2]['user']->phonenumbers); + + self::assertSame($this->fixtures[0]->status, $result[0]['status']); + self::assertSame($this->fixtures[1]->status, $result[1]['status']); + self::assertSame($this->fixtures[2]->status, $result[2]['status']); + + self::assertSame($this->fixtures[0]->username, $result[0]['cmsUserUsername']); + self::assertSame($this->fixtures[1]->username, $result[1]['cmsUserUsername']); + self::assertSame($this->fixtures[2]->username, $result[2]['cmsUserUsername']); + } + public function testNamedArguments(): void { $dql = <<<'SQL'