0

After reviewing many of the ratings plugins, I decided I wanted to keep things a bit more simple and just build out my own using ACF and a custom post type. So far, everything is working as expected, but I feel like my code could be much more clean and organized.

I'm using Roots; I've created a custom post type template and I'm doing a preg_replace on my ratings field (which is a float; e.g., 4.5) to remove the decimal so I can easily echo out the raw numbers in a css class, like so:

 $ratings_overall = get_field('provider_ratings_overall');
 $ratings_round_overall = preg_replace("/[^0-9]/", '', $ratings_overall);

 echo '<div class="class-name-' . $ratings_round_overall . '">

My issue is, this doesn't feel clean to me, and my functions file now has a ridiculously long string of functions with if/elseif statements in order to populate the ratings (these are stored in a template for each rating, which just contains the html I need to display the stars on the page).

<div class="rating-stars">
  <span class="five-stars">
    <span class="star"><i class="nc-icon nc-ic_star_24px"></i></span>
    <span class="star"><i class="nc-icon nc-ic_star_24px"></i></span>
    <span class="star"><i class="nc-icon nc-ic_star_24px"></i></span>
    <span class="star"><i class="nc-icon nc-ic_star_24px"></i></span>
    <span class="star"><i class="nc-icon nc-ic_star_24px"></i></span>
  </span>
</div>

