Menus: Reset menu_item_parent to 0 when the parent is set to the item itself.

Props: peterwilsoncc, SergeyBiryukov, azaozz.
Fixes #57169.

git-svn-id: https://develop.svn.wordpress.org/trunk@54973 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Ozz
2022-12-14 22:52:11 +00:00
parent c317dc59ce
commit 9d6a0a3513
3 changed files with 54 additions and 0 deletions

View File

@@ -117,6 +117,10 @@ switch ( $action ) {
if ( ! is_wp_error( $parent_object ) ) {
$parent_data = (array) $parent_object;
$menu_item_data['menu_item_parent'] = $parent_data['menu_item_parent'];
// Reset invalid `menu_item_parent`.
$menu_item_data = _wp_reset_invalid_menu_item_parent( $menu_item_data );
update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
}
@@ -126,6 +130,10 @@ switch ( $action ) {
$menu_item_data['menu_order'] = $menu_item_data['menu_order'] + 1;
$menu_item_data['menu_item_parent'] = $next_item_data['ID'];
// Reset invalid `menu_item_parent`.
$menu_item_data = _wp_reset_invalid_menu_item_parent( $menu_item_data );
update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
wp_update_post( $menu_item_data );
@@ -137,6 +145,10 @@ switch ( $action ) {
&& in_array( (int) $menu_item_data['menu_item_parent'], $orders_to_dbids, true )
) {
$menu_item_data['menu_item_parent'] = (int) get_post_meta( $menu_item_data['menu_item_parent'], '_menu_item_menu_item_parent', true );
// Reset invalid `menu_item_parent`.
$menu_item_data = _wp_reset_invalid_menu_item_parent( $menu_item_data );
update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
}
}
@@ -247,6 +259,10 @@ switch ( $action ) {
) {
// Just make it a child of the previous; keep the order.
$menu_item_data['menu_item_parent'] = (int) $orders_to_dbids[ $dbids_to_orders[ $menu_item_id ] - 1 ];
// Reset invalid `menu_item_parent`.
$menu_item_data = _wp_reset_invalid_menu_item_parent( $menu_item_data );
update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
wp_update_post( $menu_item_data );
}

View File

@@ -199,6 +199,11 @@ function wp_nav_menu( $args = array() ) {
$menu_items_tree = array();
$menu_items_with_children = array();
foreach ( (array) $menu_items as $menu_item ) {
// Fix invalid `menu_item_parent`. See: https://core.trac.wordpress.org/ticket/56926.
if ( (int) $menu_item->ID === (int) $menu_item->menu_item_parent ) {
$menu_item->menu_item_parent = 0;
}
$sorted_menu_items[ $menu_item->menu_order ] = $menu_item;
$menu_items_tree[ $menu_item->ID ] = $menu_item->menu_item_parent;
if ( $menu_item->menu_item_parent ) {

View File

@@ -563,6 +563,11 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item
$menu_item_db_id = (int) $menu_item_db_id;
// Reset invalid `menu_item_parent`.
if ( (int) $args['menu-item-parent-id'] === $menu_item_db_id ) {
$args['menu-item-parent-id'] = 0;
}
update_post_meta( $menu_item_db_id, '_menu_item_type', sanitize_key( $args['menu-item-type'] ) );
update_post_meta( $menu_item_db_id, '_menu_item_menu_item_parent', (string) ( (int) $args['menu-item-parent-id'] ) );
update_post_meta( $menu_item_db_id, '_menu_item_object_id', (string) ( (int) $args['menu-item-object-id'] ) );
@@ -1273,3 +1278,31 @@ function wp_map_nav_menu_locations( $new_nav_menu_locations, $old_nav_menu_locat
return $new_nav_menu_locations;
}
/**
* Prevents menu items from being their own parent.
*
* Resets menu_item_parent to 0 when the parent is set to the item itself.
* For use before saving `_menu_item_menu_item_parent` in nav-menus.php.
*
* @since 6.1.2
* @access private
*
* @param array $menu_item_data The menu item data array.
* @return array The menu item data with reset menu_item_parent.
*/
function _wp_reset_invalid_menu_item_parent( $menu_item_data ) {
if ( ! is_array( $menu_item_data ) ) {
return $menu_item_data;
}
if (
! empty( $menu_item_data['ID'] ) &&
! empty( $menu_item_data['menu_item_parent'] ) &&
(int) $menu_item_data['ID'] === (int) $menu_item_data['menu_item_parent']
) {
$menu_item_data['menu_item_parent'] = 0;
}
return $menu_item_data;
}