Page 1 of 1

stay logged into chat temp fix

PostPosted: January 21st, 2014, 12:12 pm
by Test
Functions_ajax.php with temp fix in place to stay logged in chat

Code: Select all
<?php
/*
*
* @name functions_ajax.php
* @package phpBB3 cBB Chat
* @version $Id: functions_ajax.php,v1.0.0 12/08/2013 $
*
* @copyright (c) 2013 CaniDev
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
* @ignore
*/
if(!defined('IN_PHPBB'))
{
   exit;
}

class chat_ajax
{
   var $user_key   = false;
   var $user_data   = false;

   var $actions = array(
      'pmuser'      => array('lang' => 'CHAT_SEND_PM',      'auth' => 'u_chat_sendpm',   'check' => 'chat_allow_pm'),
      'mentionuser'   => array('lang' => 'CHAT_MENTION',      'auth' => 'u_chat_post'),
      'banuser'      => array('lang' => 'CHAT_BAN_USER',      'auth' => 'm_ban'),
      'unbanuser'      => array('lang' => 'CHAT_UNBAN_USER',   'auth' => 'm_ban'),
      'deluser'      => array('lang' => 'CHAT_DELETE_USER',   'auth' => 'a_userdel'),
   );
   
   function chat_ajax($force = false)
   {
      global $config;
      
      if(!$force && !isset($_POST['icajx']))
      {
         exit_handler();
      }

      $this->user_key = request_var($config['cookie_name'] . '_chat_key', 0, false, true);
   }
   
   function auth($auth_option, $data = false)
   {
      global $auth;
      
      if($auth_option[0] == '-')
      {
         return ($auth->acl_get(substr($auth_option, 1, strlen($auth_option))) ? true : false);
      }
   
      if($data === false)
      {
         if($auth->acl_gets(array("u_chat_$auth_option", "m_chat_$auth_option"), 0))
         {
            return true;
         }
         
         return false;
      }
      else
      {
         if($auth->acl_get("u_chat_$auth_option") && $data['poster_key'] == $this->user_key)
         {
            return true;
         }
         
         if($auth->acl_get("m_chat_$auth_option"))
         {
            return true;
         }
      }
      
      return false;
   }
   
