Welcome Guest, Not a member yet? Register   Sign In
Ajax star rating bar
#1

[eluser]wiredesignz[/eluser]
Here's the completed port as discussed.

Please read page 2 of this thread for the BUG fix.

Original files can be found here: http://www.masugadesign.com/the-lab/scri...ating-bar/

You only need the assets (css, js, images) from the download and nothing needs to be altered in the original files.

Enable query strings and set uri_protocol in application/config/config.php
Code:
$config['uri_protocol']    = "PATH_INFO";

$config['enable_query_strings'] = TRUE;
$config['directory_trigger']    = 'd';
$config['controller_trigger']   = 'x';   //remove the `c` conflict
$config['function_trigger']     = 'm';

Create application/config/ratings.php
Code:
$config['rating_unitwidth'] = 30;
$config['nojspage'] = 'welcome';     //redirects here if javascript is disabled

Modify application/config/autoload.php
Code:
$autoload['config'] = array('ratings');

Modify application/config/routes.php
Code:
$route['rpc.php'] = 'ratings_rpc/index';
#2

[eluser]wiredesignz[/eluser]
Create application/controllers/ratings_rpc.php
Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Ratings_rpc extends Controller
{
    function Ratings_rpc()
    {
        parent::Controller();
        $this->load->model('ratings_model');
        
        $this->output->set_header("Cache-Control: no-cache");
        $this->output->set_header("Pragma: nocache");
    }
    
    function index()
    {
        //get the values
        $vote_sent  = preg_replace("/[^0-9]/", "", $this->input->get('j'));
        $id_sent    = preg_replace("/[^0-9a-zA-Z]/", "", $this->input->get('q'));
        $ip_num     = preg_replace("/(^0-9\.)/", "", $this->input->get('t'));
        $units      = preg_replace("/(^0-9)/", "", $this->input->get('c'));
        $ip         = $this->input->ip_address();
        
        //added detection for javascript being disabled
        $nojs = preg_replace("/(^0-1)/", "", $this->input->get('r'));

        // kill the script because normal users will never see this.
        if ($vote_sent > $units) die("Sorry, vote appears to be invalid.");
        
        //default values
        $checkIP = NULL;
        $count = 0;
        $current_rating = 0;
        $sum = 0;
        $tense = "votes"; // 0 votes
        
        //get the current values!
        if ($numbers = $this->ratings_model->findBy_id($id_sent))
        {
            $checkIP = unserialize($numbers['used_ips']);
            $count = $numbers['total_votes']; //how many votes total
            $current_rating = $numbers['total_value']; //total number of rating
            $sum = $vote_sent + $current_rating; // add together the current vote value and the total vote value
            $tense = ($count == 1) ? "vote" : "votes"; //plural form votes/vote
        }
        
        // checking to see if the first vote has been tallied or increment the current number of votes
        ($sum == 0 ? $added = 0 : $added = $count + 1);
        
        // if it is an array i.e. already has entries the push in another value
        (is_array($checkIP) ? array_push($checkIP, $ip_num) : $checkIP = array($ip_num));
        
        //if the user hasn't yet voted, then vote normally...
        if ($this->ratings_model->countBy_ip($ip, $id_sent) == 0)
        {            
            //make sure vote is valid and IP matches - no monkey business!
            if ($vote_sent > 0 && $ip == $ip_num)
            {
                $this->ratings_model->updateBy_id($id_sent, array(
                    'total_votes' => $added,
                    'total_value' => $sum,
                    'used_ips'    => serialize($checkIP),
                ));
            }
        }
        
        //get the new values!
        if ($numbers = $this->ratings_model->findBy_id($id_sent))
        {
            $checkIP = unserialize($numbers['used_ips']);
            $count = $numbers['total_votes']; //how many votes total
            $current_rating = $numbers['total_value']; //total number of rating
            $tense = ($count == 1) ? "vote" : "votes"; //plural form votes/vote
        }    
        
        $data = array(
            'id_sent' => $id_sent,
            'current_rating' => $current_rating,
            'count' => $count,
            'sum'   => $sum,
            'added' => $added,
            'units' => $units,
            'tense' => $tense,
            'rating_unitwidth' => $this->config->item('rating_unitwidth'),
        );
        
        if($nojs) //javascript is disabled
        {
            //set $nojspage value in config
            redirect($this->config->item('nojspage'));
        }

        $this->load->view('newback_view', $data);
    }
}
#3

[eluser]wiredesignz[/eluser]
Create application/models/ratings_model.php
Code:
<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

class Ratings_model extends Model
{
    function Ratings_model()
    {
        parent::Model();
    }
    
