@@ -66,7 +66,7 @@ class Node extends Eloquent {
66
66
*
67
67
* @var int
68
68
*/
69
- static $ actionsPerformed = 0 ;
69
+ protected static $ actionsPerformed = 0 ;
70
70
71
71
/**
72
72
* {@inheritdoc}
@@ -290,6 +290,7 @@ public function refreshNode()
290
290
$ attributes = $ this ->newServiceQuery ()->getNodeData ($ this ->getKey ());
291
291
292
292
$ this ->attributes = array_merge ($ this ->attributes , $ attributes );
293
+ $ this ->original = array_merge ($ this ->original , $ attributes );
293
294
}
294
295
295
296
/**
@@ -414,7 +415,7 @@ public function prev()
414
415
*/
415
416
public function ancestors ()
416
417
{
417
- return $ this ->newQuery ()->whereAncestorOf ($ this ->getKey ());
418
+ return $ this ->newQuery ()->whereAncestorOf ($ this ->getKey ())-> defaultOrder () ;
418
419
}
419
420
420
421
/**
@@ -576,68 +577,36 @@ public function down($amount = 1)
576
577
*/
577
578
protected function insertAt ($ position )
578
579
{
579
- $ this ->refreshNode ();
580
-
581
- if ($ this ->exists && $ this ->getLft () < $ position && $ position < $ this ->getRgt ())
582
- {
583
- throw new Exception ("Trying to insert node into one of it's descendants. " );
584
- }
580
+ ++static ::$ actionsPerformed ;
585
581
586
- if ($ this ->exists )
587
- {
588
- $ this ->moveNode ($ position );
589
- }
590
- else
591
- {
592
- $ this ->insertNode ($ position );
593
- }
582
+ $ result = $ this ->exists ? $ this ->moveNode ($ position ) : $ this ->insertNode ($ position );
594
583
595
- ++ static :: $ actionsPerformed ;
584
+ return $ result ;
596
585
}
597
586
598
587
/**
599
- * Move a node to new position.
588
+ * Move a node to the new position.
589
+ *
590
+ * @since 2.0
600
591
*
601
- * @param int $lft
602
- * @param int $rgt
603
- * @param int $pos
592
+ * @param int $position
604
593
*
605
594
* @return int
606
595
*/
607
- protected function moveNode ($ pos )
596
+ protected function moveNode ($ position )
608
597
{
609
- $ lft = $ this ->getLft ();
610
- $ rgt = $ this ->getRgt ();
611
-
612
- $ from = min ($ lft , $ pos );
613
- $ to = max ($ rgt , $ pos - 1 );
614
-
615
- // The height of node that is being moved
616
- $ height = $ rgt - $ lft + 1 ;
617
-
618
- // The distance that our node will travel to reach it's destination
619
- $ distance = $ to - $ from + 1 - $ height ;
620
-
621
- if ($ pos > $ lft ) $ height *= -1 ; else $ distance *= -1 ;
598
+ $ updated = $ this ->newServiceQuery ()->moveNode ($ this ->getKey (), $ position );
622
599
623
- $ params = compact ( ' lft ' , ' rgt ' , ' from ' , ' to ' , ' height ' , ' distance ' );
600
+ if ( $ updated ) $ this -> refreshNode ( );
624
601
625
- $ query = $ this ->newServiceQuery ()->getQuery ()
626
- ->whereBetween (static ::LFT , array ($ from , $ to ))
627
- ->orWhereBetween (static ::RGT , array ($ from , $ to ));
628
-
629
- $ grammar = $ query ->getGrammar ();
630
-
631
- // Sync with original since those attributes are updated after prev operation
632
- $ this ->original [static ::LFT ] = $ this ->attributes [static ::LFT ] += $ distance ;
633
- $ this ->original [static ::RGT ] = $ this ->attributes [static ::RGT ] += $ distance ;
634
-
635
- return $ query ->update ($ this ->getColumnsPatch ($ params , $ grammar ));
602
+ return $ updated > 0 ;
636
603
}
637
604
638
605
/**
639
606
* Insert new node at specified position.
640
607
*
608
+ * @since 2.0
609
+ *
641
610
* @param int $position
642
611
*/
643
612
protected function insertNode ($ position )
@@ -648,74 +617,8 @@ protected function insertNode($position)
648
617
649
618
$ this ->setAttribute (static ::LFT , $ position );
650
619
$ this ->setAttribute (static ::RGT , $ position + $ height - 1 );
651
- }
652
-
653
- /**
654
- * Make or remove gap in the tree. Negative height will remove gap.
655
- *
656
- * @param int $cut
657
- * @param int $height
658
- *
659
- * @return int the number of updated nodes.
660
- */
661
- protected function makeGap ($ cut , $ height )
662
- {
663
- $ params = compact ('cut ' , 'height ' );
664
-
665
- $ query = $ this ->newServiceQuery ()->getQuery ();
666
-
667
- return $ query
668
- ->where (static ::LFT , '>= ' , $ cut )
669
- ->orWhere (static ::RGT , '>= ' , $ cut )
670
- ->update ($ this ->getColumnsPatch ($ params , $ query ->getGrammar ()));
671
- }
672
-
673
- /**
674
- * Get patch for columns.
675
- *
676
- * @param array $params
677
- * @param \Illuminate\Database\Query\Grammars\Grammar $grammar
678
- *
679
- * @return array
680
- */
681
- protected function getColumnsPatch (array $ params , $ grammar )
682
- {
683
- $ columns = array ();
684
-
685
- foreach (array (static ::LFT , static ::RGT ) as $ col )
686
- {
687
- $ columns [$ col ] = $ this ->getColumnPatch ($ grammar ->wrap ($ col ), $ params );
688
- }
689
620
690
- return $ columns ;
691
- }
692
-
693
- /**
694
- * Get patch for single column.
695
- *
696
- * @param string $col
697
- * @param array $params
698
- *
699
- * @return string
700
- */
701
- protected function getColumnPatch ($ col , array $ params )
702
- {
703
- extract ($ params );
704
-
705
- if ($ height > 0 ) $ height = '+ ' .$ height ;
706
-
707
- if (isset ($ cut ))
708
- {
709
- return new Expression ("case when $ col >= $ cut then $ col $ height else $ col end " );
710
- }
711
-
712
- if ($ distance > 0 ) $ distance = '+ ' .$ distance ;
713
-
714
- return new Expression ("case " .
715
- "when $ col between $ lft and $ rgt then $ col $ distance " .
716
- "when $ col between $ from and $ to then $ col $ height " .
717
- "else $ col end "
718
- );
621
+ return true ;
719
622
}
720
623
721
624
/**
@@ -737,7 +640,7 @@ protected function deleteNode()
737
640
/**
738
641
* {@inheritdoc}
739
642
*
740
- * @since 1.2
643
+ * @since 2.0
741
644
*/
742
645
public function newEloquentBuilder ($ query )
743
646
{
@@ -775,7 +678,7 @@ public function newFromBuilder($attributes = array())
775
678
}
776
679
777
680
/**
778
- * Get node size (rgt- lft).
681
+ * Get node height (rgt - lft + 1 ).
779
682
*
780
683
* @return int
781
684
*/
@@ -1002,4 +905,40 @@ public function isDescendantOf(Node $other)
1002
905
{
1003
906
return $ this ->getLft () > $ other ->getLft () and $ this ->getLft () < $ other ->getRgt ();
1004
907
}
908
+
909
+ /**
910
+ * Get statistics of errors of the tree.
911
+ *
912
+ * @since 2.0
913
+ *
914
+ * @return array
915
+ */
916
+ public function countErrors ()
917
+ {
918
+ return $ this ->newServiceQuery ()->countErrors ();
919
+ }
920
+
921
+ /**
922
+ * Get the number of total errors of the tree.
923
+ *
924
+ * @since 2.0
925
+ *
926
+ * @return int
927
+ */
928
+ public function getTotalErrors ()
929
+ {
930
+ return array_sum ($ this ->countErrors ());
931
+ }
932
+
933
+ /**
934
+ * Get whether the tree is broken.
935
+ *
936
+ * @since 2.0
937
+ *
938
+ * @return bool
939
+ */
940
+ public function isBroken ()
941
+ {
942
+ return $ this ->getTotalErrors () > 0 ;
943
+ }
1005
944
}
0 commit comments