Your code uses this:
number_format((float)$results[$i]['avg_rate'], 2, '.', '')
And if we look at where $i
is set, we see this just before the loop:
$i=0;
and this:
$i++;
But I don’t see how this maps in any way to the current post when there’s a conditional, meaning that not everything in the results array is included in the post query.
Instead, don’t use $i
, use the post ID, and store the post ID as the key.
Some further notes:
- This will not scale, as the number of posts increases the query will get slower, and as the number of ratings increase, the query will get slower. 2x as many posts won’t mean twice as slow, it’ll get slower faster than that. It’ll be fast when there’s not much data, and it’ll grind to a halt afterwards.
- It could be thousands of times faster and more efficient to just recalculate a posts average rating when a new rating is added, and store the average in post meta
wp_reset_query
has no place here. Unless you’re usingquery_posts
don’t use it. Perhaps you meant to usewp_reset_postdata
?- If you’re going to write raw SQL queries, prepare your statements. Don’t just put variables inside the query strings, that’s dangerous!
$wpdb->prepare
is your friend, sanitise and make those queries safe - There are a lot of unnecessary variables, for example why use
$output
? Just echo them and save the effort of another variable, it’s a waste of resources, adds overhead when reading and typing out, and it has no benefit $avg_bef
and$avg_aft
are only assigned if that position is chosen, which will generate PHP warnings ( and in PHP 8 will generate PHP fatals ), assign them a default value beforehand of$avg_bef="";
etc, don’t just pull them out of thin air