カスタムメタの検索に関する多くの投稿と質問を調べましたが、投稿を検索し、検索クエリが著者名と一致する場合はそれらも含めたいと思います。
私は次のようなコードを思い付きましたが、うまくいきません。何らかの理由で、ステータスが "revision"の投稿を返します
まず、3つの関数をそれぞれのフックにフックしました。
add_filter('posts_join', 'custom_posts_join' );
add_filter('posts_groupby', 'custom_posts_groupby' );
add_filter('posts_where', 'custom_posts_where' );
それから、それぞれの機能を進めます。
custom_posts_join
function custom_posts_join($join){
global $wpdb;
if( is_search() && !is_admin()) {
$join .= " LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id ";
}
return $join;
}
custom_posts_groupby
function custom_posts_groupby( $groupby ) {
global $wpdb;
if( is_search() && !is_admin()) {
$groupby = "$wpdb->posts.ID";
}
return $groupby;
}
custom_posts_where
function custom_posts_where( $where = '' ){
if ( is_search() && !is_admin()) {
global $wpdb;
$search = ( isset($_GET["s"]) ) ? sanitize_text_field($_GET["s"]) : false ;
$search = (string)$search;
$users = $wpdb->get_results( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = 'first_name' AND meta_value = '$search'",OBJECT_K );
foreach ($users as $user)
{
$users_ids.=$user->user_id.',';
}
$users_ids = rtrim($users_ids, ',');
$where .= " AND ( ($wpdb->posts.post_author IN ({$users_ids}))
OR ($wpdb->posts.post_title LIKE '$search')
OR ($wpdb->posts.post_content LIKE '$search') )
AND $wpdb->posts.post_type = 'post'
AND $wpdb->posts.post_status = 'publish'";
}
return $where;
}
いくつかの努力と研究の後、私はついにこの実用的な解決策を思い付きました。
このコードを改良して、代わりの答えを投稿してください。何らかの理由で、クエリが複数回実行されているようです(私の場合は3〜4回)。
ここでは、posts_search
、posts_join
およびposts_groupby
の3つのフックを使用しています
機能 custom_search_posts は、用語とユーザーを一緒に検索することを可能にします。
- ユーザーと用語を検索します。たとえば、 Money というユーザーによる投稿がある場合 Smith 。 Smith money を検索すると、結果が投稿に表示されます。注:著者名はtermよりも先にくる必要があります。
- ユーザーのみを検索(usermeta
、first_name
OR last_name
)
- 用語だけで検索する(タイトルのみ)。
- 一度に複数のユーザーを検索することもできます。
function custom_search_posts( $search, &$wp_query )
{
global $wpdb;
if ( empty( $search ) )
return $search; // exit if search is empty
$q = $wp_query->query_vars;
$n = ! empty( $q['exact'] ) ? '' : '%';
$search = '';
$searchand = '';
add_filter('posts_join', 'custom_posts_join' );
add_filter('posts_groupby', 'custom_posts_groupby' );
foreach ( (array) $q['search_terms'] as $term ) {
$user_args = array(
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'first_name',
'value' => $term,
'compare' => 'LIKE'
),
array(
'key' => 'last_name',
'value' => $term,
'compare' => 'LIKE'
)
));
$user_query = new WP_User_Query( $user_args );
$users = $user_query ->get_results();
$term = esc_sql( like_escape( $term ) );
$search .= "{$searchand} $wpdb->posts.post_title LIKE '{$n}{$term}{$n}' ";
if (!empty($users)) {
foreach ($users as $user) {
$user_id = $user->ID;
$search .= " OR $wpdb->posts.post_author IN ('{$user_id}') ";
}
}
$searchand = ' AND ';
}
if ( ! empty( $search ) ) {
$search = " AND ({$search}) ";
if ( ! is_user_logged_in() )
$search .= " AND ($wpdb->posts.post_password = '') ";
}
$search .= " AND $wpdb->posts.post_type IN ('post')";
$search .= " AND $wpdb->posts.post_status = 'publish'";
remove_filter('posts_join', 'custom_posts_join' );
remove_filter('posts_groupby', 'custom_posts_groupby' );
return $search;
}
add_filter( 'posts_search', 'custom_search_posts', 500, 2 );
関数 custom_posts_join postmeta
上でposts
に参加して著者による投稿を検索することを可能にします。
function custom_posts_join($join){
global $wpdb;
if( is_search() && !is_admin()) {
$join .= " LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id ";
}
return $join;
}
関数 custom_posts_groupby postmeta
とposts
を投稿ごとにグループ化するID
function custom_posts_groupby( $groupby ) {
global $wpdb;
if( is_search() && !is_admin()) {
$groupby = "$wpdb->posts.ID";
}
return $groupby;
}
私はいくつかのmysqlクエリを介してユーザーを照会するのに苦労したので、代わりにWP_User_Queryを使用しました。
誰かが来て、コードを改良してくれることを願っています。大部分はパフォーマンスの面でです。
編集: この場合posts_join
とposts_groupby
は必要ありません。