Documentation is available at class.Chatter.inc
- <?php //-*-php-*-
- /* ******************************************************************** **
- ** Copyright notice **
- ** **
- ** (c) 1995-2003 PHPOpenChat Development Team **
- ** http://phpopenchat.sourceforge.net/ **
- ** **
- ** All rights reserved **
- ** **
- ** This script is part of the PHPOpenChat project. The PHPOpenChat **
- ** project is free software; you can redistribute it and/or modify **
- ** it under the terms of the GNU General Public License as published by **
- ** the Free Software Foundation; either version 2 of the License, or **
- ** (at your option) any later version. **
- ** **
- ** The GNU General Public License can be found at **
- ** http://www.gnu.org/copyleft/gpl.html. **
- ** A copy is found in the textfile GPL and important notices to the **
- ** license from the team is found in the textfile LICENSE distributed **
- ** with these scripts. **
- ** **
- ** This script is distributed in the hope that it will be useful, **
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of **
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
- ** GNU General Public License for more details. **
- ** **
- ** This copyright notice MUST APPEAR in all copies of the script! **
- ** ******************************************************************** */
- /** Get configuration settings */
- (POC_BASE.'/config.inc.php');
- require_once(POC_INCLUDE_PATH.'/class.Logger.inc');
- require_once(POC_INCLUDE_PATH.'/class.Channel.inc');
- /**
- * Class Chatter represents a person taking part in a chat session
- *
- * @package phpopenchat
- * @author Frerk Meyer <frerk@meychern.de>
- * @author Michael Oertel <michael@ortelius.de>
- * @access public
- * @version $Id: class.Chatter.inc,v 1.102 2004/05/27 09:16:51 jjaeschke Exp $
- */
- class Chatter
- {
- /**
- * every chatter is identified by a uniq nick name
- *
- * @var string
- */
- var $nick = '';
- /**
- * password of chatter
- *
- * @var string
- */
- var $password = '';
- var $password_new = '';
- /**
- * every chatter has an user name
- *
- * @var string
- */
- var $user = '';
- /**
- * user name
- *
- * @var string
- */
- var $name = '';
- /**
- * birthday of chatter
- *
- * @var string
- */
- var $birthday = '';
- /**
- * gender of chatter
- *
- * @var string
- */
- var $gender = '';
- /**
- * email of chatter
- *
- * @var string
- */
- var $email = '';
- /**
- * hide email
- *
- * @var boolean
- */
- var $hide_email = true;
- /**
- * A URL of a picture of chatter
- *
- * @var string
- */
- var $pictureURL = '';
- /**
- * A home page URL of chatter
- *
- * @var string
- */
- var $homePageURL = '';
- /**
- * Interests of chatter
- *
- * @var string
- */
- var $interests = '';
- /**
- * Motto of chatter
- *
- * @var string
- */
- var $motto = '';
- /**
- * A ICQ number of chatter
- *
- * @var integer
- */
- var $icqNumber = 0;
- /**
- * A AIM nickname of chatter
- *
- * @var string
- */
- var $aimNickname = '';
- /**
- * A YIM nickname of chatter
- *
- * @var string
- */
- var $yimNickname = '';
- /**
- * chatter grade
- *
- * @var string
- */
- var $grade = '';
- /**
- * chatter grade
- *
- * @var string
- */
- var $theme = DEFAULT_THEME;
- /**
- * chatter groups
- *
- * @var array
- */
- var $groups = array();
- /**
- * chatter disabled
- *
- * @var int
- */
- var $disabled = 0;
- /**
- * online time in seconds
- *
- * @var int
- */
- var $online_time = 0;
- /**
- * stores chatter objects of ignored chatters
- *
- * @var array
- */
- var $ignored_sender = array();
- /**
- * stores friends of chatter
- *
- * @var array
- */
- var $friends = array();
- /**
- * @var boolean
- * @access private
- */
- var $private = false;
- /**
- * @var boolean
- * @access private
- */
- var $halted = false;
- /**
- * @var boolean
- * @access private
- */
- var $bodies = false;
- /**
- * @var boolean
- * @access private
- */
- var $sys_msg = false;
- /**
- * @var string
- * @access public
- */
- var $color = '';
- /**
- * @var string
- * @access public
- */
- var $advice = null;
- /**
- * @var string
- * @access public
- */
- var $scrollspeed = -1;
- /**
- * @var string
- * @access public
- */
- var $regTime = '';
- /**
- * @var string
- * @access public
- */
- var $lastActive = '';
- /**
- * @var string
- * @access public
- */
- var $lastHost = '';
- /**
- * @var string
- * @access public
- */
- var $lastIP = '';
- /**
- * @var string
- * @access public
- */
- var $lastReferer = '';
- /**
- * @var string
- * @access public
- */
- var $lastUserAgent = '';
- /**
- * @var string
- * @access public
- */
- var $lastSessionId = '';
- /**
- * @var object
- * @access private
- * @see connect()
- */
- var $db;
- /**
- * @var boolean
- * @access private
- * @see check_user()
- */
- var $guest = false;
- /**
- * @var integer
- * @see connect()
- * @see disconnect()
- */
- var $connection_count = 0;
- /**
- * @var float
- */
- var $lines_per_day = 0;
- /**
- * @var float
- */
- var $logins_per_day = 0;
- /**
- * @var integer
- */
- var $days_registered = 0;
- /**
- * @var integer
- */
- var $db_instance_lifetime = 0;
- /**
- * @var array
- */
- var $unlocked_channels = array();
- /**
- * @var array
- */
- var $line_styles = array();
- /**
- * Constructor
- *
- * Implements a chat user
- * @desc Implements a chat user
- *
- * @param string $nick
- * @param string $password
- */
- function Chatter($user = null, $password = null )
- {
- if ( $_user = $this->check_user($user,$password) ) {
- $this->set_nick( $_user );
- if( $this->is_guest() )
- $this->register();
- $this->password = $password;
- } else {
- $this->nick = null;
- }
- }
- /**
- * Check if user name and it's account data are valid
- *
- * Return false if $user is not valid
- *
- * @param string
- * @param string
- * @return boolean
- */
- function check_user($user,$password)
- {
- //don't check if nick equals STATUS_BOT_NAME
- //note: chat users can't login as 'STATUS_BOT_NAME'
- if ( $user == strval(STATUS_BOT_NAME) )
- return STATUS_BOT_NAME;
- // nick names must be strings
- if (!isset($user))
- return '';
- // passwords can't be empty
- if ($password == '')
- {
- if( ALLOW_GUEST_LOGIN )
- {
- $this->guest = true;
- $guest_nickname = '###GUEST_NICK_PREFIX###'.'_'.rand(10000,99999);
- return $guest_nickname;
- }
- else
- return '';
- }
- // nick names must be strings
- if (!is_string($user))
- return '';
- // nick names are no longer than 16 characters
- if (strlen($user) > NICKNAME_MAX_LENGTH)
- return '';
- // nick names start with a character and go on with alphanumeric
- // Attention: Spaces are allowed
- if (!eregi("^[[:alpha:]]+[[:alnum:]]*",$user))
- return '';
- // the given password must match with the db-password
- return $this->is_authorized($user, $password);
- }
- /**
- * Provides the status of chatter
- *
- * @access public
- * @return boolean
- */
- function is_moderator()
- {
- return in_array('moderator', $this->groups);
- }
- /**
- * Provides the status of chatter
- *
- * @access public
- * @return boolean
- */
- function is_vip()
- {
- return in_array('vip', $this->groups);
- }
- /**
- * Provides the status of chatter
- *
- * @access public
- * @return boolean
- */
- function is_kicked()
- {
- $this->connect();
- $rs = $this->db->Execute( 'SELECT DISABLED FROM poc_user_account WHERE USER=\''.$this->user.'\'');
- $status = intval($rs->fields[0]);
- $rs->Close();
- $this->disconnect();
- return ($status === 1 );
- }
- function is_disabled()
- {
- return $this-is_kicked();
- }
- /**
- * Provides the online status of chatter
- *
- * @access public
- * @return boolean
- */
- function is_online()
- {
- $this->connect();
- $rs = $this->db->Execute( 'SELECT ONLINE FROM poc_user_data WHERE USER=\''.$this->user.'\'');
- $status = intval($rs->fields[0]);
- $rs->Close();
- $this->disconnect();
- return ($status === 1 );
- }
- /**
- * Provides the status of chatter
- *
- * @access public
- * @return boolean
- */
- function is_banned( $channel )
- {
- $this->connect();
- $rs = $this->db->Execute( 'SELECT TIME_BANNED FROM poc_banned_users WHERE USER=\''.$this->user.'\' AND TIME_BANNED >= '.$this->db->DBTimeStamp(time()).' AND BANNED_FOR=\''.$channel.'\'');
- $status = ( $rs->RecordCount() >= 1 );
- $rs->Close();
- $this->disconnect();
- return $status;
- }
- /**
- * Banishment of chatter
- *
- * @access public
- * @return boolean
- */
- function ban( $channel, $period )
- {
- if( $this->is_banned($channel) ) return null;
- $this->count_hit('bann');
- $this->connect();
- $rs = $this->db->Execute( 'DELETE FROM poc_banned_users WHERE USER = \''. $this->user .'\' AND BANNED_FOR = \''.$channel.'\'' );
- $rs = $this->db->Execute( 'SELECT USER,BANNED_FOR,TIME_BANNED FROM poc_banned_users WHERE USER = \''. $this->user .'\'' );
- $record = array();
- $record[ 'TIME_BANNED' ] = $this->db->DBTimeStamp( (time() + (intval($period) * 60)) );
- $record[ 'BANNED_FOR' ] = $channel;
- $record[ 'USER' ] = $this->user;
- $insert_sql = $this->db->GetInsertSQL( $rs, $record );
- $insert_sql = preg_replace('/\'\'/','\'',$insert_sql);
- //Insert the records into the database
- $status = $this->db->Execute( $insert_sql );
- $this->disconnect();
- unset($record);
- unset($insert_sql);
- unset($rs);
- return $status;
- }
- /**
- * Changes the channel
- *
- */
- function join_channel( $post_channel, $private_new_window = false )
- {
- $prefix = ($private_new_window)? abs(crc32($post_channel)).'_':'';
- $bot = &new Chatter(strval(STATUS_BOT_NAME),'');
- if(!$private_new_window)
- {
- //chatter want's to change the channel
- //we have to say goodbye in the old channel first»
- //$said = $_SESSION['chatter']->get_nick().' ###LEAVES_THIS_CHANNEL### <!--'.rand(0,15).'-->';
- $said = $_SESSION['chatter']->get_nick().htmlentities(' ###LEAVES_THIS_CHANNEL### ');
- $said .= htmlentities(' ###GOES_TO_CHANNEL### ').$post_channel;
- $bot = &new Chatter(strval(STATUS_BOT_NAME),'');
- $line = &new Line($bot, $said);
- $line->set_leave($_SESSION['chatter']->get_nick());
- $_SESSION['channel_buffer']->connect();
- $_SESSION['channel_buffer']->put_line($line);
- $_SESSION['channel_buffer']->disconnect();
- }
- //create the new channel object and write it into the session
- //because of a critical bug: http://bugs.php.net/bug.php?id=18071
- //do stupid things to register a new channel object in session
- //if bug is fixed, use:
- //$_SESSION[$prefix.'channel_buffer'] = &new Channel_Buffer(strval($post_channel));
- //$_SESSION[$prefix.'channel'] = &new Channel(strval($post_channel));
- //change buffer
- if(function_exists('session_unregister')) {
- @session_unregister($prefix.'channel_buffer');
- }
- if(function_exists('session_register')) {
- session_register($prefix.'channel_buffer');
- }
- ${$prefix.'channel_buffer'} = &new Channel_Buffer($post_channel);
- $_SESSION[$prefix.'channel_buffer'] = ${$prefix.'channel_buffer'};
- //change channel
- if(function_exists('session_unregister')) {
- @session_unregister($prefix.'channel');
- }
- if(function_exists('session_register')) {
- session_register($prefix.'channel');
- }
- ${$prefix.'channel'} = &new Channel($post_channel);
- $_SESSION[$prefix.'channel'] = ${$prefix.'channel'};
- //get current line index
- $_SESSION[$prefix.'channel_buffer']->connect();
- ${$prefix.'lastRedLine'} = $_SESSION[$prefix.'channel_buffer']->get_cur_line_idx();
- $_SESSION[$prefix.'channel_buffer']->disconnect();
- $_SESSION[$prefix.'lastRedLine'] = ${$prefix.'lastRedLine'};
- if(!$private_new_window){
- $_SESSION['chatter']->go_online($post_channel);
- //$_SESSION['chatter']->get_db_groups($post_channel);
- /*
- * Update JavaScript array in frameset.tpl of operators of current channel
- */
- if( isset($_SESSION['chat']) ) {
- $_SESSION['chat']->connect();
- $members = $_SESSION['chat']->get_group_members('operator', $post_channel);
- $_SESSION['chat']->disconnect();
- $csv_members = '';
- if( is_array($members) && count($members) > 0 ) {
- reset($members);
- do{
- $csv_members .= ',"'.current($members).'"';
- }while( next($members) );
- $csv_members = substr_replace($csv_members,'',0,1);
- }
- } else {
- $_SESSION['logger']->warning('$_SESSION[\'chat\'] doesn\'t exists.', __FILE__, __LINE__ - 9 );
- }
- unset($members);
- $operator_label =(isset($_SESSION['chatter'])&&$_SESSION['chatter']->is_operator())? OPERATOR_LABEL:'';
- //the chatter has changed the channel, so we have to update the JS array in the frameset containing all operators of current channel
- //
- $_SESSION['chat']->write_sys_msg( '<script type="text/javascript">parent.operators = new Array('.$csv_members.');parent.operator_label="'.$operator_label.'"<\/script>',$_SESSION['chatter'], true, true );
- //$_SESSION['chat']->write_sys_msg( 'debug: ',$_SESSION['chatter'], true );
- unset($csv_members);
- unset($operator_label);
- }
- //now we have to say hello in the new channel«
- $said = $_SESSION['chatter']->get_nick().htmlentities(' ###JOINS_THIS_CHANNEL### "').$_SESSION[$prefix.'channel']->get_name().'"';
- $line = &new Line($bot, $said);
- $line->set_login($_SESSION['chatter']->get_nick());
- $_SESSION[$prefix.'channel_buffer']->connect();
- $_SESSION[$prefix.'channel_buffer']->put_line($line);
- $_SESSION[$prefix.'channel_buffer']->disconnect();
- if( $_SESSION[$prefix.'channel']->get_message() != '' )
- $_SESSION['chat']->write_sys_msg( '<br />'.$_SESSION[$prefix.'channel']->get_message(),$_SESSION['chatter'], true );
- unset($bot);
- unset($said);
- unset($line);
- unset($prefix);
- }
- /* function is_authorized_for( $channel )
- {
- if( !$_SESSION['channel']->is_password_protected() ) return true;
- return ( in_array($channel,$this->unlocked_channels ) );
- } */
- function is_authorized_for( $channel )
- {
- $chnl =& new Channel($channel);
- if ( ! $chnl->get_name() ) {
- return(false);
- }
- if( !$chnl->is_password_protected() ) return true;
- return ( in_array($channel,$this->unlocked_channels ) );
- }
- function unlock_channel( $channel )
- {
- if( !is_string($channel) ) die('String expected');
- $this->unlocked_channels[] = $channel;
- }
- function lock_channel ($channel) {
- if( !is_string($channel) ) die('String expected');
- // assure duplicates are removed, too
- while ( false !== $key = array_search ($channel, $this->unlocked_channels) ) {
- unset ($this->unlocked_channels[$key]);
- }
- }
- /**
- * Provides the status of chatter
- *
- * @access public
- * @return boolean
- */
- function is_operator()
- {
- return in_array('operator', $this->groups);
- }
- /**
- * Connect to the database
- *
- * Establish a database connection
- *
- * @access public
- */
- function connect( $force_reconnect = false )
- {
- if( !$force_reconnect && ++$this->connection_count > 1 )
- return null;
- if( $force_reconnect && is_object($this->db) ) {
- $this->db->Close();
- unset($this->db);
- }
- //create a database object
- $this->db = &NewADOConnection( DATABASE_DRIVER );
- if( USE_PCONNECT )
- $this->db->PConnect( DATABASE_HOST, DATABASE_USER, DATABASE_PASSWORD, DATABASE_TABLESPACE );
- else
- $this->db->Connect( DATABASE_HOST, DATABASE_USER, DATABASE_PASSWORD, DATABASE_TABLESPACE );
- return true;
- }
- /**
- * Disconnect the database
- *
- * @access public
- * @see connect()
- */
- function disconnect()
- {
- if( --$this->connection_count == 0 )
- {
- $this->db->Close();
- /*
- * NOTE: a db->Close() will be not enough! without setting $this->db to null,
- * PHP 4.2.1 can't serialize the object $line ( see Channel_Buffer_DB::put_line() )
- * who contains a chatter object.
- */
- $this->db = null;
- return true;
- }
- return false;
- }
- /**
- * Sets chatter status to online
- *
- * @access public
- * @see go_offline()
- * @param string
- */
- function go_online( $channel )
- {
- $this->connect();
- $rs = $this->db->Execute( 'SELECT ONLINE,LAST_CHANNEL,LAST_ACTIVE_TIME,LAST_HOST,LAST_IP,LAST_USER_AGENT,LAST_SESSIONID,LAST_REFERER FROM poc_user_data WHERE NICK = \''. $this->nick .'\'' );
- $record = array();
- $record[ 'ONLINE' ] = 1;
- $record[ 'LAST_CHANNEL' ] = $channel;
- //$record[ 'LAST_ACTIVE_TIME' ] = date( "Y-m-d H:i:s", time() );
- $record[ 'LAST_ACTIVE_TIME' ] = $this->db->DBTimeStamp( time() );
- if ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '' )
- {
- $record[ 'LAST_HOST' ] = @gethostbyaddr( $_SERVER['HTTP_X_FORWARDED_FOR'] );
- $record[ 'LAST_IP' ] = $_SERVER['HTTP_X_FORWARDED_FOR'];
- }
- else
- {
- $record[ 'LAST_HOST' ] = @gethostbyaddr($_SERVER['REMOTE_ADDR']);
- $record[ 'LAST_IP' ] = $_SERVER['REMOTE_ADDR'];
- }
- $this->lastIP = (isset($record[ 'LAST_IP' ]) && $record[ 'LAST_IP' ] != '')? $record[ 'LAST_IP' ]:'-';
- $record[ 'LAST_USER_AGENT' ] = $_SERVER['HTTP_USER_AGENT'];
- $record[ 'LAST_SESSIONID' ] = session_id();
- if( $_SESSION['chat']->get_referer() != '' )
- $record[ 'LAST_REFERER' ] = $_SESSION['chat']->get_referer();
- $update_sql = $this->db->GetUpdateSQL( $rs, $record );
- $update_sql = preg_replace('/\'\'/','\'',$update_sql);
- //Insert the records into the database
- if( !$this->db->Execute( $update_sql ) )
- $_SESSION['logger']->error('DB-Update failed. SQL: "'.$update_sql.'"', __FILE__, __LINE__);
- $_SESSION['logger']->info('login '. $this->nick );
- $this->groups = $this->get_db_groups($channel);
- $this->disconnect();
- unset($record);
- unset($update_sql);
- unset($rs);
- }
- /**
- * Refreshs chatter's online time
- *
- * @access public
- * @see go_online()
- * @param string
- */
- function refresh()
- {
- $this->connect();
- $rs = $this->db->Execute( 'SELECT LAST_ACTIVE_TIME,ONLINE_TIME FROM poc_user_data WHERE USER = \''. $this->user .'\'' );
- $online_time = $rs->fields[1];
- $this->set_online_time((intval(LINE_POLLING_INTERVAL) * 2) + $online_time);
- $record = array();
- //$record[ 'LAST_ACTIVE_TIME' ] = date( "Y-m-d H:i:s", time() );//SQL92 date format
- $record[ 'LAST_ACTIVE_TIME' ] = $this->db->DBTimeStamp( time() );
- $record[ 'ONLINE_TIME' ] = (intval(LINE_POLLING_INTERVAL) * 2) + $online_time;
- unset($online_time);
- $update_sql = $this->db->GetUpdateSQL( $rs, $record );
- $update_sql = preg_replace('/\'\'/','\'',$update_sql);//DBTimeStamp and GetUpdateSQL quotes time-strings and so we have to remove the double single quotes
- //Insert the records into the database
- if( !$this->db->Execute( $update_sql ) )
- $_SESSION['logger']->error('DB-Update failed. SQL: "'.$update_sql.'"', __FILE__, __LINE__);
- $this->disconnect();
- unset($record);
- unset($update_sql);
- unset($rs);
- }
- /**
- * Sets chatter's online time
- *
- * @access public
- * @see refresh()
- * @param integer
- */
- function set_online_time( $time )
- {
- $this->online_time = $time;
- }
- /**
- * Provides chatter's online time
- *
- * @access public
- * @return integer
- */
- function get_online_time()
- {
- return $this->online_time;
- }
- /**
- * Provides chatter's online time from DB
- *
- * @access public
- * @return integer
- */
- function get_db_online_time()
- {
- $this->connect();
- $rs = $this->db->Execute(