Home > Mobile >  Displaying star rating with Font Awesome icons
Displaying star rating with Font Awesome icons

Time:11-25

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>
  •  Tags:  
  • php
  • Related