サポート » 使い方全般 » 複数のカスタムフィールドの合計値で検索結果をソートしたい

  • 解決済 7st

    (@7st)


    お世話になります。

    現在、以下のようにしてカスタムフィールド(A)の数値の多い順に検索結果をソートして表示させることには成功しています。

    <?php if ( have_posts() ) : ?>
    	<?php $my_query = new WP_Query(array('orderby'=>'meta_value','meta_key'=>'cf_a','order'=>'desc')); ?>
    
    	<header class="page-header">
    		<h1 class="page-title"><?php printf( __( 'Search Results for: %s', 'twentyfifteen' ), get_search_query() ); ?></h1>
    	</header>
    
    	<?php
    	$foo = order_search_sort($my_query,'cf_a');
    	foreach ( $foo as $post ): ?>
    
    		<?php
    		get_template_part( 'content', 'search' );
    
    	endforeach;
    
    	wp_reset_postdata();
    
    	the_posts_pagination( array(
    		'prev_text'          => __( 'Previous page', 'twentyfifteen' ),
    		'next_text'          => __( 'Next page', 'twentyfifteen' ),
    		'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( 'Page', 'twentyfifteen' ) . ' </span>',
    	) );
    
    else :
    	get_template_part( 'content', 'none' );
    
    endif;
    ?>

    さらに、カスタムフィールド(B)の数値も合計して、その数値で検索結果をソートして表示させたいと考えています。つまり、カスタムフィールド(A)と(B)の合計値の多い順で検索記事一覧を並び替えて表示させたいのですが、どのようにすればいいのかわかりません。

    お手数をおかけいたしますが、何かアドバイスを頂けましたら幸いです。

6件の返信を表示中 - 1 - 6件目 (全6件中)
  • モデレーター jim912

    (@jim912)

    更新時に、AとBの和を別のカスタムフィールドに保存して、その値を元にソートさせるのが最も簡単に実装できると思います。

    モデレーター Takuro Hishikawa

    (@hissy)

    下記をプラグインとして有効化するかテーマのfunctions.phpに追加すると実現できます。カスタムフィールドのキーはお好みで変更してくださいね

    <?php
    /*
    Plugin Name: 複数のカスタムフィールドの合計値で検索結果をソート
    */
    
    /**
     * 特定のカスタムフィールド(cf_a, cf_b)の値をJoinする
     */
    add_filter( 'posts_join_request', function($join) {
    	global $wpdb;
    	$join .= " LEFT JOIN $wpdb->postmeta cf_a ON $wpdb->posts.ID = cf_a.post_id AND cf_a.meta_key = 'cf_a'";
    	$join .= " LEFT JOIN $wpdb->postmeta cf_b ON $wpdb->posts.ID = cf_b.post_id AND cf_b.meta_key = 'cf_b'";
    	return $join;
    });
    
    /**
     * cf_a, cf_b の値の合計を cf_sum としてSelect句に追加する
     */
    add_filter( 'posts_request_ids', function($request) {
    	$request = str_replace('ID FROM', 'ID, (cf_a.meta_value + cf_b.meta_value) as cf_sum FROM', $request);
    	return $request;
    });
    
    /**
     * Orderby句に cf_sum の降順を追加する
     */
    add_filter( 'posts_orderby_request', function($posts_orderby) {
    	$posts_orderby = 'cf_sum DESC, ' . $posts_orderby;
    	return $posts_orderby;
    });

    <?php $my_query = new WP_Query(array('orderby'=>'meta_value','meta_key'=>'cf_a','order'=>'desc')); ?>$foo = order_search_sort($my_query,'cf_a'); は不要になります。

    トピック投稿者 7st

    (@7st)

    jim912様、Takuro Hishikawa様、早速のアドバイスありがとうございます!
    試してみて、追って結果をご報告します!
    まずは取り急ぎ、お礼まで。

    トピック投稿者 7st

    (@7st)

    Takuro Hishikawa様、ありがとうございます。
    ご指示いただいた方法でうまくいきました。

    ただしこの方法の場合、検索結果だけでなく、通常の記事リスト(index.phpとか)でもCFの合計値でソートされるようですが「検索の時だけ」このソートを行うようにはどうすればよいでしょうか?

    お手数をおかけいたしますが、その方法があればアドバイスいただけないでしょうか。

    モデレーター Takuro Hishikawa

    (@hissy)

    おっと、失礼しました…。検索結果以外は除外しましょう!

    <?php
    /*
    Plugin Name: 複数のカスタムフィールドの合計値で検索結果をソート
    */
    
    /**
     * 特定のカスタムフィールド(cf_a, cf_b)の値をJoinする
     */
    add_filter( 'posts_join_request', function($join) {
    	if (!is_search()) {
    		return $join;
    	}
    
    	global $wpdb;
    	$join .= " LEFT JOIN $wpdb->postmeta cf_a ON $wpdb->posts.ID = cf_a.post_id AND cf_a.meta_key = 'cf_a'";
    	$join .= " LEFT JOIN $wpdb->postmeta cf_b ON $wpdb->posts.ID = cf_b.post_id AND cf_b.meta_key = 'cf_b'";
    	return $join;
    });
    
    /**
     * cf_a, cf_b の値の合計を cf_sum としてSelect句に追加する
     */
    add_filter( 'posts_request_ids', function($request) {
    	if (!is_search()) {
    		return $request;
    	}
    
    	$request = str_replace('ID FROM', 'ID, (cf_a.meta_value + cf_b.meta_value) as cf_sum FROM', $request);
    	return $request;
    });
    
    /**
     * Orderby句に cf_sum の降順を追加する
     */
    add_filter( 'posts_orderby_request', function($posts_orderby) {
    	if (!is_search()) {
    		return $posts_orderby;
    	}
    
    	$posts_orderby = 'cf_sum DESC, ' . $posts_orderby;
    	return $posts_orderby;
    });
    トピック投稿者 7st

    (@7st)

    あ、なるほど
    is_search()じゃないときに、何もせずにreturnすればよかったんですね。

    Takuro Hishikawa様、ありがとうございました!
    とてもたすかりました!
    解決といたします。

6件の返信を表示中 - 1 - 6件目 (全6件中)
  • トピック「複数のカスタムフィールドの合計値で検索結果をソートしたい」には新たに返信することはできません。