Complex classes like NodeTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use NodeTrait, and based on these observations, apply Extract Interface, too.
1 | <?php namespace Arcanedev\LaravelNestedSet; |
||
27 | trait NodeTrait |
||
28 | { |
||
29 | /* ------------------------------------------------------------------------------------------------ |
||
30 | | Traits |
||
31 | | ------------------------------------------------------------------------------------------------ |
||
32 | */ |
||
33 | use EloquentTrait, SoftDeleteTrait; |
||
34 | |||
35 | /* ------------------------------------------------------------------------------------------------ |
||
36 | | Properties |
||
37 | | ------------------------------------------------------------------------------------------------ |
||
38 | */ |
||
39 | /** |
||
40 | * Pending operation. |
||
41 | * |
||
42 | * @var array|null |
||
43 | */ |
||
44 | protected $pending; |
||
45 | |||
46 | /** |
||
47 | * Whether the node has moved since last save. |
||
48 | * |
||
49 | * @var bool |
||
50 | */ |
||
51 | protected $moved = false; |
||
52 | |||
53 | /** |
||
54 | * Keep track of the number of performed operations. |
||
55 | * |
||
56 | * @var int |
||
57 | */ |
||
58 | public static $actionsPerformed = 0; |
||
59 | |||
60 | /* ------------------------------------------------------------------------------------------------ |
||
61 | | Boot Function |
||
62 | | ------------------------------------------------------------------------------------------------ |
||
63 | */ |
||
64 | /** |
||
65 | * Sign on model events. |
||
66 | */ |
||
67 | 280 | public static function bootNodeTrait() |
|
112 | |||
113 | /* ------------------------------------------------------------------------------------------------ |
||
114 | | Relationships |
||
115 | | ------------------------------------------------------------------------------------------------ |
||
116 | */ |
||
117 | /** |
||
118 | * Relation to the parent. |
||
119 | * |
||
120 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo |
||
121 | */ |
||
122 | 16 | public function parent() |
|
127 | |||
128 | /** |
||
129 | * Relation to children. |
||
130 | * |
||
131 | * @return \Illuminate\Database\Eloquent\Relations\HasMany |
||
132 | */ |
||
133 | 16 | public function children() |
|
138 | |||
139 | /** |
||
140 | * Get query for descendants of the node. |
||
141 | * |
||
142 | * @return \Arcanedev\LaravelNestedSet\Eloquent\DescendantsRelation |
||
143 | */ |
||
144 | 44 | public function descendants() |
|
148 | |||
149 | /** |
||
150 | * Get query for siblings of the node. |
||
151 | * |
||
152 | * @return \Arcanedev\LaravelNestedSet\Eloquent\QueryBuilder |
||
153 | */ |
||
154 | 8 | public function siblings() |
|
160 | |||
161 | /* ------------------------------------------------------------------------------------------------ |
||
162 | | Getters & Setters |
||
163 | | ------------------------------------------------------------------------------------------------ |
||
164 | */ |
||
165 | /** |
||
166 | * Get the lft key name. |
||
167 | * |
||
168 | * @return string |
||
169 | */ |
||
170 | 248 | public function getLftName() |
|
174 | |||
175 | /** |
||
176 | * Get the rgt key name. |
||
177 | * |
||
178 | * @return string |
||
179 | */ |
||
180 | 216 | public function getRgtName() |
|
184 | |||
185 | /** |
||
186 | * Get the parent id key name. |
||
187 | * |
||
188 | * @return string |
||
189 | */ |
||
190 | 164 | public function getParentIdName() |
|
194 | |||
195 | /** |
||
196 | * Get the value of the model's lft key. |
||
197 | * |
||
198 | * @return int |
||
199 | */ |
||
200 | 180 | public function getLft() |
|
204 | |||
205 | /** |
||
206 | * Set the value of the model's lft key. |
||
207 | * |
||
208 | * @param int $value |
||
209 | * |
||
210 | * @return self |
||
211 | */ |
||
212 | 92 | public function setLft($value) |
|
218 | |||
219 | /** |
||
220 | * Get the value of the model's rgt key. |
||
221 | * |
||
222 | * @return int |
||
223 | */ |
||
224 | 120 | public function getRgt() |
|
228 | |||
229 | /** |
||
230 | * Set the value of the model's rgt key. |
||
231 | * |
||
232 | * @param int $value |
||
233 | * |
||
234 | * @return self |
||
235 | */ |
||
236 | 92 | public function setRgt($value) |
|
242 | |||
243 | /** |
||
244 | * Get the value of the model's parent id key. |
||
245 | * |
||
246 | * @return int |
||
247 | */ |
||
248 | 96 | public function getParentId() |
|
252 | |||
253 | /** |
||
254 | * Set the value of the model's parent id key. |
||
255 | * |
||
256 | * @param int $value |
||
257 | * |
||
258 | * @return self |
||
259 | */ |
||
260 | 64 | public function setParentId($value) |
|
266 | |||
267 | /** |
||
268 | * Apply parent model. |
||
269 | * |
||
270 | * @param \Illuminate\Database\Eloquent\Model|null $value |
||
271 | * |
||
272 | * @return self |
||
273 | */ |
||
274 | 56 | protected function setParent($value) |
|
281 | |||
282 | /** |
||
283 | * Set the value of model's parent id key. |
||
284 | * |
||
285 | * Behind the scenes node is appended to found parent node. |
||
286 | * |
||
287 | * @param int $value |
||
288 | * |
||
289 | * @throws \Exception If parent node doesn't exists |
||
290 | */ |
||
291 | 12 | public function setParentIdAttribute($value) |
|
304 | |||
305 | /** |
||
306 | * Get the boundaries. |
||
307 | * |
||
308 | * @return array |
||
309 | */ |
||
310 | 44 | public function getBounds() |
|
314 | |||
315 | /** |
||
316 | * @return array |
||
317 | */ |
||
318 | 160 | protected function getScopeAttributes() |
|
322 | |||
323 | /** |
||
324 | * Set the lft and rgt boundaries to null. |
||
325 | * |
||
326 | * @return self |
||
327 | */ |
||
328 | 68 | protected function dirtyBounds() |
|
332 | |||
333 | /** |
||
334 | * Returns node that is next to current node without constraining to siblings. |
||
335 | * This can be either a next sibling or a next sibling of the parent node. |
||
336 | * |
||
337 | * @param array $columns |
||
338 | * |
||
339 | * @return self |
||
340 | */ |
||
341 | public function getNextNode(array $columns = ['*']) |
||
345 | |||
346 | /** |
||
347 | * Returns node that is before current node without constraining to siblings. |
||
348 | * This can be either a prev sibling or parent node. |
||
349 | * |
||
350 | * @param array $columns |
||
351 | * |
||
352 | * @return self |
||
353 | */ |
||
354 | 4 | public function getPrevNode(array $columns = ['*']) |
|
358 | |||
359 | /** |
||
360 | * Get the ancestors nodes. |
||
361 | * |
||
362 | * @param array $columns |
||
363 | * |
||
364 | * @return \Arcanedev\LaravelNestedSet\Eloquent\Collection |
||
365 | */ |
||
366 | 8 | public function getAncestors(array $columns = ['*']) |
|
372 | |||
373 | /** |
||
374 | * Get the descendants nodes. |
||
375 | * |
||
376 | * @param array $columns |
||
377 | * |
||
378 | * @return \Arcanedev\LaravelNestedSet\Eloquent\Collection|self[] |
||
379 | */ |
||
380 | 12 | public function getDescendants(array $columns = ['*']) |
|
384 | |||
385 | /** |
||
386 | * Get the siblings nodes. |
||
387 | * |
||
388 | * @param array $columns |
||
389 | * |
||
390 | * @return \Arcanedev\LaravelNestedSet\Eloquent\Collection|self[] |
||
391 | */ |
||
392 | 8 | public function getSiblings(array $columns = ['*']) |
|
396 | |||
397 | /** |
||
398 | * Get the next siblings nodes. |
||
399 | * |
||
400 | * @param array $columns |
||
401 | * |
||
402 | * @return \Arcanedev\LaravelNestedSet\Eloquent\Collection|self[] |
||
403 | */ |
||
404 | 8 | public function getNextSiblings(array $columns = ['*']) |
|
408 | |||
409 | /** |
||
410 | * Get the previous siblings nodes. |
||
411 | * |
||
412 | * @param array $columns |
||
413 | * |
||
414 | * @return \Arcanedev\LaravelNestedSet\Eloquent\Collection|self[] |
||
415 | */ |
||
416 | 8 | public function getPrevSiblings(array $columns = ['*']) |
|
420 | |||
421 | /** |
||
422 | * Get the next sibling node. |
||
423 | * |
||
424 | * @param array $columns |
||
425 | * |
||
426 | * @return self |
||
427 | */ |
||
428 | 4 | public function getNextSibling(array $columns = ['*']) |
|
432 | |||
433 | /** |
||
434 | * Get the previous sibling node. |
||
435 | * |
||
436 | * @param array $columns |
||
437 | * |
||
438 | * @return self |
||
439 | */ |
||
440 | 4 | public function getPrevSibling(array $columns = ['*']) |
|
444 | |||
445 | /** |
||
446 | * Get node height (rgt - lft + 1). |
||
447 | * |
||
448 | * @return int |
||
449 | */ |
||
450 | 36 | public function getNodeHeight() |
|
456 | |||
457 | /** |
||
458 | * Get number of descendant nodes. |
||
459 | * |
||
460 | * @return int |
||
461 | */ |
||
462 | 4 | public function getDescendantCount() |
|
466 | |||
467 | /** |
||
468 | * Set an action. |
||
469 | * |
||
470 | * @param string $action |
||
471 | * |
||
472 | * @return self |
||
473 | */ |
||
474 | 116 | protected function setNodeAction($action) |
|
481 | |||
482 | /* ------------------------------------------------------------------------------------------------ |
||
483 | | Other Functions |
||
484 | | ------------------------------------------------------------------------------------------------ |
||
485 | */ |
||
486 | /** |
||
487 | * Get the lower bound. |
||
488 | * |
||
489 | * @return int |
||
490 | */ |
||
491 | 32 | protected function getLowerBound() |
|
495 | |||
496 | /** |
||
497 | * Call pending action. |
||
498 | * |
||
499 | * @return null|false |
||
500 | */ |
||
501 | 96 | protected function callPendingAction() |
|
517 | |||
518 | /** |
||
519 | * @return bool |
||
520 | */ |
||
521 | 8 | protected function actionRaw() |
|
525 | |||
526 | /** |
||
527 | * Make a root node. |
||
528 | */ |
||
529 | 32 | protected function actionRoot() |
|
549 | |||
550 | /** |
||
551 | * Append or prepend a node to the parent. |
||
552 | * |
||
553 | * @param self $parent |
||
554 | * @param bool $prepend |
||
555 | * |
||
556 | * @return bool |
||
557 | */ |
||
558 | 32 | protected function actionAppendOrPrepend(self $parent, $prepend = false) |
|
572 | |||
573 | /** |
||
574 | * Insert node before or after another node. |
||
575 | * |
||
576 | * @param self $node |
||
577 | * @param bool $after |
||
578 | * |
||
579 | * @return bool |
||
580 | */ |
||
581 | 28 | protected function actionBeforeOrAfter(self $node, $after = false) |
|
587 | |||
588 | /** |
||
589 | * Refresh node's crucial attributes. |
||
590 | */ |
||
591 | 88 | public function refreshNode() |
|
600 | |||
601 | /** |
||
602 | * Get query for siblings after the node. |
||
603 | * |
||
604 | * @return \Arcanedev\LaravelNestedSet\Eloquent\QueryBuilder |
||
605 | */ |
||
606 | 24 | public function nextSiblings() |
|
611 | |||
612 | /** |
||
613 | * Get query for siblings before the node. |
||
614 | * |
||
615 | * @return \Arcanedev\LaravelNestedSet\Eloquent\QueryBuilder |
||
616 | */ |
||
617 | 16 | public function prevSiblings() |
|
622 | |||
623 | /** |
||
624 | * Get query for nodes after current node. |
||
625 | * |
||
626 | * @return \Arcanedev\LaravelNestedSet\Eloquent\QueryBuilder |
||
627 | */ |
||
628 | 28 | public function nextNodes() |
|
633 | |||
634 | /** |
||
635 | * Get query for nodes before current node in reversed order. |
||
636 | * |
||
637 | * @return \Arcanedev\LaravelNestedSet\Eloquent\QueryBuilder |
||
638 | */ |
||
639 | 20 | public function prevNodes() |
|
644 | |||
645 | /** |
||
646 | * Get query for ancestors to the node not including the node itself. |
||
647 | * |
||
648 | * @return \Arcanedev\LaravelNestedSet\Eloquent\QueryBuilder |
||
649 | */ |
||
650 | 4 | public function ancestors() |
|
655 | |||
656 | /** |
||
657 | * Make this node a root node. |
||
658 | * |
||
659 | * @return self |
||
660 | */ |
||
661 | 48 | public function makeRoot() |
|
665 | |||
666 | /** |
||
667 | * Save node as root. |
||
668 | * |
||
669 | * @return bool |
||
670 | */ |
||
671 | 8 | public function saveAsRoot() |
|
679 | |||
680 | /** |
||
681 | * Append and save a node. |
||
682 | * |
||
683 | * @param self $node |
||
684 | * |
||
685 | * @return bool |
||
686 | */ |
||
687 | 16 | public function appendNode(self $node) |
|
691 | |||
692 | /** |
||
693 | * Prepend and save a node. |
||
694 | * |
||
695 | * @param self $node |
||
696 | * |
||
697 | * @return bool |
||
698 | */ |
||
699 | 4 | public function prependNode(self $node) |
|
703 | |||
704 | /** |
||
705 | * Append a node to the new parent. |
||
706 | * |
||
707 | * @param self $parent |
||
708 | * |
||
709 | * @return self |
||
710 | */ |
||
711 | 40 | public function appendToNode(self $parent) |
|
715 | |||
716 | /** |
||
717 | * Prepend a node to the new parent. |
||
718 | * |
||
719 | * @param self $parent |
||
720 | * |
||
721 | * @return self |
||
722 | */ |
||
723 | 4 | public function prependToNode(self $parent) |
|
727 | |||
728 | /** |
||
729 | * @param self $parent |
||
730 | * @param bool $prepend |
||
731 | * |
||
732 | * @return self |
||
733 | */ |
||
734 | 44 | public function appendOrPrependTo(self $parent, $prepend = false) |
|
743 | |||
744 | /** |
||
745 | * Insert self after a node. |
||
746 | * |
||
747 | * @param self $node |
||
748 | * |
||
749 | * @return self |
||
750 | */ |
||
751 | 28 | public function afterNode(self $node) |
|
755 | |||
756 | /** |
||
757 | * Insert self before node. |
||
758 | * |
||
759 | * @param self $node |
||
760 | * |
||
761 | * @return self |
||
762 | */ |
||
763 | 8 | public function beforeNode(self $node) |
|
767 | |||
768 | /** |
||
769 | * @param self $node |
||
770 | * @param bool $after |
||
771 | * |
||
772 | * @return self |
||
773 | */ |
||
774 | 36 | public function beforeOrAfterNode(self $node, $after = false) |
|
786 | |||
787 | /** |
||
788 | * Insert self after a node and save. |
||
789 | * |
||
790 | * @param self $node |
||
791 | * |
||
792 | * @return bool |
||
793 | */ |
||
794 | 16 | public function insertAfterNode(self $node) |
|
798 | |||
799 | /** |
||
800 | * Insert self before a node and save. |
||
801 | * |
||
802 | * @param self $node |
||
803 | * |
||
804 | * @return bool |
||
805 | */ |
||
806 | 4 | public function insertBeforeNode(self $node) |
|
815 | |||
816 | /** |
||
817 | * @param int $lft |
||
818 | * @param int $rgt |
||
819 | * @param int $parentId |
||
820 | * |
||
821 | * @return self |
||
822 | */ |
||
823 | 8 | public function rawNode($lft, $rgt, $parentId) |
|
829 | |||
830 | /** |
||
831 | * Move node up given amount of positions. |
||
832 | * |
||
833 | * @param int $amount |
||
834 | * |
||
835 | * @return bool |
||
836 | */ |
||
837 | 4 | public function up($amount = 1) |
|
848 | |||
849 | /** |
||
850 | * Move node down given amount of positions. |
||
851 | * |
||
852 | * @param int $amount |
||
853 | * |
||
854 | * @return bool |
||
855 | */ |
||
856 | 16 | public function down($amount = 1) |
|
867 | |||
868 | /** |
||
869 | * Insert node at specific position. |
||
870 | * |
||
871 | * @param int $position |
||
872 | * |
||
873 | * @return bool |
||
874 | */ |
||
875 | 68 | protected function insertAt($position) |
|
885 | |||
886 | /** |
||
887 | * Move a node to the new position. |
||
888 | * |
||
889 | * @param int $position |
||
890 | * |
||
891 | * @return int |
||
892 | */ |
||
893 | 40 | protected function moveNode($position) |
|
902 | |||
903 | /** |
||
904 | * Insert new node at specified position. |
||
905 | * |
||
906 | * @param int $position |
||
907 | * |
||
908 | * @return bool |
||
909 | */ |
||
910 | 32 | protected function insertNode($position) |
|
921 | |||
922 | /** |
||
923 | * Update the tree when the node is removed physically. |
||
924 | */ |
||
925 | 20 | protected function deleteDescendants() |
|
947 | |||
948 | /** |
||
949 | * Restore the descendants. |
||
950 | * |
||
951 | * @param \Carbon\Carbon $deletedAt |
||
952 | */ |
||
953 | 4 | protected function restoreDescendants($deletedAt) |
|
960 | |||
961 | /** |
||
962 | * Get a new base query that includes deleted nodes. |
||
963 | * |
||
964 | * @param string|null $table |
||
965 | * |
||
966 | * @return \Arcanedev\LaravelNestedSet\Eloquent\QueryBuilder |
||
967 | */ |
||
968 | 116 | public function newNestedSetQuery($table = null) |
|
976 | |||
977 | /** |
||
978 | * @param string|null $table |
||
979 | * |
||
980 | * @return \Arcanedev\LaravelNestedSet\Eloquent\QueryBuilder |
||
981 | */ |
||
982 | 136 | public function newScopedQuery($table = null) |
|
986 | |||
987 | /** |
||
988 | * @param \Illuminate\Database\Eloquent\Builder $query |
||
989 | * @param string $table |
||
990 | * |
||
991 | * @return \Arcanedev\LaravelNestedSet\Eloquent\QueryBuilder|\Illuminate\Database\Query\Builder |
||
992 | */ |
||
993 | 204 | public function applyNestedSetScope($query, $table = null) |
|
1009 | |||
1010 | /** |
||
1011 | * @param array $attributes |
||
1012 | * |
||
1013 | * @return self |
||
1014 | */ |
||
1015 | 12 | public static function scoped(array $attributes) |
|
1023 | |||
1024 | /** |
||
1025 | * Save a new model and return the instance. |
||
1026 | * |
||
1027 | * Use `children` key on `$attributes` to create child nodes. |
||
1028 | * |
||
1029 | * @param array $attributes |
||
1030 | * @param self $parent |
||
1031 | * |
||
1032 | * @return static |
||
1033 | */ |
||
1034 | 12 | public static function create(array $attributes = [], self $parent = null) |
|
1056 | |||
1057 | /* ------------------------------------------------------------------------------------------------ |
||
1058 | | Check Functions |
||
1059 | | ------------------------------------------------------------------------------------------------ |
||
1060 | */ |
||
1061 | /** |
||
1062 | * Get whether node is root. |
||
1063 | * |
||
1064 | * @return bool |
||
1065 | */ |
||
1066 | 16 | public function isRoot() |
|
1070 | |||
1071 | /** |
||
1072 | * Get whether a node is a descendant of other node. |
||
1073 | * |
||
1074 | * @param self $other |
||
1075 | * |
||
1076 | * @return bool |
||
1077 | */ |
||
1078 | 76 | public function isDescendantOf(self $other) |
|
1085 | |||
1086 | /** |
||
1087 | * Get whether the node is immediate children of other node. |
||
1088 | * |
||
1089 | * @param self $other |
||
1090 | * |
||
1091 | * @return bool |
||
1092 | */ |
||
1093 | 4 | public function isChildOf(self $other) |
|
1097 | |||
1098 | /** |
||
1099 | * Get whether the node is a sibling of another node. |
||
1100 | * |
||
1101 | * @param self $other |
||
1102 | * |
||
1103 | * @return bool |
||
1104 | */ |
||
1105 | 32 | public function isSiblingOf(self $other) |
|
1109 | |||
1110 | /** |
||
1111 | * Get whether the node is an ancestor of other node, including immediate parent. |
||
1112 | * |
||
1113 | * @param self $other |
||
1114 | * |
||
1115 | * @return bool |
||
1116 | */ |
||
1117 | 4 | public function isAncestorOf(self $other) |
|
1121 | |||
1122 | /** |
||
1123 | * Get whether the node has moved since last save. |
||
1124 | * |
||
1125 | * @return bool |
||
1126 | */ |
||
1127 | 24 | public function hasMoved() |
|
1131 | |||
1132 | /* ------------------------------------------------------------------------------------------------ |
||
1133 | | Assertion Functions |
||
1134 | | ------------------------------------------------------------------------------------------------ |
||
1135 | */ |
||
1136 | /** |
||
1137 | * Assert that the node is not a descendant. |
||
1138 | * |
||
1139 | * @param self $node |
||
1140 | * |
||
1141 | * @return self |
||
1142 | */ |
||
1143 | 76 | protected function assertNotDescendant(self $node) |
|
1151 | |||
1152 | /** |
||
1153 | * Assert node exists. |
||
1154 | * |
||
1155 | * @param self $node |
||
1156 | * |
||
1157 | * @return self |
||
1158 | */ |
||
1159 | 76 | protected function assertNodeExists(self $node) |
|
1167 | } |
||
1168 |
This check marks calls to methods that do not seem to exist on an object.
This is most likely the result of a method being renamed without all references to it being renamed likewise.