From d5fb2aaa9dc0a668d83cfb66f9a9245768318ce0 Mon Sep 17 00:00:00 2001 From: UndefinedOffset Date: Thu, 20 Apr 2017 10:45:11 -0300 Subject: [PATCH] Fixed issue where queries could fail when using append to top and the base table does not contain the parent relationship (Fixes #101) --- code/forms/GridFieldSortableRows.php | 25 ++++--- .../GridFieldSortableRowsAutoSortTest.php | 74 ++++++++++++++++++- .../GridFieldSortableRowsAutoSortTest.yml | 18 +++++ 3 files changed, 103 insertions(+), 14 deletions(-) diff --git a/code/forms/GridFieldSortableRows.php b/code/forms/GridFieldSortableRows.php index b1652e4..e8c6020 100644 --- a/code/forms/GridFieldSortableRows.php +++ b/code/forms/GridFieldSortableRows.php @@ -122,7 +122,6 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP return $dataList->sort($headerState->SortColumn, $headerState->SortDirection); } - //var_dump($state->sortableToggle);exit; if ($state->sortableToggle === true) { $gridField->getConfig()->removeComponentsByType('GridFieldFilterHeader'); $gridField->getConfig()->removeComponentsByType('GridFieldSortableHeader'); @@ -280,21 +279,10 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP . '" SET "' . $sortColumn . '" = "' . $sortColumn .'"+1' . ' WHERE '.($list instanceof RelationList ? '"' . $list->foreignKey . '" = '. $owner->ID:$idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\''.implode('\',\'', $topIncremented).'\')':'')); - //LastEdited - DB::query('UPDATE "' . $baseDataClass - . '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\'' - . ' WHERE '.($list instanceof RelationList ? '"' . $list->foreignKey . '" = '. $owner->ID:$idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\''.implode('\',\'', $topIncremented).'\')':'')); - if($this->update_versioned_stage && class_exists($table) && Object::has_extension($table, 'Versioned')) { DB::query('UPDATE "' . $table . '_' . $this->update_versioned_stage . '" SET "' . $sortColumn . '" = "' . $sortColumn .'"+1' . ' WHERE '. ($list instanceof RelationList ? '"' . $list->foreignKey . '" = '. $owner->ID:$idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\''.implode('\',\'', $topIncremented).'\')':'')); - - if(Object::has_extension($baseDataClass, 'Versioned')) { - DB::query('UPDATE "' . $baseDataClass . '_' . $this->update_versioned_stage - . '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\'' - . ' WHERE ' . ($list instanceof RelationList ? '"' . $list->foreignKey . '" = '. $owner->ID:$idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\''.implode('\',\'', $topIncremented).'\')':'')); - } } $topIncremented[]=$obj->ID; @@ -324,6 +312,19 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP $i++; } + //Update LastEdited for affected records when using append to top on a many_many relationship + if(!$many_many && $this->append_to_top && count($topIncremented)>0) { + DB::query('UPDATE "' . $baseDataClass + . '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\'' + . ' WHERE "ID" IN(\''.implode('\',\'', $topIncremented).'\')'); + + if($this->update_versioned_stage && class_exists($table) && Object::has_extension($table, 'Versioned') && Object::has_extension($baseDataClass, 'Versioned')) { + DB::query('UPDATE "' . $baseDataClass . '_' . $this->update_versioned_stage + . '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\'' + . ' WHERE "ID" IN(\''.implode('\',\'', $topIncremented).'\')'); + } + } + //End transaction if supported if(DB::getConn()->supportsTransactions()) { diff --git a/tests/forms/GridFieldSortableRowsAutoSortTest.php b/tests/forms/GridFieldSortableRowsAutoSortTest.php index cd94596..15b6c43 100644 --- a/tests/forms/GridFieldSortableRowsAutoSortTest.php +++ b/tests/forms/GridFieldSortableRowsAutoSortTest.php @@ -4,7 +4,13 @@ class GridFieldSortableRowsAutoSortTest extends SapphireTest { public static $fixture_file = 'GridFieldSortableRowsAutoSortTest.yml'; /** @var array */ - protected $extraDataObjects = array('GridFieldAction_SortOrder_Player', 'GridFieldAction_SortOrder_VPlayer'); + protected $extraDataObjects = array( + 'GridFieldAction_SortOrder_Player', + 'GridFieldAction_SortOrder_VPlayer', + 'GridFieldAction_SortOrder_TestParent', + 'GridFieldAction_SortOrder_BaseObject', + 'GridFieldAction_SortOrder_ChildObject' + ); public function testAutoSort() { if(Member::currentUser()) { Member::currentUser()->logOut(); } @@ -157,6 +163,42 @@ class GridFieldSortableRowsAutoSortTest extends SapphireTest { $indexes=count(array_unique($list->column('SortOrder'))); $this->assertEquals(0, $count-$indexes, 'Duplicate indexes detected on Versioned stage "Live"'); } + + public function testAppendToTopAutoSortChild() { + if(Member::currentUser()) { Member::currentUser()->logOut(); } + + //Push the edit date into the past, we're checking this later + DB::query('UPDATE "GridFieldAction_SortOrder_BaseObject" SET "LastEdited"=\''.date('Y-m-d 00:00:00', strtotime('yesterday')).'\''); + + $parent = GridFieldAction_SortOrder_TestParent::get()->first(); + $list = $parent->TestRelation(); + $config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder')); + $gridField = new GridField('testfield', 'testfield', $list, $config); + $form = new Form(new Controller(), 'mockform', new FieldList(array($gridField)), new FieldList()); + $form->loadDataFrom($parent); + + $gridField->getConfig()->getComponentByType('GridFieldSortableRows')->setAppendToTop(true); + + $this->assertEquals(0, $list->last()->SortOrder, 'Auto sort should not have run'); + + $stateID = 'testGridStateActionField'; + Session::set($stateID, array('grid'=>'', 'actionName'=>'sortableRowsToggle', 'args'=>array('GridFieldSortableRows'=>array('sortableToggle'=>true)))); + $request = new SS_HTTPRequest('POST', 'url', array(), array('action_gridFieldAlterAction?StateID='.$stateID=>true, $form->getSecurityToken()->getName()=>$form->getSecurityToken()->getValue())); + $gridField->gridFieldAlterAction(array('StateID'=>$stateID), $form, $request); + + //Insure sort ran + $this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run'); + + + //Check for duplicates (there shouldn't be any) + $count=$list->Count(); + $indexes=count(array_unique($list->column('SortOrder'))); + $this->assertEquals(0, $count-$indexes, 'Duplicate indexes detected'); + + + //Make sure the last edited is today for all records + $this->assertEquals(3, $list->filter('LastEdited:GreaterThan', date('Y-m-d 00:00:00'))->count()); + } } class GridFieldAction_SortOrder_Player extends DataObject implements TestOnly { @@ -174,10 +216,38 @@ class GridFieldAction_SortOrder_VPlayer extends DataObject implements TestOnly { 'SortOrder' => 'Int' ); - static $default_sort='SortOrder'; + static $default_sort = 'SortOrder'; static $extensions=array( "Versioned('Stage', 'Live')" ); } + +class GridFieldAction_SortOrder_TestParent extends DataObject implements TestOnly { + static $db = array( + 'Name' => 'Varchar' + ); + + static $has_many = array( + 'TestRelation' => 'GridFieldAction_SortOrder_ChildObject' + ); +} + +class GridFieldAction_SortOrder_BaseObject extends DataObject implements TestOnly { + static $db = array( + 'Name' => 'Varchar' + ); +} + +class GridFieldAction_SortOrder_ChildObject extends GridFieldAction_SortOrder_BaseObject implements TestOnly { + static $db = array( + 'SortOrder' => 'Int' + ); + + static $has_one = array( + 'Parent'=>'GridFieldAction_SortOrder_TestParent' + ); + + static $default_sort='SortOrder'; +} ?> \ No newline at end of file diff --git a/tests/forms/GridFieldSortableRowsAutoSortTest.yml b/tests/forms/GridFieldSortableRowsAutoSortTest.yml index 895064f..af91f76 100644 --- a/tests/forms/GridFieldSortableRowsAutoSortTest.yml +++ b/tests/forms/GridFieldSortableRowsAutoSortTest.yml @@ -19,3 +19,21 @@ GridFieldAction_SortOrder_VPlayer: player3: Name: Player 3 SortOrder: 0 + +GridFieldAction_SortOrder_TestParent: + testparent: + Name: Test + +GridFieldAction_SortOrder_ChildObject: + testitem1: + Name: Test 1 + SortOrder: 0 + Parent: =>GridFieldAction_SortOrder_TestParent.testparent + testitem2: + Name: Test 2 + SortOrder: 0 + Parent: =>GridFieldAction_SortOrder_TestParent.testparent + testitem3: + Name: Test 3 + SortOrder: 0 + Parent: =>GridFieldAction_SortOrder_TestParent.testparent \ No newline at end of file