From 179e7cfd8c1b9628d0108f678cd23ce68523386a Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Sun, 19 Oct 2025 16:28:11 -0500 Subject: [PATCH 1/7] Alternate solution for 48655 --- src/wp-admin/includes/nav-menu.php | 38 +++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/wp-admin/includes/nav-menu.php b/src/wp-admin/includes/nav-menu.php index d63f10100752b..0a9bc47b79dda 100644 --- a/src/wp-admin/includes/nav-menu.php +++ b/src/wp-admin/includes/nav-menu.php @@ -83,16 +83,36 @@ function _wp_ajax_menu_quick_search( $request = array() ) { } elseif ( preg_match( '/quick-search-(posttype|taxonomy)-([a-zA-Z0-9_-]*\b)/', $type, $matches ) ) { if ( 'posttype' === $matches[1] && get_post_type_object( $matches[2] ) ) { $post_type_obj = _wp_nav_menu_meta_box_object( get_post_type_object( $matches[2] ) ); - $args = array_merge( + $query_args = array( + 'no_found_rows' => true, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'posts_per_page' => 10, + 'post_type' => $matches[2], + 's' => $query, + 'search_columns' => array( 'post_title' ), + ); + /** + * Filter the menu quick search arguments. + * + * @since 6.9.0 + * + * @param array $args { + * Menu quick search arguments. + * + * @type boolean $no_found_rows Whether to return found rows data. Default true. + * @type boolean $update_post_meta_cache Whether to update post meta cache. Default false. + * @type boolean $update_post_term_cache Whether to update post term cache. Default false. + * @type int $posts_per_page Number of posts to return. Default 10. + * @type string $post_type Type of post to return. + * @type string $s Search query. + * @type array $search_columns Which post table columns to query. + * } + */ + $query_args = apply_filters( 'wp_ajax_menu_quick_search_args', $args ); + $args = array_merge( $args, - array( - 'no_found_rows' => true, - 'update_post_meta_cache' => false, - 'update_post_term_cache' => false, - 'posts_per_page' => 10, - 'post_type' => $matches[2], - 's' => $query, - ) + $query_args ); if ( isset( $post_type_obj->_default_query ) ) { From e124460d529769c58b410c0fe87958e92f9ef344 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Sun, 19 Oct 2025 16:58:28 -0500 Subject: [PATCH 2/7] Change tests so they have the right data for quick search to work --- tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php b/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php index f1ada20719e91..994e224485faa 100644 --- a/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php +++ b/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php @@ -18,12 +18,14 @@ public function test_search_returns_results_for_pages() { array( 'post_type' => 'page', 'post_content' => 'foo', + 'post_title' => 'foo', ) ); self::factory()->post->create( array( 'post_type' => 'page', 'post_content' => 'bar', + 'post_title' => 'bar', ) ); @@ -132,7 +134,7 @@ public function test_search_returns_post_types_with_numeric_slugs() { self::factory()->post->create( array( - 'post_title' => 'Post Title 123', + 'post_title' => 'Post Title 123 FOO', 'post_type' => 'wptests_123', 'post_status' => 'publish', 'post_content' => 'FOO', From 02821ce395356754474c84325f4d06dd394881a0 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Sun, 19 Oct 2025 17:26:35 -0500 Subject: [PATCH 3/7] Update wpAjaxMenuQuickSearch.php --- tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php b/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php index 994e224485faa..64b01c98927ae 100644 --- a/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php +++ b/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php @@ -18,14 +18,14 @@ public function test_search_returns_results_for_pages() { array( 'post_type' => 'page', 'post_content' => 'foo', - 'post_title' => 'foo', + 'post_title' => 'foo title', ) ); self::factory()->post->create( array( 'post_type' => 'page', 'post_content' => 'bar', - 'post_title' => 'bar', + 'post_title' => 'bar title', ) ); @@ -57,7 +57,7 @@ public function test_search_returns_results_for_published_posts() { array( 'post_type' => 'post', 'post_status' => 'publish', - 'post_title' => 'Publish', + 'post_title' => 'Publish FOO', 'post_content' => 'FOO', ) ); From e886af161aed24eab010d3353cdf41b775724827 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Sun, 19 Oct 2025 17:38:58 -0500 Subject: [PATCH 4/7] Add missing query strings in test; fix filtered array --- src/wp-admin/includes/nav-menu.php | 2 +- tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wp-admin/includes/nav-menu.php b/src/wp-admin/includes/nav-menu.php index 0a9bc47b79dda..51cb529df8276 100644 --- a/src/wp-admin/includes/nav-menu.php +++ b/src/wp-admin/includes/nav-menu.php @@ -109,7 +109,7 @@ function _wp_ajax_menu_quick_search( $request = array() ) { * @type array $search_columns Which post table columns to query. * } */ - $query_args = apply_filters( 'wp_ajax_menu_quick_search_args', $args ); + $query_args = apply_filters( 'wp_ajax_menu_quick_search_args', $query_args ); $args = array_merge( $args, $query_args diff --git a/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php b/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php index 64b01c98927ae..d74bdafcc7d77 100644 --- a/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php +++ b/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php @@ -65,7 +65,7 @@ public function test_search_returns_results_for_published_posts() { array( 'post_type' => 'post', 'post_status' => 'draft', - 'post_title' => 'Draft', + 'post_title' => 'Draft FOO', 'post_content' => 'FOO', ) ); @@ -73,7 +73,7 @@ public function test_search_returns_results_for_published_posts() { array( 'post_type' => 'post', 'post_status' => 'pending', - 'post_title' => 'Pending', + 'post_title' => 'Pending FOO', 'post_content' => 'FOO', ) ); @@ -81,7 +81,7 @@ public function test_search_returns_results_for_published_posts() { array( 'post_type' => 'post', 'post_status' => 'future', - 'post_title' => 'Future', + 'post_title' => 'Future FOO', 'post_content' => 'FOO', 'post_date' => gmdate( 'Y-m-d H:i:s', strtotime( '+1 month' ) ), ) From a113c05e263b102af55a17322e8e3137eef9482f Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Sun, 19 Oct 2025 17:50:19 -0500 Subject: [PATCH 5/7] Add a test that verifies that only terms with search term in title return results. --- .../tests/menu/wpAjaxMenuQuickSearch.php | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php b/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php index d74bdafcc7d77..f687fc4b069c9 100644 --- a/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php +++ b/tests/phpunit/tests/menu/wpAjaxMenuQuickSearch.php @@ -42,6 +42,45 @@ public function test_search_returns_results_for_pages() { $this->assertCount( 3, $results ); } + /** + * Test that search only returns results for posts with term in title. + * + * @ticket 48655 + */ + public function test_search_only_returns_results_for_posts_with_term_in_title() { + require_once ABSPATH . 'wp-admin/includes/nav-menu.php'; + + // This will make sure that WP_Query sets is_admin to true. + set_current_screen( 'nav-menu.php' ); + + self::factory()->post->create( + array( + 'post_type' => 'post', + 'post_status' => 'publish', + 'post_title' => 'Publish FOO', + 'post_content' => 'FOO', + ) + ); + self::factory()->post->create( + array( + 'post_type' => 'post', + 'post_status' => 'publish', + 'post_title' => 'Publish without search term', + 'post_content' => 'FOO', + ) + ); + + $request = array( + 'type' => 'quick-search-posttype-post', + 'q' => 'FOO', + ); + $output = get_echo( '_wp_ajax_menu_quick_search', array( $request ) ); + + $this->assertNotEmpty( $output ); + $results = explode( "\n", trim( $output ) ); + $this->assertCount( 1, $results ); + } + /** * Test that search only returns results for published posts. * From debee54190c08d25a2556f5135ad6d3a9a8eeb94 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Mon, 20 Oct 2025 14:28:25 -0500 Subject: [PATCH 6/7] Improve nav menu search Adds wp.a11y.speak() on search results, clears results when no text. --- src/js/_enqueues/lib/nav-menu.js | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/js/_enqueues/lib/nav-menu.js b/src/js/_enqueues/lib/nav-menu.js index 666780a9e399b..79917c8447f1a 100644 --- a/src/js/_enqueues/lib/nav-menu.js +++ b/src/js/_enqueues/lib/nav-menu.js @@ -1406,14 +1406,25 @@ updateQuickSearchResults : function(input) { var panel, params, - minSearchLength = 2, - q = input.val(); + minSearchLength = 1, + q = input.val(), + pageSearchChecklist = $( '#page-search-checklist' ); /* - * Minimum characters for a search. Also avoid a new Ajax search when - * the pressed key (e.g. arrows) doesn't change the searched term. + * Avoid a new Ajax search when the pressed key (e.g. arrows) + * doesn't change the searched term. */ - if ( q.length < minSearchLength || api.lastSearch == q ) { + if ( api.lastSearch == q ) { + return; + } + + /* + * Reset results when search is less than or equal to + * minimum characters for searched term. + */ + if ( q.length <= minSearchLength ) { + pageSearchChecklist.empty(); + wp.a11y.speak( wp.i18n.__( 'Search results cleared' ) ); return; } @@ -1770,12 +1781,14 @@ $item; if( ! $items.length ) { + let noResults = wp.i18n.__( 'No results found.' ); const li = $( '
  • ' ); - const p = $( '

    ', { text: wp.i18n.__( 'No results found.' ) } ); + const p = $( '

    ', { text: noResults } ); li.append( p ); $('.categorychecklist', panel).empty().append( li ); $( '.spinner', panel ).removeClass( 'is-active' ); wrapper.addClass( 'has-no-menu-item' ); + wp.a11y.speak( noResults, 'assertive' ); return; } @@ -1802,6 +1815,7 @@ }); $('.categorychecklist', panel).html( $items ); + wp.a11y.speak( wp.i18n.sprintf( wp.i18n.__( '%d Search Results Found' ), $items.length ), 'assertive' ); $( '.spinner', panel ).removeClass( 'is-active' ); wrapper.removeClass( 'has-no-menu-item' ); From 90b00310a6832bee585b07b2a22131fa4a7f1a86 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Mon, 20 Oct 2025 14:33:22 -0500 Subject: [PATCH 7/7] Formatting post review --- src/wp-admin/includes/nav-menu.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/wp-admin/includes/nav-menu.php b/src/wp-admin/includes/nav-menu.php index 51cb529df8276..15d39dc6a9cd2 100644 --- a/src/wp-admin/includes/nav-menu.php +++ b/src/wp-admin/includes/nav-menu.php @@ -100,20 +100,17 @@ function _wp_ajax_menu_quick_search( $request = array() ) { * @param array $args { * Menu quick search arguments. * - * @type boolean $no_found_rows Whether to return found rows data. Default true. + * @type boolean $no_found_rows Whether to return found rows data. Default true. * @type boolean $update_post_meta_cache Whether to update post meta cache. Default false. * @type boolean $update_post_term_cache Whether to update post term cache. Default false. - * @type int $posts_per_page Number of posts to return. Default 10. - * @type string $post_type Type of post to return. - * @type string $s Search query. - * @type array $search_columns Which post table columns to query. + * @type int $posts_per_page Number of posts to return. Default 10. + * @type string $post_type Type of post to return. + * @type string $s Search query. + * @type array $search_columns Which post table columns to query. * } */ $query_args = apply_filters( 'wp_ajax_menu_quick_search_args', $query_args ); - $args = array_merge( - $args, - $query_args - ); + $args = array_merge( $args, $query_args ); if ( isset( $post_type_obj->_default_query ) ) { $args = array_merge( $args, (array) $post_type_obj->_default_query );