Facebook Like Friends Relationship System Design using PHP and MySQL

This post explains in detail of how to use the Classes created in Social network friend’s relationship to actually implement the system itself. This is designed like how the Facebook friend’s relationship system works.

Read the post on Social Network Friends Relationship System Using PHP and MySQL to understand the Class implementation.

Directory Structure

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.

  •  Friends Relation System/
    •  app/
      • Relation.php
      • Relationship.php
      • User.php
      • config.php
    •  includes/
      • blocked_friends.php
      • blocked_profile.php
      • sent_friend_requests.php
      • user_friend_requests.php
      • user_friends.php
    • login.php
    • home.php
    • check_login.php
    • logout.php
    • profile.php
    • user_action.php

config.php

This file contains the database instance creation and includes the classes in the app folder. This script will be included at the top of all the other scripts.

<?php
include_once('User.php');
include_once('Relationship.php');
include_once('Relation.php');

// Mysql credentials and details
$host = 'your-host';
$username = 'your-mysql-username';
$password = 'your-mysql-password';
$db = 'database-name';

// Connect to mysql
$mysqli = new mysqli($host, $username, $password, $db);

// Check if there is any error in creating db connection.
if ($mysqli->connect_error) {
  die('Connect Error: Could not connect to database');
}

 app/

Read the part one of this post for understanding the purpose for each of the class included.

 includes/

blocked_friends.php

This script retrieves the list of blocked friends for the currently logged in user and displays them in a list.

<?php
// Holds the list of bloced users
$blocked_friends = $relation->getBlockedFriends();

if (!empty($blocked_friends)) {
  echo '<table>';
  
  foreach ($blocked_friends as $rel) {
    echo '<tr>';
    $friend = $relation->getFriend($rel);
    echo '<td><a href="profile.php?uid=' . $friend->getUserId() . '">' . ucfirst($friend->getUsername()) . '</a></li>';
    echo '<td><a href="user_action.php?action=unblock&friend;_id='. $friend->getUserId() .'" title="Unblock">Unblock</a></td>';
    echo '</tr>';
  }
  
  echo '</table>';
} else {
  echo '<h6>No blocked friends!</h6>';
}

blocked_profile.php

This script is used when a user visits a profile page. Here we find if the profile user and the current user is blocked in any way. We use $is_blocked Boolean variable to identify this state.

<?php
// Whether the current profile is blocked in anyway
$is_blocked = false;

// Get the list of blocked friends
$logged_in_user_blocked_list = $relation->getBlockedFriends();

// check if current profile is in the blocked list of the user.
foreach ($logged_in_user_blocked_list as $blocked_rel) {
  $rel = $relation->getFriend($blocked_rel);
  // If the user is present in the bloceked user list 
  if ($rel->getUserId() == $friend_id) {
    $is_blocked = true;
  }
}  

// Get the list of blocked friends list of the profile
$profile_user_blocked_list = $profile_relation->getBlockedFriends();

// check if current profile is in the blocked list of the profile user.
foreach ($profile_user_blocked_list as $blocked_rel) {
  $rel = $profile_relation->getFriend($blocked_rel);
  // If the user is present in the bloceked user list 
  if ($rel->getUserId() == $user->getUserId()) {
    $is_blocked = true;
  }
}

sent_friend_requests.php

Shows the list of friend requests sent by the current user.

<?php
// Holds the list of Friend requests sent
$sent_friend_requests = $relation->getSentFriendRequests();

if (!empty($sent_friend_requests)) {  
  echo '<table>';
  
  foreach ($sent_friend_requests as $rel) {
    echo '<tr>';
    $friend = $relation->getFriend($rel);
    echo '<td><a href="profile.php?uid=' . $friend->getUserId() . '">' . ucfirst($friend->getUsername()) . '</a></li>';
    echo '<td><a href="user_action.php?action=cancel&friend;_id='. $friend->getUserId() .'" title="Cancel Request">Cancel</a></td>';
    echo '</tr>';
  }
  
  echo '</table>';
} else {
  echo '<h6>No friend requests sent!</h6>';
}

user_friend_requests.php

List of friend requests for the user.

<?php
// Holds the list of friend requests for user
$user_friend_requests = $relation->getFriendRequests();

if (!empty($user_friend_requests)) {
  echo '<table>';
  
  foreach ($user_friend_requests as $rel) {
    echo '<tr>';
    $friend = $relation->getFriend($rel);
    echo '<td><a href="profile.php?uid=' . $friend->getUserId() . '">' . ucfirst($friend->getUsername()) . '</a></li>';
    echo '<td><a href="user_action.php?action=accept&friend;_id='. $friend->getUserId() .'" title="Accept friend Request">Accept</a></td>';
    echo '<td><a href="user_action.php?action=decline&friend;_id='. $friend->getUserId() .'">Decline</a></td>';
    echo '</tr>';
  }
  
  echo '</table>';
} else {
  echo '<h6>No friend requests!</h6>';
}

user_friends.php

