Content organization on the number of votes

Content organization on the number of votes

3 54070
Content organization on the number of votes
Content organization on the number of votes

Content organization on the number of votes

Quite often, we have the task to display any content (from the database) on the screen, many may argue that this is quite simple and trite. This is true, but when we have additional social components, for example on how to sort records by the number of comments or by rating – many novice webmasters can fall into confusion. Today we will consider the question of how to display the records by the number of gained votes. To do this, we will prepare a simple voting system.

Live Demo

First of all, I recommend that you check our demo to understand how it works. Now, we are ready to start


Step 1. SQL

Firstly, let’s prepare a new table in the database with some dummy records. If you are not familiar with the procedure of execution SQL requests, you can search in google about how to do it. But, basically, you just need to open phpMyAdmin, select your database, then click the ‘SQL’ tab, and put here the whole SQL query, and then – execute the query.

CREATE TABLE IF NOT EXISTS `s395_posts` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `title` varchar(255) default '',
  `description` text NOT NULL,
  `when` int(11) NOT NULL default '0',
  `votecnt` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `s395_posts` (`title`, `description`, `when`, `votecnt`) VALUES
('First post', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ac neque tortor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum id convallis velit. Sed aliquet nibh vitae lorem tincidunt, quis consequat lectus blandit. Nullam augue mauris, placerat in ante non, fermentum ornare quam. Cras et fermentum purus. Ut elit mauris, blandit sit amet condimentum eu, ornare vel ligula.', UNIX_TIMESTAMP(), 0),
('Second post', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ac neque tortor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum id convallis velit. Sed aliquet nibh vitae lorem tincidunt, quis consequat lectus blandit. Nullam augue mauris, placerat in ante non, fermentum ornare quam. Cras et fermentum purus. Ut elit mauris, blandit sit amet condimentum eu, ornare vel ligula.', UNIX_TIMESTAMP() + 1, 0),
('Third post', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ac neque tortor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum id convallis velit. Sed aliquet nibh vitae lorem tincidunt, quis consequat lectus blandit. Nullam augue mauris, placerat in ante non, fermentum ornare quam. Cras et fermentum purus. Ut elit mauris, blandit sit amet condimentum eu, ornare vel ligula.', UNIX_TIMESTAMP() + 2, 0),
('Fourth post', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ac neque tortor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum id convallis velit. Sed aliquet nibh vitae lorem tincidunt, quis consequat lectus blandit. Nullam augue mauris, placerat in ante non, fermentum ornare quam. Cras et fermentum purus. Ut elit mauris, blandit sit amet condimentum eu, ornare vel ligula.', UNIX_TIMESTAMP() + 3, 0),
('Fifth post', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ac neque tortor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum id convallis velit. Sed aliquet nibh vitae lorem tincidunt, quis consequat lectus blandit. Nullam augue mauris, placerat in ante non, fermentum ornare quam. Cras et fermentum purus. Ut elit mauris, blandit sit amet condimentum eu, ornare vel ligula.', UNIX_TIMESTAMP() + 4, 0);

The table with records (s395_posts) contains the following fields:

  • id – unique post id
  • title – post title
  • description – post description (text)
  • when – post date
  • votecnt – votes count

Step 2. PHP

In order to work with the database, we will use an existing class that we developed in the past (classes/CMySQL.php). I want to remind that the database credentials are found in this file, so don’t forget to put details of your database into this file:

classes/CMySQL.php

    // constructor
    function CMySQL() {
        $this->sDbName = '_YOUR_DB_NAME_';
        $this->sDbUser = '_YOUR_DB_USERNAME_';
        $this->sDbPass = '_YOUR_DB_USERPASS_';

Now we will begin the creation of a new class where we arrange all the necessary functions for our demonstration:

  • getRecentPosts – this function returns the recent posts (with order by id)
  • getTopPosts – this function returns the recent posts (with order by count of votes)
  • resultToHtml – this function converts an array of data into html output code
  • addVote – this function accepts new votes
  • getVisitorIP – this function returns a visitor IP address

classes/CPosts.php

<?php
require_once('CMySQL.php'); // include the database class
class CPosts {
    // constructor
    function CPosts() {
    }
    // get recent (last) posts
    function getRecentPosts() {
        $a = $GLOBALS['MySQL']->getAll("SELECT * FROM `s395_posts` ORDER BY `id` DESC");
        return $this->resultToHtml($a);
    }
    // get top posts
    function getTopPosts() {
        $a = $GLOBALS['MySQL']->getAll("SELECT * FROM `s395_posts` ORDER BY `votecnt` DESC");
        return $this->resultToHtml($a);
    }
    // turn array of results into html output
    function resultToHtml($a) {
        $posts = '';
        foreach ($a as $i => $post) {
            $posts .= <<<EOF
<article id="{$post['id']}">
    <h2>{$post['title']}</h2>
    <i>{$post['description']}</i>
    <b>( {$post['votecnt']} votes )</b>
    <button>vote up</button>
</article>
EOF;
        }
        return $posts;
    }
    // add vote
    function addVote($i) {
        if ($this->getVisitorIP()) {
            $GLOBALS['MySQL']->res("UPDATE `s395_posts` SET `votecnt` = `votecnt` + 1 WHERE `id` = '{$i}'");
        }
    }
    // get visitor IP address
    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;
    }
}
$GLOBALS['CPosts'] = new CPosts();

Now, let’s create a basic index.php file which we’ll run

index.php

<?php
require_once('classes/CPosts.php'); // include the main class
// accept a vote
if ($_POST && $_POST['action'] == 'vote' && (int)$_POST['id']) {
    $GLOBALS['CPosts']->addVote((int)$_POST['id']);
    echo 1; exit;
}
$recent_posts = $GLOBALS['CPosts']->getRecentPosts();
$top_posts = $GLOBALS['CPosts']->getTopPosts();
?>
<!DOCTYPE html>
<html lang="en" >
    <head>
        <meta charset="utf-8" />
        <title>Content organization on the number of votes | Script Tutorials</title>
        <link href="css/main.css" rel="stylesheet" type="text/css" />
        <script type="text/javascript" src="js/jquery-1.10.2.js"></script>
    </head>
    <body>
        <header>
            <h2>Back to '<a href="https://www.script-tutorials.com/xxxxxxxxxxxxx/">Content organization on the number of votes</a>' tutorial</h2>
        </header>
        <div class="container">
            <div class="section">
                <h1>Top posts:</h1>
                <?= $top_posts ?>
            </div>
            <div class="section">
                <h1>Recent posts:</h1>
                <?= $recent_posts ?>
            </div>
        </div>
        <script>
        $(window).load(function() {
            $('article button').click(function(e) {
                var id = $(this).parent().attr('id');
                if (id) {
                    $.post('index.php', { action: 'vote', id: id }, function(data) {
                        if (data) {
                            location.reload();
                        }
                    });
                }
            });
        });
        </script>
    </body>
</html>

This is quite basic file which generates our page, it also accepts the POST action (upvote) that is sent by clicking on buttons that are located inside of each post.

Step 3. CSS

After the creation of the main functionality – we can move on to the design styles of all the used elements, that’s what we’ve got:

css/main.css

*{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;
}
.container {
    border:1px #111 solid;
    color:#000;
    margin:20px auto;
    overflow: hidden;
    padding:10px;
    position:relative;
    width:90%;
    border-radius:2px;
    -moz-border-radius:2px;
    -webkit-border-radius:2px;
}
.section {
    float: left;
    margin: 0 1%;
    width: 48%;
}
article {
    margin:1em 0;
}
button {
    background: #e3e3e3;
    border: 1px solid #bbb;
    border-radius: 3px;
    -webkit-box-shadow: inset 0 0 1px 1px #f6f6f6;
    box-shadow: inset 0 0 1px 1px #f6f6f6;
    color: #333;
    display: block;
    font-weight: bold;
    padding: 8px 0 9px;
    text-align: center;
    text-shadow: 0 1px 0 #fff;
    width: 150px;
}
button:hover {
    background: #d9d9d9;
    -webkit-box-shadow: inset 0 0 1px 1px #eaeaea;
    box-shadow: inset 0 0 1px 1px #eaeaea;
    color: #222;
    cursor: pointer;
}
button:active {
    background: #d0d0d0;
    -webkit-box-shadow: inset 0 0 1px 1px #e3e3e3;
    box-shadow: inset 0 0 1px 1px #e3e3e3;
    color: #000;
}

Live Demo

[sociallocker]

download in archive

[/sociallocker]


Conclusion

That’s it for today. Our rating system with the output of records which are sorted by amount of votes is ready. Welcome back to our new articles.

SIMILAR ARTICLES

Design Patterns in PHP

0 114930
Polaroid gallery

0 59965

3 COMMENTS

  1. I’m trying to incorporate this voting functionality into your Pinterest tutorial’s layout. My goal is to have the ‘Vote Up’ button on each of the Pinterest-style posts and have them rearrange based on number of votes. Is this possible?

Leave a Reply