How to Create Your Own 5 Stars Voting System

How to Create Your Own 5 Stars Voting System

11 678
How to create own voting system

How to create own voting system

Today I prepared very interesting article – today I will tell you how you can create own voting system for your items (any units at your website) with PHP. I prepared two SQL tables: first table will keep our demo items. It contain several fields: title, description, time of adding, rate value and count of rates. Another table will keep records of voting (track). Of course – we will use jQuery too (for better behavior of interface). One of features will restriction to vote twice from one IP during 1 week!

Live Demo

Now – download the source files and lets start coding !


Step 1. SQL

We will need to add 2 tables into our database:

CREATE TABLE IF NOT EXISTS `s155_items` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `title` varchar(255) default '',
  `description` text NOT NULL,
  `when` int(11) NOT NULL default '0',
  `rate` float NOT NULL,
  `rate_count` int(11) unsigned NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `s155_items` (`title`, `description`, `when`, `rate`, `rate_count`) VALUES 
('Item #1', 'Here are you can put description of Item #1', UNIX_TIMESTAMP(), '0', '0'),
('Item #2', 'Here are you can put description of Item #2', UNIX_TIMESTAMP()+1, '0', '0'),
('Item #3', 'Here are you can put description of Item #3', UNIX_TIMESTAMP()+2, '0', '0'),
('Item #4', 'Here are you can put description of Item #4', UNIX_TIMESTAMP()+3, '0', '0'),
('Item #5', 'Here are you can put description of Item #5', UNIX_TIMESTAMP()+4, '0', '0');

