赵强大数据vip课_强大的聊天系统–第7课

赵强大数据vip课

Powerful Chat System
Powerful Chat System

Powerful Chat System – Lesson 7 Today we continue a series of articles on the creation of powerful chat system. In our sevenths lesson I have added a very important feature – private messaging. Now you can send your private messages to another members (optional – to online members). Functionality looks like facebook’s chat. We have to click small icon near recipient’s name in the list of members to start talking in private mode. Welcome to start reading.

强大的聊天系统–第7课今天,我们继续撰写有关创建强大的聊天系统的系列文章。 在第七课中,我添加了一个非常重要的功能-私人消息传递。 现在,您可以将私人消息发送给其他成员(可选-在线成员)。 功能看起来像facebook的聊天。 我们必须单击成员列表中收件人姓名附近的小图标,才能开始以私密方式讲话。 欢迎开始阅读。

Today I will publish updated sources of our growing project. Whole project is well structured: system classes is in ‘classes’ folder, all javascript files in ‘js’ folder, stylesheets in ‘css’ folder, all custom avatars in ‘data’ folder, images in ‘images’ folder, template files in ‘templates’ folder (as usual).

今天,我将发布我们不断发展的项目的更新资源。 整个项目结构合理:系统类位于“类”文件夹中,所有javascript文件位于“ js”文件夹中,样式表位于“ css”文件夹中,所有自定义头像均位于“数据”文件夹中,图像位于“图像”文件夹中,模板文件位于“模板”文件夹(照常)。

现场演示
打包下载

Now – download the source files and lets start coding !

现在–下载源文件并开始编码!

步骤1. HTML (Step 1. HTML)

I updated two template files:

我更新了两个模板文件:

templates / main_page.html (templates/main_page.html)
templates / profile_page.html (templates/profile_page.html)

Please add just 2 lines (as at code below) right before closed BODY tag (for both template files):

请在闭合的BODY标记之前(对于两个模板文件)仅添加两行(如下代码所示):


....
    <div class="priv_dock_wrap"></div>
    {priv_js}
</body>
</html>

....
    <div class="priv_dock_wrap"></div>
    {priv_js}
</body>
</html>

It is our new private messages dock (fixed element at the bottom of page).

这是我们的新私人留言基座(页面底部的固定元素)。

步骤2. CSS (Step 2. CSS)

I updated the second half of our main CSS file (from line 180 till the end of file):

我更新了主CSS文件的后半部分(从第180行到文件结尾):

css / main.css (css/main.css)

