Browse Source

allow other parent field, set in find options or TreeHebavior, for threaded find. Fixes #1769

Ceeram 14 years ago
parent
commit
2a9e6771c3

+ 14 - 0
lib/Cake/Model/Behavior/TreeBehavior.php

@@ -93,6 +93,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
  *
  * Will delete the current node and all children using the deleteAll method and sync the table

+ 5 - 1
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
 			));
 		}
 	}

+ 84 - 1
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);
+	}
 }

+ 100 - 0
lib/Cake/Test/Case/Model/ModelReadTest.php

@@ -2991,6 +2991,106 @@ class ModelReadTest extends BaseModelTest {
 	}
 
 /**
+ * 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
  *
  * @return void