ある記事投稿サイトで記事を平均評価順でソートできるようにしてほしいという依頼があり少し苦戦しました。
というのも、WP Customer Reviewsというプラグインを使用して投稿に対してユーザが星マークをつけてレビューをしてもらい、平均評価を表示するところまではできていたのですが、この平均評価というものがmeta_keyとしてDBに保持されてるわけではなかったからです
(平均値はクエリで投稿IDに紐づいている評価数を取得して算出していました)。
ソート実行時に、『WPクエリを投げて取得したものに対して並び替えをかけるみたいなことをしてみたのですが、このやり方ではページネーションの壁にぶつかりました。(1ページ目だけを並び替えてしまうのです)
これは平均評価をmeta_keyとして持たせるしかないと思い少しプラグインをいじってみることにしました。
意外と少ない記述で実現できました。
※WP Customer Reviewsプラグインの導入は済んでいるという前提で進めさせていただきます。
①wp-customer-reviews-3.phpを開きます
このファイルはwp-content/plugins/wp-customer-reviewsの中にあります。
②評価ボタンクリック時に実行されているプログラムを見つけます
レビュー投稿時に平均評価を登録するということをしたいので、プログラムが実行されてる場所を見つける必要があります。
どうやら928行目のajax() という関数が実行されているようです。
1004~1009行目を見るとどうやらレビューに関する情報がDBに登録されているのがわかります。

この後に記述を追加して平均評価もDBに登録してやるように改造しましょう。
③WP Customer Reviewsを編集する
上記の1004~1009行目の後に以下のように記述します。
/**************************************************************************************
* 平均評価をDBに持たせる 
/*************************************************************************************/
   global $wpdb;
			$review_query="SELECT round(AVG(meta_value),1) AS review_avg,count(meta_value) AS review_cnt FROM $wpdb->postmeta WHERE post_id IN (SELECT post_id FROM $wpdb->postmeta WHERE meta_value=".$posted->postid." and meta_key='wpcr3_review_post') AND meta_key='wpcr3_review_rating'";
			$myreview = $wpdb->get_row($review_query);
			$review_avg=$myreview->review_avg;
			update_post_meta($posted->postid, 'wpcr3_review_avg', $review_avg); //平均評価を登録5~7行目でクエリを投げて投稿に紐づくレビューから平均評価を算出し
8行目で平均評価を登録しています。
④記事登録時に平均評価を0で登録するようにfunctions.phpを変更
meta_keyがないと取得時に記事をそもそも取得しなくなってしまうので、
 functions.phpを編集して記事登録時に平均評価を0として持たせます。
場所はどこでもいいと思います。
//記事登録時に平均評価を0として登録する
function set_default_reviewAvg_metakey($post_ID){
    $review_avg = get_post_meta($post_ID, "wpcr3_review_avg", true);
    if ($review_avg === '') {
        add_post_meta($post_ID, 'wpcr3_review_avg', 0, true);
        return $post_ID; // not sure if needed
    }
}
add_action('save_post','set_default_reviewAvg_metakey');2行目で関数を定義し、
3、4行目で投稿IDに紐づく記事にwpcr3_review_avgというmeta_keyが存在するか確認し、
もしなければ5行目で平均評価を0として登録し、
9行目は2行目で定義した関数を記事登録(save_post)時に実行するように設定しています。
これでユーザーレビュー時に平均評価をDBに登録させることができ、
平均評価でソートする準備が整いました。
⑤平均評価でソートをする
それでは先ほど作成したwpcr3_review_avgをmeta_keyとしてソートしてみます。
 (もちろんいくつかのレビューをした後で)
 ソートするには以下のように記述します。
$args=(
	'post_type' => 'ポストタイプ',
	'orderby' =>  'wpcr3_review_avg',
	'order' =>  'DESC',
);
$wpQueryPost = new WP_Query($args);
これで評価の高い順に記事が並んだのではないでしょうか。
今回のやり方ではプラグインを直接編集しているのでプラグインを更新すると③で書いた記述が上書きされて消えてしまうので、更新しないようにするか更新した場合はもう一③の部分の記述を加えてやる必要があります。
 以上、WP Customer Reviewsを使って平均評価ソートをできるようにする方法でした。









コメント