Social Network Friends Suggestion System using PHP, MySQL and jQuery
Reading Time:
Reading Time:
Relation
class and the base elements that will be used here.In the demo, view the friend suggestion panel for the suggested friends to be loaded.
Database contains 2 tables, users table which ofcourse contains the users details and the relationship table which contains the friends connection details.
The app/ directory contains the important Class’es that are used for in the system. includes/ is where the small snippets of php scripts are kept.
To get the suggested friends for a user let us assume the relationship as a graph structure. Let each Node in a graph represent a User and each Edge(connections) in the graph represent the relationship between them. If two users are connected then they are Friends.
Following is the graph representing a sample users data.
Assuming that user 1 is logged in, let’s look into how we could fetch the suggested friends for user 1.
In the above flow,
To implement this flow and test it, here is a simple python program that does this.
In the above program, all the users friends are represented as a Adjacency List. You can play around with the list and view the output for suggested friends and their mutual friends.
Now that we know the alogrithm for fetching the friends suggestions let’s implement this in the system that we have created already
From the above algorithm, we could implement the friends suggestion in the Relation
class that is already built.
Following are the additional methods added to that class to make this work,
getFriends(user_id)
– Will return the list of user’s friend id’s.getUser(user_id)
– Will return the user details of the given user id.getFriendSuggestions()
– This is the functions that actually fetches the friend suggestions for the currently logged in user..... .... ....
/**
* Get the friends id for the given user id.
*
* @param type $userId
* @return type
*/
public function getFriends($userId) {
$sql = 'SELECT * FROM `relationship` WHERE ' .
'(`user_one_id` = ' . $userId . ' OR `user_two_id` = '. $userId .') ' .
'AND `status` = 1';
$resultObj = $this->dbCon->query($sql);
$friends = array();
while($row = $resultObj->fetch_assoc()) {
if ($row['user_one_id'] !== $userId) {
$friends[] = $row['user_one_id'];
}
if ($row['user_two_id'] !== $userId) {
$friends[] = $row['user_two_id'];
}
}
return $friends;
}
/**
* Get the user details object for the given user id.
*
* @param $userId
* @return array|null
*/
public function getUser($userId) {
$user = null;
$sql = 'SELECT * FROM `users` WHERE `user_id` = ' . $userId;
$resultObj = $this->dbCon->query($sql);
if ($resultObj) {
$user = $resultObj->fetch_assoc();
}
return $user;
}
/**
* Get a list of suggested friends for the current user.
*/
public function getFriendSuggestions() {
$userId = $this->loggedInUser->getUserId();
$friends = $this->getFriends($userId);
$suggestedFriends = [];
foreach ($friends as $friendId) {
# Friends friends list.
$ff_list = $this->getFriends($friendId);
foreach ($ff_list as $ffriendId) {
# If the friendsFriend(ff) is not us, and not our friend, he can be suggested
if ($ffriendId != $userId && !in_array($ffriendId, $friends)) {
# The key is the suggested friend
$suggestedFriends[$ffriendId] = ['mutual_friends' => []];
$ff_friends = $this->getFriends($ffriendId);
foreach ($ff_friends as $ff_friendId) {
if (in_array($ff_friendId, $friends)) {
# If he is a friend of the current user, he is a mutual friend
$suggestedFriends[$ffriendId]['mutual_friends'][] = $ff_friendId;
}
}
}
}
}
# Convert the friend id's to user objects.
$suggestedFriendObjs = array();
if (!empty($suggestedFriends)) {
foreach ($suggestedFriends as $suggestedFriend => $mutualFriends) {
$suggestedFriendObj = new stdClass();
$suggestedFriendObj->suggestedUser = $this->getUser($suggestedFriend);
if (!empty($mutualFriends)) {
$mutualFriendObjs = [];
foreach ($mutualFriends['mutual_friends'] as $mutualFriend) {
$mutualFriendObjs[] = $this->getUser($mutualFriend);
}
}
$suggestedFriendObj->mutualFriends = $mutualFriendObjs;
$suggestedFriendObjs[] = $suggestedFriendObj;
}
}
return $suggestedFriendObjs;
}
... .. ...
In the Ajax script, if the user exists it will fetch the suggested friends for the given user. This script uses the newly created methods in the Relation
to achieve this.
The response is returned as JSON so that it will easier for us to parse and display the result.
<?php
include_once('../app/config.php');
$response = [
'status' => false,
'data' => 'No friends list available for this user.'
];
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['user_id'])) {
$user = new User();
$loggedInUser = $user->getUser($mysqli, (int) $_GET['user_id']);
# If the logged in user exists.
if ($loggedInUser) {
$relation = new Relation($mysqli, $loggedInUser);
$friendSuggestions = $relation->getFriendSuggestions();
$response['status'] = true;
$response['data'] = $friendSuggestions;
} else {
$response['data'] = 'User not available.';
}
}
header('Content-Type: application/json');
echo json_encode($response);
Using jQuery ajax method, we call the get_friend_suggestions.php
script to fetch the list of friend suggestions and their mutual friends.
/**
* Helper method to get the cookie value for the given key.
*
* @param cname
*/
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1);
if (c.indexOf(name) == 0) return c.substring(name.length,c.length);
}
return "";
}
setTimeout(function() {
$.ajax({
method: 'GET',
url: 'ajax/get_friend_suggestions.php',
data: {
user_id: getCookie('uid')
},
success: function(data, status) {
var ul = $('#suggestedFriends');
// Remove the loading text
$('#sfLoading').remove();
if (status === 'success' && data.status) {
// Suggested friends string
var sfs = '';
data.data.forEach(function(item) {
// Suggested friend
var sf = '<li><a href="profile.php?uid=' + item.suggestedUser.user_id +
'">' + item.suggestedUser.username + '</a>';
// Check if there are any mutual friends.
if (item.mutualFriends.length > 0) {
// Mutual friend
var mfs = ' - <small>Mutual Friends ';
item.mutualFriends.forEach(function(mf) {
mfs += ' - <a href="profile.php?uid=' + mf.user_id + '">' + mf.username + '</a>';
});
mfs += '</small>';
}
sf += mfs + '</li>';
sfs += sf;
});
if (sfs == '') {
sfs = '<li>No suggested friends</li>';
}
ul.append(sfs);
} else {
ul.append('<li>No suggested friends</li>');
}
},
error: function(err) {
console.log(err);
}
});
}, 5000);
When we make the ajax request we get a json response as shown below.
The returned data
array contains the suggested friends objects. Each object contains the suggestedUser
and the mutual friends for that suggested user in the mutualFriends
field as an array.
{
"status":true,
"data":[
{
"suggestedUser":{
"user_id":"8",
"username":"Ezio Auditori"
},
"mutualFriends":[
{
"user_id":"2",
"username":"Johny Lare"
}
]
},
{
"suggestedUser":{
"user_id":"3",
"username":"Jennifer"
},
"mutualFriends":[
{
"user_id":"4",
"username":"Carl"
},
{
"user_id":"5",
"username":"Arya"
}
]
},
{
"suggestedUser":{
"user_id":"6",
"username":"Rick Mater"
},
"mutualFriends":[
{
"user_id":"5",
"username":"Arya"
}
]
}
]
}
The markup shows a simple Loading text for 5 seconds or so, then the app.js
script will make an ajax request and fetch the json data which will be used to populate the friends suggestion list.
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Suggested Friends</h3>
</div>
<div class="panel-body">
<ul id="suggestedFriends" style="list-style: none;">
<li id="sfLoading">Loading...</li>
</ul>
</div>
</div>
This system is not production ready, this is just to give you an idea of how to implement a system like this.
Facebook Like Chat Application in PHP and MySQL
Interface and Abstract Class in PHP
Intro to working with Database in PHP