   function run($force_action = '')
   {
      global $db, $user, $template, $config, $phpbb_root_path, $phpEx;
      global $chat;

      $action         = ($force_action) ? $force_action : request_var('action', '');
      $action         = (!$chat->enabled) ? 'disable' : $action;

      $last_update    = request_var('last_update', 0);
      $submit         = request_var('submit', false);
      
      $allow_bbcode   = ($config['allow_bbcode'] && $config['chat_allow_bbcode']) ? true : false;
      $allow_smilies   = ($config['allow_smilies']) ? true : false;
      $allow_urls      = ($config['allow_post_links']) ? true : false;
      
      $json = array(
         'action'   => '',
         'success'   => true,
      );
      
      if(in_array($action, array('delete', 'edit', 'quote', 'whois')))
      {
         $message_id = request_var('id', 0);
      }

      switch($action)
      {
         case 'disable':
            $json['action'] = 'disable';
         break;

         case 'disconnect':
         case 'disconnect_on_refresh':
            $sql = 'UPDATE ' . CHAT_USERS_TABLE . '
               SET user_online = 0
               WHERE user_id = ' . $user->data['user_id'];
               
            if($user->data['user_id'] == ANONYMOUS)
            {
               $sql .= ' AND (user_key = ' . $this->user_key . "
                  OR user_ip = '" . $user->ip . "')";
            }
            
            $db->sql_query($sql);
            
            // Delete private messages
            $sql = 'DELETE FROM ' . CHAT_MESSAGES_TABLE . '
               WHERE (dest_key = ' . $this->user_key . '
               OR (poster_key = ' . $this->user_key . '
                  AND dest_key <> ' . CHAT_GUEST_ROOM . ')
               )';
            $db->sql_query($sql);
            
            if($action == 'disconnect_on_refresh')
            {
               return true;
            }
         break;

         case 'connect':
            // Recover the user session
            $this->get_current_user();
            
         // no break;
         
         case 'connect_on_post':
            $update_ary = array();
            
            // Add a new session if no exists
            if(!$this->user_data)
            {
               $username = '';

               if($user->data['user_id'] != ANONYMOUS)
               {
                  // Bots never allowed
                  if($user->data['user_type'] == USER_IGNORE)
                  {
                     break;
                  }
                  
                  $this->user_key = $user->data['user_id'];
               }
               else
               {
                  $username       = utf8_normalize_nfc(request_var('username', '', true));
                  $this->user_key   = time() - 1001;
                  
                  // Login dialog
                  if(!$username)
                  {
                     $json['action'] = $action = 'login';
                     
                     $template->assign_vars(array(
                        'S_LOGIN'   => true,
                        'S_TITLE'   => $user->lang['LOGIN']
                     ));
                     
                     break;
                  }
                  
                  // Check if username already exists
                  $sql = 'SELECT u.user_id, uc.user_id
                     FROM ' . USERS_TABLE . ' u,' . CHAT_USERS_TABLE . " uc
                     WHERE u.username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'
                     OR LOWER(uc.username) = '" . $db->sql_escape(strtolower($username)) . "'";
                  $result = $db->sql_query($sql);
                  $user_row = $db->sql_fetchrow($result);
                  $db->sql_freeresult($result);
                  
                  if($user_row)
                  {
                     $submit = false;
                     $json['action'] = $action = 'login';
                     
                     $template->assign_vars(array(
                        'S_LOGIN'   => true,
                        'S_TITLE'   => $user->lang['CHAT_USER_ALREADY_EXISTS']
                     ));
                     
                     break;
                  }
               }
               
               // Delete previous sessions from the same user
               $sql = 'DELETE FROM ' . CHAT_USERS_TABLE . '
                  WHERE user_id = ' . $user->data['user_id'];

               if($user->data['user_id'] == ANONYMOUS)
               {
                  $sql .= " AND user_ip = '" . $user->ip . "'";
               }
               
               $result = $db->sql_query($sql);
            
               $this->user_data = array(
                  'user_id'            => $user->data['user_id'],
                  'user_ip'            => $user->ip,
                  'username'            => $username,
                  'session_start'         => time(),
                  'session_viewonline'   => $user->data['session_viewonline'],
                  'user_lastjoin'         => time(),
                  'user_key'            => $this->user_key,
                  'user_online'         => 1,
               );
               
               $sql = 'INSERT INTO ' . CHAT_USERS_TABLE . ' ' . $db->sql_build_array('INSERT', $this->user_data);
               $db->sql_query($sql);
               
               $cookie_expire = ($user->data['user_id'] != ANONYMOUS) ? $user->time_now + (($config['max_autologin_time']) ? 86400 * (int) $config['max_autologin_time'] : 31536000) : 0;
               $user->set_cookie('chat_key', $this->user_key, $cookie_expire);
            }
            else
            {
               $update_ary = array(
                  'user_online'         => 1,
                  'session_start'         => time(),
                  'session_viewonline'   => $user->data['session_viewonline'],
                  'user_lastjoin'         => time(),
               );
            }
            
            // Remove exclusion
            if($this->user_data['exclude_time'] && $this->user_data['exclude_time'] != 1 && $this->user_data['exclude_time'] < time())
            {
               $update_ary['exclude_time'] = 0;
            }
            
            if(sizeof($update_ary))
            {
               $sql = 'UPDATE ' . CHAT_USERS_TABLE . '
                  SET ' . $db->sql_build_array('UPDATE', $update_ary) . '
                  WHERE user_key = ' . $this->user_key;
               $db->sql_query($sql);
               
               $this->user_data = array_merge($this->user_data, $update_ary);
            }
            
            // Cron work
            $day_limit   = time() - 86400; // yesterday (One day)
            
            if($day_limit > (int)$config['chat_cron_lock'])
            {
               // Delete inactive guests (one day of inactivity) or same session of the current user
               $sql = 'DELETE FROM ' . CHAT_USERS_TABLE . '
                  WHERE user_id = ' . ANONYMOUS . '
                  AND (user_lastjoin < ' . $day_limit . "
                  OR user_ip = '" . $this->user_data['user_ip'] . "')
                  AND user_key <> " . $this->user_data['user_key'] . '
                  AND exclude_time = 0';
               $db->sql_query($sql);
               
               // Delete messages out of store time
               if($config['chat_store_time'])
               {
                  $sql = 'DELETE FROM ' . CHAT_MESSAGES_TABLE . '
                     WHERE message_time < ' . (time() - (int)$config['chat_store_time']);
                  $db->sql_query($sql);
               }

               set_config('chat_cron_lock', time());
            }
            
            if($action == 'connect_on_post')
            {
               return true;
            }

         // no break;
         
         case 'refresh':
         case 'refresh_after_post':
            $row_users = $row_data = $user_cache = array();
            $max_time = $last_update;

            $bbcode_bitfield = '';

            // Get the user session if no exists
            $this->get_current_user(true);
           
            /* remove autodisconnect
            if(!$this->user_data || ($action == 'refresh' && $this->user_data['user_lastjoin'] < $chat->time_limit))
            {
               $this->run('disconnect_on_refresh');
               $json['action'] = 'disconnect';
               break;
            }
            */
            if(!$this->user_data)
            {
               $this->run('disconnect_on_refresh');
               $json['action'] = 'disconnect';
               break;
            }
            else
            {
            // Update the user activity
               $sql = 'UPDATE ' . CHAT_USERS_TABLE . '
                  SET user_lastjoin = ' . time() . ', user_online = 1
                  WHERE user_key = ' . $this->user_key;
               $db->sql_query($sql);
            }
           
            
            // Delete inactive users
            if($action == 'connect' || $action == 'refresh')
            {
               $sql = 'UPDATE ' . CHAT_USERS_TABLE . '
                  SET user_online = 0
                  WHERE user_lastjoin < ' . $chat->time_limit . '
                  AND user_key <> ' . $this->user_key;
               $result = $db->sql_query($sql);
            }
            
            // Get connected users
            $sql = 'SELECT *
               FROM ' . CHAT_USERS_TABLE . '
               WHERE user_online = 1';
            $result = $db->sql_query($sql);
            while($row = $db->sql_fetchrow($result))
            {
               $row_users[$row['user_key']]    = $row;
               $user_cache[$row['user_key']]    = $row['user_key'];
            }
            $db->sql_freeresult($result);
            
            // Get new messages and rooms
            
            // Always set the guest room
            $row_data[CHAT_GUEST_ROOM] = array();

            // Private Rooms
            if($config['chat_allow_pm'])
            {
               $sql = 'SELECT DISTINCT dest_key, poster_key
                  FROM ' . CHAT_MESSAGES_TABLE . "
                  WHERE message_time > $last_update
                  AND (dest_key = " . $this->user_key . '
                     OR (poster_key = ' . $this->user_key . ' AND dest_key <> ' . CHAT_GUEST_ROOM . '))
                  ORDER BY dest_key ASC';
               $result = $db->sql_query($sql);
               while($row = $db->sql_fetchrow($result))
               {
                  $key = ($row['poster_key'] != $this->user_key) ? $row['poster_key'] : $row['dest_key'];

                  if(isset($row_users[$key]) && empty($row_users[$key]['exclude_time']))
                  {
                     $row_data[$key] = array();
                  }
               }
               $db->sql_freeresult($result);
            }

            // Get messages for each room
            foreach($row_data as $dest_key => $null)
            {
               if($dest_key == CHAT_GUEST_ROOM)
               {
                  $sql_where = "dest_key = $dest_key";
               }
               else
               {
                  $sql_where = '((dest_key = ' . $dest_key . ' AND poster_key = ' . $this->user_key . ')
                     OR (poster_key = ' . $dest_key . ' AND dest_key = ' . $this->user_key . '))';
               }

               $sql = 'SELECT *
                  FROM ' . CHAT_MESSAGES_TABLE . "
                  WHERE $sql_where
                  AND message_time > $last_update
                  ORDER BY message_time DESC";
               $result = $db->sql_query_limit($sql, $config['chat_max_rows']);
               while($row = $db->sql_fetchrow($result))
               {
                  if($row['poster_key'] != $this->user_key && $dest_key != CHAT_GUEST_ROOM)
                  {
                     $row_data[$row['poster_key']][$row['message_time']] = $row;
                  }
                  else
                  {
                     $row_data[$dest_key][$row['message_time']] = $row;
                  }
                  
                  $user_cache[$row['poster_key']] = $row['poster_key'];
                  
                  if($dest_key != CHAT_GUEST_ROOM)
                  {
                     $user_cache[$dest_key] = $dest_key;
                  }
                  
                  // Define the global bbcode bitfield, will be used to load bbcodes
                  $bbcode_bitfield = $bbcode_bitfield | base64_decode($row['bbcode_bitfield']);
                  
                  $max_time = max($max_time, $row['message_time']);
               }
               $db->sql_freeresult($result);
            }
            
