@@ -66,7 +66,7 @@ class Node extends Eloquent {
6666 *
6767 * @var int
6868 */
69- static $ actionsPerformed = 0 ;
69+ protected static $ actionsPerformed = 0 ;
7070
7171 /**
7272 * {@inheritdoc}
@@ -290,6 +290,7 @@ public function refreshNode()
290290 $ attributes = $ this ->newServiceQuery ()->getNodeData ($ this ->getKey ());
291291
292292 $ this ->attributes = array_merge ($ this ->attributes , $ attributes );
293+ $ this ->original = array_merge ($ this ->original , $ attributes );
293294 }
294295
295296 /**
@@ -414,7 +415,7 @@ public function prev()
414415 */
415416 public function ancestors ()
416417 {
417- return $ this ->newQuery ()->whereAncestorOf ($ this ->getKey ());
418+ return $ this ->newQuery ()->whereAncestorOf ($ this ->getKey ())-> defaultOrder () ;
418419 }
419420
420421 /**
@@ -576,68 +577,36 @@ public function down($amount = 1)
576577 */
577578 protected function insertAt ($ position )
578579 {
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 ;
585581
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 );
594583
595- ++ static :: $ actionsPerformed ;
584+ return $ result ;
596585 }
597586
598587 /**
599- * Move a node to new position.
588+ * Move a node to the new position.
589+ *
590+ * @since 2.0
600591 *
601- * @param int $lft
602- * @param int $rgt
603- * @param int $pos
592+ * @param int $position
604593 *
605594 * @return int
606595 */
607- protected function moveNode ($ pos )
596+ protected function moveNode ($ position )
608597 {
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 );
622599
623- $ params = compact ( ' lft ' , ' rgt ' , ' from ' , ' to ' , ' height ' , ' distance ' );
600+ if ( $ updated ) $ this -> refreshNode ( );
624601
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 ;
636603 }
637604
638605 /**
639606 * Insert new node at specified position.
640607 *
608+ * @since 2.0
609+ *
641610 * @param int $position
642611 */
643612 protected function insertNode ($ position )
@@ -648,74 +617,8 @@ protected function insertNode($position)
648617
649618 $ this ->setAttribute (static ::LFT , $ position );
650619 $ 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- }
689620
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 ;
719622 }
720623
721624 /**
@@ -737,7 +640,7 @@ protected function deleteNode()
737640 /**
738641 * {@inheritdoc}
739642 *
740- * @since 1.2
643+ * @since 2.0
741644 */
742645 public function newEloquentBuilder ($ query )
743646 {
@@ -775,7 +678,7 @@ public function newFromBuilder($attributes = array())
775678 }
776679
777680 /**
778- * Get node size (rgt- lft).
681+ * Get node height (rgt - lft + 1 ).
779682 *
780683 * @return int
781684 */
@@ -1002,4 +905,40 @@ public function isDescendantOf(Node $other)
1002905 {
1003906 return $ this ->getLft () > $ other ->getLft () and $ this ->getLft () < $ other ->getRgt ();
1004907 }
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+ }
1005944}
0 commit comments