Powerful Chat System – Lesson 4

Powerful Chat System – Lesson 4

3 227
Powerful Chat System

Powerful Chat System – Lesson 4

Today we continue a series of articles on the creation of powerful chat system. Our forth lesson will contain next elements: list of profiles (for our main page) and profile page. We will display some basic info of our members, and in next article we will add avatars to them and something else.

Today I will publish updated sources of our growing project (several files was modified). All project is well structured: system classes is in ‘classes’ folder, stylesheets in ‘css’ folder, javascript files in ‘js’ folder, template files in ‘templates’ folder, and one new folder ‘images’ for our images.

Live Demo
download in package

Now – download the source files and lets start coding !


Step 1. HTML

I have updated template of our main page. As you can see – I have added new block here – profiles list.:

templates/main_page.html

<!DOCTYPE html>
<html lang="en" >
<head>
    <title>Powerful Chat System - Lesson 4</title>
    <link href="css/main.css" rel="stylesheet" type="text/css" />
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
</head>
<body>
    <header>
        <h2>Powerful Chat System - Lesson 4</h2>
        <a href="http://script-tutorials.com/powerful-chat-system-lesson-4/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
    </header>
    <div class="container">
        {form}
    </div>
    <div class="container">
        <h2>Main Chat Block</h2>
        <div class="chat_messages">
            {chat}
        </div>
        {input}
    </div>
    <div class="container">
        <h2>Profiles Block</h2>
        {profiles}
        <script>
            $(document).ready(function() { // align profiles on the center
                var iAll = $('.profiles div').size();
                var iWU = $('.profiles div:first').outerWidth({'margin':true});
                var iWC = $('.profiles').width();
                var iPerRow = parseInt(iWC/iWU);
                var iLeft = (iWC - (iAll > iPerRow ? iPerRow * iWU : iAll * iWU)) / 2;
                $('.profiles').css('padding-left', iLeft);
            });
        </script>
    </div>
</body>
</html>

Please pay attention to that javascript, it help us to align profile units on the center of block. And, I have prepared new template for our Profile page:

templates/main_page.html

<!DOCTYPE html>
<html lang="en" >
<head>
    <title>Powerful Chat System - Lesson 4</title>
    <link href="css/main.css" rel="stylesheet" type="text/css" />
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
</head>
<body>
    <header>
        <h2>Powerful Chat System - Lesson 4</h2>
        <a href="http://script-tutorials.com/powerful-chat-system-lesson-4/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
    </header>
    <div class="container">
        <div class="column">
            <h3>Name: {name}</h3>
            <h3>First name: {fname}</h3>
            <h3>Last name: {lname}</h3>
            <h3>About: {about}</h3>
            <h3>Date Reg: {datereg}</h3>
            <h3>Role: {role}</h3>
        </div>
        <div class="column">
            <p><a href="index.php">Back to chat</a></p>
        </div>
    </div>
</body>
</html>

Step 2. CSS

This file has been updated. I have added several styles at the bottom of this file:

css/main.css

/* profiles */
.profiles {
    overflow: hidden;
}
.profiles a {
    display: block;
}
.profiles div {
    float: left;
    height: 100px;
    margin: 5px;
    overflow: hidden;
    padding: 5px;
    text-align: center;
    width: 70px;
}
.profiles div p {
    font-size: 12px;
}

Step 3. PHP

Now, lets review php sources. Our index.php file has been updated too. I put our registration processing into new class ‘CProfiles’. We will use this class to work with profiles.

index.php

<?php

// set error reporting level
if (version_compare(phpversion(), '5.3.0', '>=') == 1)
  error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
  error_reporting(E_ALL & ~E_NOTICE);

require_once('classes/Services_JSON.php');
require_once('classes/CMySQL.php'); // including service class to work with database
require_once('classes/CLogin.php'); // including service class to work with login processing
require_once('classes/CProfiles.php'); // including service class to work with profiles

$sErrors = '';
// join processing
if (! isset($_SESSION['member_id']) && $_POST['Join'] == 'Join') {
    $GLOBALS['CProfiles']->registerProfile();
}

// login system init and generation code
$sLoginForm = $GLOBALS['CLogin']->getLoginBox();

$sChat = '<h2>You do not have rights to use chat</h2>';
$sInput = '';
if ($_SESSION['member_id'] && $_SESSION['member_status'] == 'active' && $_SESSION['member_role']) {
    require_once('classes/CChat.php'); // including service class to work with chat

    // get last messages
    $sChat = $GLOBALS['MainChat']->getMessages();
    if ($_GET['action'] == 'get_last_messages') { // regular updating of messages in chat
        $oJson = new Services_JSON();
        header('Content-type: application/json');
        echo $oJson->encode(array('messages' => $sChat));
        exit;
    }

    // get input form
    $sInput = $GLOBALS['MainChat']->getInputForm();

    if ($_POST['message']) { // POST-ing of message
        $iRes = $GLOBALS['MainChat']->acceptMessage();

        $oJson = new Services_JSON();
        header('Content-type: application/json');
        echo $oJson->encode(array('result' => $iRes));
        exit;
    }
}

// get profiles list
$sProfiles = $GLOBALS['CProfiles']->getProfilesBlock();

// draw common page
echo strtr(file_get_contents('templates/main_page.html'), array('{form}' => $sLoginForm . $sErrors, '{chat}' => $sChat, '{input}' => $sInput, '{profiles}' => $sProfiles));

And, our new class:

classes/CProfiles.php

<?php

// Profiles class
class CProfiles {