My dirty, dirty functions file:

    /**
    * Functions for the Review post type
    */
    function rating_overall() {

      $ratings_overall = get_field('provider_ratings_overall');

      if ($ratings_overall == 5.0) {
        echo get_template_part('templates/star-rating/five-star-rating');
      }
      elseif ($ratings_overall == 4.5) {
        echo get_template_part('templates/star-rating/four-half-star-rating');
      }
      elseif ($ratings_overall == 4.0) {
        echo get_template_part('templates/star-rating/four-star-rating');
      }
      elseif ($ratings_overall == 3.5) {
        echo get_template_part('templates/star-rating/three-half-star-rating');
      }
      elseif ($ratings_overall == 3.0) {
        echo get_template_part('templates/star-rating/three-star-rating');
      }
      elseif ($ratings_overall == 2.5) {
        echo get_template_part('templates/star-rating/two-half-star-rating');
      }
      elseif ($ratings_overall == 2.0) {
        echo get_template_part('templates/star-rating/two-star-rating');
      }
      elseif ($ratings_overall == 1.5) {
        echo get_template_part('templates/star-rating/one-half-star-rating');
      }
      elseif ($ratings_overall == 1.0) {
        echo get_template_part('templates/star-rating/one-star-rating');
      }
      elseif ($ratings_overall  == 0.5) {
        echo get_template_part('templates/star-rating/half-star-rating');
      }
      elseif ($ratings_overall == '') {
        echo get_template_part('templates/star-rating/no-star-rating');
      }

    }
    function rating_marketing() {

      $ratings_marketing = get_field('provider_ratings_marketing');

      if ($ratings_marketing == 5.0) {
        echo get_template_part('templates/star-rating/five-star-rating');
      }
      elseif ($ratings_marketing == 4.5) {
        echo get_template_part('templates/star-rating/four-half-star-rating');
      }
      elseif ($ratings_marketing == 4.0) {
        echo get_template_part('templates/star-rating/four-star-rating');
      }
      elseif ($ratings_marketing == 3.5) {
        echo get_template_part('templates/star-rating/three-half-star-rating');
      }
      elseif ($ratings_marketing == 3.0) {
        echo get_template_part('templates/star-rating/three-star-rating');
      }
      elseif ($ratings_marketing == 2.5) {
        echo get_template_part('templates/star-rating/two-half-star-rating');
      }
      elseif ($ratings_marketing == 2.0) {
        echo get_template_part('templates/star-rating/two-star-rating');
      }
      elseif ($ratings_marketing == 1.5) {
        echo get_template_part('templates/star-rating/one-half-star-rating');
      }
      elseif ($ratings_marketing == 1.0) {
        echo get_template_part('templates/star-rating/one-star-rating');
      }
      elseif ($ratings_marketing  == 0.5) {
        echo get_template_part('templates/star-rating/half-star-rating');
      }
      elseif ($ratings_marketing == '') {
        echo get_template_part('templates/star-rating/no-star-rating');
      }

    }
    function rating_sales() {

      $ratings_sales = get_field('provider_ratings_sales');

      if ($ratings_sales == 5.0) {
        echo get_template_part('templates/star-rating/five-star-rating');
      }
      elseif ($ratings_sales == 4.5) {
        echo get_template_part('templates/star-rating/four-half-star-rating');
      }
      elseif ($ratings_sales == 4.0) {
        echo get_template_part('templates/star-rating/four-star-rating');
      }
      elseif ($ratings_sales == 3.5) {
        echo get_template_part('templates/star-rating/three-half-star-rating');
      }
      elseif ($ratings_sales == 3.0) {
        echo get_template_part('templates/star-rating/three-star-rating');
      }
      elseif ($ratings_sales == 2.5) {
        echo get_template_part('templates/star-rating/two-half-star-rating');
      }
      elseif ($ratings_sales == 2.0) {
        echo get_template_part('templates/star-rating/two-star-rating');
      }
      elseif ($ratings_sales == 1.5) {
        echo get_template_part('templates/star-rating/one-half-star-rating');
      }
      elseif ($ratings_sales == 1.0) {
        echo get_template_part('templates/star-rating/one-star-rating');
      }
      elseif ($ratings_sales  == 0.5) {
        echo get_template_part('templates/star-rating/half-star-rating');
      }
      elseif ($ratings_sales == '') {
        echo get_template_part('templates/star-rating/no-star-rating');
      }

    }
    function rating_support() {

      $ratings_support = get_field('provider_ratings_support');

      if ($ratings_support == 5.0) {
        echo get_template_part('templates/star-rating/five-star-rating');
      }
      elseif ($ratings_support == 4.5) {
        echo get_template_part('templates/star-rating/four-half-star-rating');
      }
      elseif ($ratings_support == 4.0) {
        echo get_template_part('templates/star-rating/four-star-rating');
      }
      elseif ($ratings_support == 3.5) {
        echo get_template_part('templates/star-rating/three-half-star-rating');
      }
      elseif ($ratings_support == 3.0) {
        echo get_template_part('templates/star-rating/three-star-rating');
      }
      elseif ($ratings_support == 2.5) {
        echo get_template_part('templates/star-rating/two-half-star-rating');
      }
      elseif ($ratings_support == 2.0) {
        echo get_template_part('templates/star-rating/two-star-rating');
      }
      elseif ($ratings_support == 1.5) {
        echo get_template_part('templates/star-rating/one-half-star-rating');
      }
      elseif ($ratings_support == 1.0) {
        echo get_template_part('templates/star-rating/one-star-rating');
      }
      elseif ($ratings_support  == 0.5) {
        echo get_template_part('templates/star-rating/half-star-rating');
      }
      elseif ($ratings_support == '') {
        echo get_template_part('templates/star-rating/no-star-rating');
      }

    }
    function rating_pricing() {

      $ratings_pricing = get_field('provider_ratings_pricing');

      if ($ratings_pricing == 5.0) {
        echo get_template_part('templates/star-rating/five-star-rating');
      }
      elseif ($ratings_pricing == 4.5) {
        echo get_template_part('templates/star-rating/four-half-star-rating');
      }
      elseif ($ratings_pricing == 4.0) {
        echo get_template_part('templates/star-rating/four-star-rating');
      }
      elseif ($ratings_pricing == 3.5) {
        echo get_template_part('templates/star-rating/three-half-star-rating');
      }
      elseif ($ratings_pricing == 3.0) {
        echo get_template_part('templates/star-rating/three-star-rating');
      }
      elseif ($ratings_pricing == 2.5) {
        echo get_template_part('templates/star-rating/two-half-star-rating');
      }
      elseif ($ratings_pricing == 2.0) {
        echo get_template_part('templates/star-rating/two-star-rating');
      }
      elseif ($ratings_pricing == 1.5) {
        echo get_template_part('templates/star-rating/one-half-star-rating');
      }
      elseif ($ratings_pricing == 1.0) {
        echo get_template_part('templates/star-rating/one-star-rating');
      }
      elseif ($ratings_pricing  == 0.5) {
        echo get_template_part('templates/star-rating/half-star-rating');
      }
      elseif ($ratings_pricing == '') {
        echo get_template_part('templates/star-rating/no-star-rating');
      }

    }

