Posted on Leave a comment

How to create Custom 5 Stars Rating System in WordPress?

Screenshot_3

In this article I’ll show that how to create custom 5 stars Rating system in wordpress.

I’ll create WordPress Short Code to place rating anywhere in any post.

Steps:

1- Create Directory “az_rating” in the root folder of your active theme.

2- Create rating.php in az_rating/ folder. In this file we will write all code for the forntend of the rating system. and add this image in az_rating/ folder:

star   Download this image in required folder.

3- Open functions.php file from the root folder of your active theme. Or create functions.php file if it does not exist.

Database Table:

Screenshot_1

4- Create a table az_rating in your current wordpress database. Run following SQL to create the table:

--
-- Table structure for table `az_rating`
--

CREATE TABLE IF NOT EXISTS `az_rating` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_post` int(11) NOT NULL,
  `ip` varchar(40) NOT NULL,
  `rate` int(11) NOT NULL,
  `name` varchar(155) NOT NULL,
  `comment` text NOT NULL,
  `dt_rated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=38 ;

5- rating.php:

CSS code for rating styles:

<style>
   #reviews
   {
   padding-left:30px;
   }
   #reviews_list
   {
   max-height: 422px;
   overflow: auto;
   padding-right: 10px;
   text-align: left;
   margin-top: 19px;
   }
   .item {
   margin-bottom: 10px;
   border-bottom: 1px solid rgb(204, 204, 204);
   padding-bottom: 10px;
   }
   #comment_form .stars {
   margin-top: 10px;
   margin-bottom: 10px; cursor: pointer;  
   }
   #comment_form .star
   {
     width: 31px;
  height: 20px;  background-size: 27px 43px;
   }
      #comment_form h3
      {
        margin-top:20px; margin-bottom:10px;
      }
   #comment_form input.form-control, textarea {
   margin-bottom: 10px; padding:10px;
   }
   .reviews_content
   {
   padding-left:30px; 
   }

   #comment_form .star:hover, .star.active {
   background-position: top;
}

.star {
  width: 15px;
  height: 15px;
  background-image: url('<?php echo $base_url; ?>/az_rating/star.png');
  background-size: 17px 30px;
  background-position: bottom;
  display: inline-block;
}
</style>

jQuery Code:

