Skip to content

Commit

Permalink
Started to implement moving a subtree as a root
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Mar 29, 2014
1 parent 7ec8cd8 commit 5f7d8c2
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
19 changes: 18 additions & 1 deletion src/Model/Behavior/TreeBehavior.php
Expand Up @@ -91,13 +91,17 @@ public function beforeSave(Event $event, Entity $entity) {

if ($isNew && !$parent) {
$edge = $this->_getMax();
$entity->set($config['left'],$edge + 1);
$entity->set($config['left'], $edge + 1);
$entity->set($config['right'], $edge + 2);
}

if (!$isNew && $dirty && $parent) {
$this->_setParent($entity, $parent);
}

if (!$isNew && $dirty && !$parent) {
$this->_setAsRoot($entity);
}
}

protected function _getParent($id) {
Expand Down Expand Up @@ -161,6 +165,19 @@ protected function _setParent($entity, $parent) {
$entity->set($config['right'], $targetRight);
}

protected function _setAsRoot($entity) {
$config = $this->config();
$edge = $this->_getMax();
$right = $entity->get($config['right']);
$left = $entity->get($config['left']);
$internalLeft = $left + 1;
$internalRight = $right - 1;

$entity->set($config['left'], $edge + 1);
$entity->set($config['right'], $edge + $right - 1);
$this->_sync($edge - 1, '+', "BETWEEN {$internalLeft} AND {$internalRight}");
}

public function findPath($query, $options) {
if (empty($options['for'])) {
throw new \InvalidArgumentException("The 'for' key is required for find('path')");
Expand Down
20 changes: 20 additions & 0 deletions tests/TestCase/Model/Behavior/TreeBehaviorTest.php
Expand Up @@ -460,4 +460,24 @@ public function testReParentLeafRight() {
$this->assertEquals(range(1, 22), $numbers);
}

/**
* Tests moving as a new root
*
* @return void
*/
public function testRootingSubTree() {
$table = TableRegistry::get('NumberTrees');
$table->addBehavior('Tree');
$entity = $table->get(2);
$entity->parent_id = null;
$this->assertSame($entity, $table->save($entity));
$this->assertEquals(23, $entity->lft);
$this->assertEquals(30, $entity->rght);

$result = $table->find()->order('lft')->hydrate(false)->toArray();
$table->recover();
$expected = $table->find()->order('lft')->hydrate(false)->toArray();
$this->assertEquals($expected, $result);
}

}

0 comments on commit 5f7d8c2

Please sign in to comment.