    function bar($id, $units = '', $static = '')
    {
        //set some variables
        ($units)  OR $units = 10;
        ($static) OR $static = FALSE;
        
        $ip = $this->input->ip_address();
        $rating_unitwidth = $this->config->item('rating_unitwidth');
        
        //default values
        $count = 0;
        $current_rating = 0;
        $tense = "votes"; // 0 votes
        
        // get votes, values, ips for the current rating bar
        if (!$numbers = $this->findBy_id($id))
        {
            // insert the id in the DB if it doesn't exist already
            $data = array(
                'id' => $id,
                'total_votes' => $count,
                'total_value' => $current_rating,
                'used_ips' => '',
            );
            $this->insert($data);
        }
        else
        {
            $count = $numbers['total_votes']; //how many votes total        
            $current_rating = $numbers['total_value']; //total number of rating
            $tense = ($count == 1) ? "vote" : "votes"; //plural form votes/vote
        }
        
        $voted = (bool)$this->countBy_ip($ip, $id);

        //more default values
        $rating_width = 0;
        $rating1 = 0;
        $rating2 = 0;
        
        // now draw the rating bar
        if ($count > 0)
        {
            $rating_width = number_format($current_rating/$count,2) * $rating_unitwidth;
            $rating1 = number_format($current_rating/$count,1);
            $rating2 = number_format($current_rating/$count,2);
        }
        
        $data = array(
            'id' => $id,
            'current_rating' => $current_rating,
            'count' => $count,
            'units' => $units,
            'tense' => $tense,
            'voted' => $voted,
            'rating_width' => $rating_width,
            'rating1' => $rating1,
            'rating2' => $rating2,
            'rating_unitwidth' => $rating_unitwidth,
            'ip' => $ip,
        );
        
        if ($static == 'static')
        {
            return $this->load->view('static_rating_view', $data, TRUE);
        }
        else
        {
            return $this->load->view('dynamic_rating_view', $data, TRUE);
        }
    }
    
    function findBy_id($id)
    {
        $this->db->select('total_votes, total_value, used_ips');
        $query = $this->db->getwhere('ratings', "id = '{$id}'");
        return $query->row_array();
    }
    
    function countBy_ip($ip, $id)
    {
        $this->db->select('used_ips');
        $query = $this->db->getwhere('ratings', "used_ips LIKE '%{$ip}%' AND id = '{$id}'");
        return count($query->result());        
    }
    
    function updateBy_id($id, $data)
    {
        $this->db->where('id', $id);
        $this->db->update('ratings', $data);
    }
    
    function insert($data)
    {
        $this->db->insert('ratings', $data);
    }
}
#4

[eluser]wiredesignz[/eluser]
Create Views:

application/views/newback_view.php
Code:
unit_long<?= $id_sent ?>|
<ul class="unit-rating" style="width: &lt;?= $units*$rating_unitwidth ?&gt;px;">
    <li class="current-rating" style="width: &lt;?= @number_format($current_rating/$count,2)*$rating_unitwidth ?&gt;px;">Current rating.</li>
    <li class="r1-unit">1</li>
    <li class="r2-unit">2</li>
    <li class="r3-unit">3</li>
    <li class="r4-unit">4</li>
    <li class="r5-unit">5</li>
    <li class="r6-unit">6</li>
    <li class="r7-unit">7</li>
    <li class="r8-unit">8</li>
    <li class="r9-unit">9</li>
    <li class="r10-unit">10</li>
</ul>
<p class="voted">&lt;?= $id_sent ?&gt; Rating: <strong>&lt;?= @number_format($sum/$added,1) ?&gt;</strong>/&lt;?= $units.' ('.$count.' '.$tense.' cast)' ?&gt;
<span class="thanks">Thanks for voting!</span></p>

static_rating_view.php
Code:
<div class="ratingblock">
    <div id="unit_long&lt;?= $id ?&gt;">
        <ul id="unit_ul&lt;?= $id ?&gt;" class="unit-rating" style="width: &lt;?= $rating_unitwidth*$units ?&gt;px;">
            <li class="current-rating" style="width: &lt;?= $rating_width ?&gt;px;">Currently &lt;?= $rating2.'/'.$units ?&gt;</li>
        </ul>
        <p class="static">&lt;?= $id ?&gt; Rating: <strong>&lt;?= $rating1 ?&gt;</strong>/&lt;?= $units.' ('.$count.' '.$tense.' cast)' ?&gt; <em>This is static</em></p>
    </div>
</div>