            // Get the users data
            if(!empty($user_cache))
            {
               $sql = 'SELECT user_id, user_type, username, user_colour,
                  user_avatar, user_avatar_type, user_avatar_width, user_avatar_height
                  FROM ' . USERS_TABLE . '
                  WHERE ' . $db->sql_in_set('user_id', array_keys($user_cache)) . '
                  AND user_type <> ' . USER_IGNORE;
               $result = $db->sql_query($sql);
               while($row = $db->sql_fetchrow($result))
               {
                  $user_cache[$row['user_id']] = $row;
               }
               $db->sql_freeresult($result);
            }
            
            if($config['chat_show_avatars'] && !function_exists('get_user_avatar'))
            {
               include($phpbb_root_path . "includes/functions_display.$phpEx");
            }
            
            // Instantiate BBCode if needed
            if($bbcode_bitfield !== '')
            {
               if(!class_exists('bbcode'))
               {
                  include($phpbb_root_path . "includes/bbcode.$phpEx");
               }
   
               $bbcode = new bbcode(base64_encode($bbcode_bitfield));
            }

            // Update the values in javascript
            $json = array_merge($json, array(
               'action'      => 'update',
               'last_time'      => $max_time,
               'msg_direction'   => $config['chat_direction'],
               'flood_time'   => $config['chat_flood_time'] * 1000,
            ));
            