....
/* chat block */
.chat_messages {
    border: 1px solid #888;
    color: #000;
    padding: 10px;
}
.chat_messages a, .priv_conv a {
    color: #000;
}
.chat_messages a img, .priv_conv a img {
    margin-right: 10px;
    vertical-align: middle;
    width: 22px;
}
.chat_messages .message, .priv_conv .message {
    background-color: #fff;
    margin: 5px;
    padding: 5px;
    -moz-border-radius: 5px;
    -ms-border-radius: 5px;
    -o-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
}
.chat_messages .message span, .priv_conv .message span {
    color: #444;
    font-size: 10px;
    margin-left: 10px;
}
.chat_submit_form {
    margin: 10px 0px;
    overflow: hidden;
}
.chat_submit_form .error, .chat_submit_form .success, .chat_submit_form .protect {
    display: none;
}
.chat_submit_form .error {
    color: #f55;
}
.chat_submit_form .success {
    color: #5f5;
}
.chat_submit_form .protect {
    color: #55f;
}
/* profiles */
.profiles {
    overflow: hidden;
}
.profiles a {
    display: block;
}
.profiles div {
    overflow: hidden;
}
.profiles div a {
    color: #333333;
    display: block;
    padding: 2px 22px 2px 10px;
    position: relative;
}
.profiles div a:hover {
    background-color: #E0E4EE;
    box-shadow: 2px 0 2px -2px #B2B9C9 inset;
}
.profiles div img {
    border: 0;
    float: left;
    height: 48px;
    margin-right: 8px;
    width: 48px;
}
.profiles div img.pchat {
    border: 0;
    height: 16px;
    position: absolute;
    right: 5px;
    top: 5px;
    width: 16px;
}
.profiles div p {
    display: block;
    line-height: 48px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.profiles div img.status_img {
    border: 0;
    display: block;
    height: 7px;
    margin-top: -6px;
    position: absolute;
    right: 5px;
    top: 50%;
    width: 7px;
}
/* customize profile page */
.customizer_buttons #preview, .customizer_buttons #pick {
    border: 1px solid #888;
    border-radius: 3px 3px 3px 3px;
    box-shadow: 2px 3px 3px #888;
    height: 40px;
    margin-bottom: 10px;
    width: 80px;
}
/* private messaging */
.priv_dock_wrap {
    bottom: 0;
    left: auto;
    position: fixed;
    right: 275px;
    z-index: 300;
}
.priv_chat_tab {
    background-color: #FFFFFF;
    border: 1px solid #000000;
    color: #000000;
    float: left;
    height: 285px;
    margin: 0 5px;
    max-height: 342px;
    width: 260px;
}
.priv_title {
    background-color: #6D84B4;
    color: #FFFFFF;
    cursor: pointer;
    font-weight: bold;
    line-height: 18px;
    overflow: hidden;
    padding: 3px 15px 4px;
    position: relative;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.priv_title img {
    position: absolute;
    right: 4px;
    top: 5px;
}
.priv_conv {
    height: 234px;
    overflow-y: auto;
}
.priv_input {
    border-top: 1px solid #888888;
}
.priv_input input[type=text] {
    border: 0 none;
    display: block;
    height: 16px;
    margin: 0;
    max-height: 77px;
    min-height: 16px;
    outline: medium none;
    overflow-x: hidden;
    overflow-y: auto;
    padding: 5px 4px 3px 20px;
    resize: none;
    width: 234px;
    -moz-border-radius: 0;
    -ms-border-radius: 0;
    -o-border-radius: 0;
    -webkit-border-radius: 0;
    border-radius: 0;
}

....
/* chat block */
.chat_messages {
    border: 1px solid #888;
    color: #000;
    padding: 10px;
}
.chat_messages a, .priv_conv a {
    color: #000;
}
.chat_messages a img, .priv_conv a img {
    margin-right: 10px;
    vertical-align: middle;
    width: 22px;
}
.chat_messages .message, .priv_conv .message {
    background-color: #fff;
    margin: 5px;
    padding: 5px;
    -moz-border-radius: 5px;
    -ms-border-radius: 5px;
    -o-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
}
.chat_messages .message span, .priv_conv .message span {
    color: #444;
    font-size: 10px;
    margin-left: 10px;
}
.chat_submit_form {
    margin: 10px 0px;
    overflow: hidden;
}
.chat_submit_form .error, .chat_submit_form .success, .chat_submit_form .protect {
    display: none;
}
.chat_submit_form .error {
    color: #f55;
}
.chat_submit_form .success {
    color: #5f5;
}
.chat_submit_form .protect {
    color: #55f;
}
/* profiles */
.profiles {
    overflow: hidden;
}
.profiles a {
    display: block;
}
.profiles div {
    overflow: hidden;
}
.profiles div a {
    color: #333333;
    display: block;
    padding: 2px 22px 2px 10px;
    position: relative;
}
.profiles div a:hover {
    background-color: #E0E4EE;
    box-shadow: 2px 0 2px -2px #B2B9C9 inset;
}
.profiles div img {
    border: 0;
    float: left;
    height: 48px;
    margin-right: 8px;
    width: 48px;
}
.profiles div img.pchat {
    border: 0;
    height: 16px;
    position: absolute;
    right: 5px;
    top: 5px;
    width: 16px;
}
.profiles div p {
    display: block;
    line-height: 48px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.profiles div img.status_img {
    border: 0;
    display: block;
    height: 7px;
    margin-top: -6px;
    position: absolute;
    right: 5px;
    top: 50%;
    width: 7px;
}
/* customize profile page */
.customizer_buttons #preview, .customizer_buttons #pick {
    border: 1px solid #888;
    border-radius: 3px 3px 3px 3px;
    box-shadow: 2px 3px 3px #888;
    height: 40px;
    margin-bottom: 10px;
    width: 80px;
}
/* private messaging */
.priv_dock_wrap {
    bottom: 0;
    left: auto;
    position: fixed;
    right: 275px;
    z-index: 300;
}
.priv_chat_tab {
    background-color: #FFFFFF;
    border: 1px solid #000000;
    color: #000000;
    float: left;
    height: 285px;
    margin: 0 5px;
    max-height: 342px;
    width: 260px;
}
.priv_title {
    background-color: #6D84B4;
    color: #FFFFFF;
    cursor: pointer;
    font-weight: bold;
    line-height: 18px;
    overflow: hidden;
    padding: 3px 15px 4px;
    position: relative;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.priv_title img {
    position: absolute;
    right: 4px;
    top: 5px;
}
.priv_conv {
    height: 234px;
    overflow-y: auto;
}
.priv_input {
    border-top: 1px solid #888888;
}
.priv_input input[type=text] {
    border: 0 none;
    display: block;
    height: 16px;
    margin: 0;
    max-height: 77px;
    min-height: 16px;
    outline: medium none;
    overflow-x: hidden;
    overflow-y: auto;
    padding: 5px 4px 3px 20px;
    resize: none;
    width: 234px;
    -moz-border-radius: 0;
    -ms-border-radius: 0;
    -o-border-radius: 0;
    -webkit-border-radius: 0;
    border-radius: 0;
}

Now it contains new styles for our private messaging system.

现在,它包含了我们的私人消息传递系统的新样式。

步骤3. PHP (Step 3. PHP)

Now, its time to check changes in our PHP sources.

现在,该检查我们PHP源代码中的更改了。

index.php (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 = $sPrivChatJs = '';
if ($_SESSION['member_id'] && $_SESSION['member_status'] == 'active' && $_SESSION['member_role']) {
    if ($_GET['action'] == 'update_last_nav') { // update last navigate time
        $iPid = (int)$_SESSION['member_id'];
        if ($iPid) {
            $GLOBALS['MySQL']->res("UPDATE `cs_profiles` SET `date_nav` = NOW() WHERE `id` = '{$iPid}'");
        }
        exit;
    }
    require_once('classes/CChat.php'); // including service class to work with chat
    if ($_GET['action'] == 'check_new_messages') { // check for new messages
        $iPid = (int)$_SESSION['member_id'];
        $iSender = $GLOBALS['MainChat']->getRecentMessage($iPid);
        if ($iSender) {
            $aSender = $GLOBALS['CProfiles']->getProfileInfo($iSender);
            $sName = ($aSender['first_name'] && $aSender['last_name']) ? $aSender['first_name'] . ' ' . $aSender['last_name'] : $aSender['name'];
            $oJson = new Services_JSON();
            header('Content-type: application/json');
            echo $oJson->encode(array('id' => $iSender, 'name' => $sName));
        }
        exit;
    }
    if ($_GET['action'] == 'get_private_messages') { // regular updating of messages in chat
        $sChat = $GLOBALS['MainChat']->getMessages((int)$_GET['recipient']);
        $oJson = new Services_JSON();
        header('Content-type: application/json');
        echo $oJson->encode(array('messages' => $sChat));
        exit;
    }
    // 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;
    }
    // add avatar
    if ($_POST['action'] == 'add_avatar') {
        $iAvRes = $GLOBALS['CProfiles']->addAvatar();
        header('Content-Type: text/html; charset=utf-8');
        echo ($iAvRes == 1) ? '<h2 style="text-align:center">New avatar has been accepted, refresh main window to see it</h2>' : '';
        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;
    }
    if ($_POST['priv_message']) { // POST-ing of private messages
        $iRes = $GLOBALS['MainChat']->acceptPrivMessage();
        $oJson = new Services_JSON();
        header('Content-type: application/json');
        echo $oJson->encode(array('result' => $iRes));
        exit;
    }
    $sPrivChatJs = '<script src="js/priv_chat.js"></script>';
}
// get profiles lists
$sProfiles = $GLOBALS['CProfiles']->getProfilesBlock();
$sOnlineMembers = $GLOBALS['CProfiles']->getProfilesBlock(10, true);
// get profile avatar
$sAvatar = $GLOBALS['CProfiles']->getProfileAvatarBlock();
// draw common page
$aKeys = array(
    '{form}' => $sLoginForm . $sErrors,
    '{chat}' => $sChat,
    '{input}' => $sInput,
    '{profiles}' => $sProfiles,
    '{online_members}' => $sOnlineMembers,
    '{avatar}' => $sAvatar,
    '{priv_js}' => $sPrivChatJs
);
echo strtr(file_get_contents('templates/main_page.html'), $aKeys);

<?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 = $sPrivChatJs = '';
if ($_SESSION['member_id'] && $_SESSION['member_status'] == 'active' && $_SESSION['member_role']) {
    if ($_GET['action'] == 'update_last_nav') { // update last navigate time
        $iPid = (int)$_SESSION['member_id'];
        if ($iPid) {
            $GLOBALS['MySQL']->res("UPDATE `cs_profiles` SET `date_nav` = NOW() WHERE `id` = '{$iPid}'");
        }
        exit;
    }
    require_once('classes/CChat.php'); // including service class to work with chat
    if ($_GET['action'] == 'check_new_messages') { // check for new messages
        $iPid = (int)$_SESSION['member_id'];
        $iSender = $GLOBALS['MainChat']->getRecentMessage($iPid);
        if ($iSender) {
            $aSender = $GLOBALS['CProfiles']->getProfileInfo($iSender);
            $sName = ($aSender['first_name'] && $aSender['last_name']) ? $aSender['first_name'] . ' ' . $aSender['last_name'] : $aSender['name'];
            $oJson = new Services_JSON();
            header('Content-type: application/json');
            echo $oJson->encode(array('id' => $iSender, 'name' => $sName));
        }
        exit;
    }
    if ($_GET['action'] == 'get_private_messages') { // regular updating of messages in chat
        $sChat = $GLOBALS['MainChat']->getMessages((int)$_GET['recipient']);
        $oJson = new Services_JSON();
        header('Content-type: application/json');
        echo $oJson->encode(array('messages' => $sChat));
        exit;
    }
    // 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;
    }
    // add avatar
    if ($_POST['action'] == 'add_avatar') {
        $iAvRes = $GLOBALS['CProfiles']->addAvatar();
        header('Content-Type: text/html; charset=utf-8');
        echo ($iAvRes == 1) ? '<h2 style="text-align:center">New avatar has been accepted, refresh main window to see it</h2>' : '';
        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;
    }
    if ($_POST['priv_message']) { // POST-ing of private messages
        $iRes = $GLOBALS['MainChat']->acceptPrivMessage();
        $oJson = new Services_JSON();
        header('Content-type: application/json');
        echo $oJson->encode(array('result' => $iRes));
        exit;
    }
    $sPrivChatJs = '<script src="js/priv_chat.js"></script>';
}
// get profiles lists
$sProfiles = $GLOBALS['CProfiles']->getProfilesBlock();
$sOnlineMembers = $GLOBALS['CProfiles']->getProfilesBlock(10, true);
// get profile avatar
$sAvatar = $GLOBALS['CProfiles']->getProfileAvatarBlock();
// draw common page
$aKeys = array(
    '{form}' => $sLoginForm . $sErrors,
    '{chat}' => $sChat,
    '{input}' => $sInput,
    '{profiles}' => $sProfiles,
    '{online_members}' => $sOnlineMembers,
    '{avatar}' => $sAvatar,
    '{priv_js}' => $sPrivChatJs
);
echo strtr(file_get_contents('templates/main_page.html'), $aKeys);

I added here several more cases for our chat: checking for fresh messages, get private messages, posting of private messages. Our next updated file is profile view file (where I had to add our new js file priv_chat.js):

我在这里为聊天添加了其他几种情况:检查新消息,获取私人消息,发布私人消息。 我们下一个更新的文件是配置文件视图文件(我必须在其中添加新的js文件priv_chat.js):

profile.php (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'];
$sPrivChatJs = '';
if ($_SESSION['member_id'] && $_SESSION['member_status'] == 'active' && $_SESSION['member_role']) {
    if ($_GET['action'] == 'change_color') {
        $iRes = $GLOBALS['CProfiles']->changeColor($_GET['color']);
        header('Content-Type: text/html; charset=utf-8');
        echo ($iRes == 1) ? '<h2 style="text-align:center">New color has been accepted, refresh main window to see it</h2>' : '';
        exit;
    }
    $sPrivChatJs = '<script src="js/priv_chat.js"></script>';
}
$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']);
$sAvatar = $GLOBALS['CProfiles']->getProfileAvatar($iPid);
$sCustomBG = ($aInfo['color']) ? 'background-color:#'.$aInfo['color'] : '';
// get profiles lists
$sProfiles = $GLOBALS['CProfiles']->getProfilesBlock();
$sOnlineMembers = $GLOBALS['CProfiles']->getProfilesBlock(10, true);
// draw common page
$aKeys = array(
    '{id}' => $iPid,
    '{name}' => $sName,
    '{fname}' => $sFName,
    '{lname}' => $sLName,
    '{about}' => $sAbout,
    '{datereg}' => $sDate,
    '{role}' => $sRole,
    '{avatar}' => $sAvatar,
    '{custom_styles}' => $sCustomBG,
    '{cust_visible}' => ($_SESSION['member_id'] == $iPid) ? '' : 'style="display:none"',
    '{profiles}' => $sProfiles,
    '{online_members}' => $sOnlineMembers,
    '{priv_js}' => $sPrivChatJs
);
echo strtr(file_get_contents('templates/profile_page.html'), $aKeys);

<?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'];
$sPrivChatJs = '';
if ($_SESSION['member_id'] && $_SESSION['member_status'] == 'active' && $_SESSION['member_role']) {
    if ($_GET['action'] == 'change_color') {
        $iRes = $GLOBALS['CProfiles']->changeColor($_GET['color']);
        header('Content-Type: text/html; charset=utf-8');
        echo ($iRes == 1) ? '<h2 style="text-align:center">New color has been accepted, refresh main window to see it</h2>' : '';
        exit;
    }
    $sPrivChatJs = '<script src="js/priv_chat.js"></script>';
}
$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']);
$sAvatar = $GLOBALS['CProfiles']->getProfileAvatar($iPid);
$sCustomBG = ($aInfo['color']) ? 'background-color:#'.$aInfo['color'] : '';
// get profiles lists
$sProfiles = $GLOBALS['CProfiles']->getProfilesBlock();
$sOnlineMembers = $GLOBALS['CProfiles']->getProfilesBlock(10, true);
// draw common page
$aKeys = array(
    '{id}' => $iPid,
    '{name}' => $sName,
    '{fname}' => $sFName,
    '{lname}' => $sLName,
    '{about}' => $sAbout,
    '{datereg}' => $sDate,
    '{role}' => $sRole,
    '{avatar}' => $sAvatar,
    '{custom_styles}' => $sCustomBG,
    '{cust_visible}' => ($_SESSION['member_id'] == $iPid) ? '' : 'style="display:none"',
    '{profiles}' => $sProfiles,
    '{online_members}' => $sOnlineMembers,
    '{priv_js}' => $sPrivChatJs
);
echo strtr(file_get_contents('templates/profile_page.html'), $aKeys);

The next updated file:

下一个更新的文件:

classes / CChat.php (classes/CChat.php)

<?php
class CChat {
    // constructor
    function CChat() {}
    // add a message to database
    function acceptMessage() {
        $sName = $GLOBALS['MySQL']->escape($_SESSION['member_name']);
        $iPid = (int)$_SESSION['member_id'];
        $sMessage = $GLOBALS['MySQL']->escape($_POST['message']);
        if ($iPid && $sName != '' && $sMessage != '') {
            $sSQL = "
                SELECT `id`
                FROM `cs_messages`
                WHERE `sender` = '{$iPid}' AND UNIX_TIMESTAMP( ) - `when` < 5
                LIMIT 1
            ";
            $iLastId = $GLOBALS['MySQL']->getOne($sSQL);
            if ($iLastId) return 2; // as protection from very often messages
            $bRes = $GLOBALS['MySQL']->res("INSERT INTO `cs_messages` SET `sender` = '{$iPid}', `message` = '{$sMessage}', `when` = UNIX_TIMESTAMP()");
            return ($bRes) ? 1 : 3;
        }
    }
    // add a private message to database
    function acceptPrivMessage() {
        $sName = $GLOBALS['MySQL']->escape($_SESSION['member_name']);
        $iPid = (int)$_SESSION['member_id'];
        $iRecipient = (int)$_POST['recipient'];
        $sMessage = $GLOBALS['MySQL']->escape($_POST['priv_message']);
        if ($iPid && $iRecipient && $sName != '' && $sMessage != '') {
            $sSQL = "
                SELECT `id`
                FROM `cs_messages`
                WHERE `sender` = '{$iPid}' AND `recipient` = '{$iRecipient}' AND UNIX_TIMESTAMP( ) - `when` < 5
                LIMIT 1
            ";
            $iLastId = $GLOBALS['MySQL']->getOne($sSQL);
            if ($iLastId) return 2; // as protection from very often messages
            $bRes = $GLOBALS['MySQL']->res("INSERT INTO `cs_messages` SET `sender` = '{$iPid}', `recipient` = '{$iRecipient}', `message` = '{$sMessage}', `when` = UNIX_TIMESTAMP()");
            return ($bRes) ? 1 : 3;
        }
    }
    // return input text form
    function getInputForm() {
        return file_get_contents('templates/chat.html');
    }
    // get last 10 messages
    function getMessages($iRecipient = 0) {
        $sRecipientSQL = 'WHERE `recipient` = 0';
        if ($iRecipient > 0) {
            $iPid = (int)$_SESSION['member_id'];
            $sRecipientSQL = "WHERE (`sender` = '{$iRecipient}' && `recipient` = '{$iPid}') || (`recipient` = '{$iRecipient}' && `sender` = '{$iPid}')";
        }
        $sSQL = "
            SELECT `a` . * , `cs_profiles`.`name`,  `cs_profiles`.`id` as 'pid' , UNIX_TIMESTAMP( ) - `a`.`when` AS 'diff'
            FROM `cs_messages` AS `a`
            INNER JOIN `cs_profiles` ON `cs_profiles`.`id` = `a`.`sender`
            {$sRecipientSQL}
            ORDER BY `a`.`id` DESC
            LIMIT 10
        ";
        $aMessages = $GLOBALS['MySQL']->getAll($sSQL);
        asort($aMessages);
        // create list of messages
        $sMessages = '';
        foreach ($aMessages as $i => $aMessage) {
            $sExStyles = $sExJS = '';
            $iDiff = (int)$aMessage['diff'];
            if ($iDiff < 7) { // less than 7 seconds
                $sExStyles = 'style="display:none;"';
                $sExJS = "<script> $('#message_{$aMessage['id']}').fadeIn('slow'); </script>";
            }
            $sWhen = date("H:i:s", $aMessage['when']);
            $sAvatar = $GLOBALS['CProfiles']->getProfileAvatar($aMessage['pid']);
            $sMessages .= '<div class="message" id="message_'.$aMessage['id'].'" '.$sExStyles.'><b><a href="profile.php?id='.$aMessage['pid'].'" target="_blank"><img src="'. $sAvatar .'">' . $aMessage['name'] . ':</a></b> ' . $aMessage['message'] . '<span>(' . $sWhen . ')</span></div>' . $sExJS;
        }
        return $sMessages;
    }
    function getRecentMessage($iPid) {
        if ($iPid) {
            $sSQL = "
                SELECT `a` . * , `cs_profiles`.`name`,  `cs_profiles`.`id` as 'pid' , UNIX_TIMESTAMP( ) - `a`.`when` AS 'diff'
                FROM `cs_messages` AS `a`
                INNER JOIN `cs_profiles` ON `cs_profiles`.`id` = `a`.`sender`
                WHERE `recipient` = '{$iPid}'
                ORDER BY `a`.`id` DESC
                LIMIT 1
            ";
            $aMessage = $GLOBALS['MySQL']->getRow($sSQL);
            $iDiff = (int)$aMessage['diff'];
            if ($iDiff < 7) { // less than 7 seconds, = new
                return (int)$aMessage['sender'];
            }
            return;
        }
    }
}
$GLOBALS['MainChat'] = new CChat();

<?php
class CChat {
    // constructor
    function CChat() {}
    // add a message to database
    function acceptMessage() {
        $sName = $GLOBALS['MySQL']->escape($_SESSION['member_name']);
        $iPid = (int)$_SESSION['member_id'];
        $sMessage = $GLOBALS['MySQL']->escape($_POST['message']);
        if ($iPid && $sName != '' && $sMessage != '') {
            $sSQL = "
                SELECT `id`
                FROM `cs_messages`
                WHERE `sender` = '{$iPid}' AND UNIX_TIMESTAMP( ) - `when` < 5
                LIMIT 1
            ";
            $iLastId = $GLOBALS['MySQL']->getOne($sSQL);
            if ($iLastId) return 2; // as protection from very often messages
            $bRes = $GLOBALS['MySQL']->res("INSERT INTO `cs_messages` SET `sender` = '{$iPid}', `message` = '{$sMessage}', `when` = UNIX_TIMESTAMP()");
            return ($bRes) ? 1 : 3;
        }
    }
    // add a private message to database
    function acceptPrivMessage() {
        $sName = $GLOBALS['MySQL']->escape($_SESSION['member_name']);
        $iPid = (int)$_SESSION['member_id'];
        $iRecipient = (int)$_POST['recipient'];
        $sMessage = $GLOBALS['MySQL']->escape($_POST['priv_message']);
        if ($iPid && $iRecipient && $sName != '' && $sMessage != '') {
            $sSQL = "
                SELECT `id`
                FROM `cs_messages`
                WHERE `sender` = '{$iPid}' AND `recipient` = '{$iRecipient}' AND UNIX_TIMESTAMP( ) - `when` < 5
                LIMIT 1
            ";
            $iLastId = $GLOBALS['MySQL']->getOne($sSQL);
            if ($iLastId) return 2; // as protection from very often messages
            $bRes = $GLOBALS['MySQL']->res("INSERT INTO `cs_messages` SET `sender` = '{$iPid}', `recipient` = '{$iRecipient}', `message` = '{$sMessage}', `when` = UNIX_TIMESTAMP()");
            return ($bRes) ? 1 : 3;
        }
    }
    // return input text form
    function getInputForm() {
        return file_get_contents('templates/chat.html');
    }
    // get last 10 messages
    function getMessages($iRecipient = 0) {
        $sRecipientSQL = 'WHERE `recipient` = 0';
        if ($iRecipient > 0) {
            $iPid = (int)$_SESSION['member_id'];
            $sRecipientSQL = "WHERE (`sender` = '{$iRecipient}' && `recipient` = '{$iPid}') || (`recipient` = '{$iRecipient}' && `sender` = '{$iPid}')";
        }
        $sSQL = "
            SELECT `a` . * , `cs_profiles`.`name`,  `cs_profiles`.`id` as 'pid' , UNIX_TIMESTAMP( ) - `a`.`when` AS 'diff'
            FROM `cs_messages` AS `a`
            INNER JOIN `cs_profiles` ON `cs_profiles`.`id` = `a`.`sender`
            {$sRecipientSQL}
            ORDER BY `a`.`id` DESC
            LIMIT 10
        ";
        $aMessages = $GLOBALS['MySQL']->getAll($sSQL);
        asort($aMessages);
        // create list of messages
        $sMessages = '';
        foreach ($aMessages as $i => $aMessage) {
            $sExStyles = $sExJS = '';
            $iDiff = (int)$aMessage['diff'];
            if ($iDiff < 7) { // less than 7 seconds
                $sExStyles = 'style="display:none;"';
                $sExJS = "<script> $('#message_{$aMessage['id']}').fadeIn('slow'); </script>";
            }
            $sWhen = date("H:i:s", $aMessage['when']);
            $sAvatar = $GLOBALS['CProfiles']->getProfileAvatar($aMessage['pid']);
            $sMessages .= '<div class="message" id="message_'.$aMessage['id'].'" '.$sExStyles.'><b><a href="profile.php?id='.$aMessage['pid'].'" target="_blank"><img src="'. $sAvatar .'">' . $aMessage['name'] . ':</a></b> ' . $aMessage['message'] . '<span>(' . $sWhen . ')</span></div>' . $sExJS;
        }
        return $sMessages;
    }
    function getRecentMessage($iPid) {
        if ($iPid) {
            $sSQL = "
                SELECT `a` . * , `cs_profiles`.`name`,  `cs_profiles`.`id` as 'pid' , UNIX_TIMESTAMP( ) - `a`.`when` AS 'diff'
                FROM `cs_messages` AS `a`
                INNER JOIN `cs_profiles` ON `cs_profiles`.`id` = `a`.`sender`
                WHERE `recipient` = '{$iPid}'
                ORDER BY `a`.`id` DESC
                LIMIT 1
            ";
            $aMessage = $GLOBALS['MySQL']->getRow($sSQL);
            $iDiff = (int)$aMessage['diff'];
            if ($iDiff < 7) { // less than 7 seconds, = new
                return (int)$aMessage['sender'];
            }
            return;
        }
    }
}
$GLOBALS['MainChat'] = new CChat();

I made up my mind to publish whole code of this file. Because I made several changes in existed functions, plus I added two new functions: acceptPrivMessage (to accept private messages) and getRecentMessage (to find, if the member has any fresh messages or hasn’t. If he has any fresh messages and if he doesn’t have opened private chat window – we will initialize new private chat session).

我下定决心要发布此文件的整个代码。 因为我对现有函数进行了几处更改,所以我添加了两个新函数:acceptPrivMessage(接受私人消息)和getRecentMessage(查找成员是否有任何新消息。成员是否有新消息,以及尚未打开私人聊天窗口-我们将初始化新的私人聊天会话)。

The next updated file:

下一个更新的文件:

classes / CProfiles.php (classes/CProfiles.php)

    function getProfilesBlock($iLim = 10, $bOnlineOnly = false) {
        $iPLimit = PROFILE_TIMEOUT;
        $sOnlineSQL = ($bOnlineOnly) ? 'AND (`date_nav` > SUBDATE(NOW(), INTERVAL ' . $iPLimit . ' MINUTE))' : '';
        $sSQL = "
            SELECT `cs_profiles`.*,
            if (`date_nav` > SUBDATE(NOW(), INTERVAL {$iPLimit} MINUTE ), 1, 0) AS `is_online`
            FROM `cs_profiles`
            WHERE `status` = 'active'
            {$sOnlineSQL}
            ORDER BY `date_reg` DESC
            LIMIT {$iLim}
        ";
        $aProfiles = $GLOBALS['MySQL']->getAll($sSQL);
        $bCanChat = ($_SESSION['member_id'] && $_SESSION['member_status'] == 'active' && $_SESSION['member_role']);
        // 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'];
            $sAvatar = $this->getProfileAvatar($iPid);
            $sOnline = ($aProfile['is_online'] == 1) ? '<img alt="" src="images/online.png" class="status_img" />' : '';
            $sChat = ($bCanChat /*&& $aProfile['is_online'] == 1*/) ? '<img id="'.$iPid.'" alt="chat" src="images/chat.png" class="pchat" title="'.$sName.'" />' : '';
            $sCode .= '<div id="'.$iPid.'" title="'.$sName.'"><a href="profile.php?id='.$iPid.'"><img src="'.$sAvatar.'" alt="'.$sName.'"><p>'.$sSName.$sChat.'</p>'.$sOnline.'</a></div>';
        }
        $sClass = ($bOnlineOnly) ? 'profiles online_profiles' : 'profiles';
        return '<div class="'.$sClass.'">' . $sCode . '</div>';
    }

    function getProfilesBlock($iLim = 10, $bOnlineOnly = false) {
        $iPLimit = PROFILE_TIMEOUT;
        $sOnlineSQL = ($bOnlineOnly) ? 'AND (`date_nav` > SUBDATE(NOW(), INTERVAL ' . $iPLimit . ' MINUTE))' : '';
        $sSQL = "
            SELECT `cs_profiles`.*,
            if (`date_nav` > SUBDATE(NOW(), INTERVAL {$iPLimit} MINUTE ), 1, 0) AS `is_online`
            FROM `cs_profiles`
            WHERE `status` = 'active'
            {$sOnlineSQL}
            ORDER BY `date_reg` DESC
            LIMIT {$iLim}
        ";
        $aProfiles = $GLOBALS['MySQL']->getAll($sSQL);
        $bCanChat = ($_SESSION['member_id'] && $_SESSION['member_status'] == 'active' && $_SESSION['member_role']);
        // 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'];
            $sAvatar = $this->getProfileAvatar($iPid);
            $sOnline = ($aProfile['is_online'] == 1) ? '<img alt="" src="images/online.png" class="status_img" />' : '';
            $sChat = ($bCanChat /*&& $aProfile['is_online'] == 1*/) ? '<img id="'.$iPid.'" alt="chat" src="images/chat.png" class="pchat" title="'.$sName.'" />' : '';
            $sCode .= '<div id="'.$iPid.'" title="'.$sName.'"><a href="profile.php?id='.$iPid.'"><img src="'.$sAvatar.'" alt="'.$sName.'"><p>'.$sSName.$sChat.'</p>'.$sOnline.'</a></div>';
        }
        $sClass = ($bOnlineOnly) ? 'profiles online_profiles' : 'profiles';
        return '<div class="'.$sClass.'">' . $sCode . '</div>';
    }

