From a828890ce257a9e2ba2e5d6c298391c70ea3fb51 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Wed, 5 Jul 2017 21:30:30 +0000 Subject: [PATCH] Menus: Make sure `current-menu-parent` and `current-menu-ancestor` classes are properly set for parent items of post type archive submenu items. Props mrwweb, ajoah, welcher. Fixes #39800. git-svn-id: https://develop.svn.wordpress.org/trunk@41008 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/nav-menu-template.php | 11 +++++ tests/phpunit/tests/post/nav-menu.php | 59 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/src/wp-includes/nav-menu-template.php b/src/wp-includes/nav-menu-template.php index f6a38e8b67..5b49937890 100644 --- a/src/wp-includes/nav-menu-template.php +++ b/src/wp-includes/nav-menu-template.php @@ -394,6 +394,17 @@ function _wp_menu_item_classes_by_context( &$menu_items ) { ) { $classes[] = 'current-menu-item'; $menu_items[$key]->current = true; + $_anc_id = (int) $menu_item->db_id; + + while( + ( $_anc_id = get_post_meta( $_anc_id, '_menu_item_menu_item_parent', true ) ) && + ! in_array( $_anc_id, $active_ancestor_item_ids ) + ) { + $active_ancestor_item_ids[] = $_anc_id; + } + + $active_parent_item_ids[] = (int) $menu_item->menu_item_parent; + // if the menu item corresponds to the currently-requested URL } elseif ( 'custom' == $menu_item->object && isset( $_SERVER['HTTP_HOST'] ) ) { $_root_relative_current = untrailingslashit( $_SERVER['REQUEST_URI'] ); diff --git a/tests/phpunit/tests/post/nav-menu.php b/tests/phpunit/tests/post/nav-menu.php index c6a028cdad..91a68ce64a 100644 --- a/tests/phpunit/tests/post/nav-menu.php +++ b/tests/phpunit/tests/post/nav-menu.php @@ -553,4 +553,63 @@ class Test_Nav_Menus extends WP_UnitTestCase { $this->assertNotInstanceOf( 'WP_Post', get_post( $nav_created_post_ids[0] ) ); $this->assertNotInstanceOf( 'WP_Post', get_post( $nav_created_post_ids[1] ) ); } + + /** + * @ticket 39800 + */ + function test_parent_ancestor_for_post_archive() { + + register_post_type( 'books', array( 'label' => 'Books', 'public' => true, 'has_archive' => true ) ); + + $first_page_id = self::factory()->post->create( array( 'post_type' => 'page', 'post_title' => 'Top Level Page' ) ); + $second_page_id = self::factory()->post->create( array( 'post_type' => 'page', 'post_title' => 'Second Level Page' ) ); + + + $first_menu_id = wp_update_nav_menu_item( $this->menu_id, 0, array( + 'menu-item-type' => 'post_type', + 'menu-item-object' => 'page', + 'menu-item-object-id' => $first_page_id, + 'menu-item-status' => 'publish', + )); + + $second_menu_id = wp_update_nav_menu_item( $this->menu_id, 0, array( + 'menu-item-type' => 'post_type', + 'menu-item-object' => 'page', + 'menu-item-object-id' => $second_page_id, + 'menu-item-status' => 'publish', + 'menu-item-parent-id' => $first_menu_id + )); + + wp_update_nav_menu_item( $this->menu_id, 0, array( + 'menu-item-type' => 'post_type_archive', + 'menu-item-object' => 'books', + 'menu-item-status' => 'publish', + 'menu-item-parent-id' => $second_menu_id + )); + + $this->go_to( get_post_type_archive_link( 'books' ) ); + + $menu_items = wp_get_nav_menu_items( $this->menu_id ); + _wp_menu_item_classes_by_context( $menu_items ); + + $top_page_menu_item = $menu_items[0]; + $secondary_page_menu_item = $menu_items[1]; + $post_archive_menu_item = $menu_items[2]; + + $this->assertFalse( $top_page_menu_item->current_item_parent ); + $this->assertTrue( $top_page_menu_item->current_item_ancestor ); + $this->assertContains( 'current-menu-ancestor', $top_page_menu_item->classes ); + + $this->assertTrue( $secondary_page_menu_item->current_item_parent ); + $this->assertTrue( $secondary_page_menu_item->current_item_ancestor ); + $this->assertContains( 'current-menu-parent', $secondary_page_menu_item->classes ); + $this->assertContains( 'current-menu-ancestor', $secondary_page_menu_item->classes ); + + $this->assertFalse( $post_archive_menu_item->current_item_parent ); + $this->assertFalse( $post_archive_menu_item->current_item_ancestor ); + + $this->assertNotContains( 'current-menu-parent', $post_archive_menu_item->classes ); + $this->assertNotContains( 'current-menu-ancestor', $post_archive_menu_item->classes ); + } + }