[EXTENSION] Nested Set implementation using ActiveRecord
#21
Posted 03 January 2010 - 01:42 PM
I've just added a new release which fixes most bugs that were posted here and in the reviews section. Please see the changelog for more information.
I'm currently in the final 3 weeks of my study and very busy with moving and my 'new' job, so please be patient. I will add the new proposed features (like scopes) as soon as I have more time. Sadly, I don't have time to dive into Yii 1.1 at the moment, so if some could help me making it compatible it would be greatly appreciated.
#23
Posted 05 January 2010 - 06:26 PM
Remko Nolten, on 03 January 2010 - 01:42 PM, said:
It works nice with Yii 1.1rc, you just have to add ->Owner or ->getOwner() to $this->getIsNewRecord(), $sibling->getIsNewRecord(), $node->getIsNewRecord() and $node->save().
I think it's also good to change $node->save() to $node->Owner->save(false) or if(!$node->Owner->save()) throw new TreeException(print_r($node->Owner->getErrors(), true)).
And... thank you for your work
#24
Posted 08 January 2010 - 06:56 AM
Thank you, excellent extension!
It may need to add methods: getParents, getLeaves and etc. ?
/**
* Returns the parents of this node
* @param boolean $root
* @return array
*/
public function getParents($root = true) {
$builder = $this->Owner->getCommandBuilder();
$cstring = $this->_lftCol." < ? AND ".$this->_rgtCol." > ?";
if ( ! $root)
$cstring .= " AND ".$this->_lftCol ." !=1";
$cstring .= " ORDER BY ".$this->_lftCol. " ASC";
$criteria = $builder->createCriteria($cstring,array($this->getLeftValue(), $this->getRightValue()));
$command = $builder->createFindCommand($this->Owner->getTableSchema(),$criteria);
return $this->Owner->populateRecords($command->queryAll());
}
/**
* Returns a list of leaf nodes.
* @return array
*/
public function getLeaves() {
$builder = $this->Owner->getCommandBuilder();
$cstring = $this->_lftCol . " = (".$this->_rgtCol." - 1) AND "
.$this->_lftCol." >= ? AND "
.$this->_rgtCol." <= ? ORDER BY ".$this->_lftCol. " ASC";
$criteria = $builder->createCriteria($cstring,array($this->getLeftValue(),$this->getRightValue()));
$command = $builder->createFindCommand($this->Owner->getTableSchema(),$criteria);
return $this->Owner->populateRecords($command->queryAll());
}
/**
* Is the current node a root node?
* @return boolean
*/
public function isRoot() {
return ($this->getLeftValue() === 1);
}
/**
* Is the current node a leaf node
* @return boolean
*/
public function isLeaf() {
return !$this->hasChildNodes();
}
/**
* Is the current node a direct child of the supplied node
* @param object node object
* @return boolean
*/
public function isChild($target) {
return ($this->getParentNode()->getIdValue() === $target->getIdValue());
}
/**
* Is the current node the direct parent of the supplied node
*
* @param object node object
* @return boolean
**/
public function isParent($target) {
return ($this->getIdValue() === $target->getParentNode()->getIdValue());
}
/**
* Is the current node a sibling of the supplied node
*
* @param object node object
* @return boolean
**/
public function isSibling($target) {
return ($this->getParentNode()->getIdValue() === $target->getParentNode()->getIdValue());
}
/**
* Get Size
*
* Returns the current size of the node.
*
* @return int
**/
protected function getSize() {
return ($this->getRightValue() - $this->getLeftValue()) + 1;
}
This post has been edited by pirrat: 08 January 2010 - 07:48 AM
#25
Posted 08 January 2010 - 07:56 AM
lft = 1
rgt = 2
And in your example:
lft = 0
rgt = 1
Quote
(1, 0, 1, 0, 'Root');
I could be wrong...
#26
Posted 20 March 2010 - 07:04 PM
#27
Posted 20 March 2010 - 08:11 PM
There is another nested set extension with some more functionality. It was used in a real project but is not documented yet:
http://code.google.c...ors/model/trees
#28
Posted 14 May 2010 - 07:52 AM
Quote
Description
There is already an active transaction
I opened the TreeBehavior.phpAnd function was
public function appendChild($node, $brother = null)
{
// Fetch nodes information
$parent = $this;
$transaction= $this->Owner->dbConnection->beginTransaction();
if($this->Owner->getIsNewRecord())
throw new TreeException('You can\'t append a node to a parent that is not yet in the database. Add the parent node to the tree first using AppendChild or using an Insert* method.');
if(!$node->getIsNewRecord())
{
return $node->moveBelow($this);
}
try
{.....Transaction begin before moveBelow so i move it after if
public function appendChild($node, $brother = null)
{
// Fetch nodes information
$parent = $this;
if($this->Owner->getIsNewRecord())
throw new TreeException('You can\'t append a node to a parent that is not yet in the database. Add the parent node to the tree first using AppendChild or using an Insert* method.');
if(!$node->getIsNewRecord())
{
return $node->moveBelow($this);
}
$transaction= $this->Owner->dbConnection->beginTransaction();
try
{.....
And worked.
This post has been edited by tydeas_dr: 14 May 2010 - 08:12 AM
#29
Posted 16 May 2010 - 09:09 AM
$newnode->insertAfter($reference_node);
The insertAfter($node) method tries to
return $node->getParentNode()->appendChild($this);and returns false.
But if in my TreeController do
$parent=$reference_node->getParentNode(); $parent->appendChild($newnode);
Everything will work proper and the return of appendChild will be true.
#30
Posted 16 May 2010 - 09:56 AM
else
{
$minleft = $parent->getRightValue();
$minright = $parent->getRightValue();
$cond = ">= ".$parent->getRightValue();
fb("cnod: ".$cond);
$lv = $parent->getRightValue();
}
$rv = $lv + 1;
$sql = "UPDATE %3\$s SET %1\$s = %1\$s + 2 WHERE %1\$s %2\$s";
$command = $this->Owner->dbConnection->createCommand(sprintf($sql,$this->_lftCol,$cond, $this->Owner->tableName()));
$command->execute();
$command = $this->Owner->dbConnection->createCommand(sprintf($sql,$this->_rgtCol,$cond, $this->Owner->tableName()));
$command->execute();This is where the issue i am describing above happens. Is it correct to all the variables take value from $getRightValue();
This post has been edited by tydeas_dr: 16 May 2010 - 09:56 AM
#31
Posted 16 May 2010 - 11:43 AM
2010/05/16 22:43:03 [error] [application.extensions.nestedset.treebehavior] Error appending node, transaction aborted. Exception: Class TreeBehavior does not have method with name "save".
in /home/dmtrsslvdr/public_html/wwwTrans/protected/extensions/nestedset/TreeBehavior.php (435)
in /home/dmtrsslvdr/public_html/wwwTrans/protected/extensions/nestedset/TreeBehavior.php (553)
in /home/dmtrsslvdr/public_html/wwwTrans/protected/controllers/TreeController.php (359)
#32
Posted 07 September 2010 - 10:56 AM
with yii v1.1.4, running the given exemple provided in the archive file, I've got an error:
Undefined index: children
line 241 (in my category controller):
00238: $result = "<strong>".$tree['node']->name."</strong (".$tree['node']->getLeftValue().",".$tree['node']->getRightValue().")";
00239:
00240: $result .= "<ul>";
00241: foreach($tree['children'] as $key => $child)
00242: {
This look strange. This extension worked fine for me with the previous release of yii.
Luc
Let's go !

Help














