The ubiquitous “Like” button…it’s nice, easy to use and pretty damn useful.
If you ever wondered how can you implement it on your website..well, it’s very easy and it’s called Facebook Like Button: http://developers.facebook.com/docs/reference/plugins/like/, but that’s not what I want to talk about here.
Now, imagine the next situation: you have a simple web application in which each user can have a Wall and can post on each other’s or on its own wall. What? Facebook has this functionality too
?
Currently being my first language of choice, I will explain the implementation in PHP / MySQL. First of all, you should have a simple database structure, like the one below:

Just to be sure you understood the structure:
- a user (wall_entries.user_id) can post a message (wall_entries.message) on other’s or on it’s own (wall_entries.to_user_id) wall;
- the message (wall_entries_likes.wall_entry_id) can be liked/unliked by others or by the author (wall_entries_likes.user.id);
- the message can have one or more replies (wall_entries_messages.message) from others or from the author (wall_entries_messages.user_id);
- the replies (wall_entries_messages_likes.wall_entry_id) can be liked/unliked by others or by the author (wall_entries_messages_likes.user_id)
Let’s take a look at the SELECT statement which retrieve all the messages and likes that belongs to the first user Wall:
SELECT `wall_entries`.`id`, `wall_entries`.`user_id`, `users`.`name` AS `user_name`, `wall_entries`.`to_user_id`, `u2`.`name` AS `to_user_name`, `wall_entries`.`message`, ( SELECT GROUP_CONCAT(user_id) FROM wall_entries_likes WHERE wall_entry_id = wall_entries.id GROUP BY wall_entry_id )AS `user_ids_liked`, ( SELECT GROUP_CONCAT(users. NAME) FROM wall_entries_likes INNER JOIN users ON users.id = wall_entries_likes.user_id WHERE wall_entry_id = wall_entries.id GROUP BY wall_entry_id )AS `user_names_liked` FROM `wall_entries` LEFT JOIN `users` ON users.id = wall_entries.user_id LEFT JOIN `users` AS `u2` ON u2.id = wall_entries.to_user_id WHERE (to_user_id = '1')

Now, let’s take a look at the SELECT statement which retrieve all the replies and likes of all the messages that belongs to the first user Wall:
SELECT `wall_entries_messages`.`id`, `wall_entries_messages`.`wall_entry_id`, `wall_entries_messages`.`user_id`, `users`.`name` AS `user_name`, `wall_entries`.`to_user_id`, `u2`.`name` AS `to_user_name`, `wall_entries_messages`.`message`, ( SELECT GROUP_CONCAT(user_id) FROM wall_entries_messages_likes WHERE wall_entry_id = wall_entries_messages.id GROUP BY wall_entry_id )AS `user_ids_liked`, ( SELECT GROUP_CONCAT(users. NAME) FROM wall_entries_messages_likes INNER JOIN users ON users.id = wall_entries_messages_likes.user_id WHERE wall_entry_id = wall_entries_messages.id GROUP BY wall_entry_id )AS `user_names_liked` FROM `wall_entries_messages` INNER JOIN `wall_entries` ON wall_entries.id = wall_entries_messages.wall_entry_id LEFT JOIN `users` ON users.id = wall_entries_messages.user_id LEFT JOIN `users` AS `u2` ON u2.id = wall_entries.to_user_id WHERE (wall_entries.to_user_id = 1)

So far, you can clearly see that Tom Cat who posted on John Doe’s Wall got 2 replies from Indiana Jones and John Doe and only the reply from Indiana Jones was liked by two people: John Doe and Tom Cat! Whoaa!
Let’s take a look at the View Helper which generates the HTML near the Like button:
/**
* Generate the HTML that will be displayed near the Like button
*
* @return string
*/
public function wallEntryLikes($item, $userId)
{
$isLikedByCurrentUser = false;
$wallEntryLikesHtml = '';
//Check if the wall entry is liked by current user
if(XX_Utilities_Like::getInstance()->isLikedByCurrentUser(
$item, $userId)
){
$wallEntryLikesHtml .= 'You';
$isLikedByCurrentUser = true;
}
$userIds = '';
//Check if other users like the current wall entry
if($item->user_ids_liked){
$userIds = explode(',', $item->user_ids_liked);
$userNames = explode(',', $item->user_names_liked);
//The wall entry is liked by the current user and one or multiple users
if($isLikedByCurrentUser){
if(count($userIds) - 1 == 0){
$wallEntryLikesHtml .= ' like this';
}
else if(count($userIds) - 1 == 1){
$wallEntryLikesHtml .= ' and '
. $userNames[array_search($userId, $userIds)] . ' like this';
}
else {
$wallEntryLikesHtml .= ' and ' . (count($userIds) - 1) . ' others like this';
}
}
//The wall entry is liked by one or multiple users
else{
if(count($userIds) == 1){
$wallEntryLikesHtml .= $userNames[0] . ' like this';
}
else if(count($userIds) == 2){
$wallEntryLikesHtml .= $userNames[0] . ' and '
. $userNames[1] . ' like this';
}
else{
$wallEntryLikesHtml .= $userNames[0] . ' and '
. (count($userIds) - 1) . ' others like this';
}
}
}
if ($wallEntryLikesHtml){
return '' . $wallEntryLikesHtml . '';
}
return '';
}
Happy coding!