mirror of
				https://github.com/Mibew/i18n.git
				synced 2025-11-01 01:36:57 +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
 | ||||
| cron_index_messages(); | ||||
| cron_calculate_statistics(); | ||||
| 
 | ||||
| // Trigger cron event
 | ||||
| $dispatcher = EventDispatcher::getInstance(); | ||||
|  | ||||
| @ -57,6 +57,16 @@ $dbtables = array( | ||||
| 		"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( | ||||
| 		"requestid" => "int NOT NULL auto_increment PRIMARY KEY", | ||||
| 		// Use MD5 hashes as keys
 | ||||
| @ -114,6 +124,15 @@ $dbtables = array( | ||||
| 		"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( | ||||
| 		"id" => "INT NOT NULL" | ||||
| 	), | ||||
| @ -180,6 +199,9 @@ $dbtables_indexes = array( | ||||
| 	"${mysqlprefix}chatgroup" => array( | ||||
| 		"parent" => "parent" | ||||
| 	), | ||||
| 	"${mysqlprefix}chatoperatorstatistics" => array( | ||||
| 		"operatorid" => "operatorid" | ||||
| 	), | ||||
| 	"${mysqlprefix}chatgroupoperator" => array( | ||||
| 		"groupid" => "groupid", | ||||
| 		"operatorid" => "operatorid" | ||||
| @ -208,10 +230,12 @@ $memtables = array(); | ||||
| 
 | ||||
| $dbtables_can_update = array( | ||||
| 	"${mysqlprefix}chatthread" => array("agentId", "userTyping", "agentTyping", "messageCount", "nextagent", "shownmessageid", "userid", "userAgent", "groupid", "dtmchatstarted"), | ||||
| 	"${mysqlprefix}chatthreadstatistics" => array(), | ||||
| 	"${mysqlprefix}requestbuffer" => array("requestid", "requestkey", "request"), | ||||
| 	"${mysqlprefix}chatmessage" => array("agentId"), | ||||
| 	"${mysqlprefix}indexedchatmessage" => array(), | ||||
| 	"${mysqlprefix}chatoperator" => array("vcavatar", "vcjabbername", "iperm", "istatus", "idisabled", "vcemail", "dtmrestore", "vcrestoretoken"), | ||||
| 	"${mysqlprefix}chatoperatorstatistics" => array(), | ||||
| 	"${mysqlprefix}chatban" => array(), | ||||
| 	"${mysqlprefix}chatgroup" => array("vcemail", "iweight", "parent", "vctitle", "vcchattitle", "vclogo", "vchosturl"), | ||||
| 	"${mysqlprefix}chatgroupoperator" => array(), | ||||
|  | ||||
| @ -237,6 +237,9 @@ if ($act == "silentcreateall") { | ||||
| 			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'); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * 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 | ||||
|  * | ||||
|  | ||||
| @ -19,6 +19,7 @@ require_once('../libs/init.php'); | ||||
| require_once('../libs/chat.php'); | ||||
| require_once('../libs/operator.php'); | ||||
| require_once('../libs/statistics.php'); | ||||
| require_once('../libs/cron.php'); | ||||
| 
 | ||||
| $operator = check_login(); | ||||
| force_password($operator); | ||||
| @ -35,6 +36,10 @@ $page['type'] = $statisticstype; | ||||
| $page['showbydate'] = ($statisticstype == 'bydate'); | ||||
| $page['showbyagent'] = ($statisticstype == 'byagent'); | ||||
| $page['showbypage'] = ($statisticstype == 'bypage'); | ||||
| 
 | ||||
| $page['noresults'] = false; | ||||
| $page['cron_path'] = cron_get_uri(Settings::get('cron_key')); | ||||
| 
 | ||||
| $errors = array(); | ||||
| 
 | ||||
| if (isset($_GET['startday'])) { | ||||
| @ -74,45 +79,61 @@ $activetab = 0; | ||||
| $db = Database::getInstance(); | ||||
| if ($statisticstype == 'bydate') { | ||||
| 	$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 " . | ||||
| 		"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 AND m.dtmcreated < :end group by DATE(FROM_UNIXTIME(m.dtmcreated)) order by m.dtmcreated desc", | ||||
| 		"SELECT DATE(FROM_UNIXTIME(date)) AS date, " . | ||||
| 			"threads, " . | ||||
| 			"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( | ||||
| 			':kind_agent' => Thread::KIND_AGENT, | ||||
| 			':kind_user' => Thread::KIND_USER, | ||||
| 			':start' => $start, | ||||
| 			':end' => $end | ||||
| 		), | ||||
| 		array('return_rows' => Database::RETURN_ALL_ROWS) | ||||
| 	); | ||||
| 	 | ||||
| 
 | ||||
| 	$page['noresults'] = empty($page['reportByDate']); | ||||
| 
 | ||||
| 	$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 " . | ||||
| 		"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 AND m.dtmcreated < :end", | ||||
| 		"SELECT DATE(FROM_UNIXTIME(date)) AS date, " . | ||||
| 			"SUM(threads) AS threads, " . | ||||
| 			"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( | ||||
| 			':kind_agent' => Thread::KIND_AGENT, | ||||
| 			':kind_user' => Thread::KIND_USER, | ||||
| 			':start' => $start, | ||||
| 			':end' => $end | ||||
| 		), | ||||
| 		array('return_rows' => Database::RETURN_ONE_ROW) | ||||
| 	); | ||||
| 
 | ||||
| 	$activetab = 0; | ||||
| } elseif($statisticstype == 'byagent') { | ||||
| 	$page['reportByAgent'] = $db->query( | ||||
| 		"select vclocalename as name, COUNT(distinct threadid) as threads, " . | ||||
| 		"SUM(ikind = :kind_agent) as msgs, AVG(CHAR_LENGTH(tmessage)) as avglen " . | ||||
| 		"from {indexedchatmessage}, {chatoperator} " . | ||||
| 		"where agentId = operatorid AND dtmcreated >= :start " . | ||||
| 		"AND dtmcreated < :end group by operatorid", | ||||
| 		"SELECT o.vclocalename AS name, " . | ||||
| 			"s.threads AS threads, " . | ||||
| 			"s.messages AS msgs, " . | ||||
| 			"s.averagelength AS avglen " . | ||||
| 		"FROM {chatoperatorstatistics} s, {chatoperator} o " . | ||||
| 		"WHERE s.operatorid = o.operatorid " . | ||||
| 			"AND s.date >= :start " . | ||||
| 			"AND s.date < :end " . | ||||
| 		"GROUP BY s.operatorid", | ||||
| 		array( | ||||
| 			':kind_agent' => Thread::KIND_AGENT, | ||||
| 			':start' => $start, | ||||
| 			':end' => $end | ||||
| 		), | ||||
| 		array('return_rows' => Database::RETURN_ALL_ROWS) | ||||
| 	); | ||||
| 	$page['noresults'] = empty($page['reportByAgent']); | ||||
| 	$activetab = 1; | ||||
| } elseif($statisticstype == 'bypage') { | ||||
| 	$page['reportByPage'] = $db->query( | ||||
|  | ||||
| @ -24,6 +24,10 @@ $page['menuid'] = "statistics"; | ||||
| 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") ?>
 | ||||
| <br /> | ||||
| <br /> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user