Browse Source

Strating to implement removeFromTree

Jose Lorenzo Rodriguez 12 years ago
parent
commit
3c52dbc4fa

+ 21 - 1
src/Model/Behavior/TreeBehavior.php

@@ -44,7 +44,8 @@ class TreeBehavior extends Behavior {
 			'childCount' => 'childCount',
 			'moveUp' => 'moveUp',
 			'moveDown' => 'moveDown',
-			'recover' => 'recover'
+			'recover' => 'recover',
+			'removeFromTree' => 'removeFromTree'
 		],
 		'parent' => 'parent_id',
 		'left' => 'lft',
@@ -328,6 +329,25 @@ class TreeBehavior extends Behavior {
 			]);
 	}
 
+	public function removeFromTree($node) {
+		$config = $this->config();
+		$left = $node->get($config['left']);
+		$right = $node->get($config['right']);
+		$parent = $node->get($config['parent']);
+
+		if ($right - $left > 1) {
+			$this->_table->updateAll(
+				[$config['parent'] => $parent],
+				[$config['parent'] => $id]
+			);
+			$this->_sync(1, '-', 'BETWEEN ' . ($left + 1) . ' AND ' . ($right - 1));
+			$this->_sync(2, '-', "> {$right}");
+		}
+
+		$node->set($config['parent'], null);
+		return $this->_table->save($node);
+	}
+
 /**
  * Reorders the node without changing its parent.
  *

+ 25 - 0
tests/TestCase/Model/Behavior/TreeBehaviorTest.php

@@ -556,4 +556,29 @@ class TreeBehaviorTest extends TestCase {
 		$this->assertEquals($expected, $result);
 	}
 
+/**
+ * Tests that a leaf can be taken out of the tree and put in as a root
+ *
+ * @return void
+ */
+	public function testRemoveFromLeafFromTree() {
+		$table = TableRegistry::get('NumberTrees');
+		$table->addBehavior('Tree');
+		$entity = $table->get(10);
+		$this->assertSame($entity, $table->removeFromTree($entity));
+		$this->assertEquals(21, $entity->lft);
+		$this->assertEquals(22, $entity->rght);
+		$this->assertEquals(null, $entity->parent_id);
+		$result = $table->find()->order('lft')->hydrate(false);
+		$expected = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 10];
+		$this->assertEquals($expected, $result->extract('id')->toArray());
+		$numbers = [];
+		$result->each(function($v) use (&$numbers) {
+			$numbers[] = $v['lft'];
+			$numbers[] = $v['rght'];
+		});
+		sort($numbers);
+		$this->assertEquals(range(1, 22), $numbers);
+	}
+
 }