CREATE TABLE `s155_items_vote_track` (
  `item_id` int(11) unsigned NOT NULL default '0',
  `ip` varchar(20) default NULL,
  `date` datetime default NULL,
  KEY `med_ip` (`ip`,`item_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

This is simple tables: first for records of items, second one – voting tracker

Step 2. PHP

Here are source code of our main file:

index.php

<?php

if (version_compare(phpversion(), "5.3.0", ">=")  == 1)
  error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
  error_reporting(E_ALL & ~E_NOTICE); 

require_once('classes/CMySQL.php'); // including service class to work with database

$sCode = '';
$iItemId = (int)$_GET['id'];
if ($iItemId) { // View item output
    $aItemInfo = $GLOBALS['MySQL']->getRow("SELECT * FROM `s155_items` WHERE `id` = '{$iItemId}'"); // getting info about item from database
    $sCode .= '<h1>'.$aItemInfo['title'].'</h1>';
    $sCode .= '<h3>'.date('F j, Y', $aItemInfo['when']).'</h3>';
    $sCode .= '<h2>Description:</h2>';
    $sCode .= '<h3>'.$aItemInfo['description'].'</h3>';

    // draw voting element
    $iIconSize = 64;
    $iMax = 5;
    $iRate = $aItemInfo['rate'];
    $iRateCnt = $aItemInfo['rate_count'];
    $fRateAvg = ($iRate && $iRateCnt) ? $iRate / $iRateCnt : 0;
    $iWidth = $iIconSize*$iMax;
    $iActiveWidth = round($fRateAvg*($iMax ? $iWidth/$iMax : 0));

    $sVot = '';
    for ($i=1 ; $i<=$iMax ; $i++) {
        $sVot .= '<a href="#" id="'.$i.'"><img class="votes_button" src="images/empty.gif" alt="" /></a>';
    }

    $sVoting = <<<EOS
<div class="votes_main">
    <div class="votes_gray" style="width:{$iWidth}px;">
        <div class="votes_buttons" id="{$iItemId}" cnt="{$iRateCnt}" val="{$fRateAvg}">
            {$sVot}
        </div>
        <div class="votes_active" style="width:{$iActiveWidth}px;"></div>
    </div>
    <span><b>{$iRateCnt}</b> votes</span>
</div>
EOS;

    $sCode .= $sVoting;
    $sCode .= '<h3><a href="'.$_SERVER['PHP_SELF'].'">back</a></h3>';
} else {
    $sCode .= '<h1>List of items:</h1>';

    $aItems = $GLOBALS['MySQL']->getAll("SELECT * FROM `s155_items` ORDER by `when` ASC"); // taking info about all items from database
    foreach ($aItems as $i => $aItemInfo) {
        $sCode .= '<h2><a href="'.$_SERVER['PHP_SELF'].'?id='.$aItemInfo['id'].'">'.$aItemInfo['title'].' item</a></h2>';
    }
}

?>
<!DOCTYPE html>
<html lang="en" >
    <head>
        <meta charset="utf-8" />
        <title>Creating own rate system | Script Tutorials</title>

        <link href="css/main.css" rel="stylesheet" type="text/css" />
        <script type="text/javascript" src="js/jquery-1.5.2.min.js"></script>
        <script type="text/javascript" src="js/script.js"></script>
    </head>
    <body>
        <div class="container">
            <?= $sCode ?>
        </div>
        <footer>
            <h2>Creating own rate system</h2>
            <a href="http://script-tutorials.com/how-to-create-own-voting-system/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
        </footer>
    </body>
</html>

This script will draw us list of items by default. And, when we will clicking to any item – this will link like: index.php?id=1 – it will drawing item page. I decided not make something difficult – I prepared just simple page. We will display item title, time of adding (‘when’ field), description, and, most important – our Voting element. This will looks like stars (5 stars). And we can select – how many stars we will give for our vote (from 1 till 5). I added my comments in most of places for better understanding. Ok, next PHP file is:

vote.php

<?php

if (version_compare(phpversion(), "5.3.0", ">=")  == 1)
  error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
  error_reporting(E_ALL & ~E_NOTICE); 

require_once('classes/CMySQL.php');

$iItemId = (int)$_POST['id'];
$iVote = (int)$_POST['vote'];
$sIp = getVisitorIP();


$iOldId = $GLOBALS['MySQL']->getOne("SELECT `item_id` FROM `s155_items_vote_track` WHERE `item_id` = '{$iItemId}' AND `ip` = '{$sIp}' AND (`date` >= NOW() - INTERVAL 7 DAY) LIMIT 1");
if (! $iOldId) {
    $GLOBALS['MySQL']->res("INSERT INTO `s155_items_vote_track` SET `item_id` = '{$iItemId}', `ip` = '{$sIp}', `date` = NOW()");
    $GLOBALS['MySQL']->res("UPDATE `s155_items` SET `rate` = `rate` + {$iVote}, `rate_count` = `rate_count` + 1 WHERE `id` = '{$iItemId}'");
    echo 1;
}

function getVisitorIP() {
    $ip = "0.0.0.0";
    if( ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) && ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } elseif( ( isset( $_SERVER['HTTP_CLIENT_IP'])) && (!empty($_SERVER['HTTP_CLIENT_IP'] ) ) ) {
        $ip = explode(".",$_SERVER['HTTP_CLIENT_IP']);
        $ip = $ip[3].".".$ip[2].".".$ip[1].".".$ip[0];
    } elseif((!isset( $_SERVER['HTTP_X_FORWARDED_FOR'])) || (empty($_SERVER['HTTP_X_FORWARDED_FOR']))) {
        if ((!isset( $_SERVER['HTTP_CLIENT_IP'])) && (empty($_SERVER['HTTP_CLIENT_IP']))) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
    }
    return $ip;
}

?>

This file we will using to accept visitors votes and saving its into database. In our project we have another one PHP file:

classes/CMySQL.php

This is service class to work with database prepared by me. This is nice class which you can use too. Database connection details located in this class in few variables, sure that you will able to configure this to your database. I don`t will publish its sources – this is not necessary for now. Available in package.

Step 3. JS

Here are small javascript code which we will using for changing voting element styles on mouse hover. And – for sending data in case of submitting our vote.

js/script.js

$(function(){
    var width = 0;

    $('.votes_buttons a').hover( 
        function () { 
            width = $(this).attr('id') * 64;
            $('.votes_active').width(width + 'px');
        }, 
        function () { 
            width = $(this).parent().attr('val') * 64;
            $('.votes_active').width(width + 'px');
        }
    );

    $('.votes_buttons a').click(function () {  
        var idVal = $(this).parent().attr('id');
        var iCnt = $(this).parent().attr('cnt');
        var voteVal = $(this).attr('id');
        var obj = $(this);
        var iSelWidth = voteVal * 64;

        $.post('vote.php', { id: idVal, vote: voteVal }, 
            function(data){ 
                if (data == 1) {
                    width = iSelWidth;
                    $('.votes_active').width(iSelWidth + 'px');
                    iCnt = parseInt(iCnt) + 1;
                    $('.votes_main span b').text(iCnt);
                    $('.votes_buttons').attr('val', voteVal);
                }
            }
        );
    }); 
});

js/jquery-1.5.2.min.js

This is just jQuery library. Available in package.

Step 4. CSS

Now – all used CSS styles:

css/main.css

/* general styles */
*{
    margin:0;
    padding:0;
}

body {
    background-repeat:no-repeat;
    background-color:#bababa;
    background-image: -webkit-radial-gradient(600px 200px, circle, #eee, #bababa 40%);
    background-image: -moz-radial-gradient(600px 200px, circle, #eee, #bababa 40%);
    background-image: -o-radial-gradient(600px 200px, circle, #eee, #bababa 40%);
    background-image: radial-gradient(600px 200px, circle, #eee, #bababa 40%);
    color:#fff;
    font:14px/1.3 Arial,sans-serif;
    min-height:600px;
}

footer {
    background-color:#212121;
    bottom:0;
    box-shadow: 0 -1px 2px #111111;
    display:block;
    height:70px;
    left:0;
    position:fixed;
    width:100%;
    z-index:100;
}

footer h2{
    font-size:22px;
    font-weight:normal;
    left:50%;
    margin-left:-400px;
    padding:22px 0;
    position:absolute;
    width:540px;
}

footer a.stuts,a.stuts:visited{
    border:none;
    text-decoration:none;
    color:#fcfcfc;
    font-size:14px;
    left:50%;
    line-height:31px;
    margin:23px 0 0 110px;
    position:absolute;
    top:0;
}

footer .stuts span {
    font-size:22px;
    font-weight:bold;
    margin-left:5px;
}

.container {
    border:3px #111 solid;
    color:#000;
    margin:20px auto;
    padding:15px;
    position:relative;
    text-align:center;
    width:500px;

    border-radius:15px;
    -moz-border-radius:15px;
    -webkit-border-radius:15px;
}


.votes_main {
    margin: 10px auto;
    overflow: hidden;
    width: 450px;
}
.votes_gray {
    background-image: url("../images/star_gray.png");
    float: left;
    height: 64px;
    position: relative;
}
.votes_active {
    background-image: url("../images/star.png");
    height: 64px;
    left: 0;
    position: absolute;
    top: 0;
    z-index: 1;
}
.votes_buttons {
    left: 0;
    position: absolute;
    top: 0;
    z-index: 2;
}
.votes_button {
    border: medium none;
    height: 64px;
    margin: 0;
    padding: 0;
    width: 64px;
}
.votes_main span {
    color: #333333;
    display: block;
    float: left;
    font-weight: bold;
    font-size: 18px;
    line-height: 64px;
    margin-left: 10px;
}

Step 5. Images

Last step – used images:

star.png
star_gray.png

Live Demo

Conclusion

Today we prepared great voting system for your website. Sure that this material will useful for your own projects. Good luck in your work!

SIMILAR ARTICLES

Sliding single-level menu

0 59
Design Patterns in PHP

0 3178

11 COMMENTS

  1. i uploaded the files to the server and when im open in browser it says “Database query error”. Need Help

  2. Wow I’m too stupid for this. I have downloaded the whole pack so what do I do now?
    How do I get the voting stars up on my website? I have put it in my folder of my website. But how do I get the voting on one of my sites? i only know a little html. This is brain surgery damnit :S :S :S I need this so bad. there are so many files but how do I get it all to work? where’s the explanation for stupid beginners?

    Im a beginner as you can see.

    • Hello Olof,
      I recommend that you get a least some basic knowledge of PHP (and mysql) to understand our lesson.

  3. Hi,

    Having trouble downloading the package. Sharing it with facebook, but doesn’t open the download option. Any other options?

  4. Thank you Andrew, I needed this voting system… Unfortunately, I’m unable to fin the link to load the pack. Heeeelp!

    Thanks a lot for the infoemation.

    • Hello Claude,
      You need to share the post to unlock the package. Please find the corresponding section in the beginning of this tutorial

Leave a Reply to Gregory Clayton Cancel reply