            // Compose
            foreach($row_data as $room_key => $room_data)
            {
               if($room_key != CHAT_GUEST_ROOM && $row_users[$room_key]['user_id'] == ANONYMOUS)
               {
                  $user_cache[$room_key] = $row_users[$room_key];
               }
               
               // Room info
               $template->assign_block_vars('room', array(
                  'ID'      => $room_key,
                  'S_TITLE'   => ($room_key == CHAT_GUEST_ROOM) ? $user->lang['CHAT_GUEST_ROOM'] : $user_cache[$room_key]['username'],
               ));
               
               if($config['chat_direction'] != 'up')
               {
                  ksort($room_data);
               }
               
               // Messages
               foreach($room_data as $row_time => $row)
               {
                  $row_avatar = '';

                  if(is_array($user_cache[$row['poster_key']]))
                  {
                     $row += $user_cache[$row['poster_key']];
                  }
   
                  // Parse the message and subject
                  $message = censor_text($row['message_text']);
                  
                  // Second parse bbcode here
                  if($row['bbcode_bitfield'])
                  {
                     $bbcode->bbcode_second_pass($message, $row['bbcode_uid'], $row['bbcode_bitfield']);
                  }

                  $message = bbcode_nl2br($message);
                  $message = smiley_text($message);
                  
                  if($config['chat_show_avatars'])
                  {
                     if($row['poster_id'] != ANONYMOUS)
                     {
                        $row_avatar = get_user_avatar($row['user_avatar'], $row['user_avatar_type'], $row['user_avatar_width'], $row['user_avatar_height']);
                        
                        // Fix path error occurs in some cases
                        if($row_avatar && $chat->web_path != $phpbb_root_path)
                        {
                           $row_avatar = str_replace('src="' . $phpbb_root_path, 'src="' . $chat->web_path, $row_avatar);
                        }
                     }
                     
                     if(!$row_avatar)
                     {
                        $row_avatar = '<img src="' . $chat->web_path . $chat->path . 'images/no-avatar.gif" />';
                     }
                  }

                  $template->assign_block_vars('room.message', array(
                     'S_ID'            => $row['message_id'],
                     'S_AUTHOR_AVATAR'   => $row_avatar,
                     'S_AUTHOR_FULL'      => ($row['poster_id'] == ANONYMOUS) ? $row['poster_username'] : get_username_string('full', $row['poster_key'], $row['username'], $row['user_colour']),
                     'S_TEXT'         => $message,
                     'S_DATE'         => $user->format_date($row['message_time']),
                     
                     'CAN_DELETE'      => $this->auth('delete', $row),
                     'CAN_EDIT'         => $this->auth('edit', $row),
                     'CAN_QUOTE'         => (!in_array('quote', $chat->disallowed_bbcodes) && $this->auth('post')) ? true : false,
                     'CAN_VIEW_WHOIS'   => $this->auth('-a_'),
                  ));
               }
               
               // Users
               $this->generate_userlist($row_users, $user_cache, $room_key);
            }
         break;
         
         case 'clear':
            if($this->auth('-m_chat_delete'))
            {
               if($submit)
               {
                  $sql = 'DELETE FROM ' . CHAT_MESSAGES_TABLE . '
                     WHERE dest_key = ' . CHAT_GUEST_ROOM;
                  $db->sql_query($sql);
                  
                  break;
               }
               
               $template->assign_vars(array(
                  'S_CONFIRM_DIALOG'   => true,
                  'S_TITLE'         => $user->lang['CONFIRM'],
                  'S_DIALOG_CONTENT'   => $user->lang['CHAT_PURGE_CONFIRM'],
               ));
            }
         break;
         
         case 'delete':
            $sql = 'SELECT poster_key
               FROM ' . CHAT_MESSAGES_TABLE . "
               WHERE message_id = $message_id";
            $result = $db->sql_query($sql);
            $row = $db->sql_fetchrow($result);
            $db->sql_freeresult($result);
            
            if(!$row)
            {
               break;
            }
            
            if($this->get_current_user() && $this->auth('delete', $row))
            {
               $sql = 'DELETE FROM ' . CHAT_MESSAGES_TABLE . '
                  WHERE message_id = ' . $message_id;
               $db->sql_query($sql);
            }
         break;
         
         case 'edit':
            $sql = 'SELECT poster_key, message_text, bbcode_uid
               FROM ' . CHAT_MESSAGES_TABLE . "
               WHERE message_id = $message_id";
            $result = $db->sql_query($sql);
            $row = $db->sql_fetchrow($result);
            $db->sql_freeresult($result);
            
