web-dev-qa-db-ja.com

コメントステータス変更時に関数を実行する

次の場合に平均評価の更新を見つける必要があるレビューシステムを作成しています。

  • コメントは保留中/ゴミ箱/スパムから承認されます。
  • 承認からコメントが承認されない
  • 管理者投稿レビュー(自動承認)
  • コメントが編集される(ユーザーが既に行ったレビューを編集/更新/削除したい場合はバックエンドまたはフロントエンドのカスタムダッシュボードから)

これが私が書いたコードです:

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_commentswp_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();
        }
    }
}
3
Sisir

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';
3
soulseekah

If()ステートメントの中に$の結果があるのは私にとってはうまくいかないことがわかりました。

if( $result = $wpdb->get_var($wpdb->prepare($query)) ){

同じ問題がある場合は、これを試してください。

$result = $wpdb->get_var($wpdb->prepare($query));
if( $result ){ ... }
0
Jon Dingman