From 7993875f16b7eb16b362dacf1b2ca9da9bd28cff Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Tue, 26 Aug 2014 14:56:45 +1200 Subject: [PATCH] FIX: Sorting a DataQuery over a relation. When sorting a DataQuery over a relation, the SQLQuery automatically included the sort column. The issue with the implement is that potentially the joined record has a field with the same name as the source record causing it to be overridden. In the attached test case, without the patch the title will be set to 'Bar' rather than 'Foo'. This patch aliases the sort column. Alternativally a patch would be to --- model/DataQuery.php | 19 ++++++++++++++----- tests/model/DataQueryTest.php | 25 ++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/model/DataQuery.php b/model/DataQuery.php index 089f275ca..8b5b5e612 100644 --- a/model/DataQuery.php +++ b/model/DataQuery.php @@ -256,6 +256,7 @@ class DataQuery { if($orderby = $query->getOrderBy()) { $newOrderby = array(); + $i = 0; foreach($orderby as $k => $dir) { $newOrderby[$k] = $dir; @@ -268,7 +269,10 @@ class DataQuery { // Pull through SortColumn references from the originalSelect variables if(preg_match('/_SortColumn/', $col)) { - if(isset($originalSelect[$col])) $query->selectField($originalSelect[$col], $col); + if(isset($originalSelect[$col])) { + $query->selectField($originalSelect[$col], $col); + } + continue; } @@ -287,6 +291,7 @@ class DataQuery { // remove original sort unset($newOrderby[$k]); + // add new columns sort $newOrderby[$qualCol] = $dir; @@ -298,13 +303,17 @@ class DataQuery { } } else { $qualCol = '"' . implode('"."', $parts) . '"'; - - // To-do: Remove this if block once SQLQuery::$select has been refactored to store getSelect() - // format internally; then this check can be part of selectField() + if(!in_array($qualCol, $query->getSelect())) { - $query->selectField($qualCol); + unset($newOrderby[$k]); + + $newOrderby["\"_SortColumn$i\""] = $dir; + $query->selectField($qualCol, "_SortColumn$i"); + + $i++; } } + } $query->setOrderBy($newOrderby); diff --git a/tests/model/DataQueryTest.php b/tests/model/DataQueryTest.php index 09454c044..b76f6fdd1 100644 --- a/tests/model/DataQueryTest.php +++ b/tests/model/DataQueryTest.php @@ -12,6 +12,27 @@ class DataQueryTest extends SapphireTest { 'DataQueryTest_E', ); + + public function testSortByJoinedFieldRetainsSourceInformation() { + $bar = new DataQueryTest_C(); + $bar->Title = "Bar"; + $bar->write(); + + $foo = new DataQueryTest_B(); + $foo->Title = "Foo"; + $foo->TestC = $bar->ID; + $foo->write(); + + $query = new DataQuery('DataQueryTest_B'); + $result = $query->leftJoin( + 'DataQueryTest_C', + "\"DataQueryTest_B\".\"TestCID\" = \"DataQueryTest_B\".\"ID\"" + )->sort('"DataQueryTest_B"."Title"', 'ASC'); + + $result = $result->execute()->record(); + $this->assertEquals('Foo', $result['Title']); + } + /** * Test the leftJoin() and innerJoin method of the DataQuery object */ @@ -138,6 +159,7 @@ class DataQueryTest extends SapphireTest { class DataQueryTest_A extends DataObject implements TestOnly { + private static $db = array( 'Name' => 'Varchar', ); @@ -147,7 +169,8 @@ class DataQueryTest_A extends DataObject implements TestOnly { ); } -class DataQueryTest_B extends DataQueryTest_A { +class DataQueryTest_B extends DataObject implements TestOnly { + private static $db = array( 'Title' => 'Varchar', );