Show the user’s friends list

<?php
// List of user friends
$user_friends = $relation->getFriendsList();

if (!empty($user_friends)) {
  echo '<ul>';
  foreach ($user_friends as $rel) {
    $friend = $relation->getFriend($rel);
    echo '<li><a href="profile.php?uid=' . $friend->getUserId() . '">' . ucfirst($friend->getUsername()) . '</a></li>';
  }
  echo '</ul>';
} else {
  echo '<h6>You don\'t have any friends yet!</h6>';
}

Main Directory Files /

This is root directory for the system

check_login.php

Manages the login submissions.

<?php
include_once('app/config.php');

// Check if the page request type
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST) && 
    isset($_POST['email']) && isset($_POST['password'])) {
    
  $email = $_POST['email'];
  $password = $_POST['password'];
  
  // Clean user input values
  $c_email = $mysqli->real_escape_string($email);
  $c_password = $mysqli->real_escape_string($password);
  
  $resultObj = $mysqli->query('SELECT * FROM `users` '
          . ' WHERE `email` = "' . $c_email . '"'
          . ' AND `password` = "' . $c_password . '"');
          
  if ($mysqli->affected_rows > 0) {
    $user_details = $resultObj->fetch_assoc();
    setcookie('uid', $user_details['user_id'], time() + (86400 * 30), '/');
    
    // Logged in, redirect to home.
    header('Location: home.php');
  } else {
    // Not logged in, redirect to login with error.
    header('Location: login.php?err=invalid');
  }
} else if ($_SERVER['REQUEST_METHOD'] == 'GET') {
  header('Location: login.php');
}

user_action.php

Manages the user actions performed when in home and profile page.

<?php
include_once('app/config.php');

// If they try to visit this page directly
if (empty($_GET)) {
  header('Location: home.php');
}

$user = new User();

// Check for user login
if (isset($_COOKIE['uid']) && is_numeric($_COOKIE['uid']) && 
    in_array($_COOKIE['uid'], array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))) {
      
  $user = $user->getUser($mysqli, (int) $_COOKIE['uid']);
  
  $relation = new Relation($mysqli, $user);
} else {
  header('Location: login.php');
}

$allowed_actions = array(
  'accept', // status to 1
  'decline', // status to 2
  'cancel', // delete relationship
  'block', // status 3
  'unblock', // delete relationship
  'add', // insert friend request
  'unfriend', // delete a friend
);

$allowed_friends = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

if (
  isset($_GET['action']) && 
  in_array($_GET['action'], $allowed_actions) &&
  isset($_GET['friend_id']) && 
  in_array($_GET['friend_id'], $allowed_friends)
) {
  
  $action = $_GET['action'];
  $friend_id = (int) $_GET['friend_id'];
  $friend = new User();
  $friend = $friend->getUser($mysqli, $friend_id);
  
  // Process based on the action
  switch ($action) {
    case 'accept':
      $result = $relation->acceptFriendRequest($friend);
      break;
    case 'decline':
      $result = $relation->declineFriendRequest($friend);
      break;
    case 'cancel':
      $result = $relation->cancelFriendRequest($friend);
      break;
    case 'block':
      $result = $relation->block($friend);
      break;
    case 'unblock':
      $result = $relation->unblockFriend($friend);
      break;
    case 'add':
      $result = $relation->addFriendRequest($friend);
      break;
    case 'unfriend':
      $result = $relation->unfriend($friend);
      break;
  }
  
  // Set the message cookie so that it shows this message in the home page.
  if ($result) {
    setcookie('status', 'success');
  } else {
    setcookie('status', 'failed');
  }
  // Redirect to home
  header('Location: home.php');
} else {
  header('Location: home.php');
}

home.php

This is where all the user’s details along with Friends List, Sent Friend Requests, Friend Requests and Blocked Users are displayed.

<?php
include_once('app/config.php');

$user = new User();

// Check if the user is logged in
if (isset($_COOKIE['uid']) && is_numeric($_COOKIE['uid']) && 
    in_array($_COOKIE['uid'], array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))) {
      
  $user = $user->getUser($mysqli, (int) $_COOKIE['uid']);
  
  $relation = new Relation($mysqli, $user);
} else {
  header('Location: login.php');
}

$msg = '';
$status = array(
  'success' => 'Operation performed Successfully.',
  'failed' => 'Action Failed to process!'
);

if (isset($_COOKIE['status']) && array_key_exists($_COOKIE['status'], $status)) {
  $msg = $status[$_COOKIE['status']];
  // clear the cookie
  setcookie('status', '');
  unset($_COOKIE['status']);
}
?>
<!-- Basic html tags -->
<?php
if ($msg !== '') echo '<p>' . $msg . '</p>';
?>

<div class="user-details">
    <p>Username: <b><?php echo $user->getUsername(); ?></b></p>
    <p>Email: <b><?php echo $user->getEmail(); ?></b></p>
  <p><a href="logout.php" title="logout">Logout</a></p>
  <hr/>
  <h4>Friends</h4>
  <?php
  include_once('includes/user_friends.php');
  ?>
