88use Illuminate \Database \Eloquent \Relations \BelongsTo ;
99use Illuminate \Database \Eloquent \Relations \HasMany ;
1010use Illuminate \Database \Eloquent \SoftDeletingScope ;
11+ use Illuminate \Database \Query \Builder ;
1112use LogicException ;
1213
1314trait NodeTrait
@@ -164,7 +165,7 @@ protected function actionRoot()
164165 */
165166 protected function getLowerBound ()
166167 {
167- return (int )$ this ->newServiceQuery ()->max ($ this ->getRgtName ());
168+ return (int )$ this ->newNestedSetQuery ()->max ($ this ->getRgtName ());
168169 }
169170
170171 /**
@@ -226,32 +227,21 @@ public function refreshNode()
226227 {
227228 if ( ! $ this ->exists || static ::$ actionsPerformed === 0 ) return ;
228229
229- $ attributes = $ this ->newServiceQuery ()->getNodeData ($ this ->getKey ());
230+ $ attributes = $ this ->newNestedSetQuery ()->getNodeData ($ this ->getKey ());
230231
231232 $ this ->attributes = array_merge ($ this ->attributes , $ attributes );
232233 $ this ->original = array_merge ($ this ->original , $ attributes );
233234 }
234235
235- /**
236- * Get the root node.
237- *
238- * @param array $columns
239- *
240- * @return self
241- */
242- static public function root (array $ columns = ['* ' ])
243- {
244- return static ::whereIsRoot ()->first ($ columns );
245- }
246-
247236 /**
248237 * Relation to the parent.
249238 *
250239 * @return BelongsTo
251240 */
252241 public function parent ()
253242 {
254- return $ this ->belongsTo (get_class ($ this ), $ this ->getParentIdName ());
243+ return $ this ->belongsTo (get_class ($ this ), $ this ->getParentIdName ())
244+ ->setModel ($ this );
255245 }
256246
257247 /**
@@ -261,7 +251,8 @@ public function parent()
261251 */
262252 public function children ()
263253 {
264- return $ this ->hasMany (get_class ($ this ), $ this ->getParentIdName ());
254+ return $ this ->hasMany (get_class ($ this ), $ this ->getParentIdName ())
255+ ->setModel ($ this );
265256 }
266257
267258 /**
@@ -271,7 +262,7 @@ public function children()
271262 */
272263 public function descendants ()
273264 {
274- return $ this ->newQuery ()->whereDescendantOf ($ this ->getKey ());
265+ return $ this ->newScopedQuery ()->whereDescendantOf ($ this ->getKey ());
275266 }
276267
277268 /**
@@ -296,20 +287,14 @@ public function siblings($dir = null)
296287 break ;
297288
298289 default :
299- $ query = $ this ->newQuery ()
290+ $ query = $ this ->newScopedQuery ()
300291 ->defaultOrder ()
301292 ->where ($ this ->getKeyName (), '<> ' , $ this ->getKey ());
302293
303294 break ;
304295 }
305296
306- $ parentId = $ this ->getParentId ();
307-
308- if (is_null ($ parentId )) {
309- $ query ->whereNull ($ this ->getParentIdName ());
310- } else {
311- $ query ->where ($ this ->getParentIdName (), '= ' , $ parentId );
312- }
297+ $ query ->where ($ this ->getParentIdName (), '= ' , $ this ->getParentId ());
313298
314299 return $ query ;
315300 }
@@ -341,7 +326,7 @@ public function prevSiblings()
341326 */
342327 public function nextNodes ()
343328 {
344- return $ this ->newQuery ()
329+ return $ this ->newScopedQuery ()
345330 ->whereIsAfter ($ this ->getKey ())
346331 ->defaultOrder ();
347332 }
@@ -353,7 +338,7 @@ public function nextNodes()
353338 */
354339 public function prevNodes ()
355340 {
356- return $ this ->newQuery ()
341+ return $ this ->newScopedQuery ()
357342 ->whereIsBefore ($ this ->getKey ())
358343 ->reversed ();
359344 }
@@ -365,7 +350,7 @@ public function prevNodes()
365350 */
366351 public function ancestors ()
367352 {
368- return $ this ->newQuery ()
353+ return $ this ->newScopedQuery ()
369354 ->whereAncestorOf ($ this ->getKey ())
370355 ->defaultOrder ();
371356 }
@@ -588,7 +573,7 @@ protected function insertAt($position)
588573 */
589574 protected function moveNode ($ position )
590575 {
591- $ updated = $ this ->newServiceQuery ()
576+ $ updated = $ this ->newNestedSetQuery ()
592577 ->moveNode ($ this ->getKey (), $ position ) > 0 ;
593578
594579 if ($ updated ) $ this ->refreshNode ();
@@ -607,7 +592,7 @@ protected function moveNode($position)
607592 */
608593 protected function insertNode ($ position )
609594 {
610- $ this ->newServiceQuery ()->makeGap ($ position , 2 );
595+ $ this ->newNestedSetQuery ()->makeGap ($ position , 2 );
611596
612597 $ height = $ this ->getNodeHeight ();
613598
@@ -629,12 +614,15 @@ protected function deleteDescendants()
629614 ? 'forceDelete '
630615 : 'delete ' ;
631616
632- $ this ->newQuery ()->whereNodeBetween ([ $ lft + 1 , $ rgt ])->{$ method }();
617+ $ this ->newQuery ()
618+ ->applyNestedSetScope ()
619+ ->whereNodeBetween ([ $ lft + 1 , $ rgt ])
620+ ->{$ method }();
633621
634622 if ($ this ->hardDeleting ()) {
635623 $ height = $ rgt - $ lft + 1 ;
636624
637- $ this ->newServiceQuery ()->makeGap ($ rgt + 1 , -$ height );
625+ $ this ->newNestedSetQuery ()->makeGap ($ rgt + 1 , -$ height );
638626
639627 // In case if user wants to re-create the node
640628 $ this ->makeRoot ();
@@ -651,6 +639,7 @@ protected function deleteDescendants()
651639 protected function restoreDescendants ($ deletedAt )
652640 {
653641 $ this ->newQuery ()
642+ ->applyNestedSetScope ()
654643 ->whereNodeBetween ([ $ this ->getLft () + 1 , $ this ->getRgt () ])
655644 ->where ($ this ->getDeletedAtColumn (), '>= ' , $ deletedAt )
656645 ->applyScopes ()
@@ -674,9 +663,67 @@ public function newEloquentBuilder($query)
674663 *
675664 * @return QueryBuilder
676665 */
677- public function newServiceQuery ()
666+ public function newNestedSetQuery ($ table = null )
667+ {
668+ $ builder = $ this ->usesSoftDelete ()
669+ ? $ this ->withTrashed ()
670+ : $ this ->newQuery ();
671+
672+ return $ this ->applyNestedSetScope ($ builder , $ table );
673+ }
674+
675+ /**
676+ * @return mixed
677+ */
678+ public function newScopedQuery ($ table = null )
678679 {
679- return $ this ->usesSoftDelete () ? $ this ->withTrashed () : $ this ->newQuery ();
680+ return $ this ->applyNestedSetScope ($ this ->newQuery (), $ table );
681+ }
682+
683+ /**
684+ * @param mixed $query
685+ * @param string $table
686+ *
687+ * @return mixed
688+ */
689+ public function applyNestedSetScope ($ query , $ table = null )
690+ {
691+ if ( ! $ scoped = $ this ->getScopeAttributes ()) {
692+ return $ query ;
693+ }
694+
695+ if ( ! $ table ) {
696+ $ table = $ this ->getTable ();
697+ }
698+
699+ foreach ($ scoped as $ attribute ) {
700+ $ query ->where ($ table .'. ' .$ attribute , '= ' ,
701+ $ this ->getAttributeValue ($ attribute ));
702+ }
703+
704+ return $ query ;
705+ }
706+
707+ /**
708+ * @return array
709+ */
710+ protected function getScopeAttributes ()
711+ {
712+ return null ;
713+ }
714+
715+ /**
716+ * @param array $attributes
717+ *
718+ * @return self
719+ */
720+ public static function scoped (array $ attributes )
721+ {
722+ $ instance = new static ;
723+
724+ $ instance ->setRawAttributes ($ attributes );
725+
726+ return $ instance ->newScopedQuery ();
680727 }
681728
682729 /**
@@ -752,7 +799,7 @@ public function setParentIdAttribute($value)
752799 if ($ this ->getParentId () == $ value ) return ;
753800
754801 if ($ value ) {
755- $ this ->appendToNode ($ this ->newQuery ()->findOrFail ($ value ));
802+ $ this ->appendToNode ($ this ->newScopedQuery ()->findOrFail ($ value ));
756803 } else {
757804 $ this ->makeRoot ();
758805 }
@@ -863,7 +910,7 @@ public function getPrevNode(array $columns = array( '*' ))
863910 */
864911 public function getAncestors (array $ columns = array ( '* ' ))
865912 {
866- return $ this ->newQuery ()
913+ return $ this ->newScopedQuery ()
867914 ->defaultOrder ()
868915 ->ancestorsOf ($ this ->getKey (), $ columns );
869916 }
@@ -875,7 +922,7 @@ public function getAncestors(array $columns = array( '*' ))
875922 */
876923 public function getDescendants (array $ columns = array ( '* ' ))
877924 {
878- return $ this ->newQuery ()
925+ return $ this ->newScopedQuery ()
879926 ->defaultOrder ()
880927 ->descendantsOf ($ this ->getKey (), $ columns );
881928 }
0 commit comments