Just a few days before, Facebook has launched Reactions, an extension of Like button. I succeeded in implementing the same in my WallScript 8, Build Your Own Social Network. Here is a quick and easy way to implement the Reactions using PHP,Jquery and PDO MySQL. It’s a basic idea of implementing the Reactions. Hope you enjoy the new Reactions for Like button..! Take a quick look at the live demo.
Download Script Live Demo
Database Design
To build the message like reaction system, you have to create four tables such as Users, Messages, Message_Like and Reactions. This following image generated by using Mysql Workbench tool.
Users Table
User table contains all the users registration details.
CREATE TABLE `users` (
`uid` int NOT NULL PRIMARY KEY AUTO_INCREMENT ,
`username` varchar(25) NOT NULL UNIQUE,
`password` varchar(50) NOT NULL ,
`email` varchar(100) NOT NULL,
`name` varchar(100) NOT NULL,
`profile_pic` varchar(200) NOT NULL,
);
`uid` int NOT NULL PRIMARY KEY AUTO_INCREMENT ,
`username` varchar(25) NOT NULL UNIQUE,
`password` varchar(50) NOT NULL ,
`email` varchar(100) NOT NULL,
`name` varchar(100) NOT NULL,
`profile_pic` varchar(200) NOT NULL,
);
Data will store in following way, here the password data PHP login script with PDO and HASH encryption.
Users
Messages Table
This table contains user status messages data. Here uid_fk is the FOREIGN KEY to REFERENCES users.uid
CREATE TABLE `messages` (
`msg_id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`message` varchar(200) NOT NULL,
`uid_fk` int(11) NOT NULL,
`like_count` int(11) DEFAULT NULL,
`created` int(11) DEFAULT NULL,
FOREIGN KEY (uid_fk) REFERENCES users(uid)
);
`msg_id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`message` varchar(200) NOT NULL,
`uid_fk` int(11) NOT NULL,
`like_count` int(11) DEFAULT NULL,
`created` int(11) DEFAULT NULL,
FOREIGN KEY (uid_fk) REFERENCES users(uid)
);
Messages
Reactions Table
This table contains reaction data names.
CREATE TABLE reactions(
'rid' INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
'name' VARCHAR(45) NOT NULL
);
'rid' INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
'name' VARCHAR(45) NOT NULL
);
Reactions
Message Like Table
Contains all user message likes relation data. Here uid_fk is FOREIGN KEY to REFERENCES users.uid, rid_fk is FOREIGN KEY to REFERENCES reactions.rid and msg_id_fk is FOREIGN KEY to REFERENCES messages.msg_id
CREATE TABLE `message_like` (
`like_id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`msg_id_fk` int(11),
`uid_fk` int(11) NOT NULL,
`created` int(11) NOT NULL,
`rid_fk` int(11) NOT NULL,
FOREIGN KEY (uid_fk) REFERENCES users(uid),
FOREIGN KEY (msg_id_fk) REFERENCES messages(msg_id),
FOREIGN KEY (rid_fk) REFERENCES reactions(rid)
);
`like_id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`msg_id_fk` int(11),
`uid_fk` int(11) NOT NULL,
`created` int(11) NOT NULL,
`rid_fk` int(11) NOT NULL,
FOREIGN KEY (uid_fk) REFERENCES users(uid),
FOREIGN KEY (msg_id_fk) REFERENCES messages(msg_id),
FOREIGN KEY (rid_fk) REFERENCES reactions(rid)
);
message_like
JavaScript Libraries
You have to include following JavaScript libraries. I have modified jquery tooltipster plugin for reactions popup.
<link rel="stylesheet" type="text/css" href="css/tooltipsterReaction.css">
<link rel="stylesheet" type="text/css" href="css/tipsy.css">
<script src="js/jquery.min.js"></script>
<script src="js/jquery.livequery.js"></script>
<script src="js/jquery.tooltipsterReaction.js"></script>
<script src="js/jquery.tipsy.js"></script>
<link rel="stylesheet" type="text/css" href="css/tipsy.css">
<script src="js/jquery.min.js"></script>
<script src="js/jquery.livequery.js"></script>
<script src="js/jquery.tooltipsterReaction.js"></script>
<script src="js/jquery.tipsy.js"></script>
Jquery Code
Applying reaction tooltipster to the anchor tag. Tipsy plugin for reaction name tool tip.
$(document).ready(function()
{
//Black tooltip for reaction icons.
$(".likeTypeAction").tipsy({gravity: 's',live: true});
//Reactions popup on mouseover
$(".reaction").livequery(function ()
{
//Reactions HTML Content
var reactionsCode='<span class="likeTypeAction" original-title="Like" data-reaction="1"><i class="likeIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Love" data-reaction="2"><i class="loveIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Haha" data-reaction="3"><i class="hahaIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Wow" data-reaction="4"><i class="wowIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Cool" data-reaction="5"><i class="coolIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Confused" data-reaction="6"><i class="confusedIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Sad" data-reaction="7"><i class="sadIcon likeType"></i></span>'+
'<span class="likeTypeAction last" original-title="Angry" data-reaction="8"><i class="angryIcon likeType"></i></span>';
$(this).tooltipster({
contentAsHTML: true,
interactive: true,
content: $(reactionsCode),
});
});
$("body").on("click",".likeTypeAction",function()
{
.......
.......
}
$("body").on("click",".unLike",function()
{
.......
.......
}
});
//HTML Code
<a href="#" class="reaction" id="like203" rel="like">
<i class="likeIconDefault" ></i>Like</a>
{
//Black tooltip for reaction icons.
$(".likeTypeAction").tipsy({gravity: 's',live: true});
//Reactions popup on mouseover
$(".reaction").livequery(function ()
{
//Reactions HTML Content
var reactionsCode='<span class="likeTypeAction" original-title="Like" data-reaction="1"><i class="likeIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Love" data-reaction="2"><i class="loveIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Haha" data-reaction="3"><i class="hahaIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Wow" data-reaction="4"><i class="wowIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Cool" data-reaction="5"><i class="coolIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Confused" data-reaction="6"><i class="confusedIcon likeType"></i></span>'+
'<span class="likeTypeAction" original-title="Sad" data-reaction="7"><i class="sadIcon likeType"></i></span>'+
'<span class="likeTypeAction last" original-title="Angry" data-reaction="8"><i class="angryIcon likeType"></i></span>';
$(this).tooltipster({
contentAsHTML: true,
interactive: true,
content: $(reactionsCode),
});
});
$("body").on("click",".likeTypeAction",function()
{
.......
.......
}
$("body").on("click",".unLike",function()
{
.......
.......
}
});
//HTML Code
<a href="#" class="reaction" id="like203" rel="like">
<i class="likeIconDefault" ></i>Like</a>
CSS Code
I have implemented image sprite.
.likeType {
background-image: url('../images/like_types.png');
background-size: 100%;
display: block;
height: 40px;
image-rendering: crisp-edges;
line-height: 1;
width: 40px;
cursor: pointer;
}
.angryIcon {
background-position: 0px 0px;
}
.confusedIcon {
background-position: 0px -40px;
}
.hahaIcon {
background-position: 0px -80px;
}
.likeIcon {
background-position: 0px -120px
}
.loveIcon {
background-position:0px -160px;
}
.sadIcon {
background-position: 0px -200px;
}
.wowIcon {
background-position: 0px -240px;
}
.coolIcon {
background-position: 0px -280px;
}
.likeTypeAction{float: left; margin-right: 8px; cursor: pointer;}
background-image: url('../images/like_types.png');
background-size: 100%;
display: block;
height: 40px;
image-rendering: crisp-edges;
line-height: 1;
width: 40px;
cursor: pointer;
}
.angryIcon {
background-position: 0px 0px;
}
.confusedIcon {
background-position: 0px -40px;
}
.hahaIcon {
background-position: 0px -80px;
}
.likeIcon {
background-position: 0px -120px
}
.loveIcon {
background-position:0px -160px;
}
.sadIcon {
background-position: 0px -200px;
}
.wowIcon {
background-position: 0px -240px;
}
.coolIcon {
background-position: 0px -280px;
}
.likeTypeAction{float: left; margin-right: 8px; cursor: pointer;}
Like Ajax
Contains javascript code. $("body").on('click','.likeTypeAction', function(){}- here likeTypeAction is the class name of the reaction icon tag. Using $(this).parent().parent().attr("id") calling icon tag message ID value.
/*Reaction*/
$("body").on("click",".likeTypeAction",function()
{
var reactionType=$(this).attr("data-reaction");
var reactionName=$(this).attr("original-title");
var rel=$(this).parent().parent().attr("rel");
var x=$(this). parent().parent().attr("id");
var sid=x.split("reaction");
var msg_id=sid[1];
var htmlData='<i class="'+reactionName.toLowerCase()+'IconSmall likeTypeSmall" ></i>'+reactionName+'</a>';
var dataString = 'msg_id='+ msg_id +'&rid='+reactionType;
$.ajax({
type: "POST",
url: 'ajaxReaction.php',
data: dataString,
cache: false,
beforeSend: function(){},
success: function(html)
{
if(parseInt(html)==1)
{
$("#like"+msg_id).html(htmlData).removeClass('reaction').removeClass('tooltipstered').addClass('unLike').attr('rel','unlike');
$("#"+x).hide();
}
}
});
return false;
});
$("body").on("click",".likeTypeAction",function()
{
var reactionType=$(this).attr("data-reaction");
var reactionName=$(this).attr("original-title");
var rel=$(this).parent().parent().attr("rel");
var x=$(this). parent().parent().attr("id");
var sid=x.split("reaction");
var msg_id=sid[1];
var htmlData='<i class="'+reactionName.toLowerCase()+'IconSmall likeTypeSmall" ></i>'+reactionName+'</a>';
var dataString = 'msg_id='+ msg_id +'&rid='+reactionType;
$.ajax({
type: "POST",
url: 'ajaxReaction.php',
data: dataString,
cache: false,
beforeSend: function(){},
success: function(html)
{
if(parseInt(html)==1)
{
$("#like"+msg_id).html(htmlData).removeClass('reaction').removeClass('tooltipstered').addClass('unLike').attr('rel','unlike');
$("#"+x).hide();
}
}
});
return false;
});
Unlike Ajax
Contains javascript code. $("body").on('click','.unLike', function(){}- here unLike is the class name of the unlike anchor tag. Using $(this).attr("id") calling anchor tag message ID value.
$("body").on("click",".unLike",function()
{
var reactionType='1';
var x=$(this).attr("id");
var sid=x.split("like");
var msg_id=sid[1];
var dataString = 'msg_id='+ msg_id +'&rid='+reactionType;
var htmlData='<i class="likeIconDefault" ></i>Like</a>';
$.ajax({
type: "POST",
url: 'ajaxReaction.php',
data: dataString,
cache: false,
beforeSend: function(){},
success: function(html)
{
if(parseInt(html)==2)
{
$("#like"+msg_id).html(htmlData).addClass('reaction').addClass('tooltipstered').removeClass('unLike');
}
}
});
return false;
});
{
var reactionType='1';
var x=$(this).attr("id");
var sid=x.split("like");
var msg_id=sid[1];
var dataString = 'msg_id='+ msg_id +'&rid='+reactionType;
var htmlData='<i class="likeIconDefault" ></i>Like</a>';
$.ajax({
type: "POST",
url: 'ajaxReaction.php',
data: dataString,
cache: false,
beforeSend: function(){},
success: function(html)
{
if(parseInt(html)==2)
{
$("#like"+msg_id).html(htmlData).addClass('reaction').addClass('tooltipstered').removeClass('unLike');
}
}
});
return false;
});
index.php
Contains PHP and HTML code, displaying all of the user updates by calling $feed->newsFeed();
<?php
include_once 'config.php';
$feedData=$feed->newsFeed();
?>
<!DOCTYPE html >
<html>
<head>
<!-- JavaScript CSS -->
<link rel="stylesheet" type="text/css" href="css/tooltipsterReaction.css">
<link rel="stylesheet" type="text/css" href="css/tipsy.css">
<link rel="stylesheet" type="text/css" href="css/app.css">
<script src="js/jquery.min.js"></script>
<script src="js/jquery.livequery.js"></script>
<script src="js/jquery.tooltipsterReaction.js"></script>
<script src="js/jquery.tipsy.js"></script>
<script src="js/app.js"></script>
<!-- JavaScript CSS End -->
</head>
<body>
<?php
foreach($feedData as $data)
{
?>
<div class="messageBody" id="msg<?php echo $data->msg_id; ?>">
<img src="<?php echo $data->profile_pic; ?>" class="messageImg"/>
<b><a href="<?php echo BASE_URL.$data->username; ?>"><?php echo $data->name; ?></a></b>
<?php echo $data->message; ?>
<div class="messageFooter">
<a href="#" class="reaction" id="like<?php echo $data->msg_id; ?>" rel="like">
<i class="likeIconDefault" ></i>Like</a>
</div>
</div>
<?php } ?>
</body>
</html>
include_once 'config.php';
$feedData=$feed->newsFeed();
?>
<!DOCTYPE html >
<html>
<head>
<!-- JavaScript CSS -->
<link rel="stylesheet" type="text/css" href="css/tooltipsterReaction.css">
<link rel="stylesheet" type="text/css" href="css/tipsy.css">
<link rel="stylesheet" type="text/css" href="css/app.css">
<script src="js/jquery.min.js"></script>
<script src="js/jquery.livequery.js"></script>
<script src="js/jquery.tooltipsterReaction.js"></script>
<script src="js/jquery.tipsy.js"></script>
<script src="js/app.js"></script>
<!-- JavaScript CSS End -->
</head>
<body>
<?php
foreach($feedData as $data)
{
?>
<div class="messageBody" id="msg<?php echo $data->msg_id; ?>">
<img src="<?php echo $data->profile_pic; ?>" class="messageImg"/>
<b><a href="<?php echo BASE_URL.$data->username; ?>"><?php echo $data->name; ?></a></b>
<?php echo $data->message; ?>
<div class="messageFooter">
<a href="#" class="reaction" id="like<?php echo $data->msg_id; ?>" rel="like">
<i class="likeIconDefault" ></i>Like</a>
</div>
</div>
<?php } ?>
</body>
</html>
config.php
Database configuration file, modify username, password and database values. Enable PDO extension for PHP
<?php
session_start();
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'username');
define('DB_PASSWORD', 'password');
define('DB_DATABASE', 'Reations');
define("BASE_URL", "http://www.yourwebsite.com/");
function getDB()
{
$dbhost= DB_SERVER;
$dbuser= DB_USERNAME;
$dbpass= DB_PASSWORD;
$dbname= DB_DATABASE;
$dbConnection = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbConnection->exec("set names utf8"); //utf-8 support
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbConnection;
}
include_once 'feed.php';
$feed = new feed();
?>
session_start();
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'username');
define('DB_PASSWORD', 'password');
define('DB_DATABASE', 'Reations');
define("BASE_URL", "http://www.yourwebsite.com/");
function getDB()
{
$dbhost= DB_SERVER;
$dbuser= DB_USERNAME;
$dbpass= DB_PASSWORD;
$dbname= DB_DATABASE;
$dbConnection = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbConnection->exec("set names utf8"); //utf-8 support
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbConnection;
}
include_once 'feed.php';
$feed = new feed();
?>
ajaxReaction.php
Ajax post file for updating user reactions.
<?php
include_once 'config.php';
$feedData=$feed->newsFeed();
$sessions_uid=$_SESSION['uid'];
if($_POST['msg_id'] && $_POST['rid'] && $session_uid>0)
{
$msg_id=$_POST['msg_id'];
$rid=$_POST['rid'];
$data=$feed->userReaction($session_uid,$msg_id,$rid);
echo $data;
}
?>
include_once 'config.php';
$feedData=$feed->newsFeed();
$sessions_uid=$_SESSION['uid'];
if($_POST['msg_id'] && $_POST['rid'] && $session_uid>0)
{
$msg_id=$_POST['msg_id'];
$rid=$_POST['rid'];
$data=$feed->userReaction($session_uid,$msg_id,$rid);
echo $data;
}
?>
feed.php
Contains simple PHP code to update user reaction data, this will get all users update. You have to modify based on your session id.
<?php
class feed
{
/* News Feed Data */
public function newsFeed()
{
$db = getDB();
$stmt = $db->prepare("SELECT U.uid, U.name, U.username,U.profile_pic, M.msg_id, M.message, M.created, M.like_count FROM users U,messages M WHERE U.uid=M.uid_fk ORDER BY M.msg_id DESC");
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
return $data;
}
/* User Reaction Check */
public function reactionCheck($uid, $msg_id)
{
$db = getDB();
$stmt = $db->prepare("SELECT L.like_id, R.name FROM message_like L, reactions R WHERE R.rid=L.rid_fk AND L.uid_fk=:uid AND L.msg_id_fk=:msg_id");
$stmt->bindValue(':uid', $uid, PDO::PARAM_INT);
$stmt->bindValue(':msg_id', $msg_id, PDO::PARAM_INT);
$stmt->execute();
$data= $stmt->fetch(PDO::FETCH_OBJ);
$db = null;
return $data;
}
/* News Feed Data */
public function userReaction($uid,$msg_id,$rid)
{
$db = getDB();
$stmt1 = $db->prepare("SELECT like_id FROM message_like WHERE uid_fk=:uid AND msg_id_fk=:msg_id");
$stmt1->bindValue(':uid', $uid, PDO::PARAM_INT);
$stmt1->bindValue(':msg_id', $msg_id, PDO::PARAM_INT);
$stmt1->execute();
$count=$stmt1->rowCount();
if($count > 0)
{
$stmt = $db->prepare("DELETE FROM message_like WHERE uid_fk=:uid AND msg_id_fk=:msg_id");
$stmt->bindValue(':uid', $uid, PDO::PARAM_INT);
$stmt->bindValue(':msg_id', $msg_id, PDO::PARAM_INT);
$stmt->execute();
$db = null;
return 2;
}
else
{
$stmt = $db->prepare("INSERT INTO message_like (msg_id_fk, uid_fk, created, rid_fk) VALUES (:msg_id, :uid, :created, :rid)");
$stmt->bindValue(':uid', $uid, PDO::PARAM_INT);
$stmt->bindValue(':msg_id', $msg_id, PDO::PARAM_INT);
$created=time();
$stmt->bindValue(':created', $created, PDO::PARAM_INT);
$stmt->bindValue(':rid', $rid, PDO::PARAM_INT);
$stmt->execute();
$db = null;
return 1;
}
}
}
?>
class feed
{
/* News Feed Data */
public function newsFeed()
{
$db = getDB();
$stmt = $db->prepare("SELECT U.uid, U.name, U.username,U.profile_pic, M.msg_id, M.message, M.created, M.like_count FROM users U,messages M WHERE U.uid=M.uid_fk ORDER BY M.msg_id DESC");
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
return $data;
}
/* User Reaction Check */
public function reactionCheck($uid, $msg_id)
{
$db = getDB();
$stmt = $db->prepare("SELECT L.like_id, R.name FROM message_like L, reactions R WHERE R.rid=L.rid_fk AND L.uid_fk=:uid AND L.msg_id_fk=:msg_id");
$stmt->bindValue(':uid', $uid, PDO::PARAM_INT);
$stmt->bindValue(':msg_id', $msg_id, PDO::PARAM_INT);
$stmt->execute();
$data= $stmt->fetch(PDO::FETCH_OBJ);
$db = null;
return $data;
}
/* News Feed Data */
public function userReaction($uid,$msg_id,$rid)
{
$db = getDB();
$stmt1 = $db->prepare("SELECT like_id FROM message_like WHERE uid_fk=:uid AND msg_id_fk=:msg_id");
$stmt1->bindValue(':uid', $uid, PDO::PARAM_INT);
$stmt1->bindValue(':msg_id', $msg_id, PDO::PARAM_INT);
$stmt1->execute();
$count=$stmt1->rowCount();
if($count > 0)
{
$stmt = $db->prepare("DELETE FROM message_like WHERE uid_fk=:uid AND msg_id_fk=:msg_id");
$stmt->bindValue(':uid', $uid, PDO::PARAM_INT);
$stmt->bindValue(':msg_id', $msg_id, PDO::PARAM_INT);
$stmt->execute();
$db = null;
return 2;
}
else
{
$stmt = $db->prepare("INSERT INTO message_like (msg_id_fk, uid_fk, created, rid_fk) VALUES (:msg_id, :uid, :created, :rid)");
$stmt->bindValue(':uid', $uid, PDO::PARAM_INT);
$stmt->bindValue(':msg_id', $msg_id, PDO::PARAM_INT);
$created=time();
$stmt->bindValue(':created', $created, PDO::PARAM_INT);
$stmt->bindValue(':rid', $rid, PDO::PARAM_INT);
$stmt->execute();
$db = null;
return 1;
}
}
}
?>
nice article, thank you very much
ReplyDeleteWelcome back bro after long interval :) ...
ReplyDeleteYou are the man, With your tutorials i made this out http://thescript.net16.net thanks a lot, may God give you more knownledge
ReplyDeleteNice :'D
ReplyDeletethanks dude... well done
ReplyDeletethanks bob.
ReplyDeletewow Bro thanks for sharing really its cool..... I like it
ReplyDeletei am failing to download zip file from Box, any help?
ReplyDeleteThe download finally worked out..thank you for the masterpiece.
ReplyDeleteProblem is solved :-)
ReplyDeleteRegards, Frank
$created=time();
ReplyDelete$stmt = $db->prepare("INSERT INTO message_like (msg_id_fk, uid_fk, created, rid_fk) VALUES (:msg_id, :uid, :created, :rid)");
$stmt->execute(array(":uid"=>"$uid",
":msg_id"=>"$msg_id",
":created"=>"$created",
":rid"=>"$rid"
));
$db = null;
return 1;
tried to short a big code.
WOW!! Very Nice Article. Hats off your work...
ReplyDeleteThank you for sharing, how does the like_id works?
ReplyDeletethats all well and good but what if you already have a website with likes where would you possibly put this in your site classes assets and as this is a folder would you have to stick several of the files to different areas of the site or leave them in the folder and include the folder in lets say messages for example include("includes/classes/like reactions"); ???????????
ReplyDeletehaving issues with this got all the files needed
ReplyDeleteHello,
ReplyDeleteI'm getting LikeReaction.zip not found error, can you re-upload it?
Regards.
Done
Delete