I updated only single function: getProfilesBlock here. Now it draws new icon chat.png. We can click at it to start private conversation. Pay attention to commented code (/*&& $aProfile[‘is_online’] == 1*/). You can uncomment it in order to give possibility to chat only for logged in members.

我只更新了一个函数:getProfilesBlock。 现在,它绘制了新的图标chat.png。 我们可以单击它开始私人对话。 注意注释的代码(/ * && $ aProfile ['is_online'] == 1 * /)。 您可以取消注释,以便仅允许已登录成员聊天。

步骤5. Javascript (Step 5. Javascript)

js / priv_chat.js (js/priv_chat.js)

New javascript for our private chat feature:

用于我们的私人聊天功能的新JavaScript:


$(function() {
    // variables
    var aPChatTimers = [];
    // remove private chat tab
    closePchat = function(id) {
        $('.priv_dock_wrap .priv_chat_tab#pcid'+id).remove();
    }
    // initiate private chat
    initiatePrivateChat = function(id, name) {
        var oPChat = $('.priv_dock_wrap .priv_chat_tab#pcid'+id);
        if (! oPChat.length) { // create new chat dialog
            var sPCTemplate = '<div class="priv_chat_tab" id="pcid'+id+'">'+
'    <div class="priv_title">'+name+'<img src="images/close.png" /></div>'+
'    <div class="priv_conv"></div>'+
'    <div class="priv_input">'+
'        <form class="priv_chat_submit_form">'+
'            <input type="hidden" name="recipient" value="'+id+'" />'+
'            <input type="text" name="message" />'+
'        </form>'+
'    </div>'+
'</div>';
            $('.priv_dock_wrap').append(sPCTemplate);
            // bind onclick at close icon to close form
            $('.priv_chat_tab#pcid'+id+' .priv_title img').bind('click', function() {
                clearTimeout(aPChatTimers[id])
                $('.priv_dock_wrap .priv_chat_tab#pcid'+id).remove();
            });
            // bind onsubmit at input form to send message
            $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form').bind('submit', function() {
                $.post('index.php', { priv_message: $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form input[name=message]').val(),
                    recipient: $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form input[name=recipient]').val() },
                    function(data){
                        $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form input[name=message]').val('');
                        if (data.result == 1) {
                            $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form .success').fadeIn('slow', function () {
                                $(this).delay(1000).fadeOut('slow');
                            });
                        } else if (data.result == 2) {
                            $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form .protect').fadeIn('slow', function () {
                                $(this).delay(1000).fadeOut('slow');
                            });
                        } else {
                            $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form .error').fadeIn('slow', function () {
                                $(this).delay(1000).fadeOut('slow');
                            });
                        }
                    }
                );
                return false;
            });
        }
        // start collecting private messages
        getPrivateMessages(id);
    }
    // create private messages
    getPrivateMessages = function(iRecipient) {
        $.getJSON('index.php?action=get_private_messages&recipient=' + iRecipient, function(data) {
            if (data.messages) {
                $('.priv_chat_tab#pcid'+iRecipient+' .priv_conv').html(data.messages);
            }
            // get recent chat messages in loop
            aPChatTimers[iRecipient] = setTimeout(function() {
               getPrivateMessages(iRecipient);
            }, 5000);
        });
    }
    // initiate private chats by click 'chat' icon
    $('.profiles .pchat').click(function(event) {
        event.stopPropagation();
        event.preventDefault();
        initiatePrivateChat(this.id, this.title);
    });
    initiateNewChatsPeriodically = function() {
        $.getJSON('index.php?action=check_new_messages', function(data) {
            if (data != undefined && data.id) {
                initiatePrivateChat(data.id, data.name);
            }
            // refresh last nav time
            setTimeout(function(){
               initiateNewChatsPeriodically();
            }, 6000); // 1 mins
        });
    }
    initiateNewChatsPeriodically();
});

