" . myiconv($webim_encoding, "utf-8", escape_with_cdata(getstring("agent.not_logged_in"))) . ""; exit; } $threadstate_to_string = array( Thread::STATE_QUEUE => "wait", Thread::STATE_WAITING => "prio", Thread::STATE_CHATTING => "chat", Thread::STATE_CLOSED => "closed", Thread::STATE_LOADING => "wait", Thread::STATE_LEFT => "closed" ); $threadstate_key = array( Thread::STATE_QUEUE => "chat.thread.state_wait", Thread::STATE_WAITING => "chat.thread.state_wait_for_another_agent", Thread::STATE_CHATTING => "chat.thread.state_chatting_with_agent", Thread::STATE_CLOSED => "chat.thread.state_closed", Thread::STATE_LOADING => "chat.thread.state_loading" ); function thread_to_xml($thread_info) { global $threadstate_to_string, $threadstate_key, $webim_encoding, $operator, $can_viewthreads, $can_takeover; $thread = $thread_info['thread']; $state = $threadstate_to_string[$thread->state]; $result = "id . "\" stateid=\"$state\""; if ($state == "closed") return $result . "/>"; $state = getstring($threadstate_key[$thread->state]); $nextagent = $thread->nextAgent != 0 ? operator_by_id($thread->nextAgent) : null; $threadoperator = $nextagent ? get_operator_name($nextagent) : ($thread->agentName ? $thread->agentName : "-"); if ($threadoperator == "-" && $thread_info['groupname']) { $threadoperator = "- " . $thread_info['groupname'] . " -"; } if (!($thread->state == Thread::STATE_CHATTING && $thread->agentId != $operator['operatorid'] && !is_capable($can_takeover, $operator))) { $result .= " canopen=\"true\""; } if ($thread->agentId != $operator['operatorid'] && $thread->nextAgent != $operator['operatorid'] && is_capable($can_viewthreads, $operator)) { $result .= " canview=\"true\""; } if (Settings::get('enableban') == "1") { $result .= " canban=\"true\""; } $banForThread = Settings::get('enableban') == "1" ? ban_for_addr($thread->remote) : false; if ($banForThread) { $result .= " ban=\"blocked\" banid=\"" . $banForThread['banid'] . "\""; } $result .= " state=\"$state\" typing=\"" . $thread->userTyping . "\">"; $result .= ""; if ($banForThread) { $result .= htmlspecialchars(getstring('chat.client.spam.prefix')); } $result .= htmlspecialchars( htmlspecialchars(get_user_name($thread->userName, $thread->remote, $thread->userId)) ) . ""; $result .= "" . htmlspecialchars(get_user_addr($thread->remote)) . ""; $result .= "" . htmlspecialchars(htmlspecialchars($threadoperator)) . ""; $result .= ""; $result .= "" . $thread->modified . "000"; if ($banForThread) { $result .= "" . $banForThread['comment'] . ""; } $userAgent = get_useragent_version($thread->userAgent); $result .= "" . $userAgent . ""; if ($thread->shownMessageId != 0) { $db = Database::getInstance(); $line = $db->query( "select tmessage from {chatmessage} where messageid = ?", array($thread->shownMessageId), array('return_rows' => Database::RETURN_ONE_ROW) ); if ($line) { $message = preg_replace("/[\r\n\t]+/", " ", $line["tmessage"]); $result .= "" . htmlspecialchars(htmlspecialchars($message)) . ""; } } $result .= ""; return $result; } function print_pending_threads($groupids, $since) { global $webim_encoding; $db = Database::getInstance(); $revision = $since; $query = "select {chatthread}.*, " . "(select vclocalname from {chatgroup} where {chatgroup}.groupid = {chatthread}.groupid) as groupname " . "from {chatthread} where lrevision > :since " . ($since <= 0 ? "AND istate <> " . Thread::STATE_CLOSED . " AND istate <> " . Thread::STATE_LEFT . " " : "") . (Settings::get('enablegroups') == '1' ? "AND (groupid is NULL" . ($groupids ? " OR groupid IN ($groupids) OR groupid IN (SELECT parent FROM {chatgroup} WHERE groupid IN ($groupids)) " : "") . ") " : "") . "ORDER BY threadid"; $rows = $db->query( $query, array(':since' => $since), array('return_rows' => Database::RETURN_ALL_ROWS) ); $output = array(); foreach ($rows as $row) { $thread = Thread::createFromDbInfo($row); $thread_info = array( 'thread' => $thread, 'groupName' => $row['groupname'] ); $thread_as_xml = thread_to_xml($thread_info); $output[] = $thread_as_xml; if ($thread->lastRevision > $revision) { $revision = $thread->lastRevision; } } echo ""; foreach ($output as $thr) { print myiconv($webim_encoding, "utf-8", $thr); } echo ""; } function print_operators($operator) { global $webim_encoding; echo ""; $list_options = in_isolation($operator)?array('isolated_operator_id' => $operator['operatorid']):array(); $operators = get_operators_list($list_options); foreach ($operators as $operator) { if (!operator_is_online($operator)) continue; $name = myiconv($webim_encoding, "utf-8", htmlspecialchars(htmlspecialchars($operator['vclocalename']))); $away = operator_is_away($operator) ? " away=\"1\"" : ""; echo ""; } echo ""; } function visitor_to_xml($visitor) { $result = ""; // $result .= "" . htmlspecialchars($visitor['userid']) . ""; $result .= "" . htmlspecialchars($visitor['username']) . ""; $result .= ""; $result .= "" . $visitor['lasttime'] . "000"; // $result .= "" . htmlspecialchars($visitor['entry']) . ""; // $result .= ""; // $path = track_retrieve_path($visitor); // ksort($path); // foreach ($path as $k => $v) { // $result .= "" . htmlspecialchars($v) . ""; // } // $result .= ""; $details = track_retrieve_details($visitor); $userAgent = get_useragent_version($details['user_agent']); $result .= "" . $userAgent . ""; $result .= "" . htmlspecialchars(get_user_addr($details['remote_host'])) . ""; $result .= "" . $visitor['invitations'] . ""; $result .= "" . $visitor['chats'] . ""; $result .= ""; if ($visitor['invited']) { $result .= "" . $visitor['invitationtime'] . "000"; $operator = get_operator_name(operator_by_id($visitor['invitedby'])); $result .= "" . htmlspecialchars(htmlspecialchars($operator)) . ""; } $result .= ""; $result .= ""; return $result; } function print_visitors() { global $webim_encoding; $db = Database::getInstance(); // Remove old visitors $db->query( "DELETE FROM {chatsitevisitor} " . "WHERE (:now - lasttime) > :lifetime ". "AND (threadid IS NULL OR " . "(SELECT count(*) FROM {chatthread} WHERE threadid = {chatsitevisitor}.threadid " . "AND istate <> " . Thread::STATE_CLOSED . " AND istate <> " . Thread::STATE_LEFT . ") = 0)", array( ':lifetime' => Settings::get('tracking_lifetime'), ':now' => time() ) ); // Remove old invitations $db->query( "UPDATE {chatsitevisitor} SET invited = 0, invitationtime = NULL, invitedby = NULL". " WHERE threadid IS NULL AND (:now - invitationtime) > :lifetime", array( ':lifetime' => Settings::get('invitation_lifetime'), ':now' => time() ) ); // Remove associations of visitors with closed threads $db->query( "UPDATE {chatsitevisitor} SET threadid = NULL WHERE threadid IS NOT NULL AND" . " (SELECT count(*) FROM {chatthread} WHERE threadid = {chatsitevisitor}.threadid" . " AND istate <> " . Thread::STATE_CLOSED . " AND istate <> " . Thread::STATE_LEFT . ") = 0" ); // Remove old visitors' tracks $db->query( "DELETE FROM {visitedpage} WHERE (:now - visittime) > :lifetime " . " AND visitorid NOT IN (SELECT visitorid FROM {chatsitevisitor})", array( ':lifetime' => Settings::get('tracking_lifetime'), ':now' => time() ) ); $query = "SELECT visitorid, userid, username, firsttime, lasttime, " . "entry, details, invited, invitationtime, invitedby, invitations, chats " . "FROM {chatsitevisitor} " . "WHERE threadid IS NULL " . "ORDER BY invited, lasttime DESC, invitations"; $query .= (Settings::get('visitors_limit') == '0') ? "" : " LIMIT " . Settings::get('visitors_limit'); $rows = $db->query($query, NULL, array('return_rows' => Database::RETURN_ALL_ROWS)); $output = array(); foreach ($rows as $row) { $visitor = visitor_to_xml($row); $output[] = $visitor; } echo ""; foreach ($output as $thr) { print myiconv($webim_encoding, "utf-8", $thr); } echo ""; } $since = verifyparam("since", "/^\d{1,9}$/", 0); $status = verifyparam("status", "/^\d{1,2}$/", 0); $showonline = verifyparam("showonline", "/^1$/", 0); $showvisitors = verifyparam("showvisitors", "/^1$/", 0); if (!isset($_SESSION["${mysqlprefix}operatorgroups"])) { $_SESSION["${mysqlprefix}operatorgroups"] = get_operator_groupslist($operator['operatorid']); } Thread::closeOldThreads(); $groupids = $_SESSION["${mysqlprefix}operatorgroups"]; start_xml_output(); echo ''; if ($showonline) { print_operators($operator); } print_pending_threads($groupids, $since); if ($showvisitors) { print_visitors(); } echo ''; notify_operator_alive($operator['operatorid'], $status); exit; ?>