How can I implement a voting system on my site limiting votes to a single vote?
<p>I am trying to build a site with news links that can be voted, I have the following code:</p>

<pre><code> case 'vote':
                require_once('auth/auth.php');
                if(Auth::isUserLoggedIn())
                {
                    require_once('data/article.php');
                    require_once('includes/helpers.php');

                    $id = isset($_GET['param'])? $_GET['param'] : 0;
                    if($id &gt; 0)
                    {
                        $article = Article::getById($id);
                        $article-&gt;vote();
                        $article-&gt;calculateRanking();
                    }
                    if(!isset($_SESSION)) session_start();
                    redirectTo($_SESSION['action'], $_SESSION['param']);
                }
                else
                {
                    Auth::redirectToLogin(); 
                }
                break;
</code></pre>

<p>The problem right now is how to check so the same user does not vote twice, here is the article file:</p>

<pre><code>&lt;?php
require_once($_SERVER['DOCUMENT_ROOT'].'/config.php'); 
require_once(SITE_ROOT.'includes/exceptions.php'); 
require_once(SITE_ROOT.'data/model.php');
require_once(SITE_ROOT.'data/comment.php');

class Article extends Model 
{
    private $id;
    private $user_id;
    private $url;
    private $title;
    private $description;
    private $ranking;
    private $points;

    function __construct($title = ' ', $description = ' ', $url = ' ', $username = ' ', $created = ' ', $modified = '') {

        $this-&gt;setId(0);
        $this-&gt;setCreated($created);
        $this-&gt;setModified($modified);
        $this-&gt;setUsername($username);
        $this-&gt;setUrl($url);
        $this-&gt;setTitle($title);
        $this-&gt;setDescription($description);
        $this-&gt;setRanking(0.0);
        $this-&gt;setPoints(1); 
    }

    function getId(){
        return $this-&gt;id;
    }

    private function setId($value){
        $this-&gt;id = $value;
    }

    function getUsername(){
        return $this-&gt;username;
    }

    function setUsername($value){
        $this-&gt;username = $value;
    }

    function getUrl(){
        return $this-&gt;url;
    }

    function setUrl($value){
        $this-&gt;url = $value;
    }

    function getTitle()
    {
        return $this-&gt;title;
    }

    function setTitle($value) {

        $this-&gt;title = $value;
    }

    function getDescription() {

    return $this-&gt;description;
    }

    function setDescription($value)
    {
        $this-&gt;description = $value;
    }

    function getPoints()
    {
        return $this-&gt;points;
    }

    function setPoints($value) 
    {
        $this-&gt;points = $value;
    }

    function getRanking()
    {
        return $this-&gt;ranking;
    }

    function setRanking($value)
    {
        $this-&gt;ranking = $value;
    }

    function calculateRanking()
    {
        $created = $this-&gt;getCreated();

        $diff = $this-&gt;getTimeDifference($created, date('F d, Y h:i:s A'));

        $time = $diff['days'] * 24;
        $time += $diff['hours'];
        $time += ($diff['minutes'] / 60);
        $time += (($diff['seconds'] / 60)/60);

        $base = $time + 2;        

        $this-&gt;ranking = ($this-&gt;points - 1) / pow($base, 1.5);

        $this-&gt;save();
    }

    function vote()
    {
        $this-&gt;points++;
        $this-&gt;save();
    }

    function getUrlDomain()
    {
        /* We extract the domain from the URL
         * using the following regex pattern
         */

        $url = $this-&gt;getUrl();
        $matches = array(); 
        if(preg_match('/http:\/\/(.+?)\//', $url, $matches))
        {
            return $matches[1];
        }
        else
        {
            return $url;
        }
    }

    function getTimeDifference( $start, $end )
    {
        $uts['start']      =    strtotime( $start );
        $uts['end']        =    strtotime( $end );
        if( $uts['start']!==-1 &amp;&amp; $uts['end']!==-1 )
        {
            if( $uts['end'] &gt;= $uts['start'] )
            {
                $diff    =    $uts['end'] - $uts['start'];
                if( $days=intval((floor($diff/86400))) )
                    $diff = $diff % 86400;
                if( $hours=intval((floor($diff/3600))) )
                    $diff = $diff % 3600;
                if( $minutes=intval((floor($diff/60))) )
                    $diff = $diff % 60;
                $diff    =    intval( $diff );
                return( array('days'=&gt;$days, 'hours'=&gt;$hours, 'minutes'=&gt;$minutes, 'seconds'=&gt;$diff) );
            }
            else
            {
                echo( "Ending date/time is earlier than the start date/time");
            }
        }
        else
        {
            echo( "Invalid date/time data detected");
        }
        return( false );
    }



    function getElapsedDateTime()
    {
        $db = null;
        $record = null;

        $record = Article::getById($this-&gt;id);
        $created = $record-&gt;getCreated();         

        $diff = $this-&gt;getTimeDifference($created, date('F d, Y h:i:s A'));
        //echo 'new date is '.date('F d, Y h:i:s A');
        //print_r($diff);

        if($diff['days'] &gt; 0 )
        {
            return sprintf("hace %d dias", $diff['days']);
        }
        else if($diff['hours'] &gt; 0 )
        {
            return sprintf("hace %d horas", $diff['hours']);
        }
        else if($diff['minutes'] &gt; 0 )
        {
            return sprintf("hace %d minutos", $diff['minutes']);
        }
        else
        {
            return sprintf("hace %d segundos", $diff['seconds']);
        }
    }

