" . myiconv($webim_encoding, "utf-8", escape_with_cdata(getstring("agent.not_logged_in"))) . ""; exit; } $threadstate_to_string = array( $state_queue => "wait", $state_waiting => "prio", $state_chatting => "chat", $state_closed => "closed", $state_loading => "wait", $state_left => "closed" ); $threadstate_key = array( $state_queue => "chat.thread.state_wait", $state_waiting => "chat.thread.state_wait_for_another_agent", $state_chatting => "chat.thread.state_chatting_with_agent", $state_closed => "chat.thread.state_closed", $state_loading => "chat.thread.state_loading" ); function thread_to_xml($thread) { global $state_chatting, $threadstate_to_string, $threadstate_key, $webim_encoding, $operator, $can_viewthreads, $can_takeover; $state = $threadstate_to_string[$thread['istate']]; $result = ""; $state = getstring($threadstate_key[$thread['istate']]); $nextagent = $thread['nextagent'] != 0 ? operator_by_id($thread['nextagent']) : null; $threadoperator = $nextagent ? get_operator_name($nextagent) : ($thread['agentName'] ? $thread['agentName'] : "-"); if ($threadoperator == "-" && $thread['groupname']) { $threadoperator = "- " . $thread['groupname'] . " -"; } if (!($thread['istate'] == $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['unix_timestamp(dtmmodified)'] . "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, $state_closed, $state_left; $db = Database::getInstance(); $revision = $since; $query = "select threadid, userName, agentName, unix_timestamp(dtmcreated), userTyping, " . "unix_timestamp(dtmmodified), lrevision, istate, remote, nextagent, agentId, " . "userid, shownmessageid, userAgent, (select vclocalname from {chatgroup} where {chatgroup}.groupid = {chatthread}.groupid) as groupname " . "from {chatthread} where lrevision > :since " . ($since <= 0 ? "AND istate <> {$state_closed} AND istate <> {$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_to_xml($row); $output[] = $thread; if ($row['lrevision'] > $revision) $revision = $row['lrevision']; } 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['unix_timestamp(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['unix_timestamp(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, $state_closed, $state_left; $db = Database::getInstance(); // Remove old visitors $db->query( "DELETE FROM {chatsitevisitor} " . "WHERE (UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(lasttime)) > ? ". "AND (threadid IS NULL OR " . "(SELECT count(*) FROM {chatthread} WHERE threadid = {chatsitevisitor}.threadid " . "AND istate <> {$state_closed} AND istate <> {$state_left}) = 0)", array(Settings::get('tracking_lifetime')) ); // Remove old invitations $db->query( "UPDATE {chatsitevisitor} SET invited = 0, invitationtime = NULL, invitedby = NULL". " WHERE threadid IS NULL AND (UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(invitationtime)) > ?", array(Settings::get('invitation_lifetime')) ); // 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 <> {$state_closed} AND istate <> {$state_left}) = 0" ); // Remove old visitors' tracks $db->query( "DELETE FROM {visitedpage} WHERE (UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(visittime)) > ? " . " AND visitorid NOT IN (SELECT visitorid FROM {chatsitevisitor})", array(Settings::get('tracking_lifetime')) ); $query = "SELECT visitorid, userid, username, unix_timestamp(firsttime), unix_timestamp(lasttime), " . "entry, details, invited, unix_timestamp(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']); } close_old_threads(); $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; ?>