dynamic_rating_view.php
Code:
<div class="ratingblock">
    <div id="unit_long&lt;?= $id ?&gt;">
        <ul id="unit_ul&lt;?= $id ?&gt;" class="unit-rating" style="width: &lt;?= $rating_unitwidth*$units ?&gt;px;">
            <li class="current-rating" style="width: &lt;?= $rating_width ?&gt;px;">Currently &lt;?= $rating2.'/'.$units ?&gt;</li>
            &lt;?php
                for ($i = 1; $i <= $units; $i++) // loop from 1 to the number of units
                {
                   if (!$voted) // if the user hasn't yet voted, draw the voting stars
                   {
                      // r=1 in url provides for javascript being disabled
                      echo '<li><a href="rpc.php?j='.$i.'&amp;q='.$id.'&amp;t='.$ip.'&amp;c='.$units.'&amp;r=1" title="'.$i.' out of '.$units.'" class="r'.$i.'-unit rater" rel="nofollow">'.$i.'</a></li>';
                   }
                }
                $i = 0;
                $pclass = ($voted) ? ' class="voted"' : '';
              ?&gt;
        </ul>
        <p&lt;?= $pclass ?&gt;>&lt;?= $id ?&gt; Rating: <strong>&lt;?= $rating1 ?&gt;</strong>/&lt;?= $units.' ('.$count.' '.$tense.' cast)' ?&gt;</p>
    </div>
</div>
#5

[eluser]wiredesignz[/eluser]
Usage:

Create your page controller: application/controllers/welcome.php (`welcome` for this demo)
Code:
class Welcome extends Controller
{    
    function Welcome()
    {
        parent::Controller();
        $this->load->model('ratings_model', 'ratings');
    }
    
    function index()
    {                
        $this->load->view('welcome_view');
    }
}

Create application/views/welcome_view.php (css, js, images dirs are in webroot)
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
&lt;html lang="en" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&gt;
&lt;head&gt;
&lt;meta http-equiv="content-type" content="text/html; charset=utf-8"&gt;
&lt;title&gt;Multiple Ajax Star Rating Bars&lt;/title&gt;

&lt;script type="text/javascript" language="javascript" src="js/behavior.js">
&lt;script type="text/javascript" language="javascript" src="js/rating.js">

&lt;link rel="stylesheet" type="text/css" href="css/default.css" /&gt;
&lt;link rel="stylesheet" type="text/css" href="css/rating.css" /&gt;
&lt;/head&gt;

&lt;body&gt;

<div id="container">
<h1>Unobtrusive AJAX Star Rating Bar</h1>

<h2>v 1.2.2, March 18, 2007</h2>

<p>CodeIgniter port by Wiredesignz, 2008-02-14</p>
<br />
    
&lt;?php echo $this->ratings->bar('id21',''); ?&gt;
&lt;?php echo $this->ratings->bar('id22',''); ?&gt;
&lt;?php echo $this->ratings->bar('id1',''); ?&gt;
&lt;?php echo $this->ratings->bar('2id',5); ?&gt;
&lt;?php echo $this->ratings->bar('3xx',6); ?&gt;
&lt;?php echo $this->ratings->bar('4test',8); ?&gt;
&lt;?php echo $this->ratings->bar('5560'); ?&gt;
&lt;?php echo $this->ratings->bar('66234','','static'); ?&gt;
&lt;?php echo $this->ratings->bar('66334',''); ?&gt;
&lt;?php echo $this->ratings->bar('63334',''); ?&gt;

<br /><br />
<a href="http://www.masugadesign.com/the-lab/scripts/unobtrusive-ajax-star-rating-bar/">(Unobtrusive) AJAX Star Rating Bar Homepage</a>

</div>

&lt;/body&gt;
&lt;/html&gt;

And you're good to go!
#6

[eluser]wiredesignz[/eluser]
Almost forgot:

Create the ratings table:
Code:
-- Table structure for table `ratings`

CREATE TABLE `ratings` (
  `id` varchar(11) NOT NULL,
  `total_votes` int(11) NOT NULL default '0',
  `total_value` int(11) NOT NULL default '0',
  `used_ips` longtext,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

And don't forget to set up your database connection.

application/config/database.php
#7

[eluser]wiredesignz[/eluser]
The demo can be found here: [Removed]
#8

[eluser]Isern Palaus[/eluser]
Hey wiredesignz,

A very nice tutorial. I'll include on my new project for testing how it work ;-). I recently coded a "AJAX Tutorial" to, for a simple login in CI.

http://ellislab.com/forums/viewthread/71636/

Regards,
-- Isern Palaus
#9

[eluser]wiredesignz[/eluser]
Yes thanks, I saw your tutorial, very nice.
#10

[eluser]taewoo[/eluser]
wiredesignz: I bask in your super awesome gloriness.




Theme © iAndrew 2016 - Forum software by © MyBB