Skip to content

Commit 0311008

Browse files
committed
wp-cli#5047: reorder menu items after insert and delete commands
1 parent 952742d commit 0311008

File tree

1 file changed

+38
-8
lines changed

1 file changed

+38
-8
lines changed

src/Menu_Item_Command.php

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -369,19 +369,28 @@ public function delete( $args, $assoc_args ) {
369369

370370
foreach ( $args as $arg ) {
371371

372+
$post = get_post($arg);
373+
$menu_term = get_the_terms($arg, 'nav_menu');
372374
$parent_menu_id = (int) get_post_meta( $arg, '_menu_item_menu_item_parent', true );
373375
$result = wp_delete_post( $arg, true );
374376
if ( ! $result ) {
375377
WP_CLI::warning( "Couldn't delete menu item {$arg}." );
376378
$errors++;
377-
} elseif ( $parent_menu_id ) {
378-
$children = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_menu_item_menu_item_parent' AND meta_value=%s", (int) $arg ) );
379-
if ( $children ) {
380-
$children_query = $wpdb->prepare( "UPDATE $wpdb->postmeta SET meta_value = %d WHERE meta_key = '_menu_item_menu_item_parent' AND meta_value=%s", $parent_menu_id, (int) $arg );
381-
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $children_query is already prepared above.
382-
$wpdb->query( $children_query );
383-
foreach ( $children as $child ) {
384-
clean_post_cache( $child );
379+
} else {
380+
381+
if ( is_array($menu_term) && !empty($menu_term) && $post ) {
382+
$this->reorder_menu_items( $menu_term[0]->term_id, $post->menu_order, -1, 0 );
383+
}
384+
385+
if ( $parent_menu_id ) {
386+
$children = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_menu_item_menu_item_parent' AND meta_value=%s", (int) $arg ) );
387+
if ( $children ) {
388+
$children_query = $wpdb->prepare( "UPDATE $wpdb->postmeta SET meta_value = %d WHERE meta_key = '_menu_item_menu_item_parent' AND meta_value=%s", $parent_menu_id, (int) $arg );
389+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $children_query is already prepared above.
390+
$wpdb->query( $children_query );
391+
foreach ( $children as $child ) {
392+
clean_post_cache( $child );
393+
}
385394
}
386395
}
387396
}
@@ -477,6 +486,10 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) {
477486
}
478487
} else {
479488

489+
if ( 'add' === $method ) {
490+
$this->reorder_menu_items( $menu->term_id, $menu_item_args['menu-item-position'], +1, $result );
491+
}
492+
480493
/**
481494
* Set the menu
482495
*
@@ -503,6 +516,23 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) {
503516

504517
}
505518

519+
/**
520+
* Move block of items in one nav_menu up or down by incrementing/decrementing their menu_order field.
521+
* Expects the menu items to have proper menu_orders (i.e. doesn't fix errors from previous incorrect operations).
522+
*
523+
* @param int $menu_id ID of the nav_menu
524+
* @param int $min_position minimal menu_order to touch
525+
* @param int $increment how much to change menu_order: +1 to move down, -1 to move up
526+
* @param int $ignore_item_id menu item that should be ignored by the change (e.g. newly created menu item)
527+
* @return int number of rows affected
528+
*/
529+
private function reorder_menu_items( $menu_id, $min_position, $increment, $ignore_item_id = 0 )
530+
{
531+
global $wpdb;
532+
$reorder_query = $wpdb->prepare( "UPDATE $wpdb->posts SET `menu_order`=`menu_order`+(%d) WHERE `menu_order`>=%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) $menu_id, (int) $ignore_item_id );
533+
return $wpdb->query( $reorder_query );
534+
}
535+
506536
protected function get_formatter( &$assoc_args ) {
507537
return new Formatter( $assoc_args, $this->obj_fields );
508538
}

0 commit comments

Comments
 (0)