次の場合に平均評価の更新を見つける必要があるレビューシステムを作成しています。
これが私が書いたコードです:
add_action('edit_comment', 'update_business_rating_avg');
add_action('comment_post', 'update_business_rating_avg');
add_action('comment_unapproved_to_approved', 'update_business_rating_avg');
add_action('comment_approved_to_unapproved', 'update_business_rating_avg');
add_action('comment_spam_to_approved', 'update_business_rating_avg');
add_action('comment_approved_to_spam', 'update_business_rating_avg');
function update_business_rating_avg($comment){
//fb($comment);
$post_id = $comment->comment_post_ID;
$post_type = get_post_type($post_id);
if('business' == $post_type){
//fb($post_type);
$args = array(
'post_id' => $post_id,
'status' => 'approve'
);
$comments = get_comments($args);
$total_ratings = 0;
$avg = 0;
foreach($comments as $comment){
$total_points += get_comment_meta($comment->comment_ID, 'rating', true);
$total_ratings++;
}
if($total_ratings > 0){
$avg = $total_points/$total_ratings;
$avg = (float)$avg;
}
$avg = roundToNearestFraction($avg,0.5);
update_post_meta($post_id, 'avg_rating', $avg);
}
}
問題:
管理者がレビューを投稿したときに機能が起動されない(自動承認される)ため、まだ何か不足しています。
関数update_business_rating_avg()
と、foreach内でのget_comment_meta()
の使い方を確認してください。パフォーマンスキルですか?これを行うより良い方法はありますか?カスタムSQLはおそらく?
どうぞよろしくお願いします。
解決しよう:最終版
正しい方向に送ってくれた@Soulseekahに感謝します。誰かが将来それを必要とするならば、これは解決のための最終的なコードです。承認されたコメントと現在の投稿IDに関連付けられているコメントを比較するためにwp_comments
とwp_commentmeta
の両方を結合する必要があるため、SQLは複雑です。
add_action('edit_comment', 'update_business_rating_avg');
add_action('comment_post', 'update_business_rating_avg');
add_action('comment_unapproved_to_approved', 'update_business_rating_avg');
add_action('comment_approved_to_unapproved', 'update_business_rating_avg');
add_action('comment_spam_to_approved', 'update_business_rating_avg');
add_action('comment_approved_to_spam', 'update_business_rating_avg');
add_action('comment_approved_to_trash', 'update_business_rating_avg');
add_action('comment_trash_to_approved', 'update_business_rating_avg');
function update_business_rating_avg($comment){
if ( !is_object( $comment ) ){
$comment = get_comment( $comment );
}
$post_id = $comment->comment_post_ID;
$post_type = get_post_type($post_id);
if('business' == $post_type){
$avg = 0;
global $wpdb;
$query = "SELECT AVG(meta_value) FROM $wpdb->commentmeta ";
$query .= "INNER JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID " ;
$query .= "WHERE $wpdb->commentmeta.meta_key = 'rating' ";
$query .= "AND $wpdb->comments.comment_approved = 1 ";
$query .= "AND $wpdb->comments.comment_post_ID = '$post_id'";
if( $result = $wpdb->get_var($wpdb->prepare($query)) ){
$avg = roundToNearestFraction($result, 0.5);
update_post_meta($post_id, 'avg_rating', $avg);
}else{
// report error
//$wpdb->print_error();
}
}
}
comment_post
フック は、最初の引数として$comment_id
を指定して呼び出されます。あなたはあなたの機能が失敗している理由を見ることができます。 edit_comment
フック も同様です。
ビジネス機能の最初に以下を追加するだけです。
if ( !is_object( $comment ) )
$comment = get_comment( $comment );
コメントメタデータの取得にはカスタムSQLクエリを使用してください。今のように、自分の持っているものを使用すると、すべてのコメントについてデータベースにクエリを実行することになります。さらに、組み込みの SUM
および AVG
を使用することをお勧めします。 MySQLはPHPの余分なループを避けるために機能します。
SELECT SUM(`meta_value`), AVG(`meta_value`)
FROM `{$wpdb->commentmeta}`
WHERE `meta_key` = 'rating'
AND `comment_id` = '$sanitized_comment_id';
If()ステートメントの中に$の結果があるのは私にとってはうまくいかないことがわかりました。
if( $result = $wpdb->get_var($wpdb->prepare($query)) ){
同じ問題がある場合は、これを試してください。
$result = $wpdb->get_var($wpdb->prepare($query));
if( $result ){ ... }