php - How to display half star when average non-integer (Star rating)

I use this code to display the average rating with half-filled stars (if the average rating is not an integer). It works great.
<?php
$stars = '';
for ( $i = 1; $i <= $avrating + 1; $i++ ) {
$width = intval( $i - $avrating > 0 ? 20 - ( ( $i - $avrating ) * 20 ) : 20 );
if ( 0 === $width ) {
continue;
}
if($avrating < 5){
$stars .= '<span style="overflow:hidden; width:' . $width . 'px" class="dashicons dashicons-star-filled"></span>';
if ( $i - $avrating > 0 ) {
$stars .= '<span style="overflow:hidden; position:relative; left:-' . $width .'px;" class="dashicons dashicons-star-empty"></span>';
}
}
}
if($avrating >= 5){
for ($i = 1; $i <= 5; $i++) {
echo '<span style="overflow:hidden;" class="dashicons dashicons-star-filled"></span>';
}
}
echo $stars;
?>
However, in this case, not all stars are displayed. For example, if the rating is 3.5, then 4 stars are displayed, the fourth is half full. Here is the image: 1: https://i.stack.imgur.com/2aoGx.png But I need all five stars to be displayed: the last empty fourth is half filled (if the rating is 3.5, for example) and the first three are full. I can bring out all the stars. With this code:
<?php
$stars = '';
for ( $i = 1; $i <= 5 ; $i ++ ) {
if ( $i <= $avrating ) {
$stars .= '<span class="dashicons dashicons-star-filled"></span>';
} else {
$stars .= '<span class="dashicons dashicons-star-empty"></span>';
}
}
echo $stars;
?>
But as a result, I naturally do not achieve the result. Here's what I get:
You see, there is no half in the fourth star. I think it is possible to combine these two code fragments, but my knowledge is not enough how to do it. Or maybe this is not possible at all. Please help solve this problem.
Answer
Solution:
I'd make a simple function which returns the filling level of a given star against a given rating:
<?php
function getStarClass(int $starPosition, float $rating): string
{
if ($starPosition <= $rating) {
return 'filled';
}
if ($starPosition - $rating < 1) {
return 'half-filled';
}
return 'empty';
}
$avrating = 3.5;
?>
<?php for ($star = 1; $star <= 5; $star++): ?>
<span class="dashicons dashicons-star-<?= getStarClass($star, $avrating) ?>"></span>
<?php endfor ?>
Note that I'm also using PHP's alternative syntax to display the HTML, as I believe it's a better fit for that purpose, but that's entirely optional.
Answer
Solution:
You can add an extra clause which checks if the loop is greater than the rating but less than the next rating as a half start rating...
$stars = '';
for ( $i = 1; $i <= 5 ; $i ++ ) {
if ( $i <= $avrating ) {
$stars .= '<span class="dashicons dashicons-star-filled"></span>';
} elseif ( $i < $avrating + 1 && $i > $avrating ) {
$stars .= '<span class="dashicons dashicons-star-half"></span>';
} else {
$stars .= '<span class="dashicons dashicons-star-empty"></span>';
}
}
you could also reduce a lot of the repeated boiler plate HTML by adding it as parts...
$stars = '';
for ( $i = 1; $i <= 5 ; $i ++ ) {
$stars .= '<span class="dashicons dashicons-star-';
if ( $i <= $avrating ) {
$stars .= 'full';
} elseif ( $i < $avrating + 1 && $i > $avrating ) {
$stars .= 'half';
} else {
$stars .= 'empty';
}
$stars .= '"></span>';
}
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: mysqli::real_connect(): (hy000/2002): connection refused
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.