Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/NestedSetsBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@ protected function beforeInsertRootNode()
{
if ($this->treeAttribute === false && $this->owner->find()->roots()->exists()) {
throw new Exception('Can not create more than one root when "treeAttribute" is false.');
} elseif ($this->treeAttribute && $this->owner->getAttribute($this->treeAttribute) && $this->owner->find()->roots($this->owner->getAttribute($this->treeAttribute))->exists()) {
throw new Exception("Can not create more than one root with {$this->treeAttribute} ".$this->owner->getAttribute($this->treeAttribute));
}

$this->owner->setAttribute($this->leftAttribute, 1);
Expand Down Expand Up @@ -399,7 +401,7 @@ protected function beforeInsertNode($value, $depth)
*/
public function afterInsert()
{
if ($this->operation === self::OPERATION_MAKE_ROOT && $this->treeAttribute !== false) {
if ($this->operation === self::OPERATION_MAKE_ROOT && $this->treeAttribute !== false && !$this->owner->getAttribute($this->treeAttribute)) {
$this->owner->setAttribute($this->treeAttribute, $this->owner->getPrimaryKey());
$primaryKey = $this->owner->primaryKey();

Expand Down
7 changes: 6 additions & 1 deletion src/NestedSetsQueryBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,21 @@ class NestedSetsQueryBehavior extends Behavior
{
/**
* Gets the root nodes.
* @param mixed $id the optional tree id. Default is `null` to query for all root nodes.
* @return \yii\db\ActiveQuery the owner
*/
public function roots()
public function roots($id = null)
{
$model = new $this->owner->modelClass();

$this->owner
->andWhere([$model->leftAttribute => 1])
->addOrderBy([$model->primaryKey()[0] => SORT_ASC]);

if ($id!==null && $model->treeAttribute!==false) {
$this->owner->andWhere([$model->treeAttribute => $id]);
}

return $this->owner;
}

Expand Down
23 changes: 23 additions & 0 deletions tests/NestedSetsBehaviorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,29 @@ public function testIsLeaf()
$this->assertFalse(Tree::findOne(1)->isLeaf());
}

public function testMakeTreeWithTreeAttribute()
{
$dataSet = $this->createFlatXMLDataSet(__DIR__ . '/data/clean.xml');
$this->getDatabaseTester()->setDataSet($dataSet);
$this->getDatabaseTester()->onSetUp();

$node = new MultipleTree(['name' => 'Root', 'tree' => 10]);
$this->assertTrue($node->makeRoot());

$dataSet = $this->getConnection()->createDataSet(['multiple_tree']);
$expectedDataSet = $this->createFlatXMLDataSet(__DIR__ . '/data/test-make-tree-with-tree-attribute.xml');
$this->assertDataSetsEqual($expectedDataSet, $dataSet);
}

/**
* @expectedException \yii\db\Exception
*/
public function testMakeRootNewExceptionIsRaisedWhenMultiTreeIsCreatedWithExistingTreeAttribute()
{
$node = new MultipleTree(['name' => 'Root 4', 'tree' => 1]);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@creocoder Before merging, maybe you can explain why at this point there is no tree with tree Id 10 here. It is created in the previous test and the DB is not cleared as far as I can see. I'm still quite confused about the state of the DB for each test. I only came up with this solution by trial and error.

$node->makeRoot();
}

/**
* @inheritdoc
*/
Expand Down
4 changes: 4 additions & 0 deletions tests/data/test-make-tree-with-tree-attribute.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<multiple_tree id="1" tree="10" lft="1" rgt="2" depth="0" name="Root"/>
</dataset>