            if(!$row)
            {
               break;
            }

            if($this->get_current_user() && $this->auth('edit', $row))
            {
               if($submit)
               {
                  // Parse and insert the new message
                  $message = utf8_normalize_nfc(request_var('ic_edit_message', '', true));

                  // BBcode control
                  $this->strip_bbcode($message);
                  
                  if($message)
                  {
                     $uid = $bitfield = $options = '';
                     generate_text_for_storage($message, $uid, $bitfield, $options, $allow_bbcode, $allow_urls, $allow_smilies);
                     
                     $sql_ary = array(
                        'message_text'      => $message,
                        'bbcode_bitfield'   => $bitfield,
                        'bbcode_uid'      => $uid,
                     );
                     
                     $sql = 'UPDATE ' . CHAT_MESSAGES_TABLE . '
                        SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
                        WHERE message_id = ' . $message_id;
                     $db->sql_query($sql);

                     $template->assign_var('CUSTOM_PRINT', generate_text_for_display($message, $uid, $bitfield, $options));
                  }

                  break;
               }

               decode_message($row['message_text'], $row['bbcode_uid']);

               $template->assign_vars(array(
                  'S_EDIT'         => true,
                  'S_CHAT_MAX_CHARS'   => $config['chat_max_chars'],
                  
                  'S_MESSAGE'   => $row['message_text'],
                  'S_TITLE'   => $user->lang['EDIT'],
               ));
            }
         break;
         
         case 'post':
            if(!$this->get_current_user())
            {
               $this->run('connect_on_post');
            }

            $message       = utf8_normalize_nfc(request_var('ic_message', '', true));
            $room_key      = request_var('room', CHAT_GUEST_ROOM);
            $last_post_time = request_var('last_post_time', 0);

            if(!$this->user_data || !$this->auth('post') || !$message || !empty($this->user_data['exclude_time']) || ($room_key != CHAT_GUEST_ROOM && !$config['chat_allow_pm']))
            {
               break;
            }

            // Flood control
            if($config['chat_flood_time'] && !$this->auth('ignoreflood') && $this->user_data['session_start'] != $this->user_data['user_lastjoin'])
            {
               if(($last_post_time + $config['chat_flood_time']) >= time())
               {
                  break;
               }
            }

            // BBcode control
            $this->strip_bbcode($message);

            if($message)
            {
               $uid = $bitfield = $options = '';
               generate_text_for_storage($message, $uid, $bitfield, $options, $allow_bbcode, $allow_urls, $allow_smilies);

               $sql_ary = array(
                  'poster_key'      => $this->user_data['user_key'],
                  'dest_key'         => $room_key,
                  'poster_id'         => $this->user_data['user_id'],
                  'poster_ip'         => $this->user_data['user_ip'],
                  'poster_username'   => $this->user_data['username'],
                  'message_text'      => $message,
                  'message_time'      => time(),
                  'bbcode_bitfield'   => $bitfield,
                  'bbcode_uid'      => $uid,
               );

               $sql = 'INSERT INTO ' . CHAT_MESSAGES_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
               $db->sql_query($sql);

               // Update the user activity
               $sql = 'UPDATE ' . CHAT_USERS_TABLE . '
                  SET user_lastjoin = ' . $sql_ary['message_time'] . ', user_online = 1
                  WHERE user_key = ' . $this->user_key;
               $db->sql_query($sql);

               // Refresh the chat
               return $this->run('refresh_after_post');
            }
         break;
         
         case 'quote':
            if($this->auth('post') && $config['chat_allow_bbcode'] && !in_array('quote', $chat->disallowed_bbcodes))
            {
               $sql = 'SELECT m.poster_username, m.message_text, m.bbcode_uid, u.username
                  FROM ' . CHAT_MESSAGES_TABLE . ' m
                     LEFT JOIN ' . USERS_TABLE . ' u ON(u.user_id = m.poster_id AND u.user_type <> ' . USER_IGNORE . ')
                  WHERE m.message_id = ' . $message_id;
               $result = $db->sql_query($sql);
               $row = $db->sql_fetchrow($result);
               $db->sql_freeresult($result);
               
               if($row)
               {
                  decode_message($row['message_text'], $row['bbcode_uid']);

                  $new_text = '[quote=&quot;' . (($row['poster_username']) ? $row['poster_username'] : $row['username']) . '&quot;] ' . $row['message_text'] . ' [/quote]';
                  $template->assign_var('CUSTOM_PRINT', htmlspecialchars_decode($new_text));
               }
            }
         break;
         
         case 'rules':
            $rules = $chat->obtain_texts(CHAT_TEXT_RULE);

