Skip to content

Commit 9efddaa

Browse files
committed
Implemented TreeBehavior::recover()
1 parent c8d686f commit 9efddaa

File tree

4 files changed

+80
-5
lines changed

4 files changed

+80
-5
lines changed

src/Model/Behavior/TreeBehavior.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,40 @@ public function moveDown($id, $number = 1) {
269269
return true;
270270
}
271271

272+
public function recover() {
273+
$this->_table->connection()->transactional(function() {
274+
$this->_recoverTree();
275+
});
276+
}
277+
278+
protected function _recoverTree($counter = 0, $parentId = null) {
279+
$config = $this->config();
280+
list($parent, $left, $right) = [$config['parent'], $config['left'], $config['right']];
281+
$pk = (array)$this->_table->primaryKey();
282+
283+
$query = $this->_scope($this->_table->query())
284+
->select($pk)
285+
->where(function($exp) use ($parentId, $parent) {
286+
return $parentId === null ? $exp->isNull($parent) : $exp->eq($parent, $parentId);
287+
})
288+
->order($pk)
289+
->hydrate(false)
290+
->bufferResults(false);
291+
292+
$leftCounter = $counter;
293+
foreach ($query as $row) {
294+
$counter++;
295+
$counter = $this->_recoverTree($counter, $row[$pk[0]]);
296+
}
297+
298+
$this->_table->updateAll(
299+
[$left => $leftCounter, $right => $counter + 1],
300+
[$pk[0] => $parentId]
301+
);
302+
303+
return $counter + 1;
304+
}
305+
272306
/**
273307
* Get the maximum index value in the table.
274308
*

tests/Fixture/MenuLinkTreeFixture.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ class MenuLinkTreeFixture extends TestFixture {
3636
public $fields = array(
3737
'id' => ['type' => 'integer'],
3838
'menu' => ['type' => 'string', 'null' => false],
39-
'lft' => ['type' => 'integer', 'null' => false],
40-
'rght' => ['type' => 'integer', 'null' => false],
39+
'lft' => ['type' => 'integer'],
40+
'rght' => ['type' => 'integer'],
4141
'parent_id' => 'integer',
4242
'url' => ['type' => 'string', 'null' => false],
4343
'title' => ['type' => 'string', 'null' => false],

tests/Fixture/NumberTreeFixture.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ class NumberTreeFixture extends TestFixture {
3737
'id' => ['type' => 'integer'],
3838
'name' => ['type' => 'string', 'null' => false],
3939
'parent_id' => 'integer',
40-
'lft' => ['type' => 'integer', 'null' => false],
41-
'rght' => ['type' => 'integer', 'null' => false],
40+
'lft' => ['type' => 'integer'],
41+
'rght' => ['type' => 'integer'],
4242
'_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]]
4343
);
4444

@@ -55,6 +55,7 @@ class NumberTreeFixture extends TestFixture {
5555
* - flash:8
5656
* - cd:9
5757
* - radios:10
58+
* - alien ware: 11
5859
*
5960
* @var array
6061
*/
@@ -134,7 +135,7 @@ class NumberTreeFixture extends TestFixture {
134135
'name' => 'alien hardware',
135136
'parent_id' => null,
136137
'lft' => '21',
137-
'rght' => '21'
138+
'rght' => '22'
138139
)
139140
);
140141

tests/TestCase/Model/Behavior/TreeBehaviorTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,4 +251,44 @@ public function testMoveDownException() {
251251
$table->addBehavior('Tree', ['scope' => ['menu' => 'main-menu']]);
252252
$table->moveDown(500, 1);
253253
}
254+
255+
/**
256+
* Tests the recover function
257+
*
258+
* @return void
259+
*/
260+
public function testRecover() {
261+
$table = TableRegistry::get('NumberTrees');
262+
$table->addBehavior('Tree');
263+
$expected = $table->find()->order('lft')->hydrate(false)->toArray();
264+
$table->updateAll(['lft' => null, 'rght' => null], []);
265+
$table->recover();
266+
$result = $table->find()->order('lft')->hydrate(false)->toArray();
267+
$this->assertEquals($expected, $result);
268+
}
269+
270+
/**
271+
* Tests the recover function with a custom scope
272+
*
273+
* @return void
274+
*/
275+
public function testRecoverScoped() {
276+
$table = TableRegistry::get('MenuLinkTrees');
277+
$table->addBehavior('Tree', ['scope' => ['menu' => 'main-menu']]);
278+
$expected = $table->find()
279+
->where(['menu' => 'main-menu'])
280+
->order('lft')
281+
->hydrate(false)
282+
->toArray();
283+
284+
$table->updateAll(['lft' => null, 'rght' => null], ['menu' => 'main-menu']);
285+
$table->recover();
286+
$result = $table->find()
287+
->where(['menu' => 'main-menu'])
288+
->order('lft')
289+
->hydrate(false)
290+
->toArray();
291+
$this->assertEquals($expected, $result);
292+
}
293+
254294
}

0 commit comments

Comments
 (0)