@@ -11,7 +11,9 @@ __[Support this project](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hos
11
11
__ Contents:__
12
12
13
13
- [ Theory] ( #what-are-nested-sets )
14
- - [ Manipulating nodes] ( #manipulating-nodes )
14
+ - [ Documentation] ( #documentation )
15
+ - [ Inserting nodes] ( #inserting-nodes )
16
+ - [ Retrieving nodes] ( #retrieving-nodes )
15
17
- [ Requirements] ( #requirements )
16
18
- [ Installation] ( #installation )
17
19
@@ -33,8 +35,8 @@ NSM shows good performance when tree is updated rarely. It is tuned to be fast f
33
35
getting related nodes. It'is ideally suited for building multi-depth menu or
34
36
categories for shop.
35
37
36
- Manipulating nodes
37
- ------------------
38
+ Documentation
39
+ -------------
38
40
39
41
Suppose that we have a model ` Category ` ; a ` $node ` variable is an instance of that model
40
42
and 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
59
61
hit ` save ` on model (some methods implicitly call ` save ` and return boolean result
60
62
of the operation).
61
63
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 :
64
66
65
67
``` php
66
68
if ($node->save())
@@ -95,7 +97,7 @@ The node will be appended to the end of the tree.
95
97
96
98
If you want to make node a child of other node, you can make it last or first child.
97
99
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 .
99
101
100
102
There are few ways to append a node:
101
103
@@ -132,10 +134,10 @@ $parent->prepend($node);
132
134
133
135
#### Inserting before or after specified node
134
136
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:
136
138
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.*
139
141
140
142
``` php
141
143
# Explicit save
@@ -147,16 +149,20 @@ $node->insertAfter($neighbor);
147
149
$node->insertBefore($neighbor);
148
150
```
149
151
150
- #### Moving node up or down
152
+ #### Shifting a node
153
+
154
+ To shift node up or down inside parent:
151
155
152
156
``` php
153
157
$bool = $node->down();
154
158
$bool = $node->up();
155
159
156
- // Make node lower by 3 siblings
160
+ // Shift node by 3 siblings
157
161
$bool = $node->down(3);
158
162
```
159
163
164
+ The result of the operation is boolean value of whether the node has changed the position.
165
+
160
166
#### Building a tree from array
161
167
162
168
When using static method ` create ` on node, it checks whether attributes contains
@@ -184,7 +190,7 @@ $node = Category::create([
184
190
185
191
In some cases we will use an ` $id ` variable which is an id of the target node.
186
192
187
- #### Getting ancestors
193
+ #### Ancestors
188
194
189
195
``` php
190
196
// #1 Using accessor
@@ -195,15 +201,9 @@ $result = $node->ancestors()->get();
195
201
196
202
// #3 Getting ancestors by id of the node
197
203
$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();
204
204
```
205
205
206
- #### Getting descendants
206
+ #### Descendants
207
207
208
208
``` php
209
209
// #1 Using accessor
@@ -214,18 +214,9 @@ $result = $node->descendants()->get();
214
214
215
215
// #3 Getting ancestors by id of the node
216
216
$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();
226
217
```
227
218
228
- #### Getting siblings of the node
219
+ #### Siblings
229
220
230
221
``` php
231
222
$result = $node->getSiblings();
@@ -262,17 +253,38 @@ $result = $node->prevSiblings()->get();
262
253
#### Getting related models from other table
263
254
264
255
Imagine 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!
266
257
267
258
``` php
268
259
// 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();
270
264
271
265
// Get goods
272
- $goods = Goods::whereIn('category_id', $descendants )->get();
266
+ $goods = Goods::whereIn('category_id', $categories )->get();
273
267
```
274
268
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
276
288
277
289
This package provides few helpful methods for collection of nodes. You can link nodes in plain collection like so:
278
290
@@ -293,12 +305,11 @@ $tree = $results->toTree();
293
305
294
306
` $tree ` will contain only root nodes and to access children you can use ` children ` relation.
295
307
296
- #### Manipulating a query
308
+ ### Query builder extension
297
309
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.
300
311
301
- ##### Including depth level into result
312
+ #### Including node depth
302
313
303
314
If you need to know at which level the node is:
304
315
@@ -316,9 +327,9 @@ To get nodes of specified level, you can apply `having` constraint:
316
327
$result = Category::withDepth()->having('depth', '=', 1)->get();
317
328
```
318
329
319
- ##### Default order
330
+ #### Default order
320
331
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
322
333
you want node to be ordered by this value, you can use ` defaultOrder ` method on
323
334
the query builder:
324
335
@@ -333,9 +344,9 @@ You can get nodes in reversed order:
333
344
$result = Category::reversed()->get();
334
345
```
335
346
336
- ##### Constraints
347
+ #### Constraints
337
348
338
- Various constraints that can be applied to query builder:
349
+ Various constraints that can be applied to the query builder:
339
350
340
351
- __ whereIsRoot()__ to get only root nodes;
341
352
- __ hasChildren()__ to get nodes that have children;
@@ -344,25 +355,31 @@ Various constraints that can be applied to query builder:
344
355
with specified id;
345
356
- __ whereIsBefore($id)__ to get every node that is before a node with specified id.
346
357
347
- ### Deleting nodes
348
-
349
- To delete a node:
358
+ Descendants constraints:
350
359
351
360
``` 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();
353
366
```
354
367
355
- Nodes are required to be deleted as models, ** don't ** try do delete them using a query like so :
368
+ Ancestor constraints :
356
369
357
370
``` php
358
- Category::where('id', '=', $id )->delete ();
371
+ $result = Category::whereAncestorOf($node )->get ();
359
372
```
360
373
361
- This will brake the tree!
374
+ ` $node ` can be either a primary key of the model or model instance.
362
375
363
- ` SoftDeletes ` trait is supported, also on model level.
376
+ ### Node methods
377
+
378
+ Compute the number of descendants:
364
379
365
- ### Other methods
380
+ ``` php
381
+ $node->getDescendantCount();
382
+ ```
366
383
367
384
To check if node is a descendant of other node:
368
385
@@ -421,17 +438,7 @@ Installation
421
438
To install the package, in terminal:
422
439
423
440
```
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
435
442
```
436
443
437
444
### Adding required columns
@@ -461,47 +468,20 @@ If, for some reasons, you want to init everything by yourself, this is preferred
461
468
$table->unsignedInteger('_lft');
462
469
$table->unsignedInteger('_rgt');
463
470
$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.
468
471
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' ]);
477
473
```
478
474
479
- #### Changing column names
475
+ ### The model
480
476
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 ` :
483
478
484
479
``` php
485
- class Foo extends Node {
480
+ class Foo extends Kalnoy\Nestedset\ Node {
486
481
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
- }
500
482
}
501
483
```
502
484
503
- __ Important!__ Make sure that ` lft ` and ` rgt ` columns are guarded!
504
-
505
485
License
506
486
=======
507
487
0 commit comments