I'm then calling these in my template wherever I need them:

rating_overall();
rating_marketing();
rating_sales();
rating_support();
rating_pricing();

I'm trying to clean this up as best as possible, so I guess this is more a PHP refactoring question, but it also feels like there may be a better way to do it within Wordpress, or using some Wordpress coding standards?

Any help would be greatly appreciated.

1

Always try to keep your code DRY. Your code is basically a large violation of this principle. In order to refactor this, let's think about the steps that your code goes through

  • determine whether it is overall, marketing, sales, ...
  • get those ratings from db
  • convert ratings to name of template
  • get the template

The only difference between all of your functions is the first part. So this is the only thing each function should do. Since the field names all have the same prefix, you can use that as well.

function rating_helper($name) {
    $ratings = get_field('provider_ratings_' . $name);
    // template stuff
}

function rating_overall() {
    rating_helper('overall');
}
function rating_marketing() {
    rating_helper('marketing');
}
// ...

The next thing is that big block of if/else. There is no restriction with dots in template names, so no need to convert the numbers to names. If you name them templates templates/star-rating/rating-4.5.php, rating-3.0.php, ... and rating.php (for the case of == ''), then simply include them like so

function rating_helper($name) {
    $ratings = get_field('provider_ratings_' . $name);
    echo get_template_part('templates/star-rating/rating', $ratings);
}

I am using the second parameter of get_template_part() here because .. well WordPress offers it and does the string concatenation for you, so this is a bit cleaner in my opinion.


If the only thing changing in the templates themselves is the CSS class / amount of stars displayed, you do not need separate templates at all! You can use the $ratings variable from the rating_helper() function.

function rating_helper($name) {
    $ratings = get_field('provider_ratings_' . $name);
    echo get_template_part('templates/star-rating/rating');
}

and templates/star-rating/rating.php (preg_replace() isn't necessarily bad, but a bit of an overkill)

<?php
if ($ratings != '') {
    $css_class = substr($ratings, 0, 1) . substr($ratings, 2, 1);
} else {
    $css_class = '0';
}
echo '<div class="class-name-' . $css_class . '">

If you need to display various amount of stars, you can convert them to integer with floor() and add a half star if necessary

$stars = floor($ratings);
foreach ($i=0; $i<$stars; $i++) {
    echo '<span class="star"><i class="nc-icon nc-ic_star_24px"></i></span>';
}
// floor(x.0) == x.0
// floor(x.5) != x.5
if ($stars != $ratings) {
    // echo half star
}
  • Thanks so much, kero; this is exactly what I was looking for. Based on your suggestion, is there a cleaner way to handle the preg_replace function in the template file in order to embed the classnames in the html? Looking at your code, it seems much more useful to utilize the rating_to_template array and find a way inject that into the template. – Threaded Jul 13 '17 at 16:24
  • So you want classnames like class-name-50, class-name-35? Btw, you could just use the rating in the templatename and forget about that converting altogether, couldn't you? – kero Jul 13 '17 at 16:33
  • I didn't realize the lack of restriction on having dots in the template names. This is even cleaner and easier to maintain. And the classnames could either be "class-name-50" or "class-name-five"/"class-name-four-half" The idea being that I am going to utilize those classes to change the colors and other elements of the blocks I'll be using on archive pages, sidebars, etc. I realize these are very rudimentary questions; I'm a front-end guy with only a dangerous knowledge of backend languages; thanks for the patience and insight -- it is extremely helpful. – Threaded Jul 13 '17 at 16:48
  • @Threaded Wait, are all these templates basically the same, except you get the different field value? – kero Jul 13 '17 at 16:55
  • 1
    This was amazingly helpful and informative. Thanks for taking the time. I'll integrate these new changes and clean up the code even further. – Threaded Jul 13 '17 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.