$(function() {
    // variables
    var aPChatTimers = [];
    // remove private chat tab
    closePchat = function(id) {
        $('.priv_dock_wrap .priv_chat_tab#pcid'+id).remove();
    }
    // initiate private chat
    initiatePrivateChat = function(id, name) {
        var oPChat = $('.priv_dock_wrap .priv_chat_tab#pcid'+id);
        if (! oPChat.length) { // create new chat dialog
            var sPCTemplate = '<div class="priv_chat_tab" id="pcid'+id+'">'+
'    <div class="priv_title">'+name+'<img src="images/close.png" /></div>'+
'    <div class="priv_conv"></div>'+
'    <div class="priv_input">'+
'        <form class="priv_chat_submit_form">'+
'            <input type="hidden" name="recipient" value="'+id+'" />'+
'            <input type="text" name="message" />'+
'        </form>'+
'    </div>'+
'</div>';
            $('.priv_dock_wrap').append(sPCTemplate);
            // bind onclick at close icon to close form
            $('.priv_chat_tab#pcid'+id+' .priv_title img').bind('click', function() {
                clearTimeout(aPChatTimers[id])
                $('.priv_dock_wrap .priv_chat_tab#pcid'+id).remove();
            });
            // bind onsubmit at input form to send message
            $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form').bind('submit', function() {
                $.post('index.php', { priv_message: $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form input[name=message]').val(),
                    recipient: $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form input[name=recipient]').val() },
                    function(data){
                        $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form input[name=message]').val('');
                        if (data.result == 1) {
                            $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form .success').fadeIn('slow', function () {
                                $(this).delay(1000).fadeOut('slow');
                            });
                        } else if (data.result == 2) {
                            $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form .protect').fadeIn('slow', function () {
                                $(this).delay(1000).fadeOut('slow');
                            });
                        } else {
                            $('.priv_chat_tab#pcid'+id+' .priv_chat_submit_form .error').fadeIn('slow', function () {
                                $(this).delay(1000).fadeOut('slow');
                            });
                        }
                    }
                );
                return false;
            });
        }
        // start collecting private messages
        getPrivateMessages(id);
    }
    // create private messages
    getPrivateMessages = function(iRecipient) {
        $.getJSON('index.php?action=get_private_messages&recipient=' + iRecipient, function(data) {
            if (data.messages) {
                $('.priv_chat_tab#pcid'+iRecipient+' .priv_conv').html(data.messages);
            }
            // get recent chat messages in loop
            aPChatTimers[iRecipient] = setTimeout(function() {
               getPrivateMessages(iRecipient);
            }, 5000);
        });
    }
    // initiate private chats by click 'chat' icon
    $('.profiles .pchat').click(function(event) {
        event.stopPropagation();
        event.preventDefault();
        initiatePrivateChat(this.id, this.title);
    });
    initiateNewChatsPeriodically = function() {
        $.getJSON('index.php?action=check_new_messages', function(data) {
            if (data != undefined && data.id) {
                initiatePrivateChat(data.id, data.name);
            }
            // refresh last nav time
            setTimeout(function(){
               initiateNewChatsPeriodically();
            }, 6000); // 1 mins
        });
    }
    initiateNewChatsPeriodically();
});

现场演示
存档下载

结论 (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!

我希望我们有关聊天系统创建的新系列文章对您有用和有趣。 如果您想分享自己的想法,或者发现任何弱点,请随时与我们联系。 祝你好运,欢迎回来!

翻译自: https://www.script-tutorials.com/powerful-chat-system-lesson-7/

赵强大数据vip课

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值