From 28eaeaed408703fd5f86907778d28de12ae07f73 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Tue, 30 May 2023 11:19:41 +0000 Subject: [PATCH] Menus: Add a short-circuit filter to `wp_setup_nav_menu_item()`. Props: davidbinda, ironprogrammer, andizer. Fixes: #56577. git-svn-id: https://develop.svn.wordpress.org/trunk@55867 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/nav-menu.php | 16 ++++++++ tests/phpunit/tests/post/nav-menu.php | 55 ++++++++++++++++++++++----- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/wp-includes/nav-menu.php b/src/wp-includes/nav-menu.php index df22279fca..cb49f2b38c 100644 --- a/src/wp-includes/nav-menu.php +++ b/src/wp-includes/nav-menu.php @@ -820,6 +820,22 @@ function update_menu_item_cache( $menu_items ) { * @return object The menu item with standard menu item properties. */ function wp_setup_nav_menu_item( $menu_item ) { + + /** + * Short-circuit the wp_setup_nav_menu_item() output. + * + * Returning a non-null value from the filter will short-circuit wp_setup_nav_menu_item(), + * and return that value. + * + * @param object|null $modified_menu_item Modified menu item. Default null. + * @param object $menu_item The menu item to modify. + */ + $pre_menu_item = apply_filters( 'pre_wp_setup_nav_menu_item', null, $menu_item ); + + if ( null !== $pre_menu_item ) { + return $pre_menu_item; + } + if ( isset( $menu_item->post_type ) ) { if ( 'nav_menu_item' === $menu_item->post_type ) { $menu_item->db_id = (int) $menu_item->ID; diff --git a/tests/phpunit/tests/post/nav-menu.php b/tests/phpunit/tests/post/nav-menu.php index 5a0efcbde1..0768e09666 100644 --- a/tests/phpunit/tests/post/nav-menu.php +++ b/tests/phpunit/tests/post/nav-menu.php @@ -1216,7 +1216,8 @@ class Tests_Post_Nav_Menu extends WP_UnitTestCase { 'menu-item-status' => 'publish', ) ); - $post = get_post( $menu_item_id ); + + $post = get_post( $menu_item_id ); $this->assertEqualsWithDelta( strtotime( gmdate( 'Y-m-d H:i:s' ) ), strtotime( $post->post_date ), 2, 'The dates should be equal' ); $menu_item_id = wp_update_nav_menu_item( @@ -1230,7 +1231,8 @@ class Tests_Post_Nav_Menu extends WP_UnitTestCase { 'menu-item-post-date-gmt' => $post_date_gmt, ) ); - $post = get_post( $menu_item_id ); + + $post = get_post( $menu_item_id ); $this->assertSame( get_date_from_gmt( $post_date_gmt ), $post->post_date ); $menu_item_id = wp_update_nav_menu_item( @@ -1244,7 +1246,8 @@ class Tests_Post_Nav_Menu extends WP_UnitTestCase { 'menu-item-post-date-gmt' => $invalid_date, ) ); - $post = get_post( $menu_item_id ); + + $post = get_post( $menu_item_id ); $this->assertSame( '1970-01-01 00:00:00', $post->post_date ); $menu_item_id = wp_update_nav_menu_item( @@ -1258,7 +1261,8 @@ class Tests_Post_Nav_Menu extends WP_UnitTestCase { 'menu-item-post-date' => $post_date, ) ); - $post = get_post( $menu_item_id ); + + $post = get_post( $menu_item_id ); $this->assertSame( $post_date, $post->post_date ); $menu_item_id = wp_update_nav_menu_item( @@ -1273,7 +1277,8 @@ class Tests_Post_Nav_Menu extends WP_UnitTestCase { 'menu-item-post-date-gmt' => $post_date_gmt, ) ); - $post = get_post( $menu_item_id ); + + $post = get_post( $menu_item_id ); $this->assertSame( $post_date, $post->post_date ); $menu_item_id = wp_update_nav_menu_item( @@ -1288,7 +1293,8 @@ class Tests_Post_Nav_Menu extends WP_UnitTestCase { 'menu-item-post-date-gmt' => $invalid_date, ) ); - $post = get_post( $menu_item_id ); + + $post = get_post( $menu_item_id ); $this->assertSame( $post_date, $post->post_date ); $menu_item_id = wp_update_nav_menu_item( @@ -1302,7 +1308,8 @@ class Tests_Post_Nav_Menu extends WP_UnitTestCase { 'menu-item-post-date' => $invalid_date, ) ); - $post = get_post( $menu_item_id ); + + $post = get_post( $menu_item_id ); $this->assertEqualsWithDelta( strtotime( gmdate( 'Y-m-d H:i:s' ) ), strtotime( $post->post_date ), 2, 'The dates should be equal' ); $menu_item_id = wp_update_nav_menu_item( @@ -1317,7 +1324,8 @@ class Tests_Post_Nav_Menu extends WP_UnitTestCase { 'menu-item-post-date-gmt' => $post_date_gmt, ) ); - $post = get_post( $menu_item_id ); + + $post = get_post( $menu_item_id ); $this->assertEqualsWithDelta( strtotime( gmdate( 'Y-m-d H:i:s' ) ), strtotime( $post->post_date ), 2, 'The dates should be equal' ); $menu_item_id = wp_update_nav_menu_item( @@ -1332,7 +1340,36 @@ class Tests_Post_Nav_Menu extends WP_UnitTestCase { 'menu-item-post-date-gmt' => $invalid_date, ) ); - $post = get_post( $menu_item_id ); + + $post = get_post( $menu_item_id ); $this->assertEqualsWithDelta( strtotime( gmdate( 'Y-m-d H:i:s' ) ), strtotime( $post->post_date ), 2, 'The dates should be equal' ); } + + /** + * @ticket 56577 + */ + public function test_nav_menu_item_short_circuit_filter() { + // Create a nav menu item. + $menu_item_args = array( + 'menu-item-type' => 'custom', + 'menu-item-title' => 'Wordpress.org', + 'menu-item-url' => 'http://wordpress.org', + 'menu-item-status' => 'publish', + ); + + $custom_item_id = wp_update_nav_menu_item( 0, 0, $menu_item_args ); + + $pre_setup_callback = function() { + return '--empty nav menu item--'; + }; + + add_filter( 'pre_wp_setup_nav_menu_item', $pre_setup_callback ); + + // Confirm the short-circuit. + $custom_item = wp_setup_nav_menu_item( get_post( $custom_item_id ) ); + $this->assertSame( '--empty nav menu item--', $custom_item ); + + remove_filter( 'pre_wp_setup_nav_menu_item', $pre_setup_callback ); + } + }