    // constructor
    function CProfiles() {
    }

    // profile registration
    function registerProfile() {
        $sUsername = $GLOBALS['MySQL']->escape($_POST['username']);
        $sFirstname = $GLOBALS['MySQL']->escape($_POST['firstname']);
        $sLastname = $GLOBALS['MySQL']->escape($_POST['lastname']);
        $sEmail = $GLOBALS['MySQL']->escape($_POST['email']);
        $sPassword = $GLOBALS['MySQL']->escape($_POST['password']);

        if ($sUsername && $sEmail && $sPassword) {
            // check if already exist
            $aProfile = $GLOBALS['MySQL']->getRow("SELECT * FROM `cs_profiles` WHERE `email`='{$sEmail}'");
            if ($aProfile['id'] > 0) {
                $sErrors = '<h2>Another profile with same email already exist</h2>';
            } else {
                // generate Salt and Cached password
                $sSalt = $this->getRandCode();
                $sPass = sha1(md5($sPassword) . $sSalt);

                // add new member into database
                $sSQL = "
                    INSERT INTO `cs_profiles` SET 
                    `name` = '{$sUsername}',
                    `first_name` = '{$sFirstname}',
                    `last_name` = '{$sLastname}',
                    `email` = '{$sEmail}',
                    `password` = '{$sPass}',
                    `salt` = '{$sSalt}',
                    `status` = 'active',
                    `role` = '1',
                    `date_reg` = NOW();
                ";
                $GLOBALS['MySQL']->res($sSQL);

                // autologin
                $GLOBALS['CLogin']->performLogin($sUsername, $sPassword);
            }
        }
    }

    // get random code (for salt)
    function getRandCode($iLen = 8) {
        $sRes = '';

        $sChars = "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
        for ($i = 0; $i < $iLen; $i++) {
            $z = rand(0, strlen($sChars) -1);
            $sRes .= $sChars[$z];
        }
        return $sRes;
    }

    // get profiles block
    function getProfilesBlock($iLim = 16) {
        $sSQL = "
            SELECT * 
            FROM `cs_profiles`
            WHERE `status` = 'active'
            ORDER BY `date_reg` DESC
            LIMIT {$iLim} 
        ";
        $aProfiles = $GLOBALS['MySQL']->getAll($sSQL);

        // create list of messages
        $sCode = '';
        foreach ($aProfiles as $i => $aProfile) {
            $sName = ($aProfile['first_name'] && $aProfile['last_name']) ? $aProfile['first_name'] . ' ' . $aProfile['last_name'] : $aProfile['name'];
            $sSName = (strlen($sName) > 32) ? mb_substr($sName, 0, 28) . '...' : $sName;
            $iPid = $aProfile['id'];

            $sCode .= '<div id="'.$iPid.'" title="'.$sName.'"><a href="profile.php?id='.$iPid.'"><img src="images/member.png" alt="'.$sName.'"><p>'.$sSName.'</p></a></div>';
        }

        return '<div class="profiles">' . $sCode . '</div>';
    }

    // get profile info
    function getProfileInfo($i) {
        $sSQL = "
            SELECT * 
            FROM `cs_profiles`
            WHERE `id` = '{$i}'
        ";
        $aInfos = $GLOBALS['MySQL']->getAll($sSQL);
        return $aInfos[0];
    }

    // get role name
    function getRoleName($i) {
        $sRet = 'Ordinary member';
        switch ($i) {
            case 4:
                $sRet = 'Moderator';
                break;
            case 5:
                $sRet = 'Administrator';
                break;
        }
        return $sRet;
    }
}

$GLOBALS['CProfiles'] = new CProfiles();

You can see here several functions: ‘registerProfile’ (for profile registration), ‘getRandCode’ (which we will use to obtain random salt code), ‘getProfilesBlock’ (to draw list of last profiles), ‘getProfileInfo’ (to obtain profile information) and ‘getRoleName’ (to convert role ID into normal text value).

And now – new file (which will display profile info):

profile.php

<?php

// set error reporting level
if (version_compare(phpversion(), '5.3.0', '>=') == 1)
  error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
  error_reporting(E_ALL & ~E_NOTICE);

require_once('classes/CMySQL.php');
require_once('classes/CLogin.php');
require_once('classes/CProfiles.php');

$iPid = (int)$_GET['id'];
$aInfo = $GLOBALS['CProfiles']->getProfileInfo($iPid);

$sName = $aInfo['name'];
$sFName = $aInfo['first_name'];
$sLName = $aInfo['last_name'];
$sAbout = $aInfo['about'];
$sDate = $aInfo['date_reg'];
$sRole = $GLOBALS['CProfiles']->getRoleName($aInfo['role']);

// draw common page
echo strtr(file_get_contents('templates/profile_page.html'), array('{name}' => $sName, '{fname}' => $sFName, '{lname}' => $sLName, '{about}' => $sAbout, '{datereg}' => $sDate, '{role}' => $sRole));


Live Demo
download in archive

Conclusion

I hope that our new series of articles of chat system creation is useful and interesting for you. If you want to share your ideas, or you noticed any weakness – don’t hesitate to contact us. Good luck and welcome back!

SIMILAR ARTICLES

Sliding single-level menu

0 90
Design Patterns in PHP

0 3209

3 COMMENTS

  1. @admin, thanks for your chat script and its really nice. I have one thing to tell you, cant you add a features where by the person can chat with one person only, this chat window seems to be open to all, and another thing is cant you add a features like, the person can know who are the online.

    Thanks

Leave a Reply