Drop the "group by post type" in search results

Đang mở
#1,045 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
50/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
php
Lĩnh vực
backend

Hướng nghiên cứu

Start with acf_get_grouped_posts() in includes/api/api-helpers.php, where the search query's orderby and the _acf_orderby_post_type filter are applied, then with the search branch of the relationship field's AJAX query in includes/fields/class-acf-field-relationship.php. Reproduce by searching a relationship field across several post types and checking that results are grouped. Done when a search returns title matches first in a flat list, and the existing grouped behaviour still works for browsing.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Describe the bug
A clear and concise description of what the bug is.

The grouping by post type makes it near impossible to find content in very large sites through the search feature in fields like the relationship field.

Instead of surfacing a title match, the results will always first show much weaker matcher in post types that happen to appear earlier.

To Reproduce
Steps to reproduce the behavior:

  1. Have a large site with many post types
  2. Have a relationship field that allows content from multiple post types
  3. Try searching for an exact title match for something that has a post type that isn't one of the earliest when sorting types.
  4. You will see much weaker matches, i.e. individual terms matched in body content.
  5. You need to scroll through all the weaker matches before finding your exact title match

Expected behavior
A clear and concise description of what you expected to happen.

I expect search to surface title matches first.

Version Information:

  • WordPress Version 6.9
  • PHP Version 8.4
  • ACF Version latest

Suggested fix

diff --git a/includes/api/api-helpers.php b/includes/api/api-helpers.php
index c45f733b75..8a84c66f0e 100644
--- a/includes/api/api-helpers.php
+++ b/includes/api/api-helpers.php
@@ -1291,7 +1291,7 @@ function acf_get_grouped_posts( $args ) {
 			'posts_per_page'         => -1,
 			'paged'                  => 0,
 			'post_type'              => 'post',
-			'orderby'                => 'menu_order title',
+			'orderby'                => empty( $args['s'] ) ? 'menu_order title' : 'relevance',
 			'order'                  => 'ASC',
 			'post_status'            => 'any',
 			'suppress_filters'       => false,
@@ -1364,7 +1364,7 @@ function acf_get_grouped_posts( $args ) {
 	}
 
 	// add filter to orderby post type
-	if ( ! $is_single_post_type ) {
+	if ( ! $is_single_post_type && empty( $args['s'] ) ) {
 		add_filter( 'posts_orderby', '_acf_orderby_post_type', 10, 2 );
 	}
 
@@ -1372,10 +1372,30 @@ function acf_get_grouped_posts( $args ) {
 	$posts = get_posts( $args );
 
 	// remove this filter (only once)
-	if ( ! $is_single_post_type ) {
+	if ( ! $is_single_post_type && empty( $args['s'] ) ) {
 		remove_filter( 'posts_orderby', '_acf_orderby_post_type', 10, 2 );
 	}
 
+	/*
+	 * Optionally return every post as a single group, keyed by the caller supplied
+	 * label, instead of one group per post type. Grouping partitions the results by
+	 * post type, which discards the ordering the query itself established, so search
+	 * callers that care about relevance (rather than browsing by type) opt out.
+	 */
+	if ( ! empty( $args['acf_flat'] ) ) {
+		$this_group = array();
+
+		foreach ( $posts as $post ) {
+			$this_group[ $post->ID ] = $post;
+		}
+
+		if ( ! empty( $this_group ) ) {
+			$data[ $args['acf_flat'] ] = $this_group;
+		}
+
+		return $data;
+	}
+
 	// loop
 	foreach ( $post_types as $post_type ) {
 
diff --git a/includes/fields/class-acf-field-relationship.php b/includes/fields/class-acf-field-relationship.php
index 880175091f..0defe08314 100644
--- a/includes/fields/class-acf-field-relationship.php
+++ b/includes/fields/class-acf-field-relationship.php
@@ -266,6 +266,15 @@ if ( ! class_exists( 'acf_field_relationship' ) ) :
 			// Re-normalize in case a filter reset `post_status` to 'any' while leaving `perm=readable`.
 			$args = acf_ensure_perm_readable_post_status( $args );
 
+			/*
+			 * While searching, skip the per post type grouping so that results stay in
+			 * the order the query returned them (relevance), rather than being split
+			 * into post type groups that each get their own optgroup heading.
+			 */
+			if ( $is_search ) {
+				$args['acf_flat'] = 'search';
+			}
+
 			// get posts grouped by post type
 			$groups = acf_get_grouped_posts( $args );
 
@@ -306,7 +315,7 @@ if ( ! class_exists( 'acf_field_relationship' ) ) :
 			}
 
 			// add as optgroup or results
-			if ( count( $args['post_type'] ) === 1 ) {
+			if ( count( $args['post_type'] ) === 1 || ! empty( $args['acf_flat'] ) ) {
 				$results = $results[0]['children'];
 			}
 

Ngôn ngữ chính
PHP
Star
947
Fork
198
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của AdvancedCustomFields/acf

Tất cả issue của AdvancedCustomFields/acf

Issue tương tự

Thêm issue về PHP

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.