mirror of
https://github.com/Mibew/design.git
synced 2025-01-22 18:10:33 +03:00
Calculate threads and operator statistics by cron
This commit is contained in:
parent
67de68b28b
commit
6ad1828079
@ -31,6 +31,7 @@ set_time_limit(0);
|
|||||||
|
|
||||||
// Run cron jobs of the core
|
// Run cron jobs of the core
|
||||||
cron_index_messages();
|
cron_index_messages();
|
||||||
|
cron_calculate_statistics();
|
||||||
|
|
||||||
// Trigger cron event
|
// Trigger cron event
|
||||||
$dispatcher = EventDispatcher::getInstance();
|
$dispatcher = EventDispatcher::getInstance();
|
||||||
|
@ -57,6 +57,16 @@ $dbtables = array(
|
|||||||
"groupid" => "int references ${mysqlprefix}chatgroup(groupid)",
|
"groupid" => "int references ${mysqlprefix}chatgroup(groupid)",
|
||||||
),
|
),
|
||||||
|
|
||||||
|
"${mysqlprefix}chatthreadstatistics" => array(
|
||||||
|
"statid" => "int NOT NULL auto_increment PRIMARY KEY",
|
||||||
|
"date" => "int NOT NULL DEFAULT 0",
|
||||||
|
"threads" => "int NOT NULL DEFAULT 0",
|
||||||
|
"operatormessages" => "int NOT NULL DEFAULT 0",
|
||||||
|
"usermessages" => "int NOT NULL DEFAULT 0",
|
||||||
|
"averagewaitingtime" => "FLOAT(10, 1) NOT NULL DEFAULT 0",
|
||||||
|
"averagechattime" => "FLOAT(10, 1) NOT NULL DEFAULT 0"
|
||||||
|
),
|
||||||
|
|
||||||
"${mysqlprefix}requestbuffer" => array(
|
"${mysqlprefix}requestbuffer" => array(
|
||||||
"requestid" => "int NOT NULL auto_increment PRIMARY KEY",
|
"requestid" => "int NOT NULL auto_increment PRIMARY KEY",
|
||||||
// Use MD5 hashes as keys
|
// Use MD5 hashes as keys
|
||||||
@ -114,6 +124,15 @@ $dbtables = array(
|
|||||||
"vcrestoretoken" => "varchar(64)",
|
"vcrestoretoken" => "varchar(64)",
|
||||||
),
|
),
|
||||||
|
|
||||||
|
"${mysqlprefix}chatoperatorstatistics" => array(
|
||||||
|
"statid" => "int NOT NULL auto_increment PRIMARY KEY",
|
||||||
|
"date" => "int NOT NULL DEFAULT 0",
|
||||||
|
"operatorid" => "int NOT NULL",
|
||||||
|
"threads" => "int NOT NULL DEFAULT 0",
|
||||||
|
"messages" => "int NOT NULL DEFAULT 0",
|
||||||
|
"averagelength" => "FLOAT(10, 1) NOT NULL DEFAULT 0"
|
||||||
|
),
|
||||||
|
|
||||||
"${mysqlprefix}chatrevision" => array(
|
"${mysqlprefix}chatrevision" => array(
|
||||||
"id" => "INT NOT NULL"
|
"id" => "INT NOT NULL"
|
||||||
),
|
),
|
||||||
@ -180,6 +199,9 @@ $dbtables_indexes = array(
|
|||||||
"${mysqlprefix}chatgroup" => array(
|
"${mysqlprefix}chatgroup" => array(
|
||||||
"parent" => "parent"
|
"parent" => "parent"
|
||||||
),
|
),
|
||||||
|
"${mysqlprefix}chatoperatorstatistics" => array(
|
||||||
|
"operatorid" => "operatorid"
|
||||||
|
),
|
||||||
"${mysqlprefix}chatgroupoperator" => array(
|
"${mysqlprefix}chatgroupoperator" => array(
|
||||||
"groupid" => "groupid",
|
"groupid" => "groupid",
|
||||||
"operatorid" => "operatorid"
|
"operatorid" => "operatorid"
|
||||||
@ -208,10 +230,12 @@ $memtables = array();
|
|||||||
|
|
||||||
$dbtables_can_update = array(
|
$dbtables_can_update = array(
|
||||||
"${mysqlprefix}chatthread" => array("agentId", "userTyping", "agentTyping", "messageCount", "nextagent", "shownmessageid", "userid", "userAgent", "groupid", "dtmchatstarted"),
|
"${mysqlprefix}chatthread" => array("agentId", "userTyping", "agentTyping", "messageCount", "nextagent", "shownmessageid", "userid", "userAgent", "groupid", "dtmchatstarted"),
|
||||||
|
"${mysqlprefix}chatthreadstatistics" => array(),
|
||||||
"${mysqlprefix}requestbuffer" => array("requestid", "requestkey", "request"),
|
"${mysqlprefix}requestbuffer" => array("requestid", "requestkey", "request"),
|
||||||
"${mysqlprefix}chatmessage" => array("agentId"),
|
"${mysqlprefix}chatmessage" => array("agentId"),
|
||||||
"${mysqlprefix}indexedchatmessage" => array(),
|
"${mysqlprefix}indexedchatmessage" => array(),
|
||||||
"${mysqlprefix}chatoperator" => array("vcavatar", "vcjabbername", "iperm", "istatus", "idisabled", "vcemail", "dtmrestore", "vcrestoretoken"),
|
"${mysqlprefix}chatoperator" => array("vcavatar", "vcjabbername", "iperm", "istatus", "idisabled", "vcemail", "dtmrestore", "vcrestoretoken"),
|
||||||
|
"${mysqlprefix}chatoperatorstatistics" => array(),
|
||||||
"${mysqlprefix}chatban" => array(),
|
"${mysqlprefix}chatban" => array(),
|
||||||
"${mysqlprefix}chatgroup" => array("vcemail", "iweight", "parent", "vctitle", "vcchattitle", "vclogo", "vchosturl"),
|
"${mysqlprefix}chatgroup" => array("vcemail", "iweight", "parent", "vctitle", "vcchattitle", "vclogo", "vchosturl"),
|
||||||
"${mysqlprefix}chatgroupoperator" => array(),
|
"${mysqlprefix}chatgroupoperator" => array(),
|
||||||
|
@ -237,6 +237,9 @@ if ($act == "silentcreateall") {
|
|||||||
runsql("ALTER TABLE ${mysqlprefix}visitedpage ADD INDEX (visitorid)", $link);
|
runsql("ALTER TABLE ${mysqlprefix}visitedpage ADD INDEX (visitorid)", $link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array("${mysqlprefix}chatoperatorstatistics.operatorid", $absent_indexes)) {
|
||||||
|
runsql("ALTER TABLE ${mysqlprefix}chatoperatorstatistics ADD INDEX (operatorid)", $link);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +202,123 @@ function cron_index_messages() {
|
|||||||
$db->query('COMMIT');
|
$db->query('COMMIT');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate aggregated 'by thread' and 'by operator' statistics
|
||||||
|
*/
|
||||||
|
function cron_calculate_statistics() {
|
||||||
|
// Prepare database
|
||||||
|
$db = Database::getInstance();
|
||||||
|
$db->throwExeptions(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Start transaction
|
||||||
|
$db->query('START TRANSACTION');
|
||||||
|
|
||||||
|
// Build 'by thread' statistics
|
||||||
|
// Get last record date
|
||||||
|
$result = $db->query(
|
||||||
|
"SELECT MAX(date) as start FROM {chatthreadstatistics}",
|
||||||
|
array(),
|
||||||
|
array('return_rows' => Database::RETURN_ONE_ROW)
|
||||||
|
);
|
||||||
|
|
||||||
|
$start = empty($result['start']) ? 0 : $result['start'];
|
||||||
|
|
||||||
|
// Reset statistics for the last day, because cron can be ran many
|
||||||
|
// times in a day.
|
||||||
|
$result = $db->query(
|
||||||
|
"DELETE FROM {chatthreadstatistics} WHERE date = :start",
|
||||||
|
array(':start' => $start)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calculate 'by thread' statistics
|
||||||
|
$db->query(
|
||||||
|
"INSERT INTO {chatthreadstatistics} ( " .
|
||||||
|
"date, threads, operatormessages, usermessages, " .
|
||||||
|
"averagewaitingtime, averagechattime " .
|
||||||
|
") SELECT (FLOOR(t.dtmcreated / (24*60*60)) * 24*60*60) AS date, " .
|
||||||
|
"COUNT(distinct t.threadid) AS threads, " .
|
||||||
|
"SUM(m.ikind = :kind_agent) AS operators, " .
|
||||||
|
"SUM(m.ikind = :kind_user) AS users, " .
|
||||||
|
"ROUND(AVG(t.dtmchatstarted-t.dtmcreated),1) as avgwaitingtime, " .
|
||||||
|
// Prevent negative values of avgchattime field.
|
||||||
|
// If avgchattime < 0 it becomes to zero.
|
||||||
|
// For random value 'a' result of expression ((abs(a) + a) / 2)
|
||||||
|
// equals to 'a' if 'a' more than zero
|
||||||
|
// and equals to zero otherwise
|
||||||
|
"ROUND(AVG( " .
|
||||||
|
"ABS(tmp.lastmsgtime-t.dtmchatstarted) + " .
|
||||||
|
"(tmp.lastmsgtime-t.dtmchatstarted) " .
|
||||||
|
")/2,1) as avgchattime " .
|
||||||
|
"FROM {indexedchatmessage} m, " .
|
||||||
|
"{chatthread} t, " .
|
||||||
|
"(SELECT i.threadid, MAX(i.dtmcreated) AS lastmsgtime " .
|
||||||
|
"FROM {indexedchatmessage} i " .
|
||||||
|
"WHERE (ikind = :kind_user OR ikind = :kind_agent) " .
|
||||||
|
"GROUP BY i.threadid) tmp " .
|
||||||
|
"WHERE m.threadid = t.threadid " .
|
||||||
|
"AND tmp.threadid = t.threadid " .
|
||||||
|
"AND t.dtmchatstarted <> 0 " .
|
||||||
|
"AND m.dtmcreated > :start " .
|
||||||
|
"GROUP BY date " .
|
||||||
|
"ORDER BY date",
|
||||||
|
array(
|
||||||
|
':kind_agent' => Thread::KIND_AGENT,
|
||||||
|
':kind_user' => Thread::KIND_USER,
|
||||||
|
':start' => $start
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Build 'by operator' statistics
|
||||||
|
// Get last record date
|
||||||
|
$result = $db->query(
|
||||||
|
"SELECT MAX(date) as start FROM {chatoperatorstatistics}",
|
||||||
|
array(),
|
||||||
|
array('return_rows' => Database::RETURN_ONE_ROW)
|
||||||
|
);
|
||||||
|
|
||||||
|
$start = empty($result['start']) ? 0 : $result['start'];
|
||||||
|
|
||||||
|
// Reset statistics for the last day, because cron can be ran many
|
||||||
|
// times in a day.
|
||||||
|
$result = $db->query(
|
||||||
|
"DELETE FROM {chatoperatorstatistics} WHERE date = :start",
|
||||||
|
array(':start' => $start)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Caclculate 'by operator' statistics
|
||||||
|
$db->query(
|
||||||
|
"INSERT INTO {chatoperatorstatistics} ( " .
|
||||||
|
"date, operatorid, threads, messages, averagelength" .
|
||||||
|
") SELECT (FLOOR(m.dtmcreated / (24*60*60)) * 24*60*60) AS date, " .
|
||||||
|
"o.operatorid AS opid, " .
|
||||||
|
"COUNT(distinct m.threadid) AS threads, " .
|
||||||
|
"SUM(m.ikind = :kind_agent) AS msgs, " .
|
||||||
|
"AVG(CHAR_LENGTH(m.tmessage)) AS avglen " .
|
||||||
|
"FROM {indexedchatmessage} m, {chatoperator} o " .
|
||||||
|
"WHERE m.agentId = o.operatorid " .
|
||||||
|
"AND m.dtmcreated > :start " .
|
||||||
|
"GROUP BY date " .
|
||||||
|
"ORDER BY date",
|
||||||
|
array(
|
||||||
|
':kind_agent' => Thread::KIND_AGENT,
|
||||||
|
':start' => $start
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} catch(Exception $e) {
|
||||||
|
// Something went wrong: warn and rollback transaction.
|
||||||
|
trigger_error(
|
||||||
|
'Statistics calculating faild: ' . $e->getMessage(),
|
||||||
|
E_USER_WARNING
|
||||||
|
);
|
||||||
|
$db->query('ROLLBACK');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit transaction
|
||||||
|
$db->query('COMMIT');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates cron URI
|
* Generates cron URI
|
||||||
*
|
*
|
||||||
|
@ -19,6 +19,7 @@ require_once('../libs/init.php');
|
|||||||
require_once('../libs/chat.php');
|
require_once('../libs/chat.php');
|
||||||
require_once('../libs/operator.php');
|
require_once('../libs/operator.php');
|
||||||
require_once('../libs/statistics.php');
|
require_once('../libs/statistics.php');
|
||||||
|
require_once('../libs/cron.php');
|
||||||
|
|
||||||
$operator = check_login();
|
$operator = check_login();
|
||||||
force_password($operator);
|
force_password($operator);
|
||||||
@ -35,6 +36,10 @@ $page['type'] = $statisticstype;
|
|||||||
$page['showbydate'] = ($statisticstype == 'bydate');
|
$page['showbydate'] = ($statisticstype == 'bydate');
|
||||||
$page['showbyagent'] = ($statisticstype == 'byagent');
|
$page['showbyagent'] = ($statisticstype == 'byagent');
|
||||||
$page['showbypage'] = ($statisticstype == 'bypage');
|
$page['showbypage'] = ($statisticstype == 'bypage');
|
||||||
|
|
||||||
|
$page['noresults'] = false;
|
||||||
|
$page['cron_path'] = cron_get_uri(Settings::get('cron_key'));
|
||||||
|
|
||||||
$errors = array();
|
$errors = array();
|
||||||
|
|
||||||
if (isset($_GET['startday'])) {
|
if (isset($_GET['startday'])) {
|
||||||
@ -74,45 +79,61 @@ $activetab = 0;
|
|||||||
$db = Database::getInstance();
|
$db = Database::getInstance();
|
||||||
if ($statisticstype == 'bydate') {
|
if ($statisticstype == 'bydate') {
|
||||||
$page['reportByDate'] = $db->query(
|
$page['reportByDate'] = $db->query(
|
||||||
"select DATE(FROM_UNIXTIME(t.dtmcreated)) as date, COUNT(distinct t.threadid) as threads, SUM(m.ikind = :kind_agent) as agents, SUM(m.ikind = :kind_user) as users, ROUND(AVG(t.dtmchatstarted-t.dtmcreated),1) as avgwaitingtime, ROUND(AVG(tmp.lastmsgtime - t.dtmchatstarted),1) as avgchattime " .
|
"SELECT DATE(FROM_UNIXTIME(date)) AS date, " .
|
||||||
"from {indexedchatmessage} m, {chatthread} t, (SELECT i.threadid, MAX(i.dtmcreated) AS lastmsgtime FROM {indexedchatmessage} i WHERE (ikind = :kind_user OR ikind = :kind_agent) GROUP BY i.threadid) tmp " .
|
"threads, " .
|
||||||
"where m.threadid = t.threadid AND tmp.threadid = t.threadid AND t.dtmchatstarted <> 0 AND m.dtmcreated >= :start AND m.dtmcreated < :end group by DATE(FROM_UNIXTIME(m.dtmcreated)) order by m.dtmcreated desc",
|
"operatormessages AS agents, " .
|
||||||
|
"usermessages AS users, " .
|
||||||
|
"averagewaitingtime AS avgwaitingtime, " .
|
||||||
|
"averagechattime AS avgchattime " .
|
||||||
|
"FROM {chatthreadstatistics} s " .
|
||||||
|
"WHERE s.date >= :start " .
|
||||||
|
"AND s.date < :end " .
|
||||||
|
"ORDER BY s.date DESC",
|
||||||
array(
|
array(
|
||||||
':kind_agent' => Thread::KIND_AGENT,
|
|
||||||
':kind_user' => Thread::KIND_USER,
|
|
||||||
':start' => $start,
|
':start' => $start,
|
||||||
':end' => $end
|
':end' => $end
|
||||||
),
|
),
|
||||||
array('return_rows' => Database::RETURN_ALL_ROWS)
|
array('return_rows' => Database::RETURN_ALL_ROWS)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$page['noresults'] = empty($page['reportByDate']);
|
||||||
|
|
||||||
$page['reportByDateTotal'] = $db->query(
|
$page['reportByDateTotal'] = $db->query(
|
||||||
"select DATE(FROM_UNIXTIME(t.dtmcreated)) as date, COUNT(distinct t.threadid) as threads, SUM(m.ikind = :kind_agent) as agents, SUM(m.ikind = :kind_user) as users, ROUND(AVG(t.dtmchatstarted-t.dtmcreated),1) as avgwaitingtime, ROUND(AVG(tmp.lastmsgtime - t.dtmchatstarted),1) as avgchattime " .
|
"SELECT DATE(FROM_UNIXTIME(date)) AS date, " .
|
||||||
"from {indexedchatmessage} m, {chatthread} t, (SELECT i.threadid, MAX(i.dtmcreated) AS lastmsgtime FROM {indexedchatmessage} i WHERE (ikind = :kind_user OR ikind = :kind_agent) GROUP BY i.threadid) tmp " .
|
"SUM(threads) AS threads, " .
|
||||||
"where m.threadid = t.threadid AND tmp.threadid = t.threadid AND t.dtmchatstarted <> 0 AND m.dtmcreated >= :start AND m.dtmcreated < :end",
|
"SUM(operatormessages) AS agents, " .
|
||||||
|
"SUM(usermessages) AS users, " .
|
||||||
|
"ROUND(SUM(averagewaitingtime * s.threads) / SUM(s.threads),1) AS avgwaitingtime, " .
|
||||||
|
"ROUND(SUM(averagechattime * s.threads) / SUM(s.threads),1) AS avgchattime " .
|
||||||
|
"FROM {chatthreadstatistics} s " .
|
||||||
|
"WHERE s.date >= :start " .
|
||||||
|
"AND s.date < :end",
|
||||||
array(
|
array(
|
||||||
':kind_agent' => Thread::KIND_AGENT,
|
|
||||||
':kind_user' => Thread::KIND_USER,
|
|
||||||
':start' => $start,
|
':start' => $start,
|
||||||
':end' => $end
|
':end' => $end
|
||||||
),
|
),
|
||||||
array('return_rows' => Database::RETURN_ONE_ROW)
|
array('return_rows' => Database::RETURN_ONE_ROW)
|
||||||
);
|
);
|
||||||
|
|
||||||
$activetab = 0;
|
$activetab = 0;
|
||||||
} elseif($statisticstype == 'byagent') {
|
} elseif($statisticstype == 'byagent') {
|
||||||
$page['reportByAgent'] = $db->query(
|
$page['reportByAgent'] = $db->query(
|
||||||
"select vclocalename as name, COUNT(distinct threadid) as threads, " .
|
"SELECT o.vclocalename AS name, " .
|
||||||
"SUM(ikind = :kind_agent) as msgs, AVG(CHAR_LENGTH(tmessage)) as avglen " .
|
"s.threads AS threads, " .
|
||||||
"from {indexedchatmessage}, {chatoperator} " .
|
"s.messages AS msgs, " .
|
||||||
"where agentId = operatorid AND dtmcreated >= :start " .
|
"s.averagelength AS avglen " .
|
||||||
"AND dtmcreated < :end group by operatorid",
|
"FROM {chatoperatorstatistics} s, {chatoperator} o " .
|
||||||
|
"WHERE s.operatorid = o.operatorid " .
|
||||||
|
"AND s.date >= :start " .
|
||||||
|
"AND s.date < :end " .
|
||||||
|
"GROUP BY s.operatorid",
|
||||||
array(
|
array(
|
||||||
':kind_agent' => Thread::KIND_AGENT,
|
|
||||||
':start' => $start,
|
':start' => $start,
|
||||||
':end' => $end
|
':end' => $end
|
||||||
),
|
),
|
||||||
array('return_rows' => Database::RETURN_ALL_ROWS)
|
array('return_rows' => Database::RETURN_ALL_ROWS)
|
||||||
);
|
);
|
||||||
|
$page['noresults'] = empty($page['reportByAgent']);
|
||||||
$activetab = 1;
|
$activetab = 1;
|
||||||
} elseif($statisticstype == 'bypage') {
|
} elseif($statisticstype == 'bypage') {
|
||||||
$page['reportByPage'] = $db->query(
|
$page['reportByPage'] = $db->query(
|
||||||
|
@ -24,6 +24,10 @@ $page['menuid'] = "statistics";
|
|||||||
function tpl_content() { global $page, $webimroot, $errors;
|
function tpl_content() { global $page, $webimroot, $errors;
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
<?php if($page['noresults']) { ?>
|
||||||
|
<div id="formmessage"><?php echo getlocal2("cron.check.setup", array($page['cron_path'])) ?></div>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
<?php echo getlocal("statistics.description") ?>
|
<?php echo getlocal("statistics.description") ?>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
Loading…
Reference in New Issue
Block a user