            foreach($rules as $rule_text)
            {
               $template->assign_block_vars('rulerow', array(
                  'S_TEXT'   => $rule_text,
               ));
            }

            $template->assign_vars(array(
               'S_RULES'   => true,
               'S_TITLE'   => $user->lang['CHAT_RULES'],
            ));
         break;
         
         case 'whois':
            if($this->auth('-u_viewprofile'))
            {
               $sql = 'SELECT poster_ip
                  FROM ' . CHAT_MESSAGES_TABLE . '
                  WHERE message_id = ' . $message_id;
               $result = $db->sql_query($sql);
               $poster_ip = (string)$db->sql_fetchfield('poster_ip');
               $db->sql_freeresult($result);

               if($poster_ip)
               {
                  if(!function_exists('user_ipwhois'))
                  {
                     include($phpbb_root_path . "includes/functions_user.$phpEx");
                  }

                  $ipwhois = trim(user_ipwhois($poster_ip));

                  $template->assign_vars(array(
                     'S_DIALOG_CONTENT'   => (($ipwhois) ? $ipwhois : $user->lang['CHAT_NO_INFORMATION']),
                     'S_TITLE'         => $user->lang['WHOIS'],
                  ));
               }
            }
         break;
         
         case 'banuser':
         case 'unbanuser':
            if(!$this->get_current_user())
            {
               break;
            }

            if($submit || $action == 'unbanuser')
            {
               $user_key       = request_var('uk', 0);
               $period_time   = request_var('period', 0);
               $period_date   = request_var('date', '');
               $exclude_time   = 0;
               $row_users       = array();

               $sql = 'SELECT cu.*, u.username AS member_name, u.user_type, u.user_colour
                  FROM ' . CHAT_USERS_TABLE . ' cu
                     LEFT JOIN ' . USERS_TABLE . " u ON(u.user_id = cu.user_id)
                  WHERE cu.user_key = $user_key";
               $result = $db->sql_query($sql);
               $user_data = $db->sql_fetchrow($result);
               $db->sql_freeresult($result);

               if(!$user_data)
               {
                  break;
               }

               if($action == 'banuser')
               {
                  switch($period_time)
                  {
                     case 0:
                        if(preg_match('#^(\w{2})\/(\w{2})\/(\d{4}) (\w{2})\:(\w{2})\:(\w{2})#', $period_date, $match))
                        {
                           if(($exclude_time = @strtotime(vsprintf('%4$s:%3$s:%2$s %5$s:%6$s:%7$s', $match))) <= time())
                           {
                              $exclude_time = 0;
                           }
                        }
                     break;

                     case 1:
                        $exclude_time = 1;
                     break;

                     default:
                        $exclude_time = time() + $period_time;
                     break;
                  }
                  
                  if(!$user_key || !$exclude_time || $user_key == $this->user_key)
                  {
                     break;
                  }
               }

               $sql = 'UPDATE ' . CHAT_USERS_TABLE . "
                  SET exclude_time = $exclude_time
                  WHERE user_key = $user_key";
               $result = $db->sql_query($sql);

               if($db->sql_affectedrows($result))
               {
                  $user_data['exclude_time'] = $exclude_time;

                  if($user_data['user_id'] != ANONYMOUS)
                  {
                     $user_data['username'] = $user_data['member_name'];
                  }

                  $row_users[$user_data['user_key']] = $user_data;

                  $template->assign_block_vars('room', array(
                     'ID'      => 'temp_room',
                     'S_TITLE'   => 'temp',
                  ));

                  $this->generate_userlist($row_users);

                  $json = array_merge($json, array(
                     'action'   => $action,
                     'user_key'   => $user_key
                  ));
               }
               break;
            }
            
            if($action == 'banuser')
            {
               $option_ary = array(
                  1         => 'PERMANENT',
                  1800      => 'HALF_AN_HOUR',
                  3600      => 'ONE_HOUR',
                  86400      => 'ONE_DAY',
                  604800      => 'ONE_WEEK',
                  2592000      => 'ONE_MONTH',
                  31104000   => 'ONE_YEAR',
                  0         => 'CUSTOM_DATE',
               );

               $option_str = '';

               foreach($option_ary as $value => $title)
               {
                  $option_str .= '<option value="' . $value . '">' . $user->lang($title) . '</option>';
               }

               $template->assign_vars(array(
                  'S_BAN'            => true,
                  'S_PERIOD_OPTIONS'   => $option_str,
                  'S_TITLE'         => $user->lang['CHAT_BAN_USER'],
               ));
            }
         break;
         
         case 'pmuser':
            if(!$this->get_current_user())
            {
               break;
            }
            
            $row_users   = array();
            $user_key   = request_var('uk', 0);
            
