Skip to content

Commit d1110f1

Browse files
Copilotswissspidy
andcommitted
Fix position update: reorder items before wp_update_nav_menu_item call
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
1 parent e175a73 commit d1110f1

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

src/Menu_Item_Command.php

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -572,8 +572,6 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) {
572572
// `url` is protected in WP-CLI, so we use `link` instead
573573
$assoc_args['url'] = Utils\get_flag_value( $assoc_args, 'link' );
574574

575-
$old_position = 0;
576-
577575
// Need to persist the menu item data. See https://core.trac.wordpress.org/ticket/28138
578576
if ( 'update' === $method ) {
579577

@@ -637,7 +635,23 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) {
637635
}
638636

639637
$menu_item_args['menu-item-type'] = $type;
640-
$result = wp_update_nav_menu_item( $menu->term_id, $menu_item_db_id, $menu_item_args );
638+
639+
// Reorder other menu items before updating the current one.
640+
// The item being moved is at $old_position, which is never inside the affected
641+
// range ([new, old-1] for moving up or [old+1, new] for moving down), so no
642+
// exclusion of the item itself is necessary.
643+
if ( 'update' === $method ) {
644+
$new_position = (int) $menu_item_args['menu-item-position'];
645+
if ( $new_position > 0 && $new_position !== $old_position ) {
646+
if ( $new_position < $old_position ) {
647+
$this->reorder_menu_items_in_range( $menu->term_id, $new_position, $old_position - 1, +1 );
648+
} else {
649+
$this->reorder_menu_items_in_range( $menu->term_id, $old_position + 1, $new_position, -1 );
650+
}
651+
}
652+
}
653+
654+
$result = wp_update_nav_menu_item( $menu->term_id, $menu_item_db_id, $menu_item_args );
641655

642656
if ( is_wp_error( $result ) ) {
643657
WP_CLI::error( $result->get_error_message() );
@@ -651,15 +665,6 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) {
651665

652666
if ( ( 'add' === $method ) && $menu_item_args['menu-item-position'] ) {
653667
$this->reorder_menu_items( $menu->term_id, $menu_item_args['menu-item-position'], +1, $result );
654-
} elseif ( 'update' === $method ) {
655-
$new_position = (int) $menu_item_args['menu-item-position'];
656-
if ( $new_position > 0 && $new_position !== $old_position ) {
657-
if ( $new_position < $old_position ) {
658-
$this->reorder_menu_items_in_range( $menu->term_id, $new_position, $old_position - 1, +1, $result );
659-
} else {
660-
$this->reorder_menu_items_in_range( $menu->term_id, $old_position + 1, $new_position, -1, $result );
661-
}
662-
}
663668
}
664669

665670
/**
@@ -708,12 +713,11 @@ private function reorder_menu_items( $menu_id, $min_position, $increment, $ignor
708713
* @param int $min_position minimal menu_order to touch (inclusive)
709714
* @param int $max_position maximal menu_order to touch (inclusive)
710715
* @param int $increment how much to change menu_order: +1 to move down, -1 to move up
711-
* @param int $ignore_item_id menu item that should be ignored by the change (e.g. the updated menu item)
712716
* @return int|false number of rows affected, or false on failure
713717
*/
714-
private function reorder_menu_items_in_range( $menu_id, $min_position, $max_position, $increment, $ignore_item_id = 0 ) {
718+
private function reorder_menu_items_in_range( $menu_id, $min_position, $max_position, $increment ) {
715719
global $wpdb;
716-
return $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET `menu_order`=`menu_order`+(%d) WHERE `menu_order` BETWEEN %d AND %d AND ID IN (SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id=%d) AND ID<>%d", (int) $increment, (int) $min_position, (int) $max_position, (int) $menu_id, (int) $ignore_item_id ) );
720+
return $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET `menu_order`=`menu_order`+(%d) WHERE `menu_order` BETWEEN %d AND %d AND ID IN (SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id=%d)", (int) $increment, (int) $min_position, (int) $max_position, (int) $menu_id ) );
717721
}
718722

719723
protected function get_formatter( &$assoc_args ) {

0 commit comments

Comments
 (0)