Home > Software engineering >  Woocommerce - Implementation of query args in the reviews counting graph only for the currently sele
Woocommerce - Implementation of query args in the reviews counting graph only for the currently sele

Time:02-22

I have a code that displays reviews graph of the entire website and divides them into sections according to ratings. The problem is that this code calculates the total reviews of the whole website. I would need to filter the total reviews count according to the currently chosen language. I use WPML. Any advice?

Code:

function display_all_product_review_histogram($minimum_rating, $maximum_rating){
    
    $all_product_review_average_rating = get_all_product_review_average_rating($minimum_rating, $maximum_rating);
    $total_ratings = $all_product_review_average_rating[0]["total_ratings"];

    $get_all_product_review_counts_by_ratings = get_all_product_review_counts_by_ratings($minimum_rating, $maximum_rating);

    if($get_all_product_review_counts_by_ratings){
        $output = '';
        $sum = 0;
        $total = 0;
        $raw_percentages_array = array();
        $percentages_array = array();

        //When working with rounded percentages, we must make sure the total percentages add up to 100%.
        //Creating array of rating values and its percentage
        foreach ($get_all_product_review_counts_by_ratings as $key => $rating) {
            $percentage = round($rating["amount"] / $total_ratings, 2) * 100;
            $raw_percentages_array[] = array("value" => $rating["value"], "percent_of_total" => $percentage, 'amount'=> $rating["amount"]);
        }
        //Counting the total of our percents
        foreach($raw_percentages_array as $key => $percent) {
            $total  = $percent[ "percent_of_total" ];
        }
        //Creating an array that will have the actual percentages after the rounding has been applied to it.
        //This will help to see if we have 100% or we are not aligned
        foreach($raw_percentages_array as $key => $percent){
            $percentages_array[$percent["value"]] = round(($percent["percent_of_total"]/$total) * 100, 0);
        }
        $sum = array_sum($percentages_array); //Again counting the total of our new percents to see if it adds up to 100%

        if($sum != 100){ //If we do not have 100%, then we will alter the highest percentage value so that we get a total of 100%
            $highest_percentage_key = array_keys($percentages_array, max($percentages_array)); //Getting key of the highest percentage value
            $percentages_array[$highest_percentage_key[0]] = 100 - ($sum - max($percentages_array)); //Alterning the percentage
        }

        //Now we are ready to create the output that will give us 100% in total
        $r_count = 0;
        $output .= "<div class='product-review-histogram'>";
        foreach ($percentages_array as $key => $percentage) {
            $output .= "<div class='histogram-row star-rating-". $key ."'>";
            $output .= "<div class='histogram-col-1'>". $key ." star</div>";
            $output .= "<div class='histogram-col-2'><div class='histogram-meter-bar'><div class='histogram-bar-temperature' style='width: ". $percentage ."%'></div></div></div>";
            $output .= "<div class='histogram-col-3'>". $raw_percentages_array[$r_count]['amount'] ."</div>";
            $output .= "</div>";
            $r_count  ;
        }
        $output .= "</div>";

        return $output;
    }else{
        return;
    }
}

UPDATE - sharing code of get_all_product_review_average_rating function:

function get_all_product_review_average_rating($minimum_rating, $maximum_rating){
    $get_all_product_review_counts_by_ratings = get_all_product_review_counts_by_ratings($minimum_rating, $maximum_rating);

    if($get_all_product_review_counts_by_ratings){ //If we have reviews
        $average_rating_results = array();
        $total_ratings = 0;
        $total_rating_value = 0;

        foreach ($get_all_product_review_counts_by_ratings as $key => $rating) {
            $total_ratings = $total_ratings   $rating["amount"];
            $current_rating_value = $rating["amount"] * $rating["value"];
            $total_rating_value = $total_rating_value   $current_rating_value;
        }

        $average_rating = number_format($total_rating_value / $total_ratings, 1); //Rounding value to one decimal place
        $average_rating_results[] = array(
            "total_ratings" => $total_ratings,
            "average_rating" => $average_rating
        );

        return $average_rating_results;
    }else{
        return;
    }
}

UPDATE2 - sharing more of the functions related to the graph

function get_all_product_review_ratings(){
    global $wpdb;

    if ( false === ( $review_ratings = get_transient( 'all_product_review_ratings' ))){ //Checking if we have previously cached query results in order to save resources and increase speed
        $review_ratings = $wpdb->get_results("
            SELECT meta_value
            FROM {$wpdb->prefix}commentmeta as commentmeta
            JOIN {$wpdb->prefix}comments as comments ON comments.comment_id = commentmeta.comment_id
            WHERE commentmeta.meta_key = 'rating' AND comments.comment_approved = 1
            ORDER BY commentmeta.meta_value
        ", ARRAY_A);

        $expiration = 60 * 5; //Expiring query results after 5 minutes
        set_transient( 'all_product_review_ratings', $review_ratings, $expiration ); //Temporarily storing cached data in the database by giving it a custom name and a timeframe after which it will expire and be deleted

        return $review_ratings;
    }else{
        return $review_ratings;
    }
}

WHAT DO WE NEED TO CHANGE TO GET THIS IS PROBABLY THIS PART OF THE CODE:

 $review_ratings = $wpdb->get_results("
                SELECT meta_value
                FROM {$wpdb->prefix}commentmeta as commentmeta
                JOIN {$wpdb->prefix}comments as comments ON comments.comment_id = commentmeta.comment_id
                WHERE commentmeta.meta_key = 'rating' AND comments.comment_approved = 1
                ORDER BY commentmeta.meta_value
            ", ARRAY_A);

UPDATE 3:

function get_all_product_review_counts_by_ratings($minimum_rating, $maximum_rating){
    $all_product_review_ratings = get_all_product_review_ratings();
    
    if($all_product_review_ratings){ //If we have reviews
        $all_product_review_ratings_one_dimensional_array = array_map("current", $all_product_review_ratings); //Converting two dimensional array to one dimensional array

        $rating_counts = array_count_values($all_product_review_ratings_one_dimensional_array); //Creating array that consists of rating counts

        $ratings = array();

        while($maximum_rating >= $minimum_rating){
            if(array_key_exists($maximum_rating, $rating_counts)){
                $star_count = $rating_counts[$maximum_rating];
            }else{
                $star_count = 0;
            }

            //Creating array that contains information about 
            $ratings[] = array(
                "value" => $maximum_rating,
                "amount" => $star_count
            );

            $maximum_rating--;
        }
        return $ratings;
    }else{
        return;
    }
}

CodePudding user response:

function get_all_product_review_ratings() {
    global $wpdb;

    if (false === ( $review_ratings = get_transient('all_product_review_ratings'))) { //Checking if we have previously cached query results in order to save resources and increase speed
        $review_ratings = array();
        $args = array(
            'status' => 'approve',
            'type' => 'review',
            'paged' => 0,
            'meta_query' => array(
                array(
                    'key' => 'verified',
                    'value' => 1
                )
        ));

        // The Query for getting reviews - WPML respected
        $comments_query = new WP_Comment_Query;
        $comments = $comments_query->query($args);
        foreach ($comments as $comment) {
            $review_ratings[] = get_comment_meta($comment->comment_ID, 'rating', 1);
        }
        $expiration = 60 * 5; //Expiring query results after 5 minutes
        set_transient('all_product_review_ratings', $review_ratings, $expiration); //Temporarily storing cached data in the database by giving it a custom name and a timeframe after which it will expire and be deleted

        return $review_ratings;
    } else {
        return $review_ratings;
    }
}
  • Related