            $sql = 'SELECT cu.*, u.username AS member_name, u.user_type, u.user_colour
               FROM ' . CHAT_USERS_TABLE . ' cu
                  LEFT JOIN ' . USERS_TABLE . ' u ON(u.user_id = cu.user_id AND u.user_id <> ' . ANONYMOUS . ')
               WHERE ' . $db->sql_in_set('cu.user_key', array($user_key, $this->user_key));
            $result = $db->sql_query($sql);
            while($row = $db->sql_fetchrow($result))
            {
               if($row['user_id'] != ANONYMOUS)
               {
                  $row['username'] = $row['member_name'];
               }
               
               $row_users[$row['user_key']] = $row;
            }
            $db->sql_freeresult($result);
            
            $template->assign_block_vars('room', array(
               'ID'      => $user_key,
               'S_TITLE'   => $row_users[$user_key]['username'],
            ));
            
            // Users
            $this->generate_userlist($row_users);
         break;
         
         case 'close_room':
            $room_key = request_var('rk', 0);
            
            if(!$this->get_current_user())
            {
               $json['success'] = false;
               break;
            }
            
            // Delete room messages
            $sql = 'DELETE FROM ' . CHAT_MESSAGES_TABLE . '
               WHERE ((poster_key = ' . $this->user_key . ' AND dest_key = ' . $room_key . ')
               OR (poster_key = ' . $room_key . ' AND dest_key = ' . $this->user_key . '))
               AND dest_key <> ' . CHAT_GUEST_ROOM;
            $db->sql_query($sql);
         break;
      }

      $template->assign_var('S_JSON', json_encode($json));
      
      if((in_array($action, array('login', 'edit', 'rules', 'whois', 'banuser'))) && !$submit)
      {
         $template->assign_var('S_DIALOG', true);
      }

      $template->set_filenames(array(
         'body' => 'chat/chat_ajax.html'
      ));

      $template->display('body');
      
      garbage_collection();
      exit_handler();
   }
   
   function generate_userlist($row_users, $user_cache = false, $room_key = false)
   {
      global $user, $config, $template, $phpbb_root_path, $phpEx;

      $rows = array();

      foreach($row_users as $user_key => $row)
      {
         $row_actions = array();
         
         if($room_key !== false && $room_key != CHAT_GUEST_ROOM && !in_array($user_key, array($room_key, $this->user_key)))
         {
            continue;
         }
         
         if(!$this->auth('-m_ban') && $row['exclude_time'])
         {
            continue;
         }

         if($user_cache !== false && $row['user_id'] != ANONYMOUS && isset($user_cache[$user_key]))
         {
            $row = array_merge($row, $user_cache[$user_key]);
         }
         
         if($row['user_id'] != ANONYMOUS && !$row['session_viewonline'])
         {
            if(!$this->auth('-u_viewonline') && $user_key != $this->user_key)
            {
               continue;
            }
            
            $row['username'] = '<em>' . $row['username'] . '</em>';
         }

         if($user_key != $this->user_key)
         {
            foreach($this->actions as $user_action => $action_data)
            {
               $u_action    = '';
               $u_data      = $user_action . '/' . $user_key;
               
               if(isset($action_data['check']) && empty($config[$action_data['check']]))
               {
                  continue;
               }
               
               if($this->auth('-' . $action_data['auth']))
               {
                  $founder_case    = false;
                  $valid          = true;
                  
                  if(!empty($row['user_type']) && $row['user_type'] == USER_FOUNDER && $user->data['user_type'] != USER_FOUNDER)
                  {
                     $founder_case = true;
                  }

                  switch($user_action)
                  {
                     case 'banuser':
                        if($founder_case)
                        {
                           $valid = false;
                           break;
                        }

                     // no break

                     case 'pmuser':
                        if($row['exclude_time'])
                        {
                           $valid = false;
                        }
                     break;
                     
                     case 'deluser':
                        if($row['user_id'] == ANONYMOUS || $founder_case)
                        {
                           $valid = false;
                           break;
                        }

                        $u_action    = append_sid($phpbb_root_path . "adm/index.$phpEx", 'i=users&amp;mode=overview&amp;u=' . $row['user_id'], true, $user->session_id);
                        $u_data      = '';
                     break;
                     
                     case 'unbanuser':
                        if(!$row['exclude_time'])
                        {
                           $valid = false;
                        }
                     break;
                  }
                  
                  if($valid)
                  {
                     $row_actions[] = array(
                        'S_ACTION'   => $user_action,
                        'S_TITLE'   => $user->lang[$action_data['lang']],
                        'U_ACTION'   => $u_action . (($u_data) ? '#!' . $u_data : ''),
                     );
                  }
               }
            }
         }
         
         $rows[strtolower($row['username'])] = array(
            'S_KEY'         => $user_key,
            'S_USERNAME'   => ($row['user_id'] == ANONYMOUS || $row['exclude_time']) ? $row['username'] : get_username_string('no_profile', $row['user_id'], $row['username'], $row['user_colour'], $row['username']),
            'IS_EXCLUDED'   => ($row['exclude_time']) ? true : false,
            'U_ACTION'      => ($row['user_id'] == ANONYMOUS) ? '#!user' : get_username_string('profile', $row['user_id'], $row['username'], $row['user_colour'], $row['username']) . '#!user/' . $row['user_id'],
            
            'S_HAS_SUBMENU'      => (sizeof($row_actions) ? true : false),
            'contextmenu'      => $row_actions,
         );
      }
      
      if(sizeof($rows))
      {
         ksort($rows);
         
         foreach($rows as $username => $row)
         {
            $template->assign_block_vars('room.user', $row);
         }
      }
   }
   
   function get_current_user($only_online = false)
   {
      global $user, $db;

      if(empty($this->user_data))
      {
         $sql = 'SELECT *
            FROM ' . CHAT_USERS_TABLE . '
            WHERE user_id = ' . $user->data['user_id'];
            
         if($user->data['user_id'] == ANONYMOUS)
         {
            $sql .= ' AND (user_key = ' . $this->user_key . "
               OR user_ip = '" . $user->ip . "')";
         }

         $result = $db->sql_query($sql);
         $this->user_data = $db->sql_fetchrow($result);
         $db->sql_freeresult($result);

         // Check for excluded guest user
         if(!$this->user_data && !$only_online && $user->data['user_id'] == ANONYMOUS)
         {
            $sql = 'SELECT *
               FROM ' . CHAT_USERS_TABLE . "
               WHERE exclude_time > 0
               AND (user_ip = '" . $user->ip . "'
               OR user_key = " . $this->user_key . ')';
            $result = $db->sql_query($sql);
            $this->user_data = $db->sql_fetchrow($result);
            $db->sql_freeresult($result);
         }
         
         if(!$this->user_data)
         {
            return false;
         }
         
         if($only_online)
         {
            if(!$this->user_data['user_online'] && $user->data['session_time'] > $this->user_data['user_lastjoin'])
            {
               $sql = 'UPDATE ' . CHAT_USERS_TABLE . '
                  SET user_online = 1, user_lastjoin = ' . time() . '
                  WHERE user_key = ' . $this->user_data['user_key'];
               $db->sql_query($sql);
               
               $this->user_data['user_online']      = 1;
               $this->user_data['user_lastjoin']   = time();
            }
            
            if(!$this->user_data['user_online'])
            {
               $this->user_data = false;
               return false;
            }
         }
         
         $this->user_key = $this->user_data['user_key'];
      }
      
      return true;
   }
   
   function strip_bbcode(&$message)
   {
      global $config, $chat;

      $bbcode_preg = '';
      
      if(!$config['chat_allow_bbcode'])
      {
         $bbcode_preg = '#\[\/?([a-z0-9\*\+\-]+).*?\]#i';
      }
      else if(sizeof($chat->disallowed_bbcodes))
      {
         $bbcode_preg = '#\[\/?(' . implode('|', array_map('preg_quote', $chat->disallowed_bbcodes)) . ').*?\]#i';
      }
      
      if($bbcode_preg)
      {
         $message = preg_replace($bbcode_preg, '', $message);
      }
   }
}

