0

I'm trying to save an average of comments as a post meta that needs to be updated every time according to comment status.

/**
 * Gets comment average data.
 */

function sw_get_averagerev( $post_id ) {
    if (get_post_type($post_id) == 'review') {

    $prev_averating = get_post_meta( $post_id, 'wp_review_comments_rating_value', true );
    $prev_count = get_post_meta( $post_id, 'wp_review_comments_rating_count', true );

        $comments = get_comments(
                    array(
                        'post_id' => $post->ID,
                        'type'    => 'wp_review_comment',
                        'status'  => 'approve',
                    ));

    $ratings_sum = 0;

    foreach ( $comments as $comment ){
        $ratings_sum+= get_comment_meta($comment->comment_ID, 'wp_review_comment_rating', true);
    };

        $count  = count( $comments );
        $ave_reviews = $ratings_sum / $count;

        $averating = round($ave_reviews , 2);


        update_post_meta( $post_id, 'wp_review_comments_rating_value', $averating, $prev_averating );
        update_post_meta( $post_id, 'wp_review_comments_rating_count', $count, $prev_count );
}}


/**
 * Runs something when comment status change.
 */
function wp_review_on_change_comment_status( $new_status, $old_status, $comment="comment_type=wp_review_comment" ) {
     sw_get_averagerev( $post_id ); 
}
add_action( 'transition_comment_status', 'wp_review_on_change_comment_status', 10, 3 );

$comment="comment_type=wp_review_comment" might be incorrect on the function wp_review_on_change_comment_status( $new_status, $old_status, $comment="comment_type=wp_review_comment" ). So, I have also checked with the defalt $comment args, It still the same.

2
  • function foo($comment="comment_type=wp_review_comment"){} is essentially a default value syntax so your code isn't breaking because of this strange useless string. But have it in mind that no default value for function argument is better then some useless one. As you may disappoint with it some less experienced in PHP developers.I hope it's just a typo or copy\paste error.
    – Mikhail
    Mar 19 '20 at 7:01
  • As a general advice - try to use some IDE for PHP and\or PHP Code Sniffer it will save you time debugging typo\copy\paste errors and missing or undefined variables.
    – Mikhail
    Mar 19 '20 at 7:03
0

You have typo error in $post->ID as you don't have $post variable, and it really could cause you feel that it doesn't work, at least it will not calculate new value. So here's modified approach.

I've also used different hooks to trigger action when it's really necessary and not for every comment_status transition.

/**
 * Gets comment average data.
 *
 * @param int $post_id
 */
function sw_update_average_review_rating( $post_id ) {

    if ( get_post_type( $post_id ) === 'review' ) {

        $prev_averating = get_post_meta( $post_id, 'wp_review_comments_rating_value', true );
        $prev_count     = get_post_meta( $post_id, 'wp_review_comments_rating_count', true );

        $comments = get_comments(
            array(
                'post_id' => $post_id, // HERE was a typo error, you dont' have here a $post you have $post_id!
                'type'    => 'wp_review_comment',
                'status'  => 'approve',
            )
        );

        $ratings_sum = 0;

        foreach ( $comments as $comment ) {
            $ratings_sum += get_comment_meta( $comment->comment_ID, 'wp_review_comment_rating', true );
        };

        $count       = count( $comments );
        $ave_reviews = $ratings_sum / $count;

        $averating = round( $ave_reviews, 2 );

        update_post_meta( $post_id, 'wp_review_comments_rating_value', $averating, $prev_averating );
        update_post_meta( $post_id, 'wp_review_comments_rating_count', $count, $prev_count );
    }

}

/**
 * Hook action for to trigger recalculation after comment status got changed.
 *
 * @param $comment_id
 * @param WP_Comment $comment
 */
function sw_review_after_comment_status_changed( $comment_id, $comment ) {

    $post_id = $comment->comment_post_ID;
    $post    = get_post( $post_id );
    if ( 'review' === $post->post_type ) {
        // trigger calculation.
        sw_update_average_review_rating( $post_id );
    }

}

add_action('deleted_comment', 'sw_review_after_comment_status_changed', 10, 2);
add_action( 'trashed_comment', 'sw_review_after_comment_status_changed', 10, 2);

// hooks below can be tuned only to handle your custom comment type. 
add_action( 'comment_approved_', 'sw_review_after_comment_status_changed', 10, 2);
add_action( 'comment_unapproved_', 'sw_review_after_comment_status_changed', 10, 2);

// Tuned for your custom comment type to trigger only for them, use either these or pair of hooks above.
add_action( 'comment_approved_wp_review_comment', 'sw_review_after_comment_status_changed', 10, 2);
add_action( 'comment_unapproved_wp_review_comment', 'sw_review_after_comment_status_changed', 10, 2);
3
  • Yes. I first did the calculation on my template, to check the result. That's when I forgot to re-edit in the function.
    – Bikram
    Mar 19 '20 at 8:38
  • transition_comment_status is better than the individual hooks you mentioned.
    – Bikram
    Mar 19 '20 at 10:00
  • also, I checked the comment type before running the function sw_update_average_review_rating( $post_id ); with 'if ( 'wp_review_comment' === $comment->comment_type ) {'. Thanks for pointiong out the $post->ID error. thats what made me possible to play around everything.
    – Bikram
    Mar 19 '20 at 10:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.