33namespace Statamic \CP \Navigation ;
44
55use Exception ;
6+ use Illuminate \Support \Collection ;
67use Illuminate \Support \Facades \Cache ;
78use Statamic \Facades \Blink ;
89use Statamic \Facades \Preference ;
@@ -254,8 +255,8 @@ protected function applyPreferenceOverrides($preferences = null)
254255 ->each (fn ($ overrides ) => $ this ->createPendingItemsForSection ($ overrides ))
255256 ->each (fn ($ overrides ) => $ this ->applyPreferenceOverridesForSection ($ overrides ));
256257
257- if ($ navPreferencesConfig ['reorder ' ]) {
258- $ this ->setSectionOrder ($ sections );
258+ if ($ reorder = $ navPreferencesConfig ['reorder ' ]) {
259+ $ this ->setSectionOrder ($ reorder );
259260 }
260261
261262 return $ this ;
@@ -320,8 +321,8 @@ protected function applyPreferenceOverridesForSection($sectionNav)
320321 ->filter ()
321322 ->each (fn ($ item ) => $ item ->isChild (false ));
322323
323- if ($ sectionNav ['reorder ' ]) {
324- $ this ->setSectionItemOrder ($ section , $ sectionNav ['items ' ]);
324+ if ($ reorder = $ sectionNav ['reorder ' ]) {
325+ $ this ->setSectionItemOrder ($ section , $ sectionNav ['items ' ], $ reorder );
325326 }
326327 }
327328
@@ -444,62 +445,76 @@ protected function renameSection($sectionKey)
444445
445446 /**
446447 * Set section order.
447- *
448- * @param array $sections
449448 */
450- protected function setSectionOrder ($ sections )
449+ protected function setSectionOrder (array $ reorder ): void
451450 {
452- // Get conconfigured core sections...
451+ // Get unconfigured core sections...
453452 $ unconfiguredCoreSections = $ this ->sections ;
454453
455454 // Get unconfigured sections...
456- $ unconfiguredRegisteredSections = collect ($ this ->items )->map ->section ()->filter ()->unique ();
455+ $ unconfiguredRegisteredSections = collect ($ this ->items )
456+ ->mapWithKeys (fn ($ item ) => [NavItem::snakeCase ($ item ->section ()) => $ item ->section ()])
457+ ->filter ()
458+ ->unique ();
457459
458- // Merge unconfigured sections onto the end of the list and map their order...
459- $ this ->sectionsOrder = collect ($ sections )
460- ->pluck ('display ' )
461- ->merge ($ unconfiguredRegisteredSections )
460+ // Get merged unique list of sections...
461+ $ order = collect ()
462462 ->merge ($ unconfiguredCoreSections )
463- ->unique ()
463+ ->merge ($ unconfiguredRegisteredSections )
464+ ->unique ();
465+
466+ // Reorder to match `$reorder` config...
467+ collect ($ reorder )
468+ ->reverse ()
469+ ->each (fn ($ key ) => $ order ->prepend ($ order ->pull ($ key ), $ key ));
470+
471+ // Ensure `top_level` is always first...
472+ $ order ->prepend ($ order ->pull ('top_level ' ), 'top_level ' );
473+
474+ $ this ->sectionsOrder = $ order
464475 ->values ()
465476 ->mapWithKeys (fn ($ section , $ index ) => [$ section => $ index + 1 ])
466477 ->all ();
467478 }
468479
469480 /**
470481 * Set section item order.
471- *
472- * @param string $section
473- * @param array $items
474482 */
475- protected function setSectionItemOrder ($ section , $ items)
483+ protected function setSectionItemOrder (string $ section , array $ items, array $ reorder ): void
476484 {
485+ // Get unconfigured item IDs...
486+ $ unconfiguredItemIds = collect ($ this ->items )
487+ ->filter (fn ($ item ) => $ item ->section () === $ section )
488+ ->map
489+ ->id ();
490+
477491 // Generate IDs for newly created items...
478- $ itemIds = collect ($ items )
492+ $ createdItemIds = collect ($ items )
479493 ->map (function ($ item , $ id ) use ($ section , $ items ) {
480494 return $ items [$ id ]['action ' ] === '@create '
481495 ? $ this ->generateNewItemId ($ section , $ items [$ id ]['display ' ])
482496 : $ id ;
483497 })
484498 ->values ();
485499
486- // Get unconfigured item IDs...
487- $ unconfiguredItemIds = collect ($ this ->items )
488- ->filter (fn ($ item ) => $ item ->section () === $ section )
489- ->map
490- ->id ();
491-
492500 // Merge unconfigured items into the end of the list...
493- $ itemIds = $ itemIds
494- ->values ()
501+ $ itemIds = collect ()
495502 ->merge ($ unconfiguredItemIds )
503+ ->merge ($ createdItemIds )
496504 ->unique ()
497- ->values ();
505+ ->flip ();
506+
507+ // Reorder to match `$reorder` config...
508+ collect ($ reorder )
509+ ->reverse ()
510+ ->each (fn ($ key ) => $ itemIds ->prepend ($ itemIds ->pull ($ key ), $ key ));
498511
499512 // Set an explicit order value on each item...
500513 $ itemIds
514+ ->flip ()
501515 ->map (fn ($ id ) => $ this ->findItem ($ id , false ))
502516 ->filter ()
517+ ->values ()
503518 ->each (fn ($ item , $ index ) => $ item ->order ($ index + 1 ));
504519
505520 // Inform builder that section items should be ordered...
@@ -671,29 +686,29 @@ protected function userModifyItem($item, $config, $section)
671686 ->reject (fn ($ value , $ setter ) => in_array ($ setter , ['children ' , 'reorder ' ]))
672687 ->each (fn ($ value , $ setter ) => $ item ->{$ setter }($ value ));
673688
674- if ($ children = $ config ->get ('children ' )) {
675- $ this ->userModifyItemChildren ($ item , $ children , $ section , $ config ->get ('reorder ' ));
689+ $ childrenConfig = $ config ->get ('children ' );
690+ $ reorder = $ config ->get ('reorder ' );
691+
692+ if ($ childrenConfig || $ reorder ) {
693+ $ this ->userModifyItemChildren ($ item , $ childrenConfig , $ section , $ reorder );
676694 }
677695
678696 return $ item ;
679697 }
680698
681699 /**
682700 * Modify NavItem children.
683- *
684- * @param \Statamic\CP\Navigation\NavItem $item
685- * @param array $childrenOverrides
686- * @param string $section
687- * @return \Illuminate\Support\Collection
688701 */
689- protected function userModifyItemChildren ($ item , $ childrenOverrides , $ section , $ reorder )
702+ protected function userModifyItemChildren (NavItem $ item , ? array $ childrenConfig , string $ section , ? array $ reorder ): void
690703 {
704+ // Get original item children...
691705 $ itemChildren = collect ($ item ->original ()->resolveChildren ()->children ())
692706 ->each (fn ($ item , $ index ) => $ item ->order ($ index + 1000 ))
693707 ->keyBy
694708 ->id ();
695709
696- collect ($ childrenOverrides )
710+ // Apply children preferences from config...
711+ collect ($ childrenConfig )
697712 ->map (fn ($ config , $ key ) => $ this ->userModifyChild ($ config , $ section , $ key , $ item ))
698713 ->each (function ($ item , $ key ) use (&$ itemChildren ) {
699714 $ item
@@ -704,18 +719,25 @@ protected function userModifyItemChildren($item, $childrenOverrides, $section, $
704719 ->values ()
705720 ->each (fn ($ item , $ index ) => $ item ->order ($ index + 1 ));
706721
707- $ newChildren = $ reorder
708- ? $ itemChildren ->sortBy (fn ($ item ) => $ item ->order ())->values ()
709- : $ itemChildren ->values ();
722+ // Reorder to match `$reorder` config...
723+ if ($ reorder ) {
724+ collect ($ reorder )
725+ ->reverse ()
726+ ->each (fn ($ key ) => $ itemChildren ->prepend ($ itemChildren ->pull ($ key ), $ key ));
727+ }
710728
711- $ newChildren ->each (fn ($ item , $ index ) => $ item ->order ($ index + 1 ));
729+ // Update final `order`...
730+ $ itemChildren
731+ ->sortBy (fn ($ item ) => $ item ->order ())->values ()
732+ ->values ()
733+ ->each (fn ($ item , $ index ) => $ item ->order ($ index + 1 ));
734+
735+ $ item ->children ($ itemChildren , false );
712736
713737 $ item ->children (
714- items: $ newChildren ,
738+ items: $ itemChildren ,
715739 generateNewIds: false ,
716740 );
717-
718- return $ newChildren ;
719741 }
720742
721743 /**
0 commit comments