creocoder / yii2-nested-sets Goto Github PK
View Code? Open in Web Editor NEWThe nested sets behavior for the Yii framework.
License: Other
The nested sets behavior for the Yii framework.
License: Other
I`m porting my yii1.1 stuff to yii2.
Any plans on this functions?
Hello!
It would be nice to have an ability to move roots among siblings.
Try the following sample data:
-- Root1
-- -- Branch1
-- -- -- Leaf1
-- Root2
Now move Root2 to Leaf1 then move it back to root once again.
This time, using Tree::find()->roots()->all() will only list Root1 as the root node.
Also the descendants() and ancestors() not working any more.
Any suggestion on fixing this?
I'm just wondering why a separate Query behavior is needed when you could simply add those functions to the main AR behavior and just use that without having to extend ActiveQuery and add a second behavior?
e.g move roots function to NestedSetsBehavior (would be similar for leaves() function too) ...
/**
* Gets root node(s).
* @return ActiveQuery.
*/
public function roots()
{
$query = $this->owner->find();
$query->andWhere([$this->leftAttribute => 1])
->addOrderBy([$this->owner->primaryKey()[0] => SORT_ASC]);
return $query;
}
Am I wrong in thinking this?
Calling unknown method: yii\db\ActiveQuery::roots()
Getting unknown property: yii\db\ActiveQuery::title
Calling unknown method: yii\db\ActiveQuery::parent()
How to make sibling between a root models?
$model = new Category();
$model->name = 'new category';
$after = $this->findModel(1);
$model->insertAfter($after);
it will throw
throw new Exception('Can not create a node when the target node is root.');
Implementing this is very easy, although using it at a practical level I'm finding difficult.
How would I create a custom nested plain array such as the following:
[
{
'id' => 123,
'name' => 'Example',
'value' => 'Testing',
'children' => [
{
'id' => 123,
'name' => 'Example',
'value' => 'Testing',
'children' => [],
},
{
'id' => 123,
'name' => 'Example',
'value' => 'Testing',
'children' => [],
},
]
},
{
'id' => 123,
'name' => 'Example',
'value' => 'Testing',
'children' => [
{
'id' => 123,
'name' => 'Example',
'value' => 'Testing',
'children' => [
{
'id' => 123,
'name' => 'Example',
'value' => 'Testing',
'children' => [],
}
},
]
},
];
How to render a tree with all elements?
В мультируте есть такой код
$this->owner->setAttribute($this->treeAttribute, $this->owner->getPrimaryKey());
Который автоматически меняет значение treeAttribute, что делает невозможным использование поля treeAttribute в связи по foreign key с другой таблицей.
Может быть есть возможность разрешить использовать своё значение treeAttribute при создании root?
Are you going to update this? It doens't work at all
Доброго времени!
Скажите, при выборке родительских или дочерних нод как нибудь можно использовать where() ?
Дело в том, что бывает нужно указывать некоторые условия.
Например в случае хлебных крошек для вложенных страниц приходится делать так:
// treeAttribute = false
$breadcrumbs = [];
if($this->parent_id > 0) {// parent_id хранится просто для удобства
$parents = $this->parents()->all();
unset($parents[0]);
foreach($parents as $parent) {
$breadcrumbs[] = [
'label' => $parent->title,
'url' => ['/page/page/view', 'slug' => $parent->slug]
];
}
}
$breadcrumbs[] = $this->title;
return $breadcrumbs;
Спасибо.
в новом yii2 в AR нет createQuery
никак не докопаюсь.
http://www.yiiframework.ru/forum/viewtopic.php?f=19&t=17975
Please, add examples for getting the whole tree.
Did the multiroot functionality go away with the latest update? The hasManyRoots attribute is no longer supported.
I got this error with 0.9.0
Method "dmstr\modules\pages\models\Tree::delete" is not supported for deleting root node.
Stack trace:
#0 [internal function]: creocoder\nestedsets\NestedSetsBehavior->beforeDelete(Object(yii\base\ModelEvent))
#1 /app/vendor/yiisoft/yii2/base/Component.php(538): call_user_func(Array, Object(yii\base\ModelEvent))
....
Is there a special reason why this is denied?
Hey mate, I see you're going a nice way allowing people to modify specific column names. How about allowing to modify and configure the id
attribute? For example, I would love to change it to id_xxxxxx
to match the rest of the schema.
Cheers,
P.
Приветствую. Есть ли какая информация как изменить родителя ветви?
Если использовать $category->appendTo($root) то спонтанно валится структура (иногда да иногда нет), и ветвь исчезает. В базе есть но уровень не тот.
Как правильно добавить новую ветвь к указанному родителю и как изменить существующую с переносом на другого родителя?
Since composer change default stability option this no longer works:
php composer.phar require creocoder/yii2-nested-set-behavior "*"
or add
"creocoder/yii2-nested-set-behavior": "*"
php composer.phar require creocoder/yii2-nested-set-behavior "@dev"
or add
"creocoder/yii2-nested-set-behavior": "@dev"
Hello,
I need to temporarliy disable the behaviour.
In yii1 I used this on the model where the behaviour is attached to:
$model->detachBehavior('nestedSetBehavior');
But this is not working in the updated version. Or is this a yii2 issue?
Thanks for any hints... (again)
gb5256
I have menu with attribute - parent_id, how i can convert it to nested tree
Can you show example
For more convenience it would be nice, if the tree related methods would also accept an id
(or a Pk value to me more precise) instead of a loaded record. The behavior would then automatically load that record.
Owner added to $_cached first time after attaching behavior (ensureBevaviors calls $behavior->attach) and second time by processing aterFind event. Is it correct? There is another issue #19 - may be it's caused by second cache correction?
When trying to get all roots by
$roots = Category::find()->roots()->all();
I get this exception. How to fix it or get all roots in any other way.
Use [[
and ]]
for it.
I use the following code to generate a categories tree out of a nested array. The code is updated to work with the latest version of nesteset. However when it runs all the lft/rgt columns appear to be wrong. With the prev. version (before the major update - renaming of classes, etc) this was not the case.
Is this a known bug?
(example code)
/**
* @param $tree
* @param null $parentNode
* @throws Exception
* @throws \yii\base\ErrorException
*/
protected function createTree($tree, $parentNode = null)
{
foreach($tree as $node) {
$c = new Category();
$c->name = $node['name'];
if ($parentNode)
$success = $c->appendTo($parentNode);
else
$success = $c->makeRoot();
if (!$success)
throw new Exception("Could not save node!\n".VarDumper::dumpAsString($c->errors));
if (isset($node['items'])) {
$this->createTree($node['items'], $c);
}
}
}
/**
* This is a console action used to initialise the menu for the first time.
* @throws Exception
*/
public function actionReset()
{
$categoriesTree = [
[
'name' => 'Categories Demo',
'url_key' => null,
'items' => [
[
'name' => 'Eat and Drink',
'items' => [
[
'name' => 'Cafe',
],
[
'name' => 'Bar',
],
[
'name' => 'Restaurant',
],
[
'name' => 'Fast Food',
],
],
],
[
'name' => 'Sport',
'items' => [
[
'name' => 'Sportbar',
],
[
'name' => 'Fitness',
],
[
'name' => 'Bowling',
],
],
],
[
'name' => 'Games',
'items' => [
[
'name' => 'Internet Cafe',
],
[
'name' => 'Video Game Centre',
],
],
],
],
],
];
Category::deleteAll();
$this->createTree($categoriesTree);
}
Была такая иерархия:
- Радио(id=3,lft=1, rgt=2, lvl=1, root=3)
- Авто (id=4,lft=1, rgt=2, lvl=1, root=4)
Хочу такую:
- Авто (id=4,lft=1, rgt=4, lvl=1, root=4)
- - Радио(id=3,lft=2, rgt=3, lvl=2, root=4)
Но получаю вообще:
- Авто (id=4,lft=1, rgt=6, lvl=1, root=4)
- - Радио(id=3,lft=4, rgt=5, lvl=2, root=4)
После обновления страницы всё норм становится. Перемещаю методом $model->moveAsLast($parent).
Кусок кода из контроллера
$save = $model->load(Yii::$app->request->post()) && $model->saveNode() !== false;
if ( ($parent = Yii::$app->request->post('Category', ['parent'=>false])['parent']) || $parent!==false ) {
$transaction = Yii::$app->getDb()->beginTransaction();
if ($save && $parent > 0) {
$parent = $this->findModel($parent);
$save = $model->moveAsLast($parent); //Здесь эта странность
} elseif (!$model->isRoot()) {
$save = $model->isNewRecord ? $model->makeRoot() : $model->moveAsRoot();
}
if ($save)
$transaction->commit();
else
$transaction->rollBack();
}
Hi, it will be good to add method to build "tree" array with output something like this:
<? $data = [
['title' => 'Node 1'],
['title' => 'Node 2', 'children' => [
['title' => 'Node 2.1'],
['title' => 'Node 2.2']
]]
];
Does anybody have ready to use snippet? Thanks
@creocoder can you update it?
In Yii 1.x nested sets behavior there was methods for moving nodes inside tree, ex. moveAsLast(), moveAsFirst(). How to implement these methods in your Yii 2.x behavior?
https://github.com/creocoder/yii2-nested-set-behavior#adding-child-nodes
Original:
$root = Category::find(1); //returns ActiveQuery object, resulting into errors
Suggestion:
$root = Category::findOne(1); //returns Active record, which can be used by NestedSet.php
Hi. Thank you for the extension. Just want to say you have an error in the documentation. When configuring behavior with parameters we should use array and place it in array of behaviors. So instead of
public function behaviors() {
return [
'class' => NestedSetsBehavior::className(),
// 'treeAttribute' => 'tree',
// 'leftAttribute' => 'lft',
// 'rightAttribute' => 'rgt',
// 'depthAttribute' => 'depth',
];
}
there should be this
public function behaviors() {
return [
[
'class' => NestedSetsBehavior::className(),
// 'treeAttribute' => 'tree',
// 'leftAttribute' => 'lft',
// 'rightAttribute' => 'rgt',
// 'depthAttribute' => 'depth',
]
];
}
If I have my hierarchy defined in database table and it has 6 levels, can I use this extension to work with them all ?
I made a question on stack overflow, and people advised me to use your extension, but I am unsured how to use it, since I have to pull parents/chiledes from database and work with them.
Could you add some tags to your projects? I will be very greatful. After the one of your latest commits I had to change my code, becouse there was no compatibilty.
P.S. thanks for yours project. It's great.
As traits are more efficient and you don't attach to any events in the NesteSetsQueryBehavior I think it could also be implemented as a trait.
$root = new NestedMenuTree();
$root->title = Sanitizer::getSanitizedUrlValue($model->title);
if($root->saveNode()){
VarDumper::dump($root->attributes,10,true);
}else{
VarDumper::dump($root->getErrors(),10,true);
};
Thats my try result:
[
'root' => [
0 => 'Root cannot be blank.'
]
'lft' => [
0 => 'Lft cannot be blank.'
]
'rgt' => [
0 => 'Rgt cannot be blank.'
]
'level' => [
0 => 'Level cannot be blank.'
]
]
? i missunderstand anything ? your behavior will create it or not ?
I am having an issue for installing this behavior through composer.
$ composer require creocoder/yii2-nested-set-behavior "*"
[UnexpectedValueException]
Could not parse version constraint LICENSE.md: Invalid version string "LICE
NSE.md"
$_cached values could be cleared only in destructor method, meanwhile behavior might already detached and owner property will be nulled, so get_class($this->owner) values will be wrong. Also, maybe, it is sensible to clear $_cached values with behavior detaching .
Здравствуйте. Было бы здорово, если бы вы добавили старый пример в доки:
$categories = Category::find()->addOrderBy('lft')->all();
$level = 0;
foreach ($categories as $n => $category)
{
if ($category->level == $level) {
echo Html::endTag('li') . "\n";
} elseif ($category->level > $level) {
echo Html::beginTag('ul') . "\n";
} else {
echo Html::endTag('li') . "\n";
for ($i = $level - $category->level; $i; $i--) {
echo Html::endTag('ul') . "\n";
echo Html::endTag('li') . "\n";
}
}
echo Html::beginTag('li');
echo Html::encode($category->title);
$level = $category->level;
}
for ($i = $level; $i; $i--) {
echo Html::endTag('li') . "\n";
echo Html::endTag('ul') . "\n";
}
Hello,
I have an app that I move into yii2. I am already using nested set (for yii1).
In your old version, tree was called root, and also my table is set up this way.
I do not want to change the table, as lots of other things need the column root.
I thought, that changing this would do the trick:
public function behaviors() {
return [
'class' => NestedSetsBehavior::className(),
'treeAttribute' => 'root', \\ this is 'tree' by your default
// 'leftAttribute' => 'lft',
// 'rightAttribute' => 'rgt',
'depthAttribute' => 'level',
];
}
But this throws an error: Class root does not exist
Do I have to change the attribute name some where else?
thanks again,
gb5256
Call to undefined method creocoder\behaviors\NestedSet::getClass()
Модель:
https://gist.github.com/AveVlad/9dc542a5873d8295a90c
Контроллер:
https://gist.github.com/AveVlad/2f694e9cf23e3191270a
Hello,
I am just switching to yii2 from yii1, so it might be that I have a general problem of understanding.
You write "Configure query class as follows". But I do not have a query class.
I am using the advanced yii2 template.
Can you give me a hint where that has to be put?
Thanks,
gb5256
moveAsLast and moveAsFirst methods working as expected but after initialization they incorrectly overwrite 'lft' and 'rgt' properties in the current model.
And when I update my model (saveNode()), correct property in the table overwrites whith this wrong data.
There is problem with method correctCachedOnMoveNode(), when I turn it of , methods start working properly.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.