</div>

<div>
  <h3>Friend Requests</h3>
  <div>
    <?php
    include_once('includes/user_friend_requests.php');
    ?>
  </div>
</div>

<div>
  <h3>Blocked Friends</h3>
  <div>
    <?php
    include_once('includes/blocked_friends.php');
    ?>
  </div>
</div>

profile.php

This is the profile page for users

<?php

include_once('app/config.php');

$user = new User();

if (isset($_COOKIE['uid']) && is_numeric($_COOKIE['uid']) && 
    in_array($_COOKIE['uid'], array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))) {
  
  // If there is not uid redirect to home page.
  if (empty($_GET) || !isset($_GET['uid'])) {
    header('Location: home.php');
  }
  
  //################ Logged in user details ###################################
  
  // Logged in user details.
  $user = $user->getUser($mysqli, (int) $_COOKIE['uid']);
  
  // Relation of the logged in user
  $relation = new Relation($mysqli, $user);
  
  //################# Profile user details ####################################
  
  $friend_id = (int) $_GET['uid'];
  
  // Check if the profile is same as the logged in user
  if ($friend_id === $user->getUserId()) {
    $profile = $user;
    $profile_relation = $relation;
    $profile_friends = $relation->getFriendsList();
  } else {
    // Profile use details
    $profile = (new User())->getUser($mysqli, $friend_id);

    // Relation object for the current profile being showed
    $profile_relation = new Relation($mysqli, $profile);

    // Got the Friends list
    $profile_friends = $profile_relation->getFriendsList();
    
    // Get the relationship between the current user and the profile user.
    $relationship = $relation->getRelationship($profile);
  }
  // Checks if the profile is blocked
  include_once('includes/blocked_profile.php');
} else {
  header('Location: login.php');
}
?>
<div class="container">
<?php if ($is_blocked === false) { ?>
  <div>  
  <h3>Profile</h3>
    <div class="profile-body">
<?php
echo '<p><a href="home.php" style="text-decoration:none;">Home</a></p>';
echo '<p>Username: <b>' . $profile->getUsername() . '</b></p>';
echo '<p>Email: <b>' . $profile->getEmail() . '</b></p>';

// Check if the current user is not the profile user.
if ($profile->getUserId() !== $user->getUserId()) {
  // Check if user is there in any relationship record
  if ($relationship !== false) {
    switch ($relationship->getStatus()) {
      case 0:
        if ($relationship->getActionUserId() == $user->getUserId()) {
          echo '<a href="user_action.php?action=cancel&friend;_id=' . 
                  $profile->getUserId() . '">Cancel Request</a>';
        } else {
          echo '<a href="user_action.php?action=accept&friend;_id=' . 
                  $profile->getUserId() . '">Accept Request</a>';
        }
      break;
      case 1:
        echo '<a href="user_action.php?action=unfriend&friend;_id=' . 
              $profile->getUserId() . '">Unfriend</a>';
      break;
      case 2:
        echo '<small>Your request has been declined!</small>';
      break;
    }
  } else if ($relationship === false) {
    echo '<a href="user_action.php?action=add&friend;_id=' . 
            $profile->getUserId() . '">Add Friend</a>';
  }
}
echo '<hr/>';

// Display profile friends
if (!empty($profile_friends)) {
  echo '<ul>';
  foreach ($profile_friends as $rel) {
    $friend = $profile_relation->getFriend($rel);
    echo '<li><a href="profile.php?uid=' . $friend->getUserId() . '">' . 
            ucfirst($friend->getUsername()) . '</a></li>';
  }
  echo '</ul>';
} else {
  echo '<h6>No Friends</h6>';
}
?>
    </div>
  </div>
<?php } else { ?>
    <p>You can't view this profile. It is either blocked or inactive</p>
<?php } ?>
</div>

login.php

<?php
  if (isset($_COOKIE['uid']) && is_numeric($_COOKIE['uid']) 
      && in_array($_COOKIE['uid'], array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))) {
    header('Location: home.php');
  }
?>
<form class="form-signin" method="POST" action="check_login.php">
  <h2 class="form-signin-heading">sign in</h2>
  <label for="inputEmail">Email address</label>
  <input type="email" name="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
  <label for="inputPassword">Password</label>
  <input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required>
  <br/>
  <?php
    echo (isset($_GET['err']) && $_GET['err'] == 'invalid') ? '<p>Invalid Credentials</p>' : '';
  ?>
  <button type="submit">Sign in</button>
</form>

logout.php

<?php
// unset cookies
if (isset($_SERVER['HTTP_COOKIE'])) {
    $cookies = explode(';', $_SERVER['HTTP_COOKIE']);
    foreach($cookies as $cookie) {
        $parts = explode('=', $cookie);
        $name = trim($parts[0]);
        setcookie($name, '', time()-1000);
        setcookie($name, '', time()-1000, '/');
    }
}

header('Location: login.php');