Skip to content

Commit

Permalink
added moveDown method & test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
quickapps authored and lorenzo committed Mar 29, 2014
1 parent bc65eff commit a22e295
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 3 deletions.
64 changes: 61 additions & 3 deletions src/Model/Behavior/TreeBehavior.php
Expand Up @@ -185,9 +185,8 @@ public function moveUp($id, $number = 1) {

$previousNode = $this->_scope($this->_table->find())
->select([$primaryKey, $left, $right])
->where([$right => ($node->{$left} - 1)]);

$previousNode = $previousNode->first();
->where([$right => ($node->{$left} - 1)])
->first();

if (!$previousNode) {
return false;
Expand All @@ -209,6 +208,65 @@ public function moveUp($id, $number = 1) {
return true;
}

/**
* Reorder the node without changing the parent.
*
* If the node is the last child, or is a top level node with no subsequent node this method will return false
*
* @param integer|string $id The ID of the record to move
* @param integer|boolean $number how many places to move the node or true to move to last position
* @return boolean true on success, false on failure
*/
public function moveDown($id, $number = 1) {
$primaryKey = $this->_table->primaryKey();
$config = $this->config();
extract($config);

if (!$number) {
return false;
}

$node = $this->_scope($this->_table->find())
->select([$primaryKey, $parent, $left, $right])
->where([$primaryKey => $id])
->first();

if ($node->{$parent}) {
$parentNode = $this->_scope($this->_table->find())
->select([$primaryKey, $left, $right])
->where([$primaryKey => $node->{$parent}])
->first();

if (($node->{$right} + 1) == $parentNode->{$right}) {
return false;
}
}

$nextNode = $this->_scope($this->_table->find())
->select([$primaryKey, $left, $right])
->where([$left => $node->{$right} + 1])
->first();

if (!$nextNode) {
return false;
}

$edge = $this->_getMax();
$this->_sync($edge - $node->{$left} + 1, '+', "BETWEEN {$node->{$left}} AND {$node->{$right}}");
$this->_sync($nextNode->{$left} - $node->{$left}, '-', "BETWEEN {$nextNode->{$left}} AND {$nextNode->{$right}}");
$this->_sync($edge - $node->{$left} - ($nextNode->{$right} - $nextNode->{$left}), '-', "> {$edge}");

if (is_int($number)) {
$number--;
}

if ($number) {
$this->moveDown($id, $number);
}

return true;
}

/**
* Get the maximum index value in the table.
*
Expand Down
43 changes: 43 additions & 0 deletions tests/TestCase/Model/Behavior/TreeBehaviorTest.php
Expand Up @@ -200,4 +200,47 @@ public function testMoveUp() {
}
$this->assertEquals([8, 1, 6], $nodeIds);
}

/**
* Tests the moveDown() method
*
* @return void
*/
public function testMoveDown() {
$table = TableRegistry::get('MenuLinkTrees');
$table->addBehavior('Tree', ['scope' => ['menu' => 'main-menu']]);

// latest node, wont move
$this->assertEquals(false, $this->table->moveDown(8, 10));

// edge cases
$this->assertEquals(false, $this->table->moveDown(8, 0));
$this->assertEquals(false, $this->table->moveUp(8, -10));

// move inner node
$nodeIds = [];
$result = $table->moveDown(2, 1);
$nodes = $table->find('children', ['for' => 1])->all();
foreach ($nodes as $node) {
$nodeIds[] = $node->id;
}
$this->assertEquals([3, 4, 5, 2], $nodeIds);
$this->assertEquals(true, $result);

// move leaf
$this->assertEquals(false, $table->moveDown(5, 1));

// move to last position
$table->moveDown(1, true);
$nodeIds = [];
$results = $table->find()
->select(['id'])
->where(['parent_id' => 0, 'menu' => 'main-menu'])
->order(['lft' => 'ASC'])
->all();
foreach ($results as $node) {
$nodeIds[] = $node->id;
}
$this->assertEquals([6, 8, 1], $nodeIds);
}
}

0 comments on commit a22e295

Please sign in to comment.