if(!function_exists('json_encode'))
{
   function json_encode($arr)
   {
      $parts      = array();
      $is_list   = false;
      $keys      = array_keys($arr);
      $max_length   = count($arr) - 1;

      // See if the first key is 0 and last key is length - 1
      if($keys[0] == 0 && $keys[$max_length] == $max_length)
      {
         $is_list = true;

         for($i = 0; $i < count($keys); $i++)
         {
            if($i != $keys[$i])
            {
               $is_list = false; // It is an associative array.
               break;
            }
         }
      }

      foreach($arr as $key => $value)
      {
         $str = (($is_list) ? '' : "'$key':");

         // Custom handling for arrays
         if(is_array($value))
         {
            $parts[] = $str . json_encode($value); // Recursion
         }
         else
         {
            // Custom handling for multiple data types
            if(is_numeric($value))
            {
               $str .= $value; // Numbers
            }
            else if($value === false)
            {
               $str .= 'false'; // The booleans
            }
            else if($value === true)
            {
               $str .= 'true';
            }
            else
            {
               $str .= '"' . addslashes($value) . '"'; // All other things
            }

            $parts[] = $str;
         }
      }

      $json = implode(',', $parts);

      // Return numerical JSON
      if($is_list)
      {
         return '[' . $json . ']';
      }

      // Return associative JSON
      return '{' . $json . '}';
   }
}
?>