Drop the "group by post type" in search results

オープン
#1,045 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
50/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
php
領域
backend

調査の方向性

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.

索引モデルが issue の本文から書いたものです。

説明

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'];
 			}
 

主要言語
PHP
スター
947
フォーク
198
PR マージ指標
30日以内にマージされた PR はありません

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

AdvancedCustomFields/acf のほかの issue

AdvancedCustomFields/acf の issue をすべて見る

似ている issue

PHP の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。