From bf7ff5c807574a2123abb2457e9886f576d23e7b Mon Sep 17 00:00:00 2001 From: Nilambar Sharma Date: Wed, 14 Feb 2024 13:14:43 +0545 Subject: [PATCH] Fix position in menu item update --- src/Menu_Item_Command.php | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/Menu_Item_Command.php b/src/Menu_Item_Command.php index c61d9f7d..64ee83ce 100644 --- a/src/Menu_Item_Command.php +++ b/src/Menu_Item_Command.php @@ -488,6 +488,12 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { $this->reorder_menu_items( $menu->term_id, $menu_item_args['menu-item-position'], +1, $result ); } + $position_value = Utils\get_flag_value( $assoc_args, 'position' ); + + if ( 'update' === $method && ! empty( $position_value ) ) { + $this->update_menu_item_position( $menu->term_id, $menu_item_db_id, $position_value ); + } + /** * Set the menu * @@ -511,6 +517,47 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { } } + /** + * Update menu items positions. + * + * @param int $menu_id ID of the nav_menu. + * @param int $menu_item_id Menu item ID. + * @param int $position New menu item position. + */ + private function update_menu_item_position( $menu_id, $menu_item_id, $position ) { + global $wpdb; + + $position = absint( $position ); + + // Bail if position is not numeric. + if ( 0 === $position ) { + return; + } + + $menu_items = wp_get_nav_menu_items( $menu_id ); + + $position = ( $position > count( $menu_items ) ) ? count( $menu_items ) : $position; + + $all_positions = wp_list_pluck( $menu_items, 'ID', 'menu_order' ); + + $old_key = array_search( (int) $menu_item_id, $all_positions, true ); + + // Bail if new position is same as existing. + if ( $old_key === $position ) { + return; + } + + // Remove old item from the list. + unset( $all_positions[ $old_key ] ); + + // Add ID in new position. + array_splice( $all_positions, $position - 1, 0, (int) $menu_item_id ); + + foreach ( $all_positions as $key => $id ) { + $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET `menu_order`=%s WHERE ID=%s", ( $key + 1 ), $id ) ); + } + } + /** * Move block of items in one nav_menu up or down by incrementing/decrementing their menu_order field. * Expects the menu items to have proper menu_orders (i.e. doesn't fix errors from previous incorrect operations).