diff --git a/CHANGELOG b/CHANGELOG index 06e6f808c..d1c6d7682 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,7 @@ Version 1.1.18 under development - Bug #4020: Fixed PHP 7 related bug in CCacheHttpSession when destroying not cached sessions (dirx) - Chg #4033: Updated Pear/Text used by Gii so it's PHP 7 compatible (samdark) - Bug #4034: Fixed `CHttpSession::getIsStarted()` PHP 7 compatibility (tomotomo) +- Bug #4061: Fixed "Fatal Error: Nesting level too deep - recursive dependency" error in `CArrayDataProvider` (kf99916, andrewnester) Version 1.1.17 January 13, 2016 ------------------------------ diff --git a/framework/web/CArrayDataProvider.php b/framework/web/CArrayDataProvider.php index 5b4b51160..c8d1af9ba 100644 --- a/framework/web/CArrayDataProvider.php +++ b/framework/web/CArrayDataProvider.php @@ -129,7 +129,7 @@ class CArrayDataProvider extends CDataProvider */ protected function sortData($directions) { - if(empty($directions)) + if(empty($directions) || empty($this->rawData)) return; $args=array(); $dummy=array(); @@ -147,6 +147,13 @@ class CArrayDataProvider extends CDataProvider $dummy[]=&$direction; unset($direction); } + + // This fix is used for cases when main sorting specified by columns has equal values + // Without it it will lead to Fatal Error: Nesting level too deep - recursive dependency? + $args[] = range(1, count($this->rawData)); + $args[] = SORT_ASC; + $args[] = SORT_NUMERIC; + $args[]=&$this->rawData; call_user_func_array('array_multisort', $args); } diff --git a/tests/framework/web/CArrayDataProviderTest.php b/tests/framework/web/CArrayDataProviderTest.php index 92516f099..85826c2f1 100644 --- a/tests/framework/web/CArrayDataProviderTest.php +++ b/tests/framework/web/CArrayDataProviderTest.php @@ -202,4 +202,37 @@ class CArrayDataProviderTest extends CTestCase $this->assertEquals($sortedProjects, $dataProvider->getData()); } -} \ No newline at end of file + + public function testNestedObjectsSort() + { + $obj1 = new \stdClass(); + $obj1->type = "def"; + $obj1->owner = $obj1; + $obj2 = new \stdClass(); + $obj2->type = "abc"; + $obj2->owner = $obj2; + $obj3 = new \stdClass(); + $obj3->type = "abc"; + $obj3->owner = $obj3; + $models = array($obj1, $obj2, $obj3); + + $this->assertEquals($obj2, $obj3); + $dataProvider = new CArrayDataProvider($models, array( + 'sort'=>array( + 'attributes'=>array( + 'sort'=>array( + 'asc'=>'type ASC', + 'desc'=>'type DESC', + 'label'=>'Type', + 'default'=>'asc', + ), + ), + 'defaultOrder'=>array( + 'sort'=>CSort::SORT_ASC, + ) + ), + )); + $sortedArray = array($obj2, $obj3, $obj1); + $this->assertEquals($sortedArray, $dataProvider->getData()); + } +}