diff --git a/lib/Cake/Model/Behavior/TreeBehavior.php b/lib/Cake/Model/Behavior/TreeBehavior.php index be6825fb6..04897686f 100644 --- a/lib/Cake/Model/Behavior/TreeBehavior.php +++ b/lib/Cake/Model/Behavior/TreeBehavior.php @@ -92,6 +92,20 @@ class TreeBehavior extends ModelBehavior { } } +/** + * Runs before a find() operation + * + * @param Model $Model Model using the behavior + * @param array $query Query parameters as set by cake + * @return array + */ + public function beforeFind($Model, $query) { + if ($Model->findQueryType == 'threaded' && !isset($query['parent'])) { + $query['parent'] = $this->settings[$Model->alias]['parent']; + } + return $query; + } + /** * Before delete method. Called before all deletes * diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index d285774de..2e5b79135 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -2813,9 +2813,13 @@ class Model extends Object implements CakeEventListener { if ($state === 'before') { return $query; } elseif ($state === 'after') { + $parent = 'parent_id'; + if (isset($query['parent'])) { + $parent = $query['parent']; + } return Set::nest($results, array( 'idPath' => '/' . $this->alias . '/' . $this->primaryKey, - 'parentPath' => '/' . $this->alias . '/parent_id' + 'parentPath' => '/' . $this->alias . '/' . $parent )); } } diff --git a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php index c536a98c0..b3ed7516e 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php @@ -54,7 +54,7 @@ class TreeBehaviorNumberTest extends CakeTestCase { * * @var array */ - public $fixtures = array('core.number_tree'); + public $fixtures = array('core.number_tree', 'core.person'); /** * testInitialize method @@ -1284,4 +1284,87 @@ class TreeBehaviorNumberTest extends CakeTestCase { $this->assertSame($this->Tree->getParentNode(2), $this->Tree->getParentNode(array('id' => 2))); $this->assertSame($this->Tree->getPath(4), $this->Tree->getPath(array('id' => 4))); } + +/** + * testFindThreaded method + * + * @return void + */ + public function testFindThreaded() { + $this->loadFixtures('Person'); + $Model = new Person(); + $Model->recursive = -1; + $Model->Behaviors->attach('Tree', array('parent' => 'mother_id')); + + $result = $Model->find('threaded'); + $expected = array( + array( + 'Person' => array( + 'id' => '4', + 'name' => 'mother - grand mother', + 'mother_id' => '0', + 'father_id' => '0' + ), + 'children' => array( + array( + 'Person' => array( + 'id' => '2', + 'name' => 'mother', + 'mother_id' => '4', + 'father_id' => '5' + ), + 'children' => array( + array( + 'Person' => array( + 'id' => '1', + 'name' => 'person', + 'mother_id' => '2', + 'father_id' => '3' + ), + 'children' => array() + ) + ) + ) + ) + ), + array( + 'Person' => array( + 'id' => '5', + 'name' => 'mother - grand father', + 'mother_id' => '0', + 'father_id' => '0' + ), + 'children' => array() + ), + array( + 'Person' => array( + 'id' => '6', + 'name' => 'father - grand mother', + 'mother_id' => '0', + 'father_id' => '0' + ), + 'children' => array( + array( + 'Person' => array( + 'id' => '3', + 'name' => 'father', + 'mother_id' => '6', + 'father_id' => '7' + ), + 'children' => array() + ) + ) + ), + array( + 'Person' => array( + 'id' => '7', + 'name' => 'father - grand father', + 'mother_id' => '0', + 'father_id' => '0' + ), + 'children' => array() + ) + ); + $this->assertEquals($expected, $result); + } } diff --git a/lib/Cake/Test/Case/Model/ModelReadTest.php b/lib/Cake/Test/Case/Model/ModelReadTest.php index 8660714da..e1ee8c0c3 100644 --- a/lib/Cake/Test/Case/Model/ModelReadTest.php +++ b/lib/Cake/Test/Case/Model/ModelReadTest.php @@ -2990,6 +2990,106 @@ class ModelReadTest extends BaseModelTest { $this->assertEquals($afterFindData, $noAfterFindData); } +/** + * testFindThreadedNoParent method + * + * @return void + */ + public function testFindThreadedNoParent() { + $this->loadFixtures('Apple', 'Sample'); + $Apple = new Apple(); + $result = $Apple->find('threaded'); + $result = Set::extract($result, '{n}.children'); + $expected = array(array(), array(), array(), array(), array(), array(), array()); + $this->assertEquals($expected, $result); + } + +/** + * testFindThreaded method + * + * @return void + */ + public function testFindThreaded() { + $this->loadFixtures('Person'); + $Model = new Person(); + $Model->recursive = -1; + $result = $Model->find('threaded'); + $result = Set::extract($result, '{n}.children'); + $expected = array(array(), array(), array(), array(), array(), array(), array()); + $this->assertEquals($expected, $result); + + $result = $Model->find('threaded', array('parent' => 'mother_id')); + $expected = array( + array( + 'Person' => array( + 'id' => '4', + 'name' => 'mother - grand mother', + 'mother_id' => '0', + 'father_id' => '0' + ), + 'children' => array( + array( + 'Person' => array( + 'id' => '2', + 'name' => 'mother', + 'mother_id' => '4', + 'father_id' => '5' + ), + 'children' => array( + array( + 'Person' => array( + 'id' => '1', + 'name' => 'person', + 'mother_id' => '2', + 'father_id' => '3' + ), + 'children' => array() + ) + ) + ) + ) + ), + array( + 'Person' => array( + 'id' => '5', + 'name' => 'mother - grand father', + 'mother_id' => '0', + 'father_id' => '0' + ), + 'children' => array() + ), + array( + 'Person' => array( + 'id' => '6', + 'name' => 'father - grand mother', + 'mother_id' => '0', + 'father_id' => '0' + ), + 'children' => array( + array( + 'Person' => array( + 'id' => '3', + 'name' => 'father', + 'mother_id' => '6', + 'father_id' => '7' + ), + 'children' => array() + ) + ) + ), + array( + 'Person' => array( + 'id' => '7', + 'name' => 'father - grand father', + 'mother_id' => '0', + 'father_id' => '0' + ), + 'children' => array() + ) + ); + $this->assertEquals($expected, $result); + } + /** * testFindAllThreaded method *