<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script>
   $(document).ready(function(){
       $("#comment_form .star").click(function() {
               apply_rating(this);
       });
   
       $("#comment_form .submit").click(function() 
           {
              // disable the submit button to avoid multiple submission
               $(this).off();
               $(this).attr("disabled","disabled");
   
               // Call this function to start save process
               save_rating(this);
           }
           );
   });
   
   // this function will save rating to database and refresh the current view
   function save_rating()
   {
   
      // getting the star rating 
       var total_rating = $("#comment_form .star.active").length;
       var name = $("#comment_form input[name=name]").val();
       var comment = $("#comment_form textarea[name=comment]").val();
      
      // preparing the new review html
       var review = '<div class="item" style="display:none"><div class="comment">'+comment+'</div><div class="name">'+name+'</div>';
   
   
      // adding stars in the new reivew html
       for(var i=0; i<6; i++)
       {
           if( total_rating>0)
           {
               var extClass="";
               if(i<=total_rating)
               {
                   extClass="active";
               }
               review = review+'<div class="star '+extClass+'"></div>';
           }
           
       
              review = review+"</div>";
   
      
   
       // this is required url for ajax calls in the wordpress
       var ajax_url = '<?php echo admin_url('admin-ajax.php'); ?>';
   
       /* 
       *
       * "action" is the name of the action which you set up in the functions.php that 
       * will call a function to submit rating
       *
       * "get_the_ID()" will fetch the current post ID
       *
       */


   
       var data={'id_post':"<?php echo get_the_ID(); ?>", action:'submit_rating', rating:total_rating, name:name, comment:comment}
      
      $.post(ajax_url, data, function(response) {
          
            // after completion show the newly added review
           $("#reviews_list").prepend(review);
           $("#reviews_list .item:first-child").slideDown();
           $("#comment_form").slideUp();
           $("#comment_form").remove();
           $("#rating_status").slideDown();
            
            // preparing data for another ajax call
            // this ajax function will refresh the main rating to show latest calcultions
            var data={'id_post':"<?php echo get_the_ID(); ?>", action:'get_latest_rating'}
   
            $.post(ajax_url, data, function(response) {
               
               $("#reviews").html(response);
   
            });
           
       });// end wp ajax
   }
   
   // this function will be called when user select star out of five star on click to fill the star according to the selected rating 
   function apply_rating(element)
   {
       
       var total_rating = $(element).index()+1;
   
        $("#comment_form .star").removeClass('active');
           
           for(var i = 0; i<total_rating; i++)
           {
               $('#comment_form .star').eq(i).addClass('active');
           }
   
   }
</script>

HTML Section:

<!-- Main Reviews -->
<div style="cursor:pointer" onclick="$('.reviews_content').slideDown()" id="reviews" class="'.$reviews_container_class.'" style="text-align:right;">
   <div class="star <?php echo ($rating>=1)? "active":""?>"></div>
   <div class="star <?php echo ($rating>=2)? "active":""?>"></div>
   <div class="star <?php echo ($rating>=3)? "active":""?>"></div>
   <div class="star <?php echo ($rating>=4)? "active":""?>"></div>
   <div class="star <?php echo ($rating>=5)? "active":""?>"></div>
   <span>
      <totalReviews><?php echo $reviews_total; ?></totalReviews>
      Review(s)
   </span>
</div>
<div class="reviews_content" style="display:none;">
   <!-- list of rating and comments -->
   <div id="reviews_list" class="row" >
      <div class="col-xs-12">
         <?php
            foreach($reviews as $review)
            {
            ?>
         <div class="item">
            <div class="comment"><?php echo $review->comment;?></div>
            <div class="name"><?php echo $review->name; ?></div>
            <div class="star  <?php echo ($review->rate>=1)? "active":""; ?>"></div>
            <div class="star  <?php echo ($review->rate>=2)? "active":""; ?>"></div>
            <div class="star  <?php echo ($review->rate>=3)? "active":""; ?>"></div>
            <div class="star  <?php echo ($review->rate>=4)? "active":""; ?>"></div>
            <div class="star  <?php echo ($review->rate>=5)? "active":""; ?>"></div>
         </div>
         <?php
            }
            ?>
      </div>
   </div>
   <?php
      $rated = false;
      // adding ip restriction
      // following code will check to see if current user already rated this post or not
      // if user already rated then this sicript will simple hide the form to leave review
      foreach($reviews as $review_row)
      {
          if($review_row->ip==$_SERVER['REMOTE_ADDR'])
          {
              $rated = true;
          }
      }
                  if($rated==false)
                  {
      ?>
   <div id="comment_form">

      <h3>Leave your Review</h3>
      <div class="stars">
         <div class="star"></div>
         <div class="star"></div>
         <div class="star"></div>
         <div class="star"></div>
         <div class="star"></div>
      </div>

      <div class="row">
         <div class="col-xs-12">
            <input name="name" class="form-control" placeholder="Full Name">
         </div>
      </div>
      <div class="row">
         <div class="col-xs-12"> 
            <textarea class="form-control" placeholder="Your Comment" name="comment"></textarea>
         </div>
      </div>
      <div class="row">
         <div class="col-xs-12">
            <button  class="btn btn-success submit" type="button">Submit Review</button>
         </div>
         <br>
      </div>
   </div>

   <div style="font-size:15px; display:none; font-style:italic;  text-align:right; color:green; font-weight:bold; margin-top:20px;" id="rating_status">Thanks for Rating!</div>

   <?php
      }
      ?>
</div>

functions.php:

In this file we will create three functions for our reviews system:

  • az_rating()
    This function will create short code “[az_rating]”
  • submit_rating_callback()
    This function will submit review to the database and will update User Interface accodingly.
  • get_latest_rating_callback()
    This function will get the latest rating by given post id.

Put following functions at the end of this file.

6- Creating shortcode:

First of all we’ll create a wordpress shortcode function.

az_rating() function will create complete functionality for short code. We named our short code as az_rating.

function az_rating( $atts ){
	$base_url = get_stylesheet_directory_uri();
 	global $wpdb;


 	// fetching all reviews from database
 	# get_the_ID() function will just get the id of the current post in which short code is placed
    $sql="SELECT *  FROM az_rating where id_post='".sanitize_text_field(get_the_ID())."'";

    $reviews = $wpdb->get_results($sql);
    $reviews_total = count($reviews);

    // calculationg average of the ratings
    $sql="SELECT avg(rate) as avg FROM az_rating where id_post='".sanitize_text_field(get_the_ID())."'";

    $result = $wpdb->get_results($sql);
    $rating = round($result[0]->avg);

    // Loading HTML Interface into variable so we can return
	ob_start();
	include("az_rating/rating.php");
	$review_content = ob_get_contents();
	ob_end_clean();
 

	return $review_content;
}
add_shortcode( 'az_rating', 'az_rating' );

7- Function to submit rating in the databse:

submit_rating_callback():

This function will receive data from the review form through ajax.

We created custom action for ajax handling and called above function with that action call:

// add the custom action used for ajax call
add_action('wp_ajax_submit_rating', 'submit_rating_callback');
// if you are using ajax on frontend for non-authenticated users then must use following action otherwise ajax will not work as expected
add_action('wp_ajax_nopriv_submit_rating', 'submit_rating_callback');
// this function will submit rating to database. This function will be called by ajax from review form
function submit_rating_callback()
{
    global $wpdb;
    
    $ip_address = $_SERVER['REMOTE_ADDR'];
    $id_post    = sanitize_text_field($_POST['id_post']);
    $rating     = sanitize_text_field($_POST['rating']);
    $name       = sanitize_text_field($_POST['name']);
    $comment    = sanitize_text_field($_POST['comment']);
    
    // checking if this post was rated before or not
    $sql = "SELECT count(id) as total FROM az_rating where id_post='" . $id_post . "' and ip='" . $ip_address;
    
    $posts   = $wpdb->get_results($sql);
    $reviews = $posts[0]->total;
    
    if ($reviews < 1) {
        echo $wpdb->show_errors();
        $result = $wpdb->insert('az_rating', array(
            'id_post' => $id_post,
            'ip' => $ip_address,
            'rate' => $rating,
            'name' => $name,
            'comment' => $comment
        ));
        
        
        echo $wpdb->show_errors();
        if ($result) {
            echo "done :)";
        }
        
    }
    
    wp_die();
    
}

8- Geting latest stars-rating to update in user interface:

get_latest_rating_callback():

This function will be called to get latest stars-rating through get_latest_rating action.

add_action('wp_ajax_get_latest_rating', 'get_latest_rating_callback');

// if you are using ajax on frontend for non-authenticated users then must use following action otherwise ajax will not work as expected
add_action('wp_ajax_nopriv_get_latest_rating', 'get_latest_rating_callback');

function get_latest_rating_callback()
{
    global $wpdb;
    echo "asdfad";
    $id_post = sanitize_text_field($_POST['id_post']);
    $sql     = "SELECT *  FROM az_rating where id_post='" . $id_post . "'";
    
    $reviews       = $wpdb->get_results($sql);
    $reviews_total = count($reviews);
    
    $sql = "SELECT avg(rate) as avg FROM az_rating where id_post='" . $id_post . "'";
    
    $result = $wpdb->get_results($sql);
    $rating = round($result[0]->avg);
    
    $reviews = ' <div class="star ' . (($rating >= 1) ? "active" : "") . '"></div>
                        <div class="star  ' . (($rating >= 2) ? "active" : "") . '"></div>
                        <div class="star ' . (($rating >= 3) ? "active" : "") . '"></div>
                        <div class="star ' . (($rating >= 4) ? "active" : "") . '"></div>
                        <div class="star ' . (($rating >= 5) ? "active" : "") . '"></div>
                        <span><totalReviews>' . $reviews_total . '</totalReviews> Review(s)</span>';
    echo $reviews;
    wp_die();
}

Ok now our Reviews system is ready to use.

To use this add this shorcode [az_rating] anywhere inshide the while loop of your post.

If you directly want to use shortcode inside the php code then paste this code in your php script to show review content:

<?php echo do_shortcode(‘[az_rating]’); ?>

Leave a Reply

Your email address will not be published. Required fields are marked *