Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 53: Allow to use treeAttribute as external key #68

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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>