Looking to display a score based on a value stored in $averageScore. The value varies from 0 to 5. This is what I currently have, but looks bloated and I am looking for a cleaner solution with PHP:
if( $averageScore = 0 && $averageScore < 0.5 ) {
$starPattern = array('e', 'e', 'e', 'e', 'e');
} elseif( $averageScore >= 0.5 && $averageScore < 1 ) {
$starPattern = array('h', 'e', 'e', 'e', 'e');
} elseif( $averageScore >= 1 && $averageScore < 1.5 ) {
$starPattern = array('f', 'e', 'e', 'e', 'e');
} elseif( $averageScore >= 1.5 && $averageScore < 2 ) {
$starPattern = array('f', 'h', 'e', 'e', 'e');
} elseif( $averageScore >= 2 && $averageScore < 2.5 ) {
$starPattern = array('f', 'f', 'e', 'e', 'e');
} elseif( $averageScore >= 2.5 && $averageScore < 3 ) {
$starPattern = array('f', 'f', 'h', 'e', 'e');
} elseif( $averageScore >= 3 && $averageScore < 3.5 ) {
$starPattern = array('f', 'f', 'f', 'e', 'e');
} elseif( $averageScore >= 3.5 && $averageScore < 4 ) {
$starPattern = array('f', 'f', 'f', 'h', 'e');
} elseif( $averageScore >= 4 && $averageScore < 4.5 ) {
$starPattern = array('f', 'f', 'f', 'f', 'e');
} elseif( $averageScore >= 4.5 && $averageScore < 5) {
$starPattern = array('f', 'f', 'f', 'f', 'h');
} elseif( $averageScore >= 5 ) {
$starPattern = array('f', 'f', 'f', 'f', 'f');
}
foreach( $starPattern as $ratingStar ) {
if( $ratingStar == 'e' ) {
echo '<i text-yellow></i>';
}
if( $ratingStar == 'h' ) {
echo '<i ></i>';
}
if( $ratingStar == 'f' ) {
echo '<i ></i>';
}
}
I also have something similar, but it does not cover half stars. I have been trying to combine both, but without success.
$value = $averageScore;
for ($i = 1; $i <= 5; $i ) {
if ($value >= $i) {
echo '<i ></i>' . PHP_EOL;
} else {
echo '<i ></i>' . PHP_EOL;
}
}
Any thoughts?
CodePudding user response:
I'm sure there's even more concise ways to do it, but here's one way to do it a bit more concise than your initial attempt:
$averageScore = 2.5;
// get integer value of $averageScore
$wholeStarCount = (int) $averageScore;
// get integer value of 5 - $averageScore
$noStarCount = (int) (5 - $averageScore);
// is $averageScore - $wholeStarCount larger than 0?
$hasHalfStar = $averageScore - $wholeStarCount > 0;
$stars = str_repeat('<i ></i>' . PHP_EOL, $wholeStarCount) .
($hasHalfStar ? '<i ></i>' . PHP_EOL : '') .
str_repeat('<i ></i>' . PHP_EOL, $noStarCount);
echo $stars;
An example $averageScore = 2.5
prints:
<i class="fas fa-star text-yellow"></i>
<i class="fas fa-star text-yellow"></i>
<i class="fas fa-star-half-alt text-yellow"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
You could of course make it more concise by omitting the intermediate variables at the start and put the expressions directly into the string concatenation. I just wanted to put them up top for clarity.
CodePudding user response:
I would try something along these lines.
$fullCount = floor($averageScore);
$hasHalf = ($averageScore % 1 > .5) ? true : false;
for ($i = 1; $i <= $fullCount; $i ) { // Add full stars
echo '<i ></i>' . PHP_EOL;
}
if ($hasHalf) { // Add half star
echo '<i ></i>'.PHP_EOL;
}
for ($i = 1; $i <= 5 - $fullCount; $i ) { // Add empty stars
echo '<i ></i>' . PHP_EOL;
}
CodePudding user response:
Decent Dabblers answer looks better than mine, but here is my go on it.
I wrote these functions:
//Check if value is float/decimal
function is_decimal( $val )
{
return is_numeric( $val ) && floor( $val ) != $val;
}
function printWholeStars($var){
for ($i = 0; $i < $var; $i ) {
echo '<i text-yellow></i>';
}
}
function printHalvStars(){
echo '<i ></i>';
}
function emtyStars($var){
$emptyStars= floor(5-$var);
for ($i = 0; $i < $emptyStars; $i ) {
echo '<i ></i>';
}
}
function printScores($averageScore){
if (is_decimal($averageScore)) {
$averageScoreRound=floor($averageScore);
printWholeStars($averageScoreRound);
printHalvStars();
emtyStars($averageScore);
}else{
printWholeStars($averageScore);
emtyStars($averageScore);
}
}
Then use them:
$averageScore = 1.5;
printScores($averageScore);
Output:
<i class="far fa-star" text-yellow></i>
<i class="fas fa-star-half-alt text-yellow"></i>
<i class="far fa-star"></i>
<i class="far fa-star"></i>
<i class="far fa-star"></i>