Nestedset扩展升级重建树功能

http://www.yiiframework.com/extension/tree-extension/

这个tree扩展比较全,但我用的是老早的nestedset,升级比较痛苦,就添加了qq71151461的两个方法过来。在这里感谢qq71151461 :rolleyes:

这两个方法是实现重建树的功能。如果你原库是用parentId来做树的,想要左右值来做树,则可以用这两个方法建树。

TreeBehavior这个类添加


public $_parentIdCol = "parentId";


	public function rebuildTree($parentId=0, $left=0) {

		$right = $left+1;

		$rows=$this->Owner->getDbConnection()->createCommand("SELECT `{$this->_idCol}` FROM `{$this->Owner->tableName()}` WHERE `{$this->_parentIdCol}`={$parentId}")->queryColumn();

		foreach ($rows as $id) {

			$right = $this->rebuildTree($id, $right);

		}

		$this->Owner->getDbConnection()->createCommand("UPDATE `{$this->Owner->tableName()}` SET `{$this->_lftCol}`={$left},`{$this->_rgtCol}`={$right} WHERE `{$this->_idCol}`=$parentId")->execute();

		return $right + 1;

	}

	public function rebuildTreeLevel() {

		$rows=$this->Owner->getDbConnection()->createCommand("SELECT `{$this->_idCol}`,`{$this->_lftCol}`,`{$this->_rgtCol}` FROM `{$this->Owner->tableName()}` ORDER BY `{$this->_lftCol}`")->queryAll();

		foreach ($rows as $row) {

			$level=$this->Owner->getDbConnection()->createCommand("SELECT COUNT(*) FROM `{$this->Owner->tableName()}` WHERE `{$this->_lftCol}`<={$row[$this->_lftCol]} AND `{$this->_rgtCol}`>{$row[$this->_rgtCol]}")->queryScalar();

			$this->Owner->getDbConnection()->createCommand("UPDATE `{$this->Owner->tableName()}` SET `{$this->_lvlCol}`={$level} WHERE `{$this->_idCol}`={$row[$this->_idCol]}")->execute();

		}

	}

调用:

	Model::model()-&gt;rebuildTree();


	Model::model()-&gt;rebuildTreeLevel();

不错~

可惜 nestedset作者都不更新扩展 ;(

两个方法,注意先后

再增加一个 根据leve,lft,rgt更新 parentId的方法。


	public function rebuildTreeParent($parentId=1,$level=1, $left=0, $right) {

		$rows=$this->Owner->getDbConnection()->createCommand("SELECT `{$this->_idCol}`,`{$this->_lftCol}`,`{$this->_rgtCol}` FROM `{$this->Owner->tableName()}` WHERE `{$this->_lvlCol}`={$level} and `{$this->_lftCol}`>{$left} and `{$this->_rgtCol}`<{$right}")->queryAll();

		$this->Owner->getDbConnection()->createCommand("UPDATE `{$this->Owner->tableName()}` SET `{$this->_parentIdCol}`={$parentId} WHERE  `{$this->_lvlCol}`={$level} and `{$this->_lftCol}`>{$left} and `{$this->_rgtCol}`<{$right}")->execute();

		foreach ($rows as $row) {

			$this->rebuildTreeParent($row[$this->_idCol],$level+1, $row[$this->_lftCol], $row[$this->_rgtCol]);

		}

	}

修复一个我认为的bug,说明:原版当 提取 level大于0的节点的数据的时候 $nestedTree = $root->getNestedTree();返回的本节点应该出现在node里面,但在原版出现在children,有点不合逻辑。

修改

public function getNestedTree($returnrootnode = true, $keyfield = null)

里面

$depth = $this->getLevelValue(); 原来是 $depth = 0;

我需要tree的帮助.

用了qq71151461的,添加子节点的时候提示lft等几个不能为空.

rules 中要去掉 left_value right_value parnet_value level的required rule

重建功能不错的 试图做过从邻接表到嵌套集模型的相互切换 但最后还是有些问题 未能实现 这里说出这种可能 谁有兴趣可以试着实现下 ::)

留个足印 以后在回来 :lol:

不知道如何回复的好