From 6074755b91d026b2b30b5ca183e58e0122e5f138 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sun, 13 Jan 2013 22:39:59 -0200 Subject: [PATCH] Fix DDC-1376 --- .../ORM/Persisters/BasicEntityPersister.php | 42 +++++++--- .../ORM/Functional/EntityRepositoryTest.php | 76 ++++++++++++++++++- 2 files changed, 106 insertions(+), 12 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index c6c2a0165..8594f3f37 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -1138,29 +1138,49 @@ class BasicEntityPersister */ protected final function getOrderBySQL(array $orderBy, $baseTableAlias) { - $orderBySql = ''; + $orderByList = array(); foreach ($orderBy as $fieldName => $orientation) { - if ( ! isset($this->class->fieldMappings[$fieldName])) { - throw ORMException::unrecognizedField($fieldName); - } $orientation = strtoupper(trim($orientation)); + if ($orientation != 'ASC' && $orientation != 'DESC') { throw ORMException::invalidOrientation($this->class->name, $fieldName); } - $tableAlias = isset($this->class->fieldMappings[$fieldName]['inherited']) - ? $this->getSQLTableAlias($this->class->fieldMappings[$fieldName]['inherited']) - : $baseTableAlias; + if (isset($this->class->fieldMappings[$fieldName])) { + $tableAlias = isset($this->class->fieldMappings[$fieldName]['inherited']) + ? $this->getSQLTableAlias($this->class->fieldMappings[$fieldName]['inherited']) + : $baseTableAlias; - $columnName = $this->quoteStrategy->getColumnName($fieldName, $this->class, $this->platform); + $columnName = $this->quoteStrategy->getColumnName($fieldName, $this->class, $this->platform); + $orderByList[] = $tableAlias . '.' . $columnName . ' ' . $orientation; - $orderBySql .= $orderBySql ? ', ' : ' ORDER BY '; - $orderBySql .= $tableAlias . '.' . $columnName . ' ' . $orientation; + continue; + } + + if (isset($this->class->associationMappings[$fieldName])) { + + if ( ! $this->class->associationMappings[$fieldName]['isOwningSide']) { + throw ORMException::invalidFindByInverseAssociation($this->class->name, $fieldName); + } + + $tableAlias = isset($this->class->associationMappings[$fieldName]['inherited']) + ? $this->getSQLTableAlias($this->class->associationMappings[$fieldName]['inherited']) + : $baseTableAlias; + + foreach ($this->class->associationMappings[$fieldName]['joinColumns'] as $joinColumn) { + $columnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform); + $orderByList[] = $tableAlias . '.' . $columnName . ' ' . $orientation; + } + + continue; + } + + throw ORMException::unrecognizedField($fieldName); } - return $orderBySql; + return ' ORDER BY ' . implode(', ', $orderByList); } /** diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php index 5f1404dc6..5be4615fb 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php @@ -3,6 +3,7 @@ namespace Doctrine\Tests\ORM\Functional; use Doctrine\Tests\Models\CMS\CmsUser; +use Doctrine\Tests\Models\CMS\CmsEmail; use Doctrine\Tests\Models\CMS\CmsAddress; use Doctrine\Tests\Models\CMS\CmsPhonenumber; use Doctrine\Common\Collections\Criteria; @@ -89,6 +90,50 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase return array($user->id, $address->id); } + public function loadFixtureUserEmail() + { + $user1 = new CmsUser(); + $user2 = new CmsUser(); + $user3 = new CmsUser(); + + $email1 = new CmsEmail(); + $email2 = new CmsEmail(); + $email3 = new CmsEmail(); + + $user1->name = 'Test 1'; + $user1->username = 'test1'; + $user1->status = 'active'; + + $user2->name = 'Test 2'; + $user2->username = 'test2'; + $user2->status = 'active'; + + $user3->name = 'Test 3'; + $user3->username = 'test3'; + $user3->status = 'active'; + + $email1->email = 'test1@test.com'; + $email2->email = 'test2@test.com'; + $email3->email = 'test3@test.com'; + + $user1->setEmail($email1); + $user2->setEmail($email2); + $user3->setEmail($email3); + + $this->_em->persist($user1); + $this->_em->persist($user2); + $this->_em->persist($user3); + + $this->_em->persist($email1); + $this->_em->persist($email2); + $this->_em->persist($email3); + + $this->_em->flush(); + $this->_em->clear(); + + return array($user1, $user2, $user3); + } + public function buildUser($name, $username, $status, $address) { $user = new CmsUser(); @@ -476,6 +521,24 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertSame($usersAsc[3], $usersDesc[0]); } + /** + * @group DDC-1376 + */ + public function testFindByOrderByAssociation() + { + $this->loadFixtureUserEmail(); + + $repository = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsUser'); + $resultAsc = $repository->findBy(array(), array('email' => 'ASC')); + $resultDesc = $repository->findBy(array(), array('email' => 'DESC')); + + $this->assertCount(3, $resultAsc); + $this->assertCount(3, $resultDesc); + + $this->assertEquals($resultAsc[0]->getEmail()->getId(), $resultDesc[2]->getEmail()->getId()); + $this->assertEquals($resultAsc[2]->getEmail()->getId(), $resultDesc[0]->getEmail()->getId()); + } + /** * @group DDC-1426 */ @@ -538,7 +601,6 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase } - /** * @group DDC-753 * @expectedException Doctrine\ORM\ORMException @@ -550,6 +612,18 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->getConfiguration()->setDefaultRepositoryClassName("Doctrine\Tests\Models\DDC753\DDC753InvalidRepository"); } + /** + * @group DDC-1376 + * + * @expectedException Doctrine\ORM\ORMException + * @expectedExceptionMessage You cannot search for the association field 'Doctrine\Tests\Models\CMS\CmsUser#address', because it is the inverse side of an association. + */ + public function testInvalidOrderByAsssociation() + { + $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsUser') + ->findBy(array('status' => 'test'), array('address' => 'ASC')); + } + /** * @group DDC-1500 */