    function save() {

    /*
            Here we do either a create or
            update operation depending
            on the value of the id field.
            Zero means create, non-zero
            update
    */

        if(!get_magic_quotes_gpc())
        {
            $this-&gt;title = addslashes($this-&gt;title);
            $this-&gt;description = addslashes($this-&gt;description);
        }

        try
        {
            $db = parent::getConnection();
            if($this-&gt;id == 0 )
            {
                $query = 'insert into articles (modified, username, url, title, description, points )';
                $query .= " values ('$this-&gt;getModified()', '$this-&gt;username', '$this-&gt;url', '$this-&gt;title', '$this-&gt;description', $this-&gt;points)";
            }
            else if($this-&gt;id != 0)
            {
                $query = "update articles set modified = NOW()".", username = '$this-&gt;username', url = '$this-&gt;url', title = '".$this-&gt;title."', description = '".$this-&gt;description."', points = $this-&gt;points, ranking = $this-&gt;ranking where id = $this-&gt;id";
            }

            $lastid = parent::execSql2($query);

            if($this-&gt;id == 0 )
                $this-&gt;id = $lastid;

        }
        catch(Exception $e){
            throw $e;
        }
    }


    function delete()
    {
        try
        {
            $db = parent::getConnection();
            if($this-&gt;id != 0)
            {                ;
                /*$comments = $this-&gt;getAllComments();
                foreach($comments as $comment)
                {
                    $comment-&gt;delete();
                }*/
                $this-&gt;deleteAllComments();
                $query = "delete from articles where id = $this-&gt;id";
            }
            parent::execSql($query);


        }
        catch(Exception $e){
            throw $e;
        }
    }

    static function getAll($conditions = ' ')
    {
        /* Retrieve all the records from the
         * database according subject to
         * conditions
         */

        $db = null;
        $results = null;
        $records = array();
        $query = "select id, created, modified, username, url, title, description, points, ranking from articles $conditions";
        try
        {
            $db = parent::getConnection();

            $results = parent::execSql($query);

            while($row = $results-&gt;fetch_assoc())
            {
                $r_id = $row['id'];
                $r_created = $row['created'];
                $r_modified = $row['modified'];

                $r_title = $row['title'];
                $r_description = $row['description'];

                if(!get_magic_quotes_gpc())
                {
                    $r_title = stripslashes($r_title);
                    $r_description = stripslashes($r_description);
                }

                $r_url = $row['url'];
                $r_username = $row['username'];
                $r_points = $row['points'];
                $r_ranking = $row['ranking'];

                $article = new Article($r_title, $r_description , $r_url, $r_username, $r_created, $r_modified);
                $article-&gt;id = $r_id;
                $article-&gt;points = $r_points;
                $article-&gt;ranking = $r_ranking;
                $records[] = $article;
            }
            parent::closeConnection($db);
        }
        catch(Exception $e)
        {
            throw $e;
        }

        return $records;
    }

    static function getById($id)
    {/*
     *  Return one record from the database by its id */

        $db = null;
        $record = null;

        try
        {
            $db = parent::getConnection();
            $query = "select id, username, created, modified, title, url, description, points, ranking from articles where id = $id";
            $results = parent::execSQL($query);
            if(!$results) {
                throw new Exception ('Record not found', EX_RECORD_NOT_FOUND);
            }

            $row = $results-&gt;fetch_assoc();
            parent::closeConnection($db);

            if(!get_magic_quotes_gpc())
            {
                $row['title'] = stripslashes($row['title']);
                $row['description'] = stripslashes($row['description']);
            }


            $article = new Article($row['title'], $row['description'], $row['url'], $row['username'], $row['created'], $row['modified']);
            $article-&gt;id = $row['id'];
            $article-&gt;points = $row['points'];
            $article-&gt;ranking = $row['ranking']; 
            return $article;

        }
        catch (Exception $e){
            throw $e;
        }
    }

    static function getNumberOfComments($id)
    {/*
     *  Return one record from the database by its id */

        $db = null;
        $record = null;

        try
        {
            $db = parent::getConnection();
            $query = "select count(*) as 'total' from comments where article_id = $id";
            $results = parent::execSQL($query);
            if(!$results) {
                throw new Exception ('Comments Count Query Query Failed', EX_QUERY_FAILED);
            }

            $row = $results-&gt;fetch_assoc();
            $total = $row['total'];
            parent::closeConnection($db);    

            return $total;


        }
        catch (Exception $e){
            throw $e;
        }
    }

    function deleteAllComments()
    {/*
     *  Return one record from the database by its id */

        $db = null;
        try
        {
            $db = parent::getConnection();
            $query = "delete from comments where article_id = $this-&gt;id";
            $results = parent::execSQL($query);
            if(!$results) {
                throw new Exception ('Deletion Query Failed', EX_QUERY_FAILED);
            }
            parent::closeConnection($db);
        }
        catch (Exception $e){
            throw $e;
        }
    }


    function getAllComments($conditions = ' ')
    {
        /* Retrieve all the records from the
         * database according subject to
         * conditions
         */
        $conditions = "where article_id = $this-&gt;id";
        $comments = Comment::getAll($conditions);
        return $comments; 
    }


    static function getTestData($url)
    {
        $page = file_get_contents($url);




    }

}
?&gt;
</code></pre>

<p>Any suggestion or comment is appreciated, Thanks.</p>
