@@ -11,7 +11,9 @@ __[Support this project](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hos
1111__ Contents:__
1212
1313- [ Theory] ( #what-are-nested-sets )
14- - [ Manipulating nodes] ( #manipulating-nodes )
14+ - [ Documentation] ( #documentation )
15+ - [ Inserting nodes] ( #inserting-nodes )
16+ - [ Retrieving nodes] ( #retrieving-nodes )
1517- [ Requirements] ( #requirements )
1618- [ Installation] ( #installation )
1719
@@ -33,8 +35,8 @@ NSM shows good performance when tree is updated rarely. It is tuned to be fast f
3335getting related nodes. It'is ideally suited for building multi-depth menu or
3436categories for shop.
3537
36- Manipulating nodes
37- ------------------
38+ Documentation
39+ -------------
3840
3941Suppose that we have a model ` Category ` ; a ` $node ` variable is an instance of that model
4042and the node that we are manipulating. It can be a fresh model or one from database.
@@ -59,8 +61,8 @@ Another important note is that __structural manipulations are deferred__ until y
5961hit ` save ` on model (some methods implicitly call ` save ` and return boolean result
6062of the operation).
6163
62- If model is successfully saved it doesn't mean that node has moved. To check whether
63- it has, use ` hasMoved ` function :
64+ If model is successfully saved it doesn't mean that node has moved. If your application
65+ depends on whether the node has actually changed its position , use ` hasMoved ` method :
6466
6567``` php
6668if ($node->save())
@@ -95,7 +97,7 @@ The node will be appended to the end of the tree.
9597
9698If you want to make node a child of other node, you can make it last or first child.
9799
98- ` $parent ` variable is the node that exists in database, no matter how we get it .
100+ In following examples, ` $parent ` is some existing node .
99101
100102There are few ways to append a node:
101103
@@ -132,10 +134,10 @@ $parent->prepend($node);
132134
133135#### Inserting before or after specified node
134136
135- You can make a ` $node ` to be a neighbor of the ` $neighbor ` node using following methods:
137+ You can make ` $node ` to be a neighbor of the ` $neighbor ` node using following methods:
136138
137- _ Neighbor is existing node, target node can be fresh. If target node is exists,
138- it will be moved to the new position and parent will be changed if it's needed._
139+ * Neighbor is existing node, target node can be fresh. If target node is exists,
140+ it will be moved to the new position and parent will be changed if it's needed.*
139141
140142``` php
141143# Explicit save
@@ -147,16 +149,20 @@ $node->insertAfter($neighbor);
147149$node->insertBefore($neighbor);
148150```
149151
150- #### Moving node up or down
152+ #### Shifting a node
153+
154+ To shift node up or down inside parent:
151155
152156``` php
153157$bool = $node->down();
154158$bool = $node->up();
155159
156- // Make node lower by 3 siblings
160+ // Shift node by 3 siblings
157161$bool = $node->down(3);
158162```
159163
164+ The result of the operation is boolean value of whether the node has changed the position.
165+
160166#### Building a tree from array
161167
162168When using static method ` create ` on node, it checks whether attributes contains
@@ -184,7 +190,7 @@ $node = Category::create([
184190
185191In some cases we will use an ` $id ` variable which is an id of the target node.
186192
187- #### Getting ancestors
193+ #### Ancestors
188194
189195``` php
190196// #1 Using accessor
@@ -195,15 +201,9 @@ $result = $node->ancestors()->get();
195201
196202// #3 Getting ancestors by id of the node
197203$result = Category::ancestorsOf($id);
198-
199- // #4 Applying constraints
200- $result = Category::whereAncestorOf($id)->get();
201-
202- // #5 Applying constraints from existing node
203- $result = Category::whereAncestorOf($node)->get();
204204```
205205
206- #### Getting descendants
206+ #### Descendants
207207
208208``` php
209209// #1 Using accessor
@@ -214,18 +214,9 @@ $result = $node->descendants()->get();
214214
215215// #3 Getting ancestors by id of the node
216216$result = Category::descendantsOf($id);
217-
218- // #4 Applying constraints
219- $result = Category::whereDescendantOf($id)->get();
220- $result = Category::whereDescendantOf($node)->get();
221-
222- // #5 Other constraints
223- $result = Category::whereNotDescendantOf($id)->get();
224- $result = Category::orWhereDescendantOf($id)->get();
225- $result = Category::orWhereNotDescendantOf($id)->get();
226217```
227218
228- #### Getting siblings of the node
219+ #### Siblings
229220
230221``` php
231222$result = $node->getSiblings();
@@ -262,17 +253,38 @@ $result = $node->prevSiblings()->get();
262253#### Getting related models from other table
263254
264255Imagine that each category ` has many ` goods. I.e. ` HasMany ` relationship is established.
265- How can you get all goods of all categories that are descendants of some node ? Easy!
256+ How can you get all goods of ` $category ` and every its descendant ? Easy!
266257
267258``` php
268259// Get ids of descendants
269- $descendants = $node->descendants()->lists('id');
260+ $categories = $category->descendants()->lists('id');
261+
262+ // Include the id of category itself
263+ $categories[] = $category->getKey();
270264
271265// Get goods
272- $goods = Goods::whereIn('category_id', $descendants )->get();
266+ $goods = Goods::whereIn('category_id', $categories )->get();
273267```
274268
275- #### Working with query results
269+ ### Deleting nodes
270+
271+ To delete a node:
272+
273+ ``` php
274+ $node->delete();
275+ ```
276+
277+ Nodes are required to be deleted as models, ** don't** try do delete them using a query like so:
278+
279+ ``` php
280+ Category::where('id', '=', $id)->delete();
281+ ```
282+
283+ This will brake the tree!
284+
285+ ` SoftDeletes ` trait is supported, also on model level.
286+
287+ ### Collection extension
276288
277289This package provides few helpful methods for collection of nodes. You can link nodes in plain collection like so:
278290
@@ -293,12 +305,11 @@ $tree = $results->toTree();
293305
294306` $tree ` will contain only root nodes and to access children you can use ` children ` relation.
295307
296- #### Manipulating a query
308+ ### Query builder extension
297309
298- You have noticed that some methods return a query builder instance. It has some
299- features.
310+ This packages extends default query builder to introduce few helpful features.
300311
301- ##### Including depth level into result
312+ #### Including node depth
302313
303314If you need to know at which level the node is:
304315
@@ -316,9 +327,9 @@ To get nodes of specified level, you can apply `having` constraint:
316327$result = Category::withDepth()->having('depth', '=', 1)->get();
317328```
318329
319- ##### Default order
330+ #### Default order
320331
321- Each node has it's own unique value that determines its position in the tree. If
332+ Each node has it's own unique ` _lft ` value that determines its position in the tree. If
322333you want node to be ordered by this value, you can use ` defaultOrder ` method on
323334the query builder:
324335
@@ -333,9 +344,9 @@ You can get nodes in reversed order:
333344$result = Category::reversed()->get();
334345```
335346
336- ##### Constraints
347+ #### Constraints
337348
338- Various constraints that can be applied to query builder:
349+ Various constraints that can be applied to the query builder:
339350
340351- __ whereIsRoot()__ to get only root nodes;
341352- __ hasChildren()__ to get nodes that have children;
@@ -344,25 +355,31 @@ Various constraints that can be applied to query builder:
344355 with specified id;
345356- __ whereIsBefore($id)__ to get every node that is before a node with specified id.
346357
347- ### Deleting nodes
348-
349- To delete a node:
358+ Descendants constraints:
350359
351360``` php
352- $node->delete();
361+ $result = Category::whereDescendantOf($node)->get();
362+ $result = Category::whereDescendantOf($node)->get();
363+ $result = Category::whereNotDescendantOf($node)->get();
364+ $result = Category::orWhereDescendantOf($node)->get();
365+ $result = Category::orWhereNotDescendantOf($node)->get();
353366```
354367
355- Nodes are required to be deleted as models, ** don't ** try do delete them using a query like so :
368+ Ancestor constraints :
356369
357370``` php
358- Category::where('id', '=', $id )->delete ();
371+ $result = Category::whereAncestorOf($node )->get ();
359372```
360373
361- This will brake the tree!
374+ ` $node ` can be either a primary key of the model or model instance.
362375
363- ` SoftDeletes ` trait is supported, also on model level.
376+ ### Node methods
377+
378+ Compute the number of descendants:
364379
365- ### Other methods
380+ ``` php
381+ $node->getDescendantCount();
382+ ```
366383
367384To check if node is a descendant of other node:
368385
@@ -421,17 +438,7 @@ Installation
421438To install the package, in terminal:
422439
423440```
424- composer require kalnoy/nestedset:~2.0
425- ```
426-
427- Add some aliases:
428-
429- ``` php
430- 'aliases' => array(
431- ...
432- 'NestedSet' => 'Kalnoy\Nestedset\NestedSet',
433- 'Node' => 'Kalnoy\Nestedset\Node',
434- ),
441+ composer require kalnoy/nestedset
435442```
436443
437444### Adding required columns
@@ -461,47 +468,20 @@ If, for some reasons, you want to init everything by yourself, this is preferred
461468$table->unsignedInteger('_lft');
462469$table->unsignedInteger('_rgt');
463470$table->unsignedInteger('parent_id')->nullable();
464- ```
465-
466- You can change names of the columns, in this case you need to [ alter constants] ( #changing-column-names )
467- on your model class.
468471
469- ### Transforming a model
470-
471- Your model is now extended from ` Node ` class, not ` Eloquent ` :
472-
473- ``` php
474- class Foo extends Node {
475-
476- }
472+ $table->index([ '_lft', '_rgt', 'parent_id' ]);
477473```
478474
479- #### Changing column names
475+ ### The model
480476
481- If you're using custom columns, you need to make shure that it's reflected on
482- the model:
477+ Your model is now extended from ` Kalnoy\Nestedset\Node ` class, not ` Eloquent ` :
483478
484479``` php
485- class Foo extends Node {
480+ class Foo extends Kalnoy\Nestedset\ Node {
486481
487- const LFT = 'lft';
488-
489- const RGT = 'rgt';
490-
491- const PARENT_ID = 'parent';
492-
493- protected $guarded = [ 'lft', 'rgt' ];
494-
495- // To allow mass asignment on parent attribute
496- public function setParentAttribute($value)
497- {
498- $this->setParentIdAttribute($value);
499- }
500482}
501483```
502484
503- __ Important!__ Make sure that ` lft ` and ` rgt ` columns are guarded!
504-
505485License
506486=======
507487
0 commit comments