Advertisement
Guest User

Untitled

a guest
Feb 16th, 2017
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 97.02 KB | None | 0 0
  1. <?php
  2. /*
  3.  * @package AJAX_Chat
  4.  * @author Sebastian Tschan
  5.  * @copyright (c) Sebastian Tschan
  6.  * @license Modified MIT License
  7.  * @link https://blueimp.net/ajax/
  8.  */
  9.  
  10. // Ajax Chat backend logic:
  11. class AJAXChat {
  12.  
  13.     var $db;
  14.     var $_config;
  15.     var $_requestVars;
  16.     var $_infoMessages;
  17.     var $_channels;
  18.     var $_allChannels;
  19.     var $_view;
  20.     var $_lang;
  21.     var $_invitations;
  22.     var $_customVars;
  23.     var $_sessionNew;
  24.     var $_onlineUsersData;
  25.     var $_bannedUsersData;
  26.    
  27.     function __construct() {
  28.         $this->initialize();
  29.     }
  30.  
  31.     function initialize() {
  32.         // Initialize configuration settings:
  33.         $this->initConfig();
  34.  
  35.         // Initialize the DataBase connection:
  36.         $this->initDataBaseConnection();
  37.  
  38.         // Initialize request variables:
  39.         $this->initRequestVars();
  40.        
  41.         // Initialize the chat session:
  42.         $this->initSession();
  43.        
  44.         // Handle the browser request and send the response content:
  45.         $this->handleRequest();
  46.     }
  47.  
  48.     function initConfig() {
  49.         $config = null;
  50.         if (!include(AJAX_CHAT_PATH.'lib/config.php')) {
  51.             echo('<strong>Error:</strong> Could not find a config.php file in "'.AJAX_CHAT_PATH.'"lib/". Check to make sure the file exists.');
  52.             die();
  53.         }
  54.         $this->_config = &$config;
  55.  
  56.         // Initialize custom configuration settings:
  57.         $this->initCustomConfig();
  58.     }
  59.    
  60.     function initRequestVars() {
  61.         $this->_requestVars = array();
  62.         $this->_requestVars['ajax']         = isset($_REQUEST['ajax'])          ? true                          : false;
  63.         $this->_requestVars['userID']       = isset($_REQUEST['userID'])        ? (int)$_REQUEST['userID']      : null;
  64.         $this->_requestVars['userName']     = isset($_REQUEST['userName'])      ? $_REQUEST['userName']         : null;
  65.         $this->_requestVars['channelID']    = isset($_REQUEST['channelID'])     ? (int)$_REQUEST['channelID']   : null;
  66.         $this->_requestVars['channelName']  = isset($_REQUEST['channelName'])   ? $_REQUEST['channelName']      : null;
  67.         $this->_requestVars['text']         = isset($_POST['text'])             ? $_POST['text']                : null;
  68.         $this->_requestVars['lastID']       = isset($_REQUEST['lastID'])        ? (int)$_REQUEST['lastID']      : 0;
  69.         $this->_requestVars['login']        = isset($_REQUEST['login'])         ? true                          : false;
  70.         $this->_requestVars['logout']       = isset($_REQUEST['logout'])        ? true                          : false;
  71.         $this->_requestVars['password']     = isset($_REQUEST['password'])      ? $_REQUEST['password']         : null;
  72.         $this->_requestVars['view']         = isset($_REQUEST['view'])          ? $_REQUEST['view']             : null;
  73.         $this->_requestVars['year']         = isset($_REQUEST['year'])          ? (int)$_REQUEST['year']        : null;
  74.         $this->_requestVars['month']        = isset($_REQUEST['month'])         ? (int)$_REQUEST['month']       : null;
  75.         $this->_requestVars['day']          = isset($_REQUEST['day'])           ? (int)$_REQUEST['day']         : null;
  76.         $this->_requestVars['hour']         = isset($_REQUEST['hour'])          ? (int)$_REQUEST['hour']        : null;
  77.         $this->_requestVars['search']       = isset($_REQUEST['search'])        ? $_REQUEST['search']           : null;
  78.         $this->_requestVars['shoutbox']     = isset($_REQUEST['shoutbox'])      ? true                          : false;
  79.         $this->_requestVars['getInfos']     = isset($_REQUEST['getInfos'])      ? $_REQUEST['getInfos']         : null;
  80.         $this->_requestVars['lang']         = isset($_REQUEST['lang'])          ? $_REQUEST['lang']             : null;
  81.         $this->_requestVars['delete']       = isset($_REQUEST['delete'])        ? (int)$_REQUEST['delete']      : null;
  82.        
  83.         // Initialize custom request variables:
  84.         $this->initCustomRequestVars();
  85.        
  86.         // Remove slashes which have been added to user input strings if magic_quotes_gpc is On:
  87.         if(get_magic_quotes_gpc()) {
  88.             // It is safe to remove the slashes as we escape user data ourself
  89.             array_walk(
  90.                 $this->_requestVars,
  91.                 create_function(
  92.                     '&$value, $key',
  93.                     'if(is_string($value)) $value = stripslashes($value);'
  94.                 )
  95.             );
  96.         }
  97.     }
  98.    
  99.     function initDataBaseConnection() {
  100.         // Create a new database object:
  101.         $this->db = new AJAXChatDataBase(
  102.             $this->_config['dbConnection']
  103.         );
  104.         // Use a new database connection if no existing is given:
  105.         if(!$this->_config['dbConnection']['link']) {
  106.             // Connect to the database server:
  107.             $this->db->connect($this->_config['dbConnection']);
  108.             if($this->db->error()) {
  109.                 echo $this->db->getError();
  110.                 die();
  111.             }
  112.             // Select the database:
  113.             $this->db->select($this->_config['dbConnection']['name']);
  114.             if($this->db->error()) {
  115.                 echo $this->db->getError();
  116.                 die();
  117.             }
  118.         }
  119.         // Unset the dbConnection array for safety purposes:
  120.         unset($this->_config['dbConnection']);         
  121.     }
  122.    
  123.     function getDataBaseTable($table) {
  124.         return ($this->db->getName() ? '`'.$this->db->getName().'`.'.$this->getConfig('dbTableNames',$table) : $this->getConfig('dbTableNames',$table));
  125.     }
  126.  
  127.     function initSession() {
  128.         // Start the PHP session (if not already started):
  129.         $this->startSession();
  130.  
  131.         if($this->isLoggedIn()) {
  132.             // Logout if we receive a logout request, the chat has been closed or the userID could not be revalidated:
  133.             if($this->getRequestVar('logout') || !$this->isChatOpen() || !$this->revalidateUserID()) {
  134.                 $this->logout();
  135.                 return;
  136.             }
  137.             // Logout if the Session IP is not the same when logged in and ipCheck is enabled:
  138.             if($this->getConfig('ipCheck') && ($this->getSessionIP() === null || $this->getSessionIP() != $_SERVER['REMOTE_ADDR'])) {
  139.                 $this->logout('IP');
  140.                 return;
  141.             }
  142.         } else if(
  143.             // Login if auto-login enabled or a login, userName or shoutbox parameter is given:
  144.             $this->getConfig('forceAutoLogin') ||
  145.             $this->getRequestVar('login') ||
  146.             $this->getRequestVar('userName') ||
  147.             $this->getRequestVar('shoutbox')
  148.             ) {
  149.             $this->login();
  150.         }
  151.  
  152.         // Initialize the view:
  153.         $this->initView();
  154.  
  155.         if($this->getView() == 'chat') {
  156.             $this->initChatViewSession();
  157.         } else if($this->getView() == 'logs') {
  158.             $this->initLogsViewSession();
  159.         }
  160.  
  161.         if(!$this->getRequestVar('ajax') && !headers_sent()) {
  162.             // Set style cookie:
  163.             $this->setStyle();
  164.             // Set langCode cookie:
  165.             $this->setLangCodeCookie();
  166.         }
  167.        
  168.         $this->initCustomSession();
  169.     }
  170.  
  171.     function initLogsViewSession() {
  172.         if($this->getConfig('socketServerEnabled')) {
  173.             if(!$this->getSessionVar('logsViewSocketAuthenticated')) {
  174.                 $this->updateLogsViewSocketAuthentication();
  175.                 $this->setSessionVar('logsViewSocketAuthenticated', true);
  176.             }
  177.         }
  178.     }
  179.  
  180.     function updateLogsViewSocketAuthentication() {
  181.         if($this->getUserRole() != AJAX_CHAT_ADMIN) {
  182.             $channels = array();
  183.             foreach($this->getChannels() as $channel) {
  184.                 if($this->getConfig('logsUserAccessChannelList') && !in_array($channel, $this->getConfig('logsUserAccessChannelList'))) {
  185.                     continue;
  186.                 }
  187.                 array_push($channels, $channel);
  188.             }
  189.             array_push($channels, $this->getPrivateMessageID());
  190.             array_push($channels, $this->getPrivateChannelID());
  191.         } else {
  192.             // The channelID "ALL" authenticates for all channels:
  193.             $channels = array('ALL');
  194.         }
  195.         $this->updateSocketAuthentication(
  196.             $this->getUserID(),
  197.             $this->getSocketRegistrationID(),
  198.             $channels
  199.         );
  200.     }
  201.  
  202.     function initChatViewSession() {
  203.         // If channel is not null we are logged in to the chat view:
  204.         if($this->getChannel() !== null) {
  205.             // Check if the current user has been logged out due to inactivity:
  206.             if(!$this->isUserOnline()) {
  207.                 $this->logout();
  208.                 return;
  209.             }
  210.             if($this->getRequestVar('ajax')) {
  211.                 $this->initChannel();
  212.                 $this->updateOnlineStatus();
  213.                 $this->checkAndRemoveInactive();
  214.             }
  215.         } else {
  216.             if($this->getRequestVar('ajax')) {
  217.                 // Set channel, insert login messages and add to online list on first ajax request in chat view:
  218.                 $this->chatViewLogin();
  219.             }
  220.         }
  221.     }
  222.  
  223.     function isChatOpen() {
  224.         if($this->getUserRole() == AJAX_CHAT_ADMIN)
  225.             return true;
  226.         if($this->getConfig('chatClosed'))
  227.             return false;
  228.         $time = time();
  229.         if($this->getConfig('timeZoneOffset') !== null) {
  230.             // Subtract the server timezone offset and add the config timezone offset:
  231.             $time -= date('Z', $time);
  232.             $time += $this->getConfig('timeZoneOffset');
  233.         }
  234.         // Check the opening hours:
  235.         if($this->getConfig('openingHour') < $this->getConfig('closingHour'))
  236.         {
  237.             if(($this->getConfig('openingHour') > date('G', $time)) || ($this->getConfig('closingHour') <= date('G', $time)))
  238.                 return false;
  239.         }
  240.         else
  241.         {
  242.             if(($this->getConfig('openingHour') > date('G', $time)) && ($this->getConfig('closingHour') <= date('G', $time)))
  243.                 return false;
  244.         }
  245.         // Check the opening weekdays:
  246.         if(!in_array(date('w', $time), $this->getConfig('openingWeekDays')))
  247.             return false;
  248.         return true;   
  249.     }
  250.  
  251.     function handleRequest() {
  252.         if($this->getRequestVar('ajax')) {
  253.             if($this->isLoggedIn()) {
  254.                 // Parse info requests (for current userName, etc.):
  255.                 $this->parseInfoRequests();
  256.    
  257.                 // Parse command requests (e.g. message deletion):
  258.                 $this->parseCommandRequests();
  259.    
  260.                 // Parse message requests:
  261.                 $this->initMessageHandling();
  262.             }
  263.             // Send chat messages and online user list in XML format:
  264.             $this->sendXMLMessages();
  265.         } else {
  266.             // Display XHTML content for non-ajax requests:
  267.             $this->sendXHTMLContent();
  268.         }
  269.     }
  270.  
  271.     function parseCommandRequests() {
  272.         if($this->getRequestVar('delete') !== null) {
  273.             $this->deleteMessage($this->getRequestVar('delete'));
  274.         }
  275.     }
  276.  
  277.     function parseInfoRequests() {
  278.         if($this->getRequestVar('getInfos')) {
  279.             $infoRequests = explode(',', $this->getRequestVar('getInfos'));        
  280.             foreach($infoRequests as $infoRequest) {
  281.                 $this->parseInfoRequest($infoRequest);
  282.             }
  283.         }
  284.     }
  285.    
  286.     function parseInfoRequest($infoRequest) {
  287.         switch($infoRequest) {
  288.             case 'userID':
  289.                 $this->addInfoMessage($this->getUserID(), 'userID');
  290.                 break;
  291.             case 'userName':
  292.                 $this->addInfoMessage($this->getUserName(), 'userName');
  293.                 break;
  294.             case 'userRole':
  295.                 $this->addInfoMessage($this->getUserRole(), 'userRole');
  296.                 break;
  297.             case 'channelID':
  298.                 $this->addInfoMessage($this->getChannel(), 'channelID');
  299.                 break;
  300.             case 'channelName':
  301.                 $this->addInfoMessage($this->getChannelName(), 'channelName');
  302.                 break;
  303.             case 'socketRegistrationID':
  304.                 $this->addInfoMessage($this->getSocketRegistrationID(), 'socketRegistrationID');
  305.                 break;
  306.             default:
  307.                 $this->parseCustomInfoRequest($infoRequest);
  308.         }
  309.     }
  310.  
  311.     function sendXHTMLContent() {
  312.         $httpHeader = new AJAXChatHTTPHeader($this->getConfig('contentEncoding'), $this->getConfig('contentType'));
  313.  
  314.         $template = new AJAXChatTemplate($this, $this->getTemplateFileName(), $httpHeader->getContentType());
  315.  
  316.         // Send HTTP header:
  317.         $httpHeader->send();       
  318.  
  319.         // Send parsed template content:
  320.         echo $template->getParsedContent();
  321.     }
  322.  
  323.     function getTemplateFileName() {
  324.         switch($this->getView()) {
  325.             case 'chat':
  326.                 return AJAX_CHAT_PATH.'lib/template/loggedIn.html';
  327.             case 'logs':
  328.                 return AJAX_CHAT_PATH.'lib/template/logs.html';
  329.             default:
  330.                 return AJAX_CHAT_PATH.'lib/template/loggedOut.html';
  331.         }
  332.     }
  333.  
  334.     function initView() {
  335.         $this->_view = null;
  336.         // "chat" is the default view:
  337.         $view = ($this->getRequestVar('view') === null) ? 'chat' : $this->getRequestVar('view');
  338.         if($this->hasAccessTo($view)) {
  339.             $this->_view = $view;
  340.         }
  341.     }
  342.  
  343.     function getView() {
  344.         return $this->_view;
  345.     }
  346.  
  347.     function hasAccessTo($view) {
  348.         switch($view) {
  349.             case 'chat':
  350.             case 'teaser':
  351.                 if($this->isLoggedIn()) {
  352.                     return true;   
  353.                 }
  354.                 return false;
  355.             case 'logs':
  356.                 if($this->isLoggedIn() && ($this->getUserRole() == AJAX_CHAT_ADMIN ||
  357.                     ($this->getConfig('logsUserAccess') &&
  358.                     ($this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == AJAX_CHAT_USER))
  359.                     )) {
  360.                     return true;
  361.                 }
  362.                 return false;
  363.             default:
  364.                 return false;
  365.         }
  366.     }
  367.    
  368.     function login() {
  369.         // Retrieve valid login user data (from request variables or session data):
  370.         $userData = $this->getValidLoginUserData();
  371.        
  372.         if(!$userData) {
  373.             $this->addInfoMessage('errorInvalidUser');
  374.             return false;
  375.         }
  376.  
  377.         // If the chat is closed, only the admin may login:
  378.         if(!$this->isChatOpen() && $userData['userRole'] != AJAX_CHAT_ADMIN) {
  379.             $this->addInfoMessage('errorChatClosed');
  380.             return false;
  381.         }
  382.        
  383.         if(!$this->getConfig('allowGuestLogins') && $userData['userRole'] == AJAX_CHAT_GUEST) {
  384.             return false;
  385.         }
  386.  
  387.         // Check if userID or userName are already listed online:
  388.         if($this->isUserOnline($userData['userID']) || $this->isUserNameInUse($userData['userName'])) {
  389.             if($userData['userRole'] == AJAX_CHAT_USER || $userData['userRole'] == AJAX_CHAT_MODERATOR || $userData['userRole'] == AJAX_CHAT_ADMIN) {
  390.                 // Set the registered user inactive and remove the inactive users so the user can be logged in again:
  391.                 $this->setInactive($userData['userID'], $userData['userName']);
  392.                 $this->removeInactive();
  393.             } else {
  394.                 $this->addInfoMessage('errorUserInUse');
  395.                 return false;
  396.             }
  397.         }
  398.        
  399.         // Check if user is banned:
  400.         if($userData['userRole'] != AJAX_CHAT_ADMIN && $this->isUserBanned($userData['userName'], $userData['userID'], $_SERVER['REMOTE_ADDR'])) {
  401.             $this->addInfoMessage('errorBanned');
  402.             return false;
  403.         }
  404.        
  405.         // Check if the max number of users is logged in (not affecting moderators or admins):
  406.         if(!($userData['userRole'] == AJAX_CHAT_MODERATOR || $userData['userRole'] == AJAX_CHAT_ADMIN) && $this->isMaxUsersLoggedIn()) {
  407.             $this->addInfoMessage('errorMaxUsersLoggedIn');
  408.             return false;
  409.         }
  410.  
  411.         // Use a new session id (if session has been started by the chat):
  412.         $this->regenerateSessionID();
  413.  
  414.         // Log in:
  415.         $this->setUserID($userData['userID']);
  416.         $this->setUserName($userData['userName']);
  417.         $this->setLoginUserName($userData['userName']);
  418.         $this->setUserRole($userData['userRole']);
  419.         $this->setLoggedIn(true);  
  420.         $this->setLoginTimeStamp(time());
  421.  
  422.         // IP Security check variable:
  423.         $this->setSessionIP($_SERVER['REMOTE_ADDR']);
  424.  
  425.         // The client authenticates to the socket server using a socketRegistrationID:
  426.         if($this->getConfig('socketServerEnabled')) {
  427.             $this->setSocketRegistrationID(
  428.                 md5(uniqid(rand(), true))
  429.             );
  430.         }
  431.  
  432.         // Add userID, userName and userRole to info messages:
  433.         $this->addInfoMessage($this->getUserID(), 'userID');
  434.         $this->addInfoMessage($this->getUserName(), 'userName');
  435.         $this->addInfoMessage($this->getUserRole(), 'userRole');
  436.  
  437.         // Purge logs:
  438.         if($this->getConfig('logsPurgeLogs')) {
  439.             $this->purgeLogs();
  440.         }
  441.  
  442.         return true;
  443.     }
  444.    
  445.     function chatViewLogin() {
  446.         $this->setChannel($this->getValidRequestChannelID());
  447.         $this->addToOnlineList();
  448.        
  449.         // Add channelID and channelName to info messages:
  450.         $this->addInfoMessage($this->getChannel(), 'channelID');
  451.         $this->addInfoMessage($this->getChannelName(), 'channelName');
  452.        
  453.         // Login message:
  454.         $text = '/login '.$this->getUserName();
  455.         $this->insertChatBotMessage(
  456.             $this->getChannel(),
  457.             $text,
  458.             null,
  459.             1
  460.         ); 
  461.     }
  462.  
  463.     function getValidRequestChannelID() {
  464.         $channelID = $this->getRequestVar('channelID');
  465.         $channelName = $this->getRequestVar('channelName');    
  466.         // Check the given channelID, or get channelID from channelName:
  467.         if($channelID === null) {
  468.             if($channelName !== null) {
  469.                 $channelID = $this->getChannelIDFromChannelName($channelName);
  470.                 // channelName might need encoding conversion:
  471.                 if($channelID === null) {
  472.                     $channelID = $this->getChannelIDFromChannelName(
  473.                                     $this->trimChannelName($channelName, $this->getConfig('contentEncoding'))
  474.                                 );
  475.                 }
  476.             }
  477.         }
  478.         // Validate the resulting channelID:
  479.         if(!$this->validateChannel($channelID)) {
  480.             if($this->getChannel() !== null) {
  481.                 return $this->getChannel();
  482.             }
  483.             return $this->getConfig('defaultChannelID');
  484.         }
  485.         return $channelID;
  486.     }
  487.  
  488.     function initChannel() {
  489.         $channelID = $this->getRequestVar('channelID');
  490.         $channelName = $this->getRequestVar('channelName');
  491.         if($channelID !== null) {
  492.             $this->switchChannel($this->getChannelNameFromChannelID($channelID));          
  493.         } else if($channelName !== null) {
  494.             if($this->getChannelIDFromChannelName($channelName) === null) {
  495.                 // channelName might need encoding conversion:
  496.                 $channelName = $this->trimChannelName($channelName, $this->getConfig('contentEncoding'));
  497.             }      
  498.             $this->switchChannel($channelName);
  499.         }
  500.     }
  501.    
  502.     function logout($type=null) {
  503.         // Update the socket server authentication for the user:
  504.         if($this->getConfig('socketServerEnabled')) {
  505.             $this->updateSocketAuthentication($this->getUserID());
  506.         }
  507.         if($this->isUserOnline()) {
  508.             $this->chatViewLogout($type);
  509.         }  
  510.         $this->setLoggedIn(false);     
  511.         $this->destroySession();
  512.  
  513.         // Re-initialize the view:
  514.         $this->initView();
  515.     }
  516.    
  517.     function chatViewLogout($type) {
  518.         $this->removeFromOnlineList();
  519.         if($type !== null) {
  520.             $type = ' '.$type;
  521.         }
  522.         // Logout message
  523.         $text = '/logout '.$this->getUserName().$type;
  524.         $this->insertChatBotMessage(
  525.             $this->getChannel(),
  526.             $text,
  527.             null,
  528.             1
  529.         );
  530.     }
  531.    
  532.     function switchChannel($channelName) {
  533.         $channelID = $this->getChannelIDFromChannelName($channelName);
  534.  
  535.         if($channelID !== null && $this->getChannel() == $channelID) {
  536.             // User is already in the given channel, return:
  537.             return;
  538.         }
  539.  
  540.         // Check if we have a valid channel:
  541.         if(!$this->validateChannel($channelID)) {
  542.             // Invalid channel:
  543.             $text = '/error InvalidChannelName '.$channelName;
  544.             $this->insertChatBotMessage(
  545.                 $this->getPrivateMessageID(),
  546.                 $text
  547.             );
  548.             return;
  549.         }
  550.  
  551.         $oldChannel = $this->getChannel();
  552.  
  553.         $this->setChannel($channelID);
  554.         $this->updateOnlineList();
  555.        
  556.         // Channel leave message
  557.         $text = '/channelLeave '.$this->getUserName();
  558.         $this->insertChatBotMessage(
  559.             $oldChannel,
  560.             $text,
  561.             null,
  562.             1
  563.         );
  564.  
  565.         // Channel enter message
  566.         $text = '/channelEnter '.$this->getUserName();
  567.         $this->insertChatBotMessage(
  568.             $this->getChannel(),
  569.             $text,
  570.             null,
  571.             1
  572.         );
  573.  
  574.         $this->addInfoMessage($channelName, 'channelSwitch');
  575.         $this->addInfoMessage($channelID, 'channelID');
  576.         $this->_requestVars['lastID'] = 0;
  577.     }
  578.    
  579.     function addToOnlineList() {
  580.         $sql = 'INSERT INTO '.$this->getDataBaseTable('online').'(
  581.                     userID,
  582.                     userName,
  583.                     userRole,
  584.                     channel,
  585.                     dateTime,
  586.                     ip
  587.                 )
  588.                 VALUES (
  589.                     '.$this->db->makeSafe($this->getUserID()).',
  590.                     '.$this->db->makeSafe($this->getUserName()).',
  591.                     '.$this->db->makeSafe($this->getUserRole()).',
  592.                     '.$this->db->makeSafe($this->getChannel()).',
  593.                     NOW(),
  594.                     '.$this->db->makeSafe($this->ipToStorageFormat($_SERVER['REMOTE_ADDR'])).'
  595.                 );';   
  596.        
  597.         // Create a new SQL query:
  598.         $result = $this->db->sqlQuery($sql);
  599.        
  600.         // Stop if an error occurs:
  601.         if($result->error()) {
  602.             echo $result->getError();
  603.             die();
  604.         }
  605.        
  606.         $this->resetOnlineUsersData();
  607.     }
  608.    
  609.     function removeFromOnlineList() {
  610.         $sql = 'DELETE FROM
  611.                     '.$this->getDataBaseTable('online').'
  612.                 WHERE
  613.                     userID = '.$this->db->makeSafe($this->getUserID()).';';
  614.        
  615.         // Create a new SQL query:
  616.         $result = $this->db->sqlQuery($sql);
  617.        
  618.         // Stop if an error occurs:
  619.         if($result->error()) {
  620.             echo $result->getError();
  621.             die();
  622.         }
  623.        
  624.         $this->removeUserFromOnlineUsersData();
  625.     }
  626.    
  627.     function updateOnlineList() {
  628.         $sql = 'UPDATE
  629.                     '.$this->getDataBaseTable('online').'
  630.                 SET
  631.                     userName    = '.$this->db->makeSafe($this->getUserName()).',
  632.                     channel     = '.$this->db->makeSafe($this->getChannel()).',
  633.                     dateTime    = NOW(),
  634.                     ip          = '.$this->db->makeSafe($this->ipToStorageFormat($_SERVER['REMOTE_ADDR'])).'
  635.                 WHERE
  636.                     userID = '.$this->db->makeSafe($this->getUserID()).';';
  637.                    
  638.         // Create a new SQL query:
  639.         $result = $this->db->sqlQuery($sql);
  640.        
  641.         // Stop if an error occurs:
  642.         if($result->error()) {
  643.             echo $result->getError();
  644.             die();
  645.         }
  646.        
  647.         $this->resetOnlineUsersData();
  648.     }
  649.    
  650.     function initMessageHandling() {
  651.         // Don't handle messages if we are not in chat view:
  652.         if($this->getView() != 'chat') {
  653.             return;
  654.         }
  655.  
  656.         // Check if we have been uninvited from a private or restricted channel:
  657.         if(!$this->validateChannel($this->getChannel())) {
  658.             // Switch to the default channel:
  659.             $this->switchChannel($this->getChannelNameFromChannelID($this->getConfig('defaultChannelID')));
  660.             return;
  661.         }
  662.                    
  663.         if($this->getRequestVar('text') !== null) {
  664.             $this->insertMessage($this->getRequestVar('text'));
  665.         }
  666.     }
  667.    
  668.     function insertParsedMessage($text) {
  669.  
  670.         // If a queryUserName is set, sent all messages as private messages to this userName:
  671.         if($this->getQueryUserName() !== null && strpos($text, '/') !== 0) {
  672.             $text = '/msg '.$this->getQueryUserName().' '.$text;
  673.         }
  674.        
  675.         // Parse IRC-style commands:
  676.         if(strpos($text, '/') === 0) {
  677.             $textParts = explode(' ', $text);
  678.  
  679.             switch($textParts[0]) {
  680.                
  681.                 // Channel switch:
  682.                 case '/join':
  683.                     $this->insertParsedMessageJoin($textParts);
  684.                     break;
  685.                    
  686.                 // Logout:
  687.                 case '/quit':
  688.                     $this->logout();
  689.                     break;
  690.                    
  691.                 // Private message:
  692.                 case '/msg':
  693.                 case '/describe':
  694.                     $this->insertParsedMessagePrivMsg($textParts);
  695.                     break;
  696.                
  697.                 // Invitation:
  698.                 case '/invite':
  699.                     $this->insertParsedMessageInvite($textParts);
  700.                     break;
  701.  
  702.                 // Uninvitation:
  703.                 case '/uninvite':      
  704.                     $this->insertParsedMessageUninvite($textParts);
  705.                     break;
  706.  
  707.                 // Private messaging:
  708.                 case '/query':
  709.                     $this->insertParsedMessageQuery($textParts);
  710.                     break;
  711.                
  712.                 // Kicking offending users from the chat:
  713.                 case '/kick':
  714.                     $this->insertParsedMessageKick($textParts);
  715.                     break;
  716.                
  717.                 // Listing banned users:
  718.                 case '/bans':
  719.                     $this->insertParsedMessageBans($textParts);
  720.                     break;
  721.                
  722.                 // Unban user (remove from ban list):
  723.                 case '/unban':
  724.                     $this->insertParsedMessageUnban($textParts);
  725.                     break;
  726.                
  727.                 // Describing actions:
  728.                 case '/me':
  729.                 case '/action':
  730.                     $this->insertParsedMessageAction($textParts);
  731.                     break;
  732.  
  733.  
  734.                 // Listing online Users:
  735.                 case '/who':   
  736.                     $this->insertParsedMessageWho($textParts);
  737.                     break;
  738.                
  739.                 // Listing available channels:
  740.                 case '/list':  
  741.                     $this->insertParsedMessageList($textParts);
  742.                     break;
  743.  
  744.                 // Retrieving the channel of a User:
  745.                 case '/whereis':
  746.                     $this->insertParsedMessageWhereis($textParts);
  747.                     break;
  748.                
  749.                 // Listing information about a User:
  750.                 case '/whois':
  751.                     $this->insertParsedMessageWhois($textParts);
  752.                     break;
  753.                
  754.                 // Rolling dice:
  755.                 case '/roll':              
  756.                     $this->insertParsedMessageRoll($textParts);
  757.                     break;
  758.  
  759.                 // Switching userName:
  760.                 case '/nick':              
  761.                     $this->insertParsedMessageNick($textParts);
  762.                     break;
  763.            
  764.                 // Custom or unknown command:
  765.                 default:
  766.                     if(!$this->parseCustomCommands($text, $textParts)) {               
  767.                         $this->insertChatBotMessage(
  768.                             $this->getPrivateMessageID(),
  769.                             '/error UnknownCommand '.$textParts[0]
  770.                         );
  771.                     }
  772.             }
  773.  
  774.         } else {
  775.             // No command found, just insert the plain message:
  776.             $this->insertCustomMessage(
  777.                 $this->getUserID(),
  778.                 $this->getUserName(),
  779.                 $this->getUserRole(),
  780.                 $this->getChannel(),
  781.                 $text
  782.             );
  783.         }
  784.     }
  785.  
  786.     function insertParsedMessageJoin($textParts) {
  787.         if(count($textParts) == 1) {
  788.             // join with no arguments is the own private channel, if allowed:
  789.             if($this->isAllowedToCreatePrivateChannel()) {
  790.                 // Private channels are identified by square brackets:
  791.                 $this->switchChannel($this->getChannelNameFromChannelID($this->getPrivateChannelID()));
  792.             } else {
  793.                 $this->insertChatBotMessage(
  794.                     $this->getPrivateMessageID(),
  795.                     '/error MissingChannelName'
  796.                 );
  797.             }
  798.         } else {
  799.             $this->switchChannel($textParts[1]);
  800.         }
  801.     }
  802.    
  803.     function insertParsedMessagePrivMsg($textParts) {
  804.         if($this->isAllowedToSendPrivateMessage()) {
  805.             if(count($textParts) < 3) {
  806.                 if(count($textParts) == 2) {
  807.                     $this->insertChatBotMessage(
  808.                         $this->getPrivateMessageID(),
  809.                         '/error MissingText'
  810.                     );
  811.                 } else {
  812.                     $this->insertChatBotMessage(
  813.                         $this->getPrivateMessageID(),
  814.                         '/error MissingUserName'
  815.                     );
  816.                 }
  817.             } else {
  818.                 // Get UserID from UserName:
  819.                 $toUserID = $this->getIDFromName($textParts[1]);
  820.                 if($toUserID === null) {
  821.                     if($this->getQueryUserName() !== null) {
  822.                         // Close the current query:
  823.                         $this->insertMessage('/query');
  824.                     } else {
  825.                         $this->insertChatBotMessage(
  826.                             $this->getPrivateMessageID(),
  827.                             '/error UserNameNotFound '.$textParts[1]
  828.                         );
  829.                     }
  830.                 } else {
  831.                     // Insert /privaction command if /describe is used:
  832.                     $command = ($textParts[0] == '/describe') ? '/privaction' : '/privmsg';                        
  833.                     // Copy of private message to current User:
  834.                     $this->insertCustomMessage(
  835.                         $this->getUserID(),
  836.                         $this->getUserName(),
  837.                         $this->getUserRole(),
  838.                         $this->getPrivateMessageID(),
  839.                         $command.'to '.$textParts[1].' '.implode(' ', array_slice($textParts, 2))
  840.                     );                             
  841.                     // Private message to requested User:
  842.                     $this->insertCustomMessage(
  843.                         $this->getUserID(),
  844.                         $this->getUserName(),
  845.                         $this->getUserRole(),
  846.                         $this->getPrivateMessageID($toUserID),
  847.                         $command.' '.implode(' ', array_slice($textParts, 2))
  848.                     );
  849.                 }
  850.             }
  851.         } else {
  852.             $this->insertChatBotMessage(
  853.                 $this->getPrivateMessageID(),
  854.                 '/error PrivateMessageNotAllowed'
  855.             );
  856.         }
  857.     }
  858.    
  859.     function insertParsedMessageInvite($textParts) {
  860.         if($this->getChannel() == $this->getPrivateChannelID() || in_array($this->getChannel(), $this->getChannels())) {
  861.             if(count($textParts) == 1) {
  862.                 $this->insertChatBotMessage(
  863.                     $this->getPrivateMessageID(),
  864.                     '/error MissingUserName'
  865.                 );
  866.             } else {
  867.                 $toUserID = $this->getIDFromName($textParts[1]);
  868.                 if($toUserID === null) {
  869.                     $this->insertChatBotMessage(
  870.                         $this->getPrivateMessageID(),
  871.                         '/error UserNameNotFound '.$textParts[1]
  872.                     );
  873.                 } else {                       
  874.                     // Add the invitation to the database:
  875.                     $this->addInvitation($toUserID);
  876.                     $invitationChannelName = $this->getChannelNameFromChannelID($this->getChannel());
  877.                     // Copy of invitation to current User:
  878.                     $this->insertChatBotMessage(
  879.                         $this->getPrivateMessageID(),
  880.                         '/inviteto '.$textParts[1].' '.$invitationChannelName
  881.                     );                         
  882.                     // Invitation to requested User:
  883.                     $this->insertChatBotMessage(
  884.                         $this->getPrivateMessageID($toUserID),
  885.                         '/invite '.$this->getUserName().' '.$invitationChannelName
  886.                     );
  887.                 }
  888.             }                      
  889.         } else {
  890.             $this->insertChatBotMessage(
  891.                 $this->getPrivateMessageID(),
  892.                 '/error InviteNotAllowed'
  893.             );
  894.         }
  895.     }
  896.        
  897.     function insertParsedMessageUninvite($textParts) {
  898.         if($this->getChannel() == $this->getPrivateChannelID() || in_array($this->getChannel(), $this->getChannels())) {
  899.             if(count($textParts) == 1) {
  900.                 $this->insertChatBotMessage(
  901.                     $this->getPrivateMessageID(),
  902.                     '/error MissingUserName'
  903.                 );
  904.             } else {
  905.                 $toUserID = $this->getIDFromName($textParts[1]);
  906.                 if($toUserID === null) {
  907.                     $this->insertChatBotMessage(
  908.                         $this->getPrivateMessageID(),
  909.                         '/error UserNameNotFound '.$textParts[1]
  910.                     );
  911.                 } else {                       
  912.                     // Remove the invitation from the database:
  913.                     $this->removeInvitation($toUserID);
  914.                     $invitationChannelName = $this->getChannelNameFromChannelID($this->getChannel());
  915.                     // Copy of uninvitation to current User:
  916.                     $this->insertChatBotMessage(
  917.                         $this->getPrivateMessageID(),
  918.                         '/uninviteto '.$textParts[1].' '.$invitationChannelName
  919.                     );         
  920.                     // Uninvitation to requested User:
  921.                     $this->insertChatBotMessage(
  922.                         $this->getPrivateMessageID($toUserID),
  923.                         '/uninvite '.$this->getUserName().' '.$invitationChannelName
  924.                     );
  925.                 }
  926.             }                      
  927.         } else {
  928.             $this->insertChatBotMessage(
  929.                 $this->getPrivateMessageID(),
  930.                 '/error UninviteNotAllowed'
  931.             );                     
  932.         }
  933.     }
  934.        
  935.     function insertParsedMessageQuery($textParts) {
  936.         if($this->isAllowedToSendPrivateMessage()) {
  937.             if(count($textParts) == 1) {
  938.                 if($this->getQueryUserName() !== null) {
  939.                     $this->insertChatBotMessage(
  940.                         $this->getPrivateMessageID(),
  941.                         '/queryClose '.$this->getQueryUserName()
  942.                     );                         
  943.                     // Close the current query:
  944.                     $this->setQueryUserName(null);
  945.                 } else {
  946.                     $this->insertChatBotMessage(
  947.                         $this->getPrivateMessageID(),
  948.                         '/error NoOpenQuery'
  949.                     );
  950.                 }
  951.             } else {
  952.                 if($this->getIDFromName($textParts[1]) === null) {
  953.                     $this->insertChatBotMessage(
  954.                         $this->getPrivateMessageID(),
  955.                         '/error UserNameNotFound '.$textParts[1]
  956.                     );
  957.                 } else {
  958.                     if($this->getQueryUserName() !== null) {
  959.                         // Close the current query:
  960.                         $this->insertMessage('/query');
  961.                     }
  962.                     // Open a query to the requested user:
  963.                     $this->setQueryUserName($textParts[1]);
  964.                     $this->insertChatBotMessage(
  965.                         $this->getPrivateMessageID(),
  966.                         '/queryOpen '.$textParts[1]
  967.                     );
  968.                 }
  969.             }
  970.         } else {
  971.             $this->insertChatBotMessage(
  972.                 $this->getPrivateMessageID(),
  973.                 '/error PrivateMessageNotAllowed'
  974.             );
  975.         }
  976.     }
  977.        
  978.     function insertParsedMessageKick($textParts) {
  979.         // Only moderators/admins may kick users:
  980.         if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR) {
  981.             if(count($textParts) == 1) {
  982.                 $this->insertChatBotMessage(
  983.                     $this->getPrivateMessageID(),
  984.                     '/error MissingUserName'
  985.                 );
  986.             } else {
  987.                 // Get UserID from UserName:
  988.                 $kickUserID = $this->getIDFromName($textParts[1]);
  989.                 if($kickUserID === null) {
  990.                     $this->insertChatBotMessage(
  991.                         $this->getPrivateMessageID(),
  992.                         '/error UserNameNotFound '.$textParts[1]
  993.                     );
  994.                 } else {
  995.                     // Check the role of the user to kick:
  996.                     $kickUserRole = $this->getRoleFromID($kickUserID);
  997.                     if($kickUserRole == AJAX_CHAT_ADMIN || ($kickUserRole == AJAX_CHAT_MODERATOR && $this->getUserRole() != AJAX_CHAT_ADMIN)) {
  998.                         // Admins and moderators may not be kicked:
  999.                         $this->insertChatBotMessage(
  1000.                             $this->getPrivateMessageID(),
  1001.                             '/error KickNotAllowed '.$textParts[1]
  1002.                         );
  1003.                     } else {
  1004.                         // Kick user and insert message:
  1005.                         $channel = $this->getChannelFromID($kickUserID);
  1006.                         $banMinutes = (count($textParts) > 2) ? $textParts[2] : null;
  1007.                         $this->kickUser($textParts[1], $banMinutes, $kickUserID);
  1008.                         // If no channel found, user logged out before he could be kicked
  1009.                         if($channel !== null) {
  1010.                             $this->insertChatBotMessage(
  1011.                                 $channel,
  1012.                                 '/kick '.$textParts[1],
  1013.                                 null,
  1014.                                 1
  1015.                             );
  1016.                             // Send a copy of the message to the current user, if not in the channel:
  1017.                             if($channel != $this->getChannel()) {
  1018.                                 $this->insertChatBotMessage(
  1019.                                     $this->getPrivateMessageID(),
  1020.                                     '/kick '.$textParts[1],
  1021.                                     null,
  1022.                                     1
  1023.                                 );
  1024.                             }
  1025.                         }
  1026.                     }
  1027.                 }
  1028.             }
  1029.         } else {
  1030.             $this->insertChatBotMessage(
  1031.                 $this->getPrivateMessageID(),
  1032.                 '/error CommandNotAllowed '.$textParts[0]
  1033.             );
  1034.         }
  1035.     }
  1036.        
  1037.     function insertParsedMessageBans($textParts) {
  1038.         // Only moderators/admins may see the list of banned users:
  1039.         if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR) {
  1040.             $this->removeExpiredBans();
  1041.             $bannedUsers = $this->getBannedUsers();
  1042.             if(count($bannedUsers) > 0) {
  1043.                 $this->insertChatBotMessage(
  1044.                     $this->getPrivateMessageID(),
  1045.                     '/bans '.implode(' ', $bannedUsers)
  1046.                 );
  1047.             } else {
  1048.                 $this->insertChatBotMessage(
  1049.                     $this->getPrivateMessageID(),
  1050.                     '/bansEmpty -'
  1051.                 );
  1052.             }
  1053.         } else {
  1054.             $this->insertChatBotMessage(
  1055.                 $this->getPrivateMessageID(),
  1056.                 '/error CommandNotAllowed '.$textParts[0]
  1057.             );
  1058.         }
  1059.     }
  1060.        
  1061.     function insertParsedMessageUnban($textParts) {
  1062.         // Only moderators/admins may unban users:
  1063.         if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR) {
  1064.             $this->removeExpiredBans();
  1065.             if(count($textParts) == 1) {
  1066.                 $this->insertChatBotMessage(
  1067.                     $this->getPrivateMessageID(),
  1068.                     '/error MissingUserName'
  1069.                 );
  1070.             } else {
  1071.                 if(!in_array($textParts[1], $this->getBannedUsers())) {
  1072.                     $this->insertChatBotMessage(
  1073.                         $this->getPrivateMessageID(),
  1074.                         '/error UserNameNotFound '.$textParts[1]
  1075.                     );
  1076.                 } else {
  1077.                     // Unban user and insert message:
  1078.                     $this->unbanUser($textParts[1]);
  1079.                     $this->insertChatBotMessage(
  1080.                         $this->getPrivateMessageID(),
  1081.                         '/unban '.$textParts[1]
  1082.                     ); 
  1083.                 }
  1084.             }
  1085.         } else {
  1086.             $this->insertChatBotMessage(
  1087.                 $this->getPrivateMessageID(),
  1088.                 '/error CommandNotAllowed '.$textParts[0]
  1089.             );
  1090.         }
  1091.     }
  1092.        
  1093.     function insertParsedMessageAction($textParts) {
  1094.         if(count($textParts) == 1) {
  1095.             $this->insertChatBotMessage(
  1096.                 $this->getPrivateMessageID(),
  1097.                 '/error MissingText'
  1098.             );
  1099.         } else {
  1100.             if($this->getQueryUserName() !== null) {
  1101.                 // If we are in query mode, sent the action to the query user:
  1102.                 $this->insertMessage('/describe '.$this->getQueryUserName().' '.implode(' ', array_slice($textParts, 1)));
  1103.             } else {
  1104.                 $this->insertCustomMessage(
  1105.                     $this->getUserID(),
  1106.                     $this->getUserName(),
  1107.                     $this->getUserRole(),
  1108.                     $this->getChannel(),
  1109.                     implode(' ', $textParts)
  1110.                 );
  1111.             }
  1112.         }
  1113.     }
  1114.        
  1115.     function insertParsedMessageWho($textParts) {
  1116.         if(count($textParts) == 1) {
  1117.             if($this->isAllowedToListHiddenUsers()) {
  1118.                 // List online users from any channel:
  1119.                 $this->insertChatBotMessage(
  1120.                     $this->getPrivateMessageID(),
  1121.                     '/who '.implode(' ', $this->getOnlineUsers())
  1122.                 );
  1123.             } else {
  1124.                 // Get online users for all accessible channels:
  1125.                 $channels = $this->getChannels();
  1126.                 // Add the own private channel if allowed:
  1127.                 if($this->isAllowedToCreatePrivateChannel()) {
  1128.                     array_push($channels, $this->getPrivateChannelID());
  1129.                 }
  1130.                 // Add the invitation channels:
  1131.                 foreach($this->getInvitations() as $channelID) {
  1132.                     if(!in_array($channelID, $channels)) {
  1133.                         array_push($channels, $channelID);
  1134.                     }
  1135.                 }
  1136.                 $this->insertChatBotMessage(
  1137.                     $this->getPrivateMessageID(),
  1138.                     '/who '.implode(' ', $this->getOnlineUsers($channels))
  1139.                 );
  1140.             }
  1141.         } else {
  1142.             $channelName = $textParts[1];                  
  1143.             $channelID = $this->getChannelIDFromChannelName($channelName);
  1144.             if(!$this->validateChannel($channelID)) {
  1145.                 // Invalid channel:
  1146.                 $this->insertChatBotMessage(
  1147.                     $this->getPrivateMessageID(),
  1148.                     '/error InvalidChannelName '.$channelName
  1149.                 );
  1150.             } else {
  1151.                 // Get online users for the given channel:
  1152.                 $onlineUsers = $this->getOnlineUsers(array($channelID));
  1153.                 if(count($onlineUsers) > 0) {
  1154.                     $this->insertChatBotMessage(
  1155.                         $this->getPrivateMessageID(),
  1156.                         '/whoChannel '.$channelName.' '.implode(' ', $onlineUsers)
  1157.                     );
  1158.                 } else {
  1159.                     $this->insertChatBotMessage(
  1160.                         $this->getPrivateMessageID(),
  1161.                         '/whoEmpty -'
  1162.                     );
  1163.                 }
  1164.             }
  1165.         }
  1166.     }
  1167.        
  1168.     function insertParsedMessageList($textParts) {
  1169.         // Get the names of all accessible channels:
  1170.         $channelNames = $this->getChannelNames();
  1171.         // Add the own private channel, if allowed:
  1172.         if($this->isAllowedToCreatePrivateChannel()) {
  1173.             array_push($channelNames, $this->getPrivateChannelName());
  1174.         }
  1175.         // Add the invitation channels:
  1176.         foreach($this->getInvitations() as $channelID) {
  1177.             $channelName = $this->getChannelNameFromChannelID($channelID);
  1178.             if($channelName !== null && !in_array($channelName, $channelNames)) {
  1179.                 array_push($channelNames, $channelName);
  1180.             }
  1181.         }
  1182.         $this->insertChatBotMessage(
  1183.             $this->getPrivateMessageID(),
  1184.             '/list '.implode(' ', $channelNames)
  1185.         );
  1186.     }
  1187.  
  1188.     function insertParsedMessageWhereis($textParts) {
  1189.         if(count($textParts) == 1) {
  1190.             $this->insertChatBotMessage(
  1191.                 $this->getPrivateMessageID(),
  1192.                 '/error MissingUserName'
  1193.             );
  1194.         } else {
  1195.             // Get UserID from UserName:
  1196.             $whereisUserID = $this->getIDFromName($textParts[1]);      
  1197.             if($whereisUserID === null) {
  1198.                 $this->insertChatBotMessage(
  1199.                     $this->getPrivateMessageID(),
  1200.                     '/error UserNameNotFound '.$textParts[1]
  1201.                 );
  1202.             } else {                   
  1203.                 $channelID = $this->getChannelFromID($whereisUserID);
  1204.                 if($this->validateChannel($channelID)) {
  1205.                     $channelName = $this->getChannelNameFromChannelID($channelID);                 
  1206.                 } else {
  1207.                     $channelName = null;
  1208.                 }
  1209.                 if($channelName === null) {
  1210.                     $this->insertChatBotMessage(
  1211.                         $this->getPrivateMessageID(),
  1212.                         '/error UserNameNotFound '.$textParts[1]
  1213.                     );
  1214.                 } else {
  1215.                     // List user information:
  1216.                     $this->insertChatBotMessage(
  1217.                         $this->getPrivateMessageID(),
  1218.                         '/whereis '.$textParts[1].' '.$channelName
  1219.                     ); 
  1220.                 }
  1221.             }
  1222.         }
  1223.     }
  1224.            
  1225.     function insertParsedMessageWhois($textParts) {
  1226.         // Only moderators/admins:
  1227.         if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR) {
  1228.             if(count($textParts) == 1) {
  1229.                 $this->insertChatBotMessage(
  1230.                     $this->getPrivateMessageID(),
  1231.                     '/error MissingUserName'
  1232.                 );
  1233.             } else {
  1234.                 // Get UserID from UserName:
  1235.                 $whoisUserID = $this->getIDFromName($textParts[1]);
  1236.                 if($whoisUserID === null) {
  1237.                     $this->insertChatBotMessage(
  1238.                         $this->getPrivateMessageID(),
  1239.                         '/error UserNameNotFound '.$textParts[1]
  1240.                     );
  1241.                 } else {
  1242.                     // List user information:
  1243.                     $this->insertChatBotMessage(
  1244.                         $this->getPrivateMessageID(),
  1245.                         '/whois '.$textParts[1].' '.$this->getIPFromID($whoisUserID)
  1246.                     );
  1247.                 }
  1248.             }
  1249.         } else {
  1250.             $this->insertChatBotMessage(
  1251.                 $this->getPrivateMessageID(),
  1252.                 '/error CommandNotAllowed '.$textParts[0]
  1253.             );
  1254.         }
  1255.     }
  1256.            
  1257.     function insertParsedMessageRoll($textParts) {
  1258.         if(count($textParts) == 1) {
  1259.             // default is one d6:
  1260.             $text = '/roll '.$this->getUserName().' 1d6 '.$this->rollDice(6);
  1261.         } else {
  1262.             $diceParts = explode('d', $textParts[1]);
  1263.             if(count($diceParts) == 2) {
  1264.                 $number = (int)$diceParts[0];
  1265.                 $sides = (int)$diceParts[1];
  1266.                
  1267.                 // Dice number must be an integer between 1 and 100, else roll only one:
  1268.                 $number = ($number > 0 && $number <= 100) ?  $number : 1;
  1269.                
  1270.                 // Sides must be an integer between 1 and 100, else take 6:
  1271.                 $sides = ($sides > 0 && $sides <= 100) ?  $sides : 6;
  1272.                
  1273.                 $text = '/roll '.$this->getUserName().' '.$number.'d'.$sides.' ';
  1274.                 for($i=0; $i<$number; $i++) {
  1275.                     if($i != 0)
  1276.                         $text .= ',';
  1277.                     $text .= $this->rollDice($sides);
  1278.                 }
  1279.             } else {
  1280.                 // if dice syntax is invalid, roll one d6:
  1281.                 $text = '/roll '.$this->getUserName().' 1d6 '.$this->rollDice(6);
  1282.             }
  1283.         }
  1284.         $this->insertChatBotMessage(
  1285.             $this->getChannel(),
  1286.             $text
  1287.         );
  1288.     }
  1289.            
  1290.     function insertParsedMessageNick($textParts) {
  1291.         if(!$this->getConfig('allowNickChange') ||
  1292.             (!$this->getConfig('allowGuestUserName') && $this->getUserRole() == AJAX_CHAT_GUEST)) {
  1293.             $this->insertChatBotMessage(
  1294.                 $this->getPrivateMessageID(),
  1295.                 '/error CommandNotAllowed '.$textParts[0]
  1296.             );
  1297.         } else if(count($textParts) == 1) {
  1298.             $this->insertChatBotMessage(
  1299.                 $this->getPrivateMessageID(),
  1300.                 '/error MissingUserName'
  1301.             );
  1302.         } else {
  1303.             $newUserName = implode(' ', array_slice($textParts, 1));
  1304.             if($newUserName == $this->getLoginUserName()) {
  1305.                 // Allow the user to regain the original login userName:
  1306.                 $prefix = '';
  1307.                 $suffix = '';
  1308.             } else if($this->getUserRole() == AJAX_CHAT_GUEST) {
  1309.                 $prefix = $this->getConfig('guestUserPrefix');
  1310.                 $suffix = $this->getConfig('guestUserSuffix');
  1311.             } else {
  1312.                 $prefix = $this->getConfig('changedNickPrefix');
  1313.                 $suffix = $this->getConfig('changedNickSuffix');
  1314.             }
  1315.             $maxLength =    $this->getConfig('userNameMaxLength')
  1316.                             - $this->stringLength($prefix)
  1317.                             - $this->stringLength($suffix);
  1318.             $newUserName = $this->trimString($newUserName, 'UTF-8', $maxLength, true);
  1319.             if(!$newUserName) {
  1320.                 $this->insertChatBotMessage(
  1321.                     $this->getPrivateMessageID(),
  1322.                     '/error InvalidUserName'
  1323.                 );
  1324.             } else {
  1325.                 $newUserName = $prefix.$newUserName.$suffix;
  1326.                 if($this->isUserNameInUse($newUserName)) {
  1327.                     $this->insertChatBotMessage(
  1328.                         $this->getPrivateMessageID(),
  1329.                         '/error UserNameInUse'
  1330.                     );
  1331.                 } else {
  1332.                     $oldUserName = $this->getUserName();
  1333.                     $this->setUserName($newUserName);
  1334.                     $this->updateOnlineList();
  1335.                     // Add info message to update the client-side stored userName:
  1336.                     $this->addInfoMessage($this->getUserName(), 'userName');
  1337.                     $this->insertChatBotMessage(
  1338.                         $this->getChannel(),
  1339.                         '/nick '.$oldUserName.' '.$newUserName,
  1340.                         null,
  1341.                         2
  1342.                     );
  1343.                 }
  1344.             }
  1345.         }
  1346.     }
  1347.    
  1348.     function insertMessage($text) {
  1349.         if(!$this->isAllowedToWriteMessage())
  1350.             return;
  1351.  
  1352.         if(!$this->floodControl())
  1353.             return;
  1354.  
  1355.         $text = $this->trimMessageText($text); 
  1356.         if($text == '')
  1357.             return;
  1358.        
  1359.         if(!$this->onNewMessage($text))
  1360.             return;
  1361.        
  1362.         $text = $this->replaceCustomText($text);
  1363.        
  1364.         $this->insertParsedMessage($text);
  1365.     }
  1366.  
  1367.     function deleteMessage($messageID) {
  1368.         // Retrieve the channel of the given message:
  1369.         $sql = 'SELECT
  1370.                     channel
  1371.                 FROM
  1372.                     '.$this->getDataBaseTable('messages').'
  1373.                 WHERE
  1374.                     id='.$this->db->makeSafe($messageID).';';
  1375.        
  1376.         // Create a new SQL query:
  1377.         $result = $this->db->sqlQuery($sql);
  1378.        
  1379.         // Stop if an error occurs:
  1380.         if($result->error()) {
  1381.             echo $result->getError();
  1382.             die();
  1383.         }
  1384.        
  1385.         $row = $result->fetch();
  1386.        
  1387.         if($row['channel'] !== null) {
  1388.             $channel = $row['channel'];
  1389.            
  1390.             if($this->getUserRole() == AJAX_CHAT_ADMIN) {
  1391.                 $condition = '';
  1392.             } else if($this->getUserRole() == AJAX_CHAT_MODERATOR) {
  1393.                 $condition = '  AND
  1394.                                     NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_ADMIN).')
  1395.                                 AND
  1396.                                     NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_CHATBOT).')';
  1397.             } else if($this->getUserRole() == AJAX_CHAT_USER && $this->getConfig('allowUserMessageDelete')) {
  1398.                 $condition = 'AND
  1399.                                 (
  1400.                                 userID='.$this->db->makeSafe($this->getUserID()).'
  1401.                                 OR
  1402.                                     (
  1403.                                     channel = '.$this->db->makeSafe($this->getPrivateMessageID()).'
  1404.                                     OR
  1405.                                     channel = '.$this->db->makeSafe($this->getPrivateChannelID()).'
  1406.                                     )
  1407.                                     AND
  1408.                                         NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_ADMIN).')
  1409.                                     AND
  1410.                                         NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_CHATBOT).')
  1411.                                 )';
  1412.             } else {
  1413.                 return false;
  1414.             }
  1415.    
  1416.             // Remove given message from the database:
  1417.             $sql = 'DELETE FROM
  1418.                         '.$this->getDataBaseTable('messages').'
  1419.                     WHERE
  1420.                         id='.$this->db->makeSafe($messageID).'
  1421.                         '.$condition.';';
  1422.            
  1423.             // Create a new SQL query:
  1424.             $result = $this->db->sqlQuery($sql);
  1425.            
  1426.             // Stop if an error occurs:
  1427.             if($result->error()) {
  1428.                 echo $result->getError();
  1429.                 die();
  1430.             }
  1431.            
  1432.             if($result->affectedRows() == 1) {
  1433.                 // Insert a deletion command to remove the message from the clients chatlists:
  1434.                 $this->insertChatBotMessage($channel, '/delete '.$messageID);
  1435.                 return true;
  1436.             }
  1437.         }
  1438.         return false;
  1439.     }
  1440.    
  1441.     function floodControl() {
  1442.         // Moderators and Admins need no flood control:
  1443.         if($this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == AJAX_CHAT_ADMIN) {
  1444.             return true;
  1445.         }
  1446.         $time = time();
  1447.         // Check the time of the last inserted message:
  1448.         if($this->getInsertedMessagesRateTimeStamp()+60 < $time) {
  1449.             $this->setInsertedMessagesRateTimeStamp($time);
  1450.             $this->setInsertedMessagesRate(1);
  1451.         } else {
  1452.             // Increase the inserted messages rate:
  1453.             $rate = $this->getInsertedMessagesRate()+1;
  1454.             $this->setInsertedMessagesRate($rate);
  1455.             // Check if message rate is too high:
  1456.             if($rate > $this->getConfig('maxMessageRate')) {
  1457.                 $this->insertChatBotMessage(
  1458.                     $this->getPrivateMessageID(),
  1459.                     '/error MaxMessageRate'
  1460.                 );
  1461.                 // Return false so the message is not inserted:
  1462.                 return false;
  1463.             }
  1464.         }
  1465.         return true;
  1466.     }
  1467.    
  1468.     function isAllowedToWriteMessage() {
  1469.         if($this->getUserRole() != AJAX_CHAT_GUEST)
  1470.             return true;
  1471.         if($this->getConfig('allowGuestWrite'))
  1472.             return true;
  1473.         return false;
  1474.     }
  1475.  
  1476.     function insertChatBotMessage($channelID, $messageText, $ip=null, $mode=0) {
  1477.         $this->insertCustomMessage(
  1478.             $this->getConfig('chatBotID'),
  1479.             $this->getConfig('chatBotName'),
  1480.             AJAX_CHAT_CHATBOT,
  1481.             $channelID,
  1482.             $messageText,
  1483.             $ip,
  1484.             $mode
  1485.         );
  1486.     }
  1487.    
  1488.     function insertCustomMessage($userID, $userName, $userRole, $channelID, $text, $ip=null, $mode=0) {
  1489.         // The $mode parameter is used for socket updates:
  1490.         // 0 = normal messages
  1491.         // 1 = channel messages (e.g. login/logout, channel enter/leave, kick)
  1492.         // 2 = messages with online user updates (nick)
  1493.        
  1494.         $ip = $ip ? $ip : $_SERVER['REMOTE_ADDR'];
  1495.        
  1496.         $sql = 'INSERT INTO '.$this->getDataBaseTable('messages').'(
  1497.                                 userID,
  1498.                                 userName,
  1499.                                 userRole,
  1500.                                 channel,
  1501.                                 dateTime,
  1502.                                 ip,
  1503.                                 text
  1504.                             )
  1505.                 VALUES (
  1506.                     '.$this->db->makeSafe($userID).',
  1507.                     '.$this->db->makeSafe($userName).',
  1508.                     '.$this->db->makeSafe($userRole).',
  1509.                     '.$this->db->makeSafe($channelID).',
  1510.                     NOW(),
  1511.                     '.$this->db->makeSafe($this->ipToStorageFormat($ip)).',
  1512.                     '.$this->db->makeSafe($text).'
  1513.                 );';
  1514.  
  1515.         // Create a new SQL query:
  1516.         $result = $this->db->sqlQuery($sql);
  1517.        
  1518.         // Stop if an error occurs:
  1519.         if($result->error()) {
  1520.             echo $result->getError();
  1521.             die();
  1522.         }
  1523.        
  1524.         if($this->getConfig('socketServerEnabled')) {
  1525.             $this->sendSocketMessage(
  1526.                 $this->getSocketBroadcastMessage(
  1527.                     $this->db->getLastInsertedID(),
  1528.                     time(),
  1529.                     $userID,
  1530.                     $userName,
  1531.                     $userRole,
  1532.                     $channelID,
  1533.                     $text,
  1534.                     $mode
  1535.                 )
  1536.             ); 
  1537.         }
  1538.     }
  1539.  
  1540.     function getSocketBroadcastMessage(
  1541.         $messageID,
  1542.         $timeStamp,
  1543.         $userID,
  1544.         $userName,
  1545.         $userRole,
  1546.         $channelID,
  1547.         $text,
  1548.         $mode  
  1549.         ) {
  1550.         // The $mode parameter:
  1551.         // 0 = normal messages
  1552.         // 1 = channel messages (e.g. login/logout, channel enter/leave, kick)
  1553.         // 2 = messages with online user updates (nick)
  1554.  
  1555.         // Get the message XML content:
  1556.         $xml = '<root chatID="'.$this->getConfig('socketServerChatID').'" channelID="'.$channelID.'" mode="'.$mode.'">';
  1557.         if($mode) {
  1558.             // Add the list of online users if the user list has been updated ($mode > 0):
  1559.             $xml .= $this->getChatViewOnlineUsersXML(array($channelID));
  1560.         }
  1561.         if($mode != 1 || $this->getConfig('showChannelMessages')) {
  1562.             $xml .= '<messages>';
  1563.             $xml .= $this->getChatViewMessageXML(
  1564.                 $messageID,
  1565.                 $timeStamp,
  1566.                 $userID,
  1567.                 $userName,
  1568.                 $userRole,
  1569.                 $channelID,
  1570.                 $text
  1571.             );
  1572.             $xml .= '</messages>'; 
  1573.         }
  1574.         $xml .= '</root>';
  1575.         return $xml;
  1576.     }
  1577.  
  1578.     function sendSocketMessage($message) {
  1579.         // Open a TCP socket connection to the socket server:
  1580.         if($socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) {
  1581.             if(@socket_connect($socket, $this->getConfig('socketServerIP'), $this->getConfig('socketServerPort'))) {
  1582.                 // Append a null-byte to the string as EOL (End Of Line) character
  1583.                 // which is required by Flash XML socket communication:
  1584.                 $message .= "\0";
  1585.                 @socket_write(
  1586.                     $socket,
  1587.                     $message,
  1588.                     strlen($message) // Using strlen to count the bytes instead of the number of UTF-8 characters
  1589.                 );
  1590.             }
  1591.             @socket_close($socket);
  1592.         }      
  1593.     }
  1594.  
  1595.     function updateSocketAuthentication($userID, $socketRegistrationID=null, $channels=null) {
  1596.         // If no $socketRegistrationID or no $channels are given the authentication is removed for the given user:
  1597.         $authentication = '<authenticate chatID="'.$this->getConfig('socketServerChatID').'" userID="'.$userID.'" regID="'.$socketRegistrationID.'">';
  1598.         if($channels) {
  1599.             foreach($channels as $channelID) {
  1600.                 $authentication .= '<channel id="'.$channelID.'"/>';
  1601.             }
  1602.         }
  1603.         $authentication .= '</authenticate>';
  1604.         $this->sendSocketMessage($authentication);
  1605.     }
  1606.  
  1607.     function setSocketRegistrationID($value) {
  1608.         $this->setSessionVar('SocketRegistrationID', $value);
  1609.     }
  1610.    
  1611.     function getSocketRegistrationID() {
  1612.         return $this->getSessionVar('SocketRegistrationID');
  1613.     }
  1614.    
  1615.     function rollDice($sides) {
  1616.         return mt_rand(1, $sides);
  1617.     }
  1618.    
  1619.     function kickUser($userName, $banMinutes=null, $userID=null) {
  1620.         if($userID === null) {
  1621.             $userID = $this->getIDFromName($userName);
  1622.         }
  1623.         if($userID === null) {
  1624.             return;
  1625.         }
  1626.  
  1627.         $banMinutes = ($banMinutes !== null) ? $banMinutes : $this->getConfig('defaultBanTime');
  1628.  
  1629.         if($banMinutes) {
  1630.             // Ban User for the given time in minutes:
  1631.             $this->banUser($userName, $banMinutes, $userID);
  1632.         }
  1633.  
  1634.         // Remove given User from online list:
  1635.         $sql = 'DELETE FROM
  1636.                     '.$this->getDataBaseTable('online').'
  1637.                 WHERE
  1638.                     userID = '.$this->db->makeSafe($userID).';';
  1639.        
  1640.         // Create a new SQL query:
  1641.         $result = $this->db->sqlQuery($sql);
  1642.        
  1643.         // Stop if an error occurs:
  1644.         if($result->error()) {
  1645.             echo $result->getError();
  1646.             die();
  1647.         }
  1648.  
  1649.         // Update the socket server authentication for the kicked user:
  1650.         if($this->getConfig('socketServerEnabled')) {
  1651.             $this->updateSocketAuthentication($userID);
  1652.         }
  1653.        
  1654.         $this->removeUserFromOnlineUsersData($userID);
  1655.     }
  1656.  
  1657.     function getBannedUsersData($key=null, $value=null) {
  1658.         if($this->_bannedUsersData === null) {
  1659.             $this->_bannedUsersData = array();
  1660.  
  1661.             $sql = 'SELECT
  1662.                         userID,
  1663.                         userName,
  1664.                         ip
  1665.                     FROM
  1666.                         '.$this->getDataBaseTable('bans').'
  1667.                     WHERE
  1668.                         NOW() < dateTime;';
  1669.            
  1670.             // Create a new SQL query:
  1671.             $result = $this->db->sqlQuery($sql);
  1672.            
  1673.             // Stop if an error occurs:
  1674.             if($result->error()) {
  1675.                 echo $result->getError();
  1676.                 die();
  1677.             }
  1678.            
  1679.             while($row = $result->fetch()) {
  1680.                 $row['ip'] = $this->ipFromStorageFormat($row['ip']);
  1681.                 array_push($this->_bannedUsersData, $row);
  1682.             }
  1683.            
  1684.             $result->free();
  1685.         }
  1686.        
  1687.         if($key) {
  1688.             $bannedUsersData = array();    
  1689.             foreach($this->_bannedUsersData as $bannedUserData) {
  1690.                 if(!isset($bannedUserData[$key])) {
  1691.                     return $bannedUsersData;
  1692.                 }
  1693.                 if($value) {
  1694.                     if($bannedUserData[$key] == $value) {
  1695.                         array_push($bannedUsersData, $bannedUserData);
  1696.                     } else {
  1697.                         continue;
  1698.                     }
  1699.                 } else {
  1700.                     array_push($bannedUsersData, $bannedUserData[$key]);   
  1701.                 }
  1702.             }
  1703.             return $bannedUsersData;
  1704.         }
  1705.        
  1706.         return $this->_bannedUsersData;
  1707.     }
  1708.    
  1709.     function getBannedUsers() {
  1710.         return $this->getBannedUsersData('userName');
  1711.     }
  1712.    
  1713.     function banUser($userName, $banMinutes=null, $userID=null) {
  1714.         if($userID === null) {
  1715.             $userID = $this->getIDFromName($userName);
  1716.         }
  1717.         $ip = $this->getIPFromID($userID);
  1718.         if(!$ip || $userID === null) {
  1719.             return;
  1720.         }
  1721.  
  1722.         // Remove expired bans:
  1723.         $this->removeExpiredBans();
  1724.        
  1725.         $banMinutes = (int)$banMinutes;
  1726.         if(!$banMinutes) {
  1727.             // If banMinutes is not a valid integer, use the defaultBanTime:
  1728.             $banMinutes = $this->getConfig('defaultBanTime');
  1729.         }
  1730.        
  1731.         $sql = 'INSERT INTO '.$this->getDataBaseTable('bans').'(
  1732.                     userID,
  1733.                     userName,
  1734.                     dateTime,
  1735.                     ip
  1736.                 )
  1737.                 VALUES (
  1738.                     '.$this->db->makeSafe($userID).',
  1739.                     '.$this->db->makeSafe($userName).',
  1740.                     DATE_ADD(NOW(), interval '.$this->db->makeSafe($banMinutes).' MINUTE),
  1741.                     '.$this->db->makeSafe($this->ipToStorageFormat($ip)).'
  1742.                 );';   
  1743.        
  1744.         // Create a new SQL query:
  1745.         $result = $this->db->sqlQuery($sql);
  1746.        
  1747.         // Stop if an error occurs:
  1748.         if($result->error()) {
  1749.             echo $result->getError();
  1750.             die();
  1751.         }
  1752.     }
  1753.    
  1754.     function unbanUser($userName) {
  1755.         $sql = 'DELETE FROM
  1756.                     '.$this->getDataBaseTable('bans').'
  1757.                 WHERE
  1758.                     userName = '.$this->db->makeSafe($userName).';';
  1759.        
  1760.         // Create a new SQL query:
  1761.         $result = $this->db->sqlQuery($sql);
  1762.        
  1763.         // Stop if an error occurs:
  1764.         if($result->error()) {
  1765.             echo $result->getError();
  1766.             die();
  1767.         }
  1768.     }
  1769.    
  1770.     function removeExpiredBans() {
  1771.         $sql = 'DELETE FROM
  1772.                     '.$this->getDataBaseTable('bans').'
  1773.                 WHERE
  1774.                     dateTime < NOW();';
  1775.        
  1776.         // Create a new SQL query:
  1777.         $result = $this->db->sqlQuery($sql);
  1778.        
  1779.         // Stop if an error occurs:
  1780.         if($result->error()) {
  1781.             echo $result->getError();
  1782.             die();
  1783.         }
  1784.     }
  1785.    
  1786.     function setInactive($userID, $userName=null) {
  1787.         $condition = 'userID='.$this->db->makeSafe($userID);
  1788.         if($userName !== null) {
  1789.             $condition .= ' OR userName='.$this->db->makeSafe($userName);
  1790.         }
  1791.         $sql = 'UPDATE
  1792.                     '.$this->getDataBaseTable('online').'
  1793.                 SET
  1794.                     dateTime = DATE_SUB(NOW(), interval '.(intval($this->getConfig('inactiveTimeout'))+1).' MINUTE)
  1795.                 WHERE
  1796.                     '.$condition.';';
  1797.                    
  1798.         // Create a new SQL query:
  1799.         $result = $this->db->sqlQuery($sql);
  1800.        
  1801.         // Stop if an error occurs:
  1802.         if($result->error()) {
  1803.             echo $result->getError();
  1804.             die();
  1805.         }
  1806.        
  1807.         $this->resetOnlineUsersData();
  1808.     }
  1809.    
  1810.     function removeInactive() {
  1811.         $sql = 'SELECT
  1812.                     userID,
  1813.                     userName,
  1814.                     channel
  1815.                 FROM
  1816.                     '.$this->getDataBaseTable('online').'
  1817.                 WHERE
  1818.                     NOW() > DATE_ADD(dateTime, interval '.$this->getConfig('inactiveTimeout').' MINUTE);';
  1819.        
  1820.         // Create a new SQL query:
  1821.         $result = $this->db->sqlQuery($sql);
  1822.        
  1823.         // Stop if an error occurs:
  1824.         if($result->error()) {
  1825.             echo $result->getError();
  1826.             die();
  1827.         }
  1828.        
  1829.         if($result->numRows() > 0) {
  1830.             $condition = '';
  1831.             while($row = $result->fetch()) {
  1832.                 if(!empty($condition))
  1833.                     $condition .= ' OR ';
  1834.                 // Add userID to condition for removal:
  1835.                 $condition .= 'userID='.$this->db->makeSafe($row['userID']);
  1836.  
  1837.                 // Update the socket server authentication for the kicked user:
  1838.                 if($this->getConfig('socketServerEnabled')) {
  1839.                     $this->updateSocketAuthentication($row['userID']);
  1840.                 }
  1841.  
  1842.                 $this->removeUserFromOnlineUsersData($row['userID']);
  1843.                
  1844.                 // Insert logout timeout message:
  1845.                 $text = '/logout '.$row['userName'].' Timeout';
  1846.                 $this->insertChatBotMessage(
  1847.                     $row['channel'],
  1848.                     $text,
  1849.                     null,
  1850.                     1
  1851.                 );
  1852.             }
  1853.            
  1854.             $result->free();
  1855.            
  1856.             $sql = 'DELETE FROM
  1857.                         '.$this->getDataBaseTable('online').'
  1858.                     WHERE
  1859.                         '.$condition.';';
  1860.            
  1861.             // Create a new SQL query:
  1862.             $result = $this->db->sqlQuery($sql);
  1863.            
  1864.             // Stop if an error occurs:
  1865.             if($result->error()) {
  1866.                 echo $result->getError();
  1867.                 die();
  1868.             }
  1869.         }
  1870.     }
  1871.  
  1872.     function updateOnlineStatus() {
  1873.         // Update online status every 50 seconds (this allows update requests to be in time):
  1874.         if(!$this->getStatusUpdateTimeStamp() || ((time() - $this->getStatusUpdateTimeStamp()) > 50)) {
  1875.             $this->updateOnlineList();
  1876.             $this->setStatusUpdateTimeStamp(time());
  1877.         }
  1878.     }
  1879.    
  1880.     function checkAndRemoveInactive() {
  1881.         // Remove inactive users every inactiveCheckInterval:
  1882.         if(!$this->getInactiveCheckTimeStamp() || ((time() - $this->getInactiveCheckTimeStamp()) > $this->getConfig('inactiveCheckInterval')*60)) {
  1883.             $this->removeInactive();
  1884.             $this->setInactiveCheckTimeStamp(time());
  1885.         }
  1886.     }
  1887.    
  1888.     function sendXMLMessages() {       
  1889.         $httpHeader = new AJAXChatHTTPHeader('UTF-8', 'text/xml');
  1890.  
  1891.         // Send HTTP header:
  1892.         $httpHeader->send();
  1893.        
  1894.         // Output XML messages:
  1895.         echo $this->getXMLMessages();
  1896.     }
  1897.  
  1898.     function getXMLMessages() {
  1899.         switch($this->getView()) {
  1900.             case 'chat':
  1901.                 return $this->getChatViewXMLMessages();
  1902.             case 'teaser':
  1903.                 return $this->getTeaserViewXMLMessages();
  1904.             case 'logs':
  1905.                 return $this->getLogsViewXMLMessages();
  1906.             default:
  1907.                 return $this->getLogoutXMLMessage();
  1908.         }
  1909.     }
  1910.  
  1911.     function getMessageCondition() {
  1912.         $condition =    'id > '.$this->db->makeSafe($this->getRequestVar('lastID')).'
  1913.                         AND (
  1914.                             channel = '.$this->db->makeSafe($this->getChannel()).'
  1915.                             OR
  1916.                             channel = '.$this->db->makeSafe($this->getPrivateMessageID()).'
  1917.                         )
  1918.                         AND
  1919.                         ';
  1920.         if($this->getConfig('requestMessagesPriorChannelEnter') ||
  1921.             ($this->getConfig('requestMessagesPriorChannelEnterList') && in_array($this->getChannel(), $this->getConfig('requestMessagesPriorChannelEnterList')))) {
  1922.             $condition .= 'NOW() < DATE_ADD(dateTime, interval '.$this->getConfig('requestMessagesTimeDiff').' HOUR)';
  1923.         } else {
  1924.             $condition .= 'dateTime >= FROM_UNIXTIME(' . $this->getChannelEnterTimeStamp() . ')';
  1925.         }
  1926.         return $condition;
  1927.     }
  1928.    
  1929.     function getMessageFilter() {
  1930.             $filterChannelMessages = '';
  1931.             if(!$this->getConfig('showChannelMessages') || $this->getRequestVar('shoutbox')) {
  1932.                 $filterChannelMessages = '  AND NOT (
  1933.                                             text LIKE (\'/login%\')
  1934.                                             OR
  1935.                                             text LIKE (\'/logout%\')
  1936.                                             OR
  1937.                                             text LIKE (\'/channelEnter%\')
  1938.                                             OR
  1939.                                             text LIKE (\'/channelLeave%\')
  1940.                                             OR
  1941.                                             text LIKE (\'/kick%\')
  1942.                                         )';
  1943.             }
  1944.             return $filterChannelMessages;     
  1945.     }
  1946.  
  1947.     function getInfoMessagesXML() {
  1948.         $xml = '<infos>';
  1949.         // Go through the info messages:
  1950.         foreach($this->getInfoMessages() as $type=>$infoArray) {
  1951.             foreach($infoArray as $info) {
  1952.                 $xml .= '<info type="'.$type.'">';
  1953.                 $xml .= '<![CDATA['.$this->encodeSpecialChars($info).']]>';
  1954.                 $xml .= '</info>';
  1955.             }
  1956.         }
  1957.         $xml .= '</infos>';
  1958.         return $xml;
  1959.     }
  1960.  
  1961.     function getChatViewOnlineUsersXML($channelIDs) {
  1962.         // Get the online users for the given channels:
  1963.         $onlineUsersData = $this->getOnlineUsersData($channelIDs);     
  1964.         $xml = '<users>';
  1965.         foreach($onlineUsersData as $onlineUserData) {
  1966.             $xml .= '<user';
  1967.             $xml .= ' userID="'.$onlineUserData['userID'].'"';
  1968.             $xml .= ' userRole="'.$onlineUserData['userRole'].'"';
  1969.             $xml .= ' channelID="'.$onlineUserData['channel'].'"';
  1970.             $xml .= '>';
  1971.             $xml .= '<![CDATA['.$this->encodeSpecialChars($onlineUserData['userName']).']]>';
  1972.             $xml .= '</user>';
  1973.         }
  1974.         $xml .= '</users>';
  1975.         return $xml;
  1976.     }
  1977.  
  1978.     function getLogoutXMLMessage() {
  1979.         $xml = '<?xml version="1.0" encoding="UTF-8"?>';
  1980.         $xml .= '<root>';
  1981.         $xml .= '<infos>';
  1982.         $xml .= '<info type="logout">';
  1983.         $xml .= '<![CDATA['.$this->encodeSpecialChars($this->getConfig('logoutData')).']]>';
  1984.         $xml .= '</info>';
  1985.         $xml .= '</infos>';
  1986.         $xml .= '</root>';
  1987.         return $xml;
  1988.     }
  1989.  
  1990.     function getChatViewMessageXML(
  1991.         $messageID,
  1992.         $timeStamp,
  1993.         $userID,
  1994.         $userName,
  1995.         $userRole,
  1996.         $channelID,
  1997.         $text
  1998.         ) {
  1999.         $message = '<message';
  2000.         $message .= ' id="'.$messageID.'"';
  2001.         $message .= ' dateTime="'.date('r', $timeStamp).'"';
  2002.         $message .= ' userID="'.$userID.'"';
  2003.         $message .= ' userRole="'.$userRole.'"';
  2004.         $message .= ' channelID="'.$channelID.'"';
  2005.         $message .= '>';
  2006.         $message .= '<username><![CDATA['.$this->encodeSpecialChars($userName).']]></username>';
  2007.         $message .= '<text><![CDATA['.$this->encodeSpecialChars($text).']]></text>';
  2008.         $message .= '</message>';
  2009.         return $message;
  2010.     }
  2011.  
  2012.     function getChatViewMessagesXML() {
  2013.         // Get the last messages in descending order (this optimises the LIMIT usage):
  2014.         $sql = 'SELECT
  2015.                     id,
  2016.                     userID,
  2017.                     userName,
  2018.                     userRole,
  2019.                     channel AS channelID,
  2020.                     UNIX_TIMESTAMP(dateTime) AS timeStamp,
  2021.                     text
  2022.                 FROM
  2023.                     '.$this->getDataBaseTable('messages').'
  2024.                 WHERE
  2025.                     '.$this->getMessageCondition().'
  2026.                     '.$this->getMessageFilter().'
  2027.                 ORDER BY
  2028.                     id
  2029.                     DESC
  2030.                 LIMIT '.$this->getConfig('requestMessagesLimit').';';
  2031.  
  2032.         // Create a new SQL query:
  2033.         $result = $this->db->sqlQuery($sql);
  2034.        
  2035.         // Stop if an error occurs:
  2036.         if($result->error()) {
  2037.             echo $result->getError();
  2038.             die();
  2039.         }
  2040.        
  2041.         $messages = '';
  2042.        
  2043.         // Add the messages in reverse order so it is ascending again:
  2044.         while($row = $result->fetch()) {           
  2045.             $message = $this->getChatViewMessageXML(
  2046.                 $row['id'],
  2047.                 $row['timeStamp'],
  2048.                 $row['userID'],
  2049.                 $row['userName'],
  2050.                 $row['userRole'],
  2051.                 $row['channelID'],
  2052.                 $row['text']
  2053.             );     
  2054.             $messages = $message.$messages;
  2055.         }
  2056.         $result->free();       
  2057.        
  2058.         $messages = '<messages>'.$messages.'</messages>';
  2059.         return $messages;
  2060.     }
  2061.    
  2062.     function getChatViewXMLMessages() {
  2063.         $xml = '<?xml version="1.0" encoding="UTF-8"?>';
  2064.         $xml .= '<root>';
  2065.         $xml .= $this->getInfoMessagesXML();
  2066.         $xml .= $this->getChatViewOnlineUsersXML(array($this->getChannel()));
  2067.         $xml .= $this->getChatViewMessagesXML();
  2068.         $xml .= '</root>';     
  2069.         return $xml;
  2070.     }
  2071.  
  2072.     function getTeaserMessageCondition() {
  2073.         $channelID = $this->getValidRequestChannelID();    
  2074.         $condition =    'channel = '.$this->db->makeSafe($channelID).'
  2075.                         AND
  2076.                         ';
  2077.         if($this->getConfig('requestMessagesPriorChannelEnter') ||
  2078.             ($this->getConfig('requestMessagesPriorChannelEnterList') && in_array($channelID, $this->getConfig('requestMessagesPriorChannelEnterList')))) {
  2079.             $condition .= 'NOW() < DATE_ADD(dateTime, interval '.$this->getConfig('requestMessagesTimeDiff').' HOUR)';
  2080.         } else {
  2081.             // Teaser content may not be shown for this channel:
  2082.             $condition .= '0 = 1'; 
  2083.         }
  2084.         return $condition;
  2085.     }
  2086.  
  2087.     function getTeaserViewMessagesXML() {
  2088.         // Get the last messages in descending order (this optimises the LIMIT usage):
  2089.         $sql = 'SELECT
  2090.                     id,
  2091.                     userID,
  2092.                     userName,
  2093.                     userRole,
  2094.                     channel AS channelID,
  2095.                     UNIX_TIMESTAMP(dateTime) AS timeStamp,
  2096.                     text
  2097.                 FROM
  2098.                     '.$this->getDataBaseTable('messages').'
  2099.                 WHERE
  2100.                     '.$this->getTeaserMessageCondition().'
  2101.                     '.$this->getMessageFilter().'
  2102.                 ORDER BY
  2103.                     id
  2104.                     DESC
  2105.                 LIMIT '.$this->getConfig('requestMessagesLimit').';';
  2106.  
  2107.         // Create a new SQL query:
  2108.         $result = $this->db->sqlQuery($sql);
  2109.        
  2110.         // Stop if an error occurs:
  2111.         if($result->error()) {
  2112.             echo $result->getError();
  2113.             die();
  2114.         }
  2115.        
  2116.         $messages = '';
  2117.        
  2118.         // Add the messages in reverse order so it is ascending again:
  2119.         while($row = $result->fetch()) {           
  2120.             $message = '';
  2121.             $message .= '<message';
  2122.             $message .= ' id="'.$row['id'].'"';
  2123.             $message .= ' dateTime="'.date('r', $row['timeStamp']).'"';
  2124.             $message .= ' userID="'.$row['userID'].'"';
  2125.             $message .= ' userRole="'.$row['userRole'].'"';
  2126.             $message .= ' channelID="'.$row['channelID'].'"';
  2127.             $message .= '>';
  2128.             $message .= '<username><![CDATA['.$this->encodeSpecialChars($row['userName']).']]></username>';
  2129.             $message .= '<text><![CDATA['.$this->encodeSpecialChars($row['text']).']]></text>';
  2130.             $message .= '</message>';
  2131.             $messages = $message.$messages;
  2132.         }
  2133.         $result->free();   
  2134.        
  2135.         $messages = '<messages>'.$messages.'</messages>';
  2136.         return $messages;
  2137.     }
  2138.  
  2139.     function getTeaserViewXMLMessages() {
  2140.         $xml = '<?xml version="1.0" encoding="UTF-8"?>';
  2141.         $xml .= '<root>';
  2142.         $xml .= $this->getInfoMessagesXML();
  2143.         $xml .= $this->getTeaserViewMessagesXML();
  2144.         $xml .= '</root>';     
  2145.         return $xml;
  2146.     }
  2147.    
  2148.     function getLogsViewCondition() {
  2149.         $condition = 'id > '.$this->db->makeSafe($this->getRequestVar('lastID'));
  2150.        
  2151.         // Check the channel condition:
  2152.         switch($this->getRequestVar('channelID')) {
  2153.             case '-3':
  2154.                 // Just display messages from all accessible channels
  2155.                 if($this->getUserRole() != AJAX_CHAT_ADMIN) {
  2156.                     $condition .= ' AND (channel = '.$this->db->makeSafe($this->getPrivateMessageID());
  2157.                     $condition .= ' OR channel = '.$this->db->makeSafe($this->getPrivateChannelID());
  2158.                     foreach($this->getChannels() as $channel) {
  2159.                         if($this->getConfig('logsUserAccessChannelList') && !in_array($channel, $this->getConfig('logsUserAccessChannelList'))) {
  2160.                             continue;
  2161.                         }
  2162.                         $condition .= ' OR channel = '.$this->db->makeSafe($channel);
  2163.                     }
  2164.                     $condition .= ')';
  2165.                 }
  2166.                 break;
  2167.             case '-2':
  2168.                 if($this->getUserRole() != AJAX_CHAT_ADMIN) {
  2169.                     $condition .= ' AND channel = '.($this->getPrivateMessageID());
  2170.                 } else {
  2171.                     $condition .= ' AND channel > '.($this->getConfig('privateMessageDiff')-1);
  2172.                 }
  2173.                 break;
  2174.             case '-1':
  2175.                 if($this->getUserRole() != AJAX_CHAT_ADMIN) {
  2176.                     $condition .= ' AND channel = '.($this->getPrivateChannelID());
  2177.                 } else {
  2178.                     $condition .= ' AND (channel > '.($this->getConfig('privateChannelDiff')-1).' AND channel < '.($this->getConfig('privateMessageDiff')).')';
  2179.                 }
  2180.                 break;
  2181.             default:
  2182.                 if(($this->getUserRole() == AJAX_CHAT_ADMIN || !$this->getConfig('logsUserAccessChannelList') || in_array($this->getRequestVar('channelID'), $this->getConfig('logsUserAccessChannelList')))
  2183.                     && $this->validateChannel($this->getRequestVar('channelID'))) {
  2184.                     $condition .= ' AND channel = '.$this->db->makeSafe($this->getRequestVar('channelID'));
  2185.                 } else {
  2186.                     // No valid channel:
  2187.                     $condition .= ' AND 0 = 1';
  2188.                 }
  2189.         }
  2190.        
  2191.         // Check the period condition:
  2192.         $hour   = ($this->getRequestVar('hour') === null || $this->getRequestVar('hour') > 23 || $this->getRequestVar('hour') < 0) ? null : $this->getRequestVar('hour');
  2193.         $day    = ($this->getRequestVar('day') === null || $this->getRequestVar('day') > 31 || $this->getRequestVar('day') < 1) ? null : $this->getRequestVar('day');
  2194.         $month  = ($this->getRequestVar('month') === null || $this->getRequestVar('month') > 12 || $this->getRequestVar('month') < 1) ? null : $this->getRequestVar('month');
  2195.         $year   = ($this->getRequestVar('year') === null || $this->getRequestVar('year') > date('Y') || $this->getRequestVar('year') < $this->getConfig('logsFirstYear')) ? null : $this->getRequestVar('year');
  2196.  
  2197.         // If a time (hour) is given but no date (year, month, day), use the current date:
  2198.         if($hour !== null) {
  2199.             if($day === null)
  2200.                 $day = date('j');
  2201.             if($month === null)
  2202.                 $month = date('n');
  2203.             if($year === null)
  2204.                 $year = date('Y');
  2205.         }
  2206.        
  2207.         if($year === null) {
  2208.             // No year given, so no period condition
  2209.         } else if($month === null) {
  2210.             // Define the given year as period:
  2211.             $periodStart = mktime(0, 0, 0, 1, 1, $year);
  2212.             // The last day in a month can be expressed by using 0 for the day of the next month:
  2213.             $periodEnd = mktime(23, 59, 59, 13, 0, $year);
  2214.         } else if($day === null) {
  2215.             // Define the given month as period:
  2216.             $periodStart = mktime(0, 0, 0, $month, 1, $year);
  2217.             // The last day in a month can be expressed by using 0 for the day of the next month:
  2218.             $periodEnd = mktime(23, 59, 59, $month+1, 0, $year);
  2219.         } else if($hour === null){
  2220.             // Define the given day as period:
  2221.             $periodStart = mktime(0, 0, 0, $month, $day, $year);
  2222.             $periodEnd = mktime(23, 59, 59, $month, $day, $year);
  2223.         } else {
  2224.             // Define the given hour as period:
  2225.             $periodStart = mktime($hour, 0, 0, $month, $day, $year);
  2226.             $periodEnd = mktime($hour, 59, 59, $month, $day, $year);
  2227.         }
  2228.        
  2229.         if(isset($periodStart))
  2230.             $condition .= ' AND dateTime > \''.date('Y-m-d H:i:s', $periodStart).'\' AND dateTime <= \''.date('Y-m-d H:i:s', $periodEnd).'\'';
  2231.        
  2232.         // Check the search condition:
  2233.         if($this->getRequestVar('search')) {
  2234.             if(($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR) && strpos($this->getRequestVar('search'), 'ip=') === 0) {
  2235.                 // Search for messages with the given IP:
  2236.                 $ip = substr($this->getRequestVar('search'), 3);
  2237.                 $condition .= ' AND (ip = '.$this->db->makeSafe($this->ipToStorageFormat($ip)).')';
  2238.             } else if(strpos($this->getRequestVar('search'), 'userID=') === 0) {
  2239.                 // Search for messages with the given userID:
  2240.                 $userID = substr($this->getRequestVar('search'), 7);
  2241.                 $condition .= ' AND (userID = '.$this->db->makeSafe($userID).')';
  2242.             } else {
  2243.                 // Use the search value as regular expression on message text and username:
  2244.                 $condition .= ' AND (userName REGEXP '.$this->db->makeSafe($this->getRequestVar('search')).' OR text REGEXP '.$this->db->makeSafe($this->getRequestVar('search')).')';
  2245.             }
  2246.         }
  2247.        
  2248.         // If no period or search condition is given, just monitor the last messages on the given channel:
  2249.         if(!isset($periodStart) && !$this->getRequestVar('search')) {
  2250.             $condition .= ' AND NOW() < DATE_ADD(dateTime, interval '.$this->getConfig('logsRequestMessagesTimeDiff').' HOUR)';
  2251.         }
  2252.  
  2253.         return $condition;
  2254.     }
  2255.  
  2256.     function getLogsViewMessagesXML() {
  2257.         $sql = 'SELECT
  2258.                     id,
  2259.                     userID,
  2260.                     userName,
  2261.                     userRole,
  2262.                     channel AS channelID,
  2263.                     UNIX_TIMESTAMP(dateTime) AS timeStamp,
  2264.                     ip,
  2265.                     text
  2266.                 FROM
  2267.                     '.$this->getDataBaseTable('messages').'
  2268.                 WHERE
  2269.                     '.$this->getLogsViewCondition().'
  2270.                 ORDER BY
  2271.                     id
  2272.                 LIMIT '.$this->getConfig('logsRequestMessagesLimit').';';
  2273.                    
  2274.         // Create a new SQL query:
  2275.         $result = $this->db->sqlQuery($sql);
  2276.        
  2277.         // Stop if an error occurs:
  2278.         if($result->error()) {
  2279.             echo $result->getError();
  2280.             die();
  2281.         }
  2282.  
  2283.         $xml = '<messages>';
  2284.         while($row = $result->fetch()) {
  2285.             $xml .= '<message';
  2286.             $xml .= ' id="'.$row['id'].'"';
  2287.             $xml .= ' dateTime="'.date('r', $row['timeStamp']).'"';
  2288.             $xml .= ' userID="'.$row['userID'].'"';
  2289.             $xml .= ' userRole="'.$row['userRole'].'"';
  2290.             $xml .= ' channelID="'.$row['channelID'].'"';
  2291.             if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR) {
  2292.                 $xml .= ' ip="'.$this->ipFromStorageFormat($row['ip']).'"';                
  2293.             }
  2294.             $xml .= '>';
  2295.             $xml .= '<username><![CDATA['.$this->encodeSpecialChars($row['userName']).']]></username>';
  2296.             $xml .= '<text><![CDATA['.$this->encodeSpecialChars($row['text']).']]></text>';
  2297.             $xml .= '</message>';
  2298.         }
  2299.         $result->free();
  2300.  
  2301.         $xml .= '</messages>';
  2302.        
  2303.         return $xml;
  2304.     }
  2305.    
  2306.     function getLogsViewXMLMessages() {
  2307.         $xml = '<?xml version="1.0" encoding="UTF-8"?>';
  2308.         $xml .= '<root>';
  2309.         $xml .= $this->getInfoMessagesXML();
  2310.         $xml .= $this->getLogsViewMessagesXML();
  2311.         $xml .= '</root>';     
  2312.         return $xml;
  2313.     }
  2314.        
  2315.     function purgeLogs() {
  2316.         $sql = 'DELETE FROM
  2317.                     '.$this->getDataBaseTable('messages').'
  2318.                 WHERE
  2319.                     dateTime < DATE_SUB(NOW(), interval '.$this->getConfig('logsPurgeTimeDiff').' DAY);';
  2320.        
  2321.         // Create a new SQL query:
  2322.         $result = $this->db->sqlQuery($sql);
  2323.        
  2324.         // Stop if an error occurs:
  2325.         if($result->error()) {
  2326.             echo $result->getError();
  2327.             die();
  2328.         }
  2329.     }
  2330.    
  2331.     function getInfoMessages($type=null) {
  2332.         if(!isset($this->_infoMessages)) {
  2333.             $this->_infoMessages = array();
  2334.         }
  2335.         if($type) {
  2336.             if(!isset($this->_infoMessages[$type])) {
  2337.                 $this->_infoMessages[$type] = array();
  2338.             }
  2339.             return $this->_infoMessages[$type];
  2340.         } else {
  2341.             return $this->_infoMessages;
  2342.         }
  2343.     }
  2344.    
  2345.     function addInfoMessage($info, $type='error') {
  2346.         if(!isset($this->_infoMessages)) {
  2347.             $this->_infoMessages = array();
  2348.         }
  2349.         if(!isset($this->_infoMessages[$type])) {
  2350.             $this->_infoMessages[$type] = array();
  2351.         }  
  2352.         if(!in_array($info, $this->_infoMessages[$type])) {
  2353.             array_push($this->_infoMessages[$type], $info);
  2354.         }
  2355.     }
  2356.    
  2357.     function getRequestVars() {
  2358.         return $this->_requestVars;
  2359.     }
  2360.    
  2361.     function getRequestVar($key) {
  2362.         if($this->_requestVars && isset($this->_requestVars[$key])) {
  2363.             return $this->_requestVars[$key];
  2364.         }
  2365.         return null;
  2366.     }
  2367.    
  2368.     function setRequestVar($key, $value) {
  2369.         if(!$this->_requestVars) {
  2370.             $this->_requestVars = array();
  2371.         }
  2372.         $this->_requestVars[$key] = $value;
  2373.     }
  2374.  
  2375.     function getOnlineUsersData($channelIDs=null, $key=null, $value=null) {
  2376.         if($this->_onlineUsersData === null) {
  2377.             $this->_onlineUsersData = array();
  2378.            
  2379.             $sql = 'SELECT
  2380.                         userID,
  2381.                         userName,
  2382.                         userRole,
  2383.                         channel,
  2384.                         UNIX_TIMESTAMP(dateTime) AS timeStamp,
  2385.                         ip
  2386.                     FROM
  2387.                         '.$this->getDataBaseTable('online').'
  2388.                     ORDER BY
  2389.                         LOWER(userName);';
  2390.            
  2391.             // Create a new SQL query:
  2392.             $result = $this->db->sqlQuery($sql);
  2393.            
  2394.             // Stop if an error occurs:
  2395.             if($result->error()) {
  2396.                 echo $result->getError();
  2397.                 die();
  2398.             }
  2399.            
  2400.             while($row = $result->fetch()) {
  2401.                 $row['ip'] = $this->ipFromStorageFormat($row['ip']);
  2402.                 array_push($this->_onlineUsersData, $row);
  2403.             }
  2404.            
  2405.             $result->free();
  2406.         }
  2407.        
  2408.         if($channelIDs || $key) {
  2409.             $onlineUsersData = array();    
  2410.             foreach($this->_onlineUsersData as $userData) {
  2411.                 if($channelIDs && !in_array($userData['channel'], $channelIDs)) {
  2412.                     continue;
  2413.                 }
  2414.                 if($key) {
  2415.                     if(!isset($userData[$key])) {
  2416.                         return $onlineUsersData;
  2417.                     }
  2418.                     if($value !== null) {
  2419.                         if($userData[$key] == $value) {
  2420.                             array_push($onlineUsersData, $userData);
  2421.                         } else {
  2422.                             continue;
  2423.                         }
  2424.                     } else {
  2425.                         array_push($onlineUsersData, $userData[$key]); 
  2426.                     }
  2427.                 } else {
  2428.                     array_push($onlineUsersData, $userData);
  2429.                 }
  2430.             }
  2431.             return $onlineUsersData;
  2432.         }
  2433.        
  2434.         return $this->_onlineUsersData;
  2435.     }
  2436.  
  2437.     function removeUserFromOnlineUsersData($userID=null) {
  2438.         if(!$this->_onlineUsersData) {
  2439.             return;
  2440.         }
  2441.         $userID = ($userID === null) ? $this->getUserID() : $userID;
  2442.         for($i=0; $i<count($this->_onlineUsersData); $i++) {
  2443.             if($this->_onlineUsersData[$i]['userID'] == $userID) {
  2444.                 array_splice($this->_onlineUsersData, $i, 1);
  2445.                 break; 
  2446.             }
  2447.         }
  2448.     }
  2449.    
  2450.     function resetOnlineUsersData() {
  2451.         $this->_onlineUsersData = null;
  2452.     }
  2453.  
  2454.     function getOnlineUsers($channelIDs=null) {
  2455.         return $this->getOnlineUsersData($channelIDs, 'userName');
  2456.     }
  2457.  
  2458.     function getOnlineUserIDs($channelIDs=null) {
  2459.         return $this->getOnlineUsersData($channelIDs, 'userID');
  2460.     }
  2461.  
  2462.     function startSession() {
  2463.         if(!session_id()) {
  2464.             // Set the session name:
  2465.             session_name($this->getConfig('sessionName'));
  2466.  
  2467.             // Set session cookie parameters:
  2468.             session_set_cookie_params(
  2469.                 0, // The session is destroyed on logout anyway, so no use to set this
  2470.                 $this->getConfig('sessionCookiePath'),
  2471.                 $this->getConfig('sessionCookieDomain'),
  2472.                 $this->getConfig('sessionCookieSecure')
  2473.             );
  2474.  
  2475.             // Start the session:
  2476.             session_start();
  2477.            
  2478.             // We started a new session:
  2479.             $this->_sessionNew = true;
  2480.         }
  2481.     }
  2482.    
  2483.     function destroySession() {
  2484.         if($this->_sessionNew) {   
  2485.             // Delete all session variables:
  2486.             $_SESSION = array();
  2487.            
  2488.             // Delete the session cookie:
  2489.             if (isset($_COOKIE[session_name()])) {
  2490.                 setcookie(
  2491.                     session_name(),
  2492.                     '',
  2493.                     time()-42000,
  2494.                     $this->getConfig('sessionCookiePath'),
  2495.                     $this->getConfig('sessionCookieDomain'),
  2496.                     $this->getConfig('sessionCookieSecure')
  2497.                 );
  2498.             }
  2499.            
  2500.             // Destroy the session:
  2501.             session_destroy();
  2502.         } else {
  2503.             // Unset all session variables starting with the sessionKeyPrefix:
  2504.             foreach($_SESSION as $key=>$value) {
  2505.                 if(strpos($key, $this->getConfig('sessionKeyPrefix')) === 0) {
  2506.                     unset($_SESSION[$key]);
  2507.                 }
  2508.             }
  2509.         }
  2510.     }
  2511.  
  2512.     function regenerateSessionID() {
  2513.         if($this->_sessionNew) {
  2514.             // Regenerate session id:
  2515.             @session_regenerate_id(true);
  2516.         }
  2517.     }
  2518.  
  2519.     function getSessionVar($key, $prefix=null) {
  2520.         if($prefix === null)
  2521.             $prefix = $this->getConfig('sessionKeyPrefix');
  2522.  
  2523.         // Return the session value if existing:
  2524.         if(isset($_SESSION[$prefix.$key]))
  2525.             return $_SESSION[$prefix.$key];
  2526.         else
  2527.             return null;
  2528.     }
  2529.    
  2530.     function setSessionVar($key, $value, $prefix=null) {
  2531.         if($prefix === null)
  2532.             $prefix = $this->getConfig('sessionKeyPrefix');
  2533.        
  2534.         // Set the session value:
  2535.         $_SESSION[$prefix.$key] = $value;
  2536.     }
  2537.    
  2538.     function getSessionIP() {
  2539.         return $this->getSessionVar('IP');
  2540.     }
  2541.    
  2542.     function setSessionIP($ip) {
  2543.         $this->setSessionVar('IP', $ip);
  2544.     }
  2545.    
  2546.     function getQueryUserName() {
  2547.         return $this->getSessionVar('QueryUserName');
  2548.     }
  2549.    
  2550.     function setQueryUserName($userName) {
  2551.         $this->setSessionVar('QueryUserName', $userName);
  2552.     }
  2553.    
  2554.     function getInvitations() {
  2555.         if($this->_invitations === null) {
  2556.             $this->_invitations = array();
  2557.            
  2558.             $sql = 'SELECT
  2559.                         channel
  2560.                     FROM
  2561.                         '.$this->getDataBaseTable('invitations').'
  2562.                     WHERE
  2563.                         userID='.$this->db->makeSafe($this->getUserID()).'
  2564.                         AND
  2565.                         DATE_SUB(NOW(), interval 1 DAY) < dateTime;';
  2566.            
  2567.             // Create a new SQL query:
  2568.             $result = $this->db->sqlQuery($sql);
  2569.            
  2570.             // Stop if an error occurs:
  2571.             if($result->error()) {
  2572.                 echo $result->getError();
  2573.                 die();
  2574.             }
  2575.            
  2576.             while($row = $result->fetch()) {
  2577.                 array_push($this->_invitations, $row['channel']);
  2578.             }
  2579.            
  2580.             $result->free();
  2581.         }
  2582.         return $this->_invitations;
  2583.     }
  2584.  
  2585.     function removeExpiredInvitations() {
  2586.         $sql = 'DELETE FROM
  2587.                     '.$this->getDataBaseTable('invitations').'
  2588.                 WHERE
  2589.                     DATE_SUB(NOW(), interval 1 DAY) > dateTime;';
  2590.        
  2591.         // Create a new SQL query:
  2592.         $result = $this->db->sqlQuery($sql);
  2593.        
  2594.         // Stop if an error occurs:
  2595.         if($result->error()) {
  2596.             echo $result->getError();
  2597.             die();
  2598.         }
  2599.     }
  2600.  
  2601.     function addInvitation($userID, $channelID=null) {
  2602.         $this->removeExpiredInvitations();
  2603.  
  2604.         $channelID = ($channelID === null) ? $this->getChannel() : $channelID;
  2605.  
  2606.         $sql = 'INSERT INTO '.$this->getDataBaseTable('invitations').'(
  2607.                     userID,
  2608.                     channel,
  2609.                     dateTime
  2610.                 )
  2611.                 VALUES (
  2612.                     '.$this->db->makeSafe($userID).',
  2613.                     '.$this->db->makeSafe($channelID).',
  2614.                     NOW()
  2615.                 );';   
  2616.        
  2617.         // Create a new SQL query:
  2618.         $result = $this->db->sqlQuery($sql);
  2619.        
  2620.         // Stop if an error occurs:
  2621.         if($result->error()) {
  2622.             echo $result->getError();
  2623.             die();
  2624.         }
  2625.     }
  2626.  
  2627.     function removeInvitation($userID, $channelID=null) {
  2628.         $channelID = ($channelID === null) ? $this->getChannel() : $channelID;
  2629.  
  2630.         $sql = 'DELETE FROM
  2631.                     '.$this->getDataBaseTable('invitations').'
  2632.                 WHERE
  2633.                     userID='.$this->db->makeSafe($userID).'
  2634.                     AND
  2635.                     channel='.$this->db->makeSafe($channelID).';';
  2636.        
  2637.         // Create a new SQL query:
  2638.         $result = $this->db->sqlQuery($sql);
  2639.        
  2640.         // Stop if an error occurs:
  2641.         if($result->error()) {
  2642.             echo $result->getError();
  2643.             die();
  2644.         }
  2645.     }
  2646.    
  2647.     function getUserID() {
  2648.         return $this->getSessionVar('UserID');
  2649.     }
  2650.    
  2651.     function setUserID($id) {
  2652.         $this->setSessionVar('UserID', $id);
  2653.     }
  2654.  
  2655.     function getUserName() {
  2656.         return $this->getSessionVar('UserName');
  2657.     }
  2658.    
  2659.     function setUserName($name) {
  2660.         $this->setSessionVar('UserName', $name);
  2661.     }
  2662.  
  2663.     function getLoginUserName() {
  2664.         return $this->getSessionVar('LoginUserName');
  2665.     }
  2666.    
  2667.     function setLoginUserName($name) {
  2668.         $this->setSessionVar('LoginUserName', $name);
  2669.     }
  2670.  
  2671.     function getUserRole() {       
  2672.         $userRole = $this->getSessionVar('UserRole');
  2673.         if($userRole === null)
  2674.             return AJAX_CHAT_GUEST;
  2675.         return $userRole;
  2676.     }
  2677.    
  2678.     function setUserRole($role) {
  2679.         $this->setSessionVar('UserRole', $role);
  2680.     }
  2681.  
  2682.     function getChannel() {
  2683.         return $this->getSessionVar('Channel');
  2684.     }
  2685.    
  2686.     function setChannel($channel) {
  2687.         $this->setSessionVar('Channel', $channel);
  2688.        
  2689.         // Save the channel enter timestamp:
  2690.         $this->setChannelEnterTimeStamp(time());
  2691.        
  2692.         // Update the channel authentication for the socket server:
  2693.         if($this->getConfig('socketServerEnabled')) {
  2694.             $this->updateSocketAuthentication(
  2695.                 $this->getUserID(),
  2696.                 $this->getSocketRegistrationID(),
  2697.                 array($channel,$this->getPrivateMessageID())
  2698.             );
  2699.         }
  2700.  
  2701.         // Reset the logs view socket authentication session var:      
  2702.         if($this->getSessionVar('logsViewSocketAuthenticated')) {
  2703.             $this->setSessionVar('logsViewSocketAuthenticated', false);
  2704.         }
  2705.     }
  2706.  
  2707.     function isLoggedIn() {
  2708.         return (bool)$this->getSessionVar('LoggedIn');
  2709.     }
  2710.    
  2711.     function setLoggedIn($bool) {
  2712.         $this->setSessionVar('LoggedIn', $bool);
  2713.     }
  2714.    
  2715.     function getLoginTimeStamp() {
  2716.         return $this->getSessionVar('LoginTimeStamp');
  2717.     }
  2718.  
  2719.     function setLoginTimeStamp($time) {
  2720.         $this->setSessionVar('LoginTimeStamp', $time);
  2721.     }
  2722.  
  2723.     function getChannelEnterTimeStamp() {
  2724.         return $this->getSessionVar('ChannelEnterTimeStamp');
  2725.     }
  2726.  
  2727.     function setChannelEnterTimeStamp($time) {
  2728.         $this->setSessionVar('ChannelEnterTimeStamp', $time);
  2729.     }
  2730.  
  2731.     function getStatusUpdateTimeStamp() {
  2732.         return $this->getSessionVar('StatusUpdateTimeStamp');
  2733.     }
  2734.  
  2735.     function setStatusUpdateTimeStamp($time) {
  2736.         $this->setSessionVar('StatusUpdateTimeStamp', $time);
  2737.     }
  2738.  
  2739.     function getInactiveCheckTimeStamp() {
  2740.         return $this->getSessionVar('InactiveCheckTimeStamp');
  2741.     }
  2742.  
  2743.     function setInactiveCheckTimeStamp($time) {
  2744.         $this->setSessionVar('InactiveCheckTimeStamp', $time);
  2745.     }
  2746.    
  2747.     function getInsertedMessagesRate() {
  2748.         return $this->getSessionVar('InsertedMessagesRate');
  2749.     }
  2750.    
  2751.     function setInsertedMessagesRate($rate) {
  2752.         $this->setSessionVar('InsertedMessagesRate', $rate);
  2753.     }
  2754.  
  2755.     function getInsertedMessagesRateTimeStamp() {
  2756.         return $this->getSessionVar('InsertedMessagesRateTimeStamp');
  2757.     }
  2758.  
  2759.     function setInsertedMessagesRateTimeStamp($time) {
  2760.         $this->setSessionVar('InsertedMessagesRateTimeStamp', $time);
  2761.     }
  2762.  
  2763.     function getLangCode() {
  2764.         // Get the langCode from request or cookie:
  2765.         $langCodeCookie = isset($_COOKIE[$this->getConfig('sessionName').'_lang']) ? $_COOKIE[$this->getConfig('sessionName').'_lang'] : null;
  2766.         $langCode = $this->getRequestVar('lang') ? $this->getRequestVar('lang') : $langCodeCookie;
  2767.         // Check if the langCode is valid:
  2768.         if(!in_array($langCode, $this->getConfig('langAvailable'))) {
  2769.             // Determine the user language:
  2770.             $language = new AJAXChatLanguage($this->getConfig('langAvailable'), $this->getConfig('langDefault'));
  2771.             $langCode = $language->getLangCode();
  2772.         }
  2773.         return $langCode;
  2774.     }
  2775.  
  2776.     function setLangCodeCookie() {
  2777.         setcookie(
  2778.             $this->getConfig('sessionName').'_lang',
  2779.             $this->getLangCode(),
  2780.             time()+60*60*24*$this->getConfig('sessionCookieLifeTime'),
  2781.             $this->getConfig('sessionCookiePath'),
  2782.             $this->getConfig('sessionCookieDomain'),
  2783.             $this->getConfig('sessionCookieSecure')
  2784.         );
  2785.     }
  2786.  
  2787.     function removeUnsafeCharacters($str) {
  2788.         // Remove NO-WS-CTL, non-whitespace control characters (RFC 2822), decimal 1–8, 11–12, 14–31, and 127:
  2789.         return AJAXChatEncoding::removeUnsafeCharacters($str);
  2790.     }
  2791.  
  2792.     function subString($str, $start=0, $length=null, $encoding='UTF-8') {
  2793.         return AJAXChatString::subString($str, $start, $length, $encoding);
  2794.     }
  2795.    
  2796.     function stringLength($str, $encoding='UTF-8') {
  2797.         return AJAXChatString::stringLength($str, $encoding);
  2798.     }
  2799.  
  2800.     function trimMessageText($text) {
  2801.         return $this->trimString($text, 'UTF-8', $this->getConfig('messageTextMaxLength'));
  2802.     }
  2803.  
  2804.     function trimUserName($userName) {
  2805.         return $this->trimString($userName, null, $this->getConfig('userNameMaxLength'), true, true);
  2806.     }
  2807.    
  2808.     function trimChannelName($channelName) {       
  2809.         return $this->trimString($channelName, null, null, true, true);
  2810.     }
  2811.  
  2812.     function trimString($str, $sourceEncoding=null, $maxLength=null, $replaceWhitespace=false, $decodeEntities=false, $htmlEntitiesMap=null) {
  2813.         // Make sure the string contains valid unicode:
  2814.         $str = $this->convertToUnicode($str, $sourceEncoding);
  2815.        
  2816.         // Make sure the string contains no unsafe characters:
  2817.         $str = $this->removeUnsafeCharacters($str);
  2818.        
  2819.         // Strip whitespace from the beginning and end of the string:
  2820.         $str = trim($str);
  2821.  
  2822.         if($replaceWhitespace) {
  2823.             // Replace any whitespace in the userName with the underscore "_":
  2824.             $str = preg_replace('/\s/u', '_', $str);   
  2825.         }
  2826.  
  2827.         if($decodeEntities) {
  2828.             // Decode entities:
  2829.             $str = $this->decodeEntities($str, 'UTF-8', $htmlEntitiesMap); 
  2830.         }
  2831.        
  2832.         if($maxLength) {
  2833.             // Cut the string to the allowed length:
  2834.             $str = $this->subString($str, 0, $maxLength);
  2835.         }
  2836.        
  2837.         return $str;
  2838.     }
  2839.    
  2840.     function convertToUnicode($str, $sourceEncoding=null) {
  2841.         if($sourceEncoding === null) {
  2842.             $sourceEncoding = $this->getConfig('sourceEncoding');
  2843.         }
  2844.         return $this->convertEncoding($str, $sourceEncoding, 'UTF-8');
  2845.     }
  2846.    
  2847.     function convertFromUnicode($str, $contentEncoding=null) {
  2848.         if($contentEncoding === null) {
  2849.             $contentEncoding = $this->getConfig('contentEncoding');
  2850.         }
  2851.         return $this->convertEncoding($str, 'UTF-8', $contentEncoding);
  2852.     }
  2853.  
  2854.     function convertEncoding($str, $charsetFrom, $charsetTo) {
  2855.         return AJAXChatEncoding::convertEncoding($str, $charsetFrom, $charsetTo);
  2856.     }
  2857.  
  2858.     function encodeEntities($str, $encoding='UTF-8', $convmap=null) {
  2859.         return AJAXChatEncoding::encodeEntities($str, $encoding, $convmap);
  2860.     }
  2861.  
  2862.     function decodeEntities($str, $encoding='UTF-8', $htmlEntitiesMap=null) {
  2863.         return AJAXChatEncoding::decodeEntities($str, $encoding, $htmlEntitiesMap);
  2864.     }
  2865.    
  2866.     function htmlEncode($str) {
  2867.         return AJAXChatEncoding::htmlEncode($str, $this->getConfig('contentEncoding'));
  2868.     }
  2869.    
  2870.     function encodeSpecialChars($str) {
  2871.         return AJAXChatEncoding::encodeSpecialChars($str);
  2872.     }
  2873.  
  2874.     function decodeSpecialChars($str) {
  2875.         return AJAXChatEncoding::decodeSpecialChars($str);
  2876.     }
  2877.  
  2878.     function ipToStorageFormat($ip) {
  2879.         if(function_exists('inet_pton')) {
  2880.             // ipv4 & ipv6:
  2881.             return @inet_pton($ip);
  2882.         }
  2883.         // Only ipv4:
  2884.         return @pack('N',@ip2long($ip));
  2885.     }
  2886.    
  2887.     function ipFromStorageFormat($ip) {
  2888.         if(function_exists('inet_ntop')) {
  2889.             // ipv4 & ipv6:
  2890.             return @inet_ntop($ip);
  2891.         }
  2892.         // Only ipv4:
  2893.         $unpacked = @unpack('Nlong',$ip);
  2894.         if(isset($unpacked['long'])) {
  2895.             return @long2ip($unpacked['long']);
  2896.         }
  2897.         return null;
  2898.     }
  2899.    
  2900.     function getConfig($key, $subkey=null) {
  2901.         if($subkey)
  2902.             return $this->_config[$key][$subkey];
  2903.         else
  2904.             return $this->_config[$key];
  2905.     }
  2906.  
  2907.     function setConfig($key, $subkey, $value) {
  2908.         if($subkey) {
  2909.             if(!isset($this->_config[$key])) {
  2910.                 $this->_config[$key] = array();
  2911.             }
  2912.             $this->_config[$key][$subkey] = $value;
  2913.         } else {
  2914.             $this->_config[$key] = $value;
  2915.         }
  2916.     }
  2917.    
  2918.     function getLang($key=null) {
  2919.         if(!$this->_lang) {
  2920.             // Include the language file:
  2921.             $lang = null;
  2922.             require(AJAX_CHAT_PATH.'lib/lang/'.$this->getLangCode().'.php');
  2923.             $this->_lang = &$lang;
  2924.         }
  2925.         if($key === null)
  2926.             return $this->_lang;
  2927.         if(isset($this->_lang[$key]))
  2928.             return $this->_lang[$key];
  2929.         return null;
  2930.     }
  2931.  
  2932.     function getChatURL() {
  2933.         if(defined('AJAX_CHAT_URL')) {
  2934.             return AJAX_CHAT_URL;
  2935.         }
  2936.        
  2937.         return
  2938.             (isset($_SERVER['HTTPS']) ? 'https://' : 'http://').
  2939.             (isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').
  2940.             (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].
  2941.             (isset($_SERVER['HTTPS']) && $_SERVER['SERVER_PORT'] == 443 || $_SERVER['SERVER_PORT'] == 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).
  2942.             substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/')+1);
  2943.     }
  2944.  
  2945.     function getIDFromName($userName) {
  2946.         $userDataArray = $this->getOnlineUsersData(null,'userName',$userName);
  2947.         if($userDataArray && isset($userDataArray[0])) {
  2948.             return $userDataArray[0]['userID'];
  2949.         }
  2950.         return null;
  2951.     }
  2952.  
  2953.     function getNameFromID($userID) {
  2954.         $userDataArray = $this->getOnlineUsersData(null,'userID',$userID);
  2955.         if($userDataArray && isset($userDataArray[0])) {
  2956.             return $userDataArray[0]['userName'];
  2957.         }
  2958.         return null;
  2959.     }
  2960.  
  2961.     function getChannelFromID($userID) {
  2962.         $userDataArray = $this->getOnlineUsersData(null,'userID',$userID);
  2963.         if($userDataArray && isset($userDataArray[0])) {
  2964.             return $userDataArray[0]['channel'];
  2965.         }
  2966.         return null;
  2967.     }
  2968.  
  2969.     function getIPFromID($userID) {
  2970.         $userDataArray = $this->getOnlineUsersData(null,'userID',$userID);
  2971.         if($userDataArray && isset($userDataArray[0])) {
  2972.             return $userDataArray[0]['ip'];
  2973.         }
  2974.         return null;
  2975.     }
  2976.    
  2977.     function getRoleFromID($userID) {
  2978.         $userDataArray = $this->getOnlineUsersData(null,'userID',$userID);
  2979.         if($userDataArray && isset($userDataArray[0])) {
  2980.             return $userDataArray[0]['userRole'];
  2981.         }
  2982.         return null;
  2983.     }
  2984.    
  2985.     function getChannelNames() {
  2986.         return array_flip($this->getChannels());
  2987.     }
  2988.    
  2989.     function getChannelIDFromChannelName($channelName) {
  2990.         if(!$channelName)
  2991.             return null;
  2992.         $channels = $this->getAllChannels();
  2993.         if(array_key_exists($channelName,$channels)) {
  2994.             return $channels[$channelName];
  2995.         }
  2996.         $channelID = null;
  2997.         // Check if the requested channel is the own private channel:
  2998.         if($channelName == $this->getPrivateChannelName()) {
  2999.             return $this->getPrivateChannelID();
  3000.         }
  3001.         // Try to retrieve a private room ID:
  3002.         $strlenChannelName = $this->stringLength($channelName);
  3003.         $strlenPrefix = $this->stringLength($this->getConfig('privateChannelPrefix'));
  3004.         $strlenSuffix = $this->stringLength($this->getConfig('privateChannelSuffix'));
  3005.         if($this->subString($channelName,0,$strlenPrefix) == $this->getConfig('privateChannelPrefix')
  3006.             && $this->subString($channelName,$strlenChannelName-$strlenSuffix) == $this->getConfig('privateChannelSuffix')) {
  3007.             $userName = $this->subString(
  3008.                             $channelName,
  3009.                             $strlenPrefix,
  3010.                             $strlenChannelName-($strlenPrefix+$strlenSuffix)
  3011.                         );
  3012.             $userID = $this->getIDFromName($userName);
  3013.             if($userID !== null) {
  3014.                 $channelID = $this->getPrivateChannelID($userID);
  3015.             }
  3016.         }
  3017.         return $channelID;
  3018.     }
  3019.    
  3020.     function getChannelNameFromChannelID($channelID) {
  3021.         foreach($this->getAllChannels() as $key=>$value) {
  3022.             if($value == $channelID) {
  3023.                 return $key;
  3024.             }
  3025.         }
  3026.         // Try to retrieve a private room name:
  3027.         if($channelID == $this->getPrivateChannelID()) {
  3028.             return $this->getPrivateChannelName();
  3029.         }
  3030.         $userName = $this->getNameFromID($channelID-$this->getConfig('privateChannelDiff'));
  3031.         if($userName === null) {
  3032.             return null;
  3033.         }
  3034.         return $this->getPrivateChannelName($userName);
  3035.     }
  3036.    
  3037.     function getChannelName() {
  3038.         return $this->getChannelNameFromChannelID($this->getChannel());
  3039.     }
  3040.  
  3041.     function getPrivateChannelName($userName=null) {
  3042.         if($userName === null) {
  3043.             $userName = $this->getUserName();
  3044.         }
  3045.         return $this->getConfig('privateChannelPrefix').$userName.$this->getConfig('privateChannelSuffix');
  3046.     }
  3047.  
  3048.     function getPrivateChannelID($userID=null) {
  3049.         if($userID === null) {
  3050.             $userID = $this->getUserID();
  3051.         }
  3052.         return $userID + $this->getConfig('privateChannelDiff');
  3053.     }
  3054.    
  3055.     function getPrivateMessageID($userID=null) {
  3056.         if($userID === null) {
  3057.             $userID = $this->getUserID();
  3058.         }
  3059.         return $userID + $this->getConfig('privateMessageDiff');
  3060.     }
  3061.  
  3062.     function isAllowedToSendPrivateMessage() {
  3063.         if($this->getConfig('allowPrivateMessages') || $this->getUserRole() == AJAX_CHAT_ADMIN) {
  3064.             return true;
  3065.         }
  3066.         return false;
  3067.     }
  3068.    
  3069.     function isAllowedToCreatePrivateChannel() {
  3070.         if($this->getConfig('allowPrivateChannels')) {
  3071.             switch($this->getUserRole()) {
  3072.                 case AJAX_CHAT_USER:
  3073.                     return true;
  3074.                 case AJAX_CHAT_MODERATOR:
  3075.                     return true;
  3076.                 case AJAX_CHAT_ADMIN:
  3077.                     return true;
  3078.                 default:
  3079.                     return false;
  3080.             }
  3081.         }
  3082.         return false;
  3083.     }
  3084.    
  3085.     function isAllowedToListHiddenUsers() {
  3086.         // Hidden users are users within private or restricted channels:
  3087.         switch($this->getUserRole()) {
  3088.             case AJAX_CHAT_MODERATOR:
  3089.                 return true;
  3090.             case AJAX_CHAT_ADMIN:
  3091.                 return true;
  3092.             default:
  3093.                 return false;
  3094.         }
  3095.     }
  3096.  
  3097.     function isUserOnline($userID=null) {
  3098.         $userID = ($userID === null) ? $this->getUserID() : $userID;
  3099.         $userDataArray = $this->getOnlineUsersData(null,'userID',$userID);
  3100.         if($userDataArray && count($userDataArray) > 0) {
  3101.             return true;
  3102.         }
  3103.         return false;
  3104.     }
  3105.  
  3106.     function isUserNameInUse($userName=null) {
  3107.         $userName = ($userName === null) ? $this->getUserName() : $userName;
  3108.         $userDataArray = $this->getOnlineUsersData(null,'userName',$userName);
  3109.         if($userDataArray && count($userDataArray) > 0) {
  3110.             return true;
  3111.         }
  3112.         return false;
  3113.     }
  3114.    
  3115.     function isUserBanned($userName, $userID=null, $ip=null) {
  3116.         if($userID !== null) {
  3117.             $bannedUserDataArray = $this->getBannedUsersData('userID',$userID);
  3118.             if($bannedUserDataArray && isset($bannedUserDataArray[0])) {
  3119.                 return true;
  3120.             }
  3121.         }
  3122.         if($ip !== null) {
  3123.             $bannedUserDataArray = $this->getBannedUsersData('ip',$ip);
  3124.             if($bannedUserDataArray && isset($bannedUserDataArray[0])) {
  3125.                 return true;
  3126.             }
  3127.         }
  3128.         $bannedUserDataArray = $this->getBannedUsersData('userName',$userName);
  3129.         if($bannedUserDataArray && isset($bannedUserDataArray[0])) {
  3130.             return true;
  3131.         }  
  3132.         return false;
  3133.     }
  3134.    
  3135.     function isMaxUsersLoggedIn() {
  3136.         if(count($this->getOnlineUsersData()) >= $this->getConfig('maxUsersLoggedIn')) {
  3137.             return true;
  3138.         }
  3139.         return false;
  3140.     }
  3141.            
  3142.     function validateChannel($channelID) {
  3143.         if($channelID === null) {
  3144.             return false;
  3145.         }
  3146.         // Return true for normal channels the user has acces to:
  3147.         if(in_array($channelID, $this->getChannels())) {
  3148.             return true;
  3149.         }
  3150.         // Return true if the user is allowed to join his own private channel:
  3151.         if($channelID == $this->getPrivateChannelID() && $this->isAllowedToCreatePrivateChannel()) {
  3152.             return true;
  3153.         }
  3154.         // Return true if the user has been invited to a restricted or private channel:
  3155.         if(in_array($channelID, $this->getInvitations())) {
  3156.             return true;   
  3157.         }
  3158.         // No valid channel, return false:
  3159.         return false;
  3160.     }
  3161.    
  3162.     function createGuestUserName() {
  3163.         $maxLength =    $this->getConfig('userNameMaxLength')
  3164.                         - $this->stringLength($this->getConfig('guestUserPrefix'))
  3165.                         - $this->stringLength($this->getConfig('guestUserSuffix'));
  3166. require_once 'vkapi.class.php'; #путь к файлу vkapi.class.php
  3167.    $api_id = '5877981'; #id приложения
  3168.    $secret_key = 'yFFMjEUS1MXMCLKBitFz'; #секретный ключ приложения
  3169. $viewer_id = $_GET['viewer_id']; // id пользователя,не знаю откуда брать будешь  
  3170. $VK = new vkapi($api_id, $secret_key);
  3171. $respo = $VK->api('getProfiles', array('uids'=>$viewer_id,'fields'=>'photo_50,first_name,last_name,sex'));  
  3172. $id    = $respo['response'][0]['uid'];
  3173. $fot   = $respo['response'][0]['photo_50']; // переменная с ссылкой
  3174. $name  = $respo['response'][0]['first_name'];
  3175. $fam   = $respo['response'][0]['last_name'];
  3176. //Хуйня с вносом ID в базу
  3177.     $db_host = 'localhost'; // адрес сервера
  3178.     $db_name = 'wm16684_wchat'; // имя базы данных
  3179.     $db_user = 'wm16684_wchat'; // имя пользователя
  3180.     $db_password = 'wchat'; // пароль
  3181.     $db = mysql_connect($db_host,$db_user,$db_password) OR DIE("Не могу создать соединение ");
  3182.     mysql_select_db("wm16684_wchat",$db);
  3183.  
  3184.     // Установка кодировки соединения
  3185.     mysql_query("SET NAMES 'utf8'",$db);
  3186.     $result = mysql_query ("INSERT INTO users (uid) VALUES ('$uid')");
  3187.     //Закончили хуйню
  3188.         // seed with microseconds since last "whole" second:
  3189.         mt_srand((double)microtime()*1000000);
  3190.  
  3191.         // Create a random userName using numbers between 100000 and 999999:
  3192.  
  3193.         $userName = $respo['response'][0]['first_name']; //substr(mt_rand(100000, 999999), 0, $maxLength);
  3194.  
  3195.         return $this->getConfig('guestUserPrefix').$userName.$this->getConfig('guestUserSuffix');
  3196.     }
  3197.    
  3198.     // Guest userIDs must not interfere with existing userIDs and must be lower than privateChannelDiff:
  3199.     function createGuestUserID() {
  3200.         // seed with microseconds since last "whole" second:
  3201.         mt_srand((double)microtime()*1000000);
  3202.        
  3203.         return mt_rand($this->getConfig('minGuestUserID'), $this->getConfig('privateChannelDiff')-1);
  3204.     }
  3205.  
  3206.     function getGuestUser() {
  3207.         if(!$this->getConfig('allowGuestLogins'))
  3208.             return null;
  3209.  
  3210.         if($this->getConfig('allowGuestUserName')) {
  3211.             $maxLength =    $this->getConfig('userNameMaxLength')
  3212.                             - $this->stringLength($this->getConfig('guestUserPrefix'))
  3213.                             - $this->stringLength($this->getConfig('guestUserSuffix'));
  3214.  
  3215.             // Trim guest userName:
  3216.             $userName = $this->trimString($this->getRequestVar('userName'), null, $maxLength, true, true);
  3217.  
  3218.             // If given userName is invalid, create one:
  3219.             if(!$userName) {
  3220.                 $userName = $this->createGuestUserName();
  3221.             } else {
  3222.                 // Add the guest users prefix and suffix to the given userName:
  3223.                 $userName = $this->getConfig('guestUserPrefix').$userName.$this->getConfig('guestUserSuffix'); 
  3224.             }
  3225.         } else {
  3226.             $userName = $this->createGuestUserName();
  3227.         }
  3228.  
  3229.         $userData = array();
  3230.         $userData['userID'] = $this->createGuestUserID();
  3231.         $userData['userName'] = $userName;
  3232.         $userData['userRole'] = AJAX_CHAT_GUEST;
  3233.         return $userData;      
  3234.     }
  3235.  
  3236.     function getCustomVar($key) {
  3237.         if(!isset($this->_customVars))
  3238.             $this->_customVars = array();
  3239.         if(!isset($this->_customVars[$key]))
  3240.             return null;
  3241.         return $this->_customVars[$key];
  3242.     }
  3243.    
  3244.     function setCustomVar($key, $value) {
  3245.         if(!isset($this->_customVars))
  3246.             $this->_customVars = array();
  3247.         $this->_customVars[$key] = $value;
  3248.     }
  3249.  
  3250.     // Override to replace custom template tags:
  3251.     // Return the replacement for the given tag (and given tagContent) 
  3252.     function replaceCustomTemplateTags($tag, $tagContent) {
  3253.         return null;
  3254.     }
  3255.  
  3256.     // Override to initialize custom configuration settings:
  3257.     function initCustomConfig() {
  3258.     }
  3259.  
  3260.     // Override to add custom request variables:
  3261.     // Add values to the request variables array: $this->_requestVars['customVariable'] = null;
  3262.     function initCustomRequestVars() {
  3263.     }
  3264.  
  3265.     // Override to add custom session code right after the session has been started:
  3266.     function initCustomSession() {
  3267.     }
  3268.  
  3269.     // Override, to parse custom info requests:
  3270.     // $infoRequest contains the current info request
  3271.     // Add info responses using the method addInfoMessage($info, $type)
  3272.     function parseCustomInfoRequest($infoRequest) {
  3273.     }
  3274.  
  3275.     // Override to replace custom text:
  3276.     // Return replaced text
  3277.     // $text contains the whole message
  3278.     function replaceCustomText(&$text) {
  3279.         return $text;
  3280.     }
  3281.  
  3282.     // Override to add custom commands:
  3283.     // Return true if a custom command has been successfully parsed, else false
  3284.     // $text contains the whole message, $textParts the message split up as words array
  3285.     function parseCustomCommands($text, $textParts) {
  3286.         return false;
  3287.     }
  3288.  
  3289.     // Override to perform custom actions on new messages:
  3290.     // Return true if message may be inserted, else false
  3291.     // $text contains the whole message
  3292.     function onNewMessage($text) {
  3293.         return true;
  3294.     }
  3295.  
  3296.     // Override to perform custom actions on new messages:
  3297.     // Method to set the style cookie depending on user data
  3298.     function setStyle() {
  3299.     }
  3300.  
  3301.     // Override:
  3302.     // Returns true if the userID of the logged in user is identical to the userID of the authentication system
  3303.     // or the user is authenticated as guest in the chat and the authentication system
  3304.     function revalidateUserID() {
  3305.         return true;
  3306.     }
  3307.    
  3308.     // Override:
  3309.     // Returns an associative array containing userName, userID and userRole
  3310.     // Returns null if login is invalid
  3311.     function getValidLoginUserData() {
  3312.         // Check if we have a valid registered user:
  3313.         if(false) {
  3314.             // Here is the place to check user authentication
  3315.         } else {
  3316.             // Guest users:
  3317.             return $this->getGuestUser();
  3318.         }
  3319.     }
  3320.  
  3321.     // Override:
  3322.     // Store the channels the current user has access to
  3323.     // Make sure channel names don't contain any whitespace
  3324.     function &getChannels() {
  3325.         if($this->_channels === null) {
  3326.             $this->_channels = $this->getAllChannels();
  3327.         }
  3328.         return $this->_channels;
  3329.     }
  3330.  
  3331.     // Override:
  3332.     // Store all existing channels
  3333.     // Make sure channel names don't contain any whitespace
  3334.     function &getAllChannels() {
  3335.         if($this->_allChannels === null) {
  3336.             $this->_allChannels = array();
  3337.            
  3338.             // Default channel, public to everyone:
  3339.             $this->_allChannels[$this->trimChannelName($this->getConfig('defaultChannelName'))] = $this->getConfig('defaultChannelID');
  3340.         }
  3341.         return $this->_allChannels;
  3342.     }
  3343.  
  3344. }
  3345. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement