258 lines
8.5 KiB
PHP
258 lines
8.5 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Call logging class
|
||
|
*/
|
||
|
class TWP_Call_Logger {
|
||
|
|
||
|
/**
|
||
|
* Log a new call
|
||
|
*/
|
||
|
public static function log_call($call_data) {
|
||
|
global $wpdb;
|
||
|
$table_name = $wpdb->prefix . 'twp_call_log';
|
||
|
|
||
|
$data = array(
|
||
|
'call_sid' => sanitize_text_field($call_data['call_sid']),
|
||
|
'from_number' => sanitize_text_field($call_data['from_number'] ?? ''),
|
||
|
'to_number' => sanitize_text_field($call_data['to_number'] ?? ''),
|
||
|
'status' => sanitize_text_field($call_data['status'] ?? 'initiated'),
|
||
|
'duration' => intval($call_data['duration'] ?? 0),
|
||
|
'workflow_id' => intval($call_data['workflow_id'] ?? 0),
|
||
|
'workflow_name' => sanitize_text_field($call_data['workflow_name'] ?? ''),
|
||
|
'queue_time' => intval($call_data['queue_time'] ?? 0),
|
||
|
'actions_taken' => sanitize_textarea_field($call_data['actions_taken'] ?? ''),
|
||
|
'call_data' => json_encode($call_data)
|
||
|
);
|
||
|
|
||
|
$format = array('%s', '%s', '%s', '%s', '%d', '%d', '%s', '%d', '%s', '%s');
|
||
|
|
||
|
return $wpdb->insert($table_name, $data, $format);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update call log
|
||
|
*/
|
||
|
public static function update_call($call_sid, $updates) {
|
||
|
global $wpdb;
|
||
|
$table_name = $wpdb->prefix . 'twp_call_log';
|
||
|
|
||
|
$update_data = array();
|
||
|
$format = array();
|
||
|
|
||
|
if (isset($updates['status'])) {
|
||
|
$update_data['status'] = sanitize_text_field($updates['status']);
|
||
|
$format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($updates['duration'])) {
|
||
|
$update_data['duration'] = intval($updates['duration']);
|
||
|
$format[] = '%d';
|
||
|
}
|
||
|
|
||
|
if (isset($updates['queue_time'])) {
|
||
|
$update_data['queue_time'] = intval($updates['queue_time']);
|
||
|
$format[] = '%d';
|
||
|
}
|
||
|
|
||
|
if (isset($updates['actions_taken'])) {
|
||
|
// Append to existing actions
|
||
|
$existing = $wpdb->get_var($wpdb->prepare(
|
||
|
"SELECT actions_taken FROM $table_name WHERE call_sid = %s",
|
||
|
$call_sid
|
||
|
));
|
||
|
|
||
|
$new_action = sanitize_textarea_field($updates['actions_taken']);
|
||
|
$update_data['actions_taken'] = $existing ? $existing . '; ' . $new_action : $new_action;
|
||
|
$format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($updates['call_data'])) {
|
||
|
// Merge with existing call data
|
||
|
$existing_data = $wpdb->get_var($wpdb->prepare(
|
||
|
"SELECT call_data FROM $table_name WHERE call_sid = %s",
|
||
|
$call_sid
|
||
|
));
|
||
|
|
||
|
$existing_array = $existing_data ? json_decode($existing_data, true) : array();
|
||
|
$new_data = array_merge($existing_array, $updates['call_data']);
|
||
|
$update_data['call_data'] = json_encode($new_data);
|
||
|
$format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (empty($update_data)) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return $wpdb->update(
|
||
|
$table_name,
|
||
|
$update_data,
|
||
|
array('call_sid' => $call_sid),
|
||
|
$format,
|
||
|
array('%s')
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get call log by SID
|
||
|
*/
|
||
|
public static function get_call_log($call_sid) {
|
||
|
global $wpdb;
|
||
|
$table_name = $wpdb->prefix . 'twp_call_log';
|
||
|
|
||
|
return $wpdb->get_row($wpdb->prepare(
|
||
|
"SELECT * FROM $table_name WHERE call_sid = %s",
|
||
|
$call_sid
|
||
|
));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get call logs with filtering
|
||
|
*/
|
||
|
public static function get_call_logs($filters = array(), $limit = 100, $offset = 0) {
|
||
|
global $wpdb;
|
||
|
$table_name = $wpdb->prefix . 'twp_call_log';
|
||
|
|
||
|
$where_clauses = array();
|
||
|
$where_values = array();
|
||
|
|
||
|
if (!empty($filters['from_number'])) {
|
||
|
$where_clauses[] = "from_number = %s";
|
||
|
$where_values[] = $filters['from_number'];
|
||
|
}
|
||
|
|
||
|
if (!empty($filters['status'])) {
|
||
|
$where_clauses[] = "status = %s";
|
||
|
$where_values[] = $filters['status'];
|
||
|
}
|
||
|
|
||
|
if (!empty($filters['date_from'])) {
|
||
|
$where_clauses[] = "DATE(created_at) >= %s";
|
||
|
$where_values[] = $filters['date_from'];
|
||
|
}
|
||
|
|
||
|
if (!empty($filters['date_to'])) {
|
||
|
$where_clauses[] = "DATE(created_at) <= %s";
|
||
|
$where_values[] = $filters['date_to'];
|
||
|
}
|
||
|
|
||
|
$where_sql = '';
|
||
|
if (!empty($where_clauses)) {
|
||
|
$where_sql = 'WHERE ' . implode(' AND ', $where_clauses);
|
||
|
}
|
||
|
|
||
|
$sql = "SELECT * FROM $table_name $where_sql ORDER BY created_at DESC LIMIT %d OFFSET %d";
|
||
|
$where_values[] = $limit;
|
||
|
$where_values[] = $offset;
|
||
|
|
||
|
return $wpdb->get_results($wpdb->prepare($sql, $where_values));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get call statistics
|
||
|
*/
|
||
|
public static function get_call_statistics($period = 'today') {
|
||
|
global $wpdb;
|
||
|
$table_name = $wpdb->prefix . 'twp_call_log';
|
||
|
|
||
|
$where_clause = '';
|
||
|
switch ($period) {
|
||
|
case 'today':
|
||
|
$where_clause = "WHERE DATE(created_at) = CURDATE()";
|
||
|
break;
|
||
|
case 'week':
|
||
|
$where_clause = "WHERE YEARWEEK(created_at) = YEARWEEK(NOW())";
|
||
|
break;
|
||
|
case 'month':
|
||
|
$where_clause = "WHERE YEAR(created_at) = YEAR(NOW()) AND MONTH(created_at) = MONTH(NOW())";
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
$stats = array();
|
||
|
|
||
|
// Total calls
|
||
|
$stats['total_calls'] = $wpdb->get_var("SELECT COUNT(*) FROM $table_name $where_clause");
|
||
|
|
||
|
// Answered calls
|
||
|
$stats['answered_calls'] = $wpdb->get_var("SELECT COUNT(*) FROM $table_name $where_clause AND status = 'completed' AND duration > 0");
|
||
|
|
||
|
// Average duration
|
||
|
$avg_duration = $wpdb->get_var("SELECT AVG(duration) FROM $table_name $where_clause AND duration > 0");
|
||
|
$stats['avg_duration'] = $avg_duration ? round($avg_duration) : 0;
|
||
|
|
||
|
// Average queue time
|
||
|
$avg_queue_time = $wpdb->get_var("SELECT AVG(queue_time) FROM $table_name $where_clause AND queue_time > 0");
|
||
|
$stats['avg_queue_time'] = $avg_queue_time ? round($avg_queue_time) : 0;
|
||
|
|
||
|
// Call status breakdown
|
||
|
$status_breakdown = $wpdb->get_results("
|
||
|
SELECT status, COUNT(*) as count
|
||
|
FROM $table_name $where_clause
|
||
|
GROUP BY status
|
||
|
", ARRAY_A);
|
||
|
|
||
|
$stats['status_breakdown'] = array();
|
||
|
foreach ($status_breakdown as $status) {
|
||
|
$stats['status_breakdown'][$status['status']] = $status['count'];
|
||
|
}
|
||
|
|
||
|
return $stats;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Log action taken during call
|
||
|
*/
|
||
|
public static function log_action($call_sid, $action) {
|
||
|
$timestamp = current_time('mysql');
|
||
|
$action_with_time = "[{$timestamp}] {$action}";
|
||
|
|
||
|
return self::update_call($call_sid, array(
|
||
|
'actions_taken' => $action_with_time
|
||
|
));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get call timeline
|
||
|
*/
|
||
|
public static function get_call_timeline($call_sid) {
|
||
|
$log = self::get_call_log($call_sid);
|
||
|
if (!$log) {
|
||
|
return array();
|
||
|
}
|
||
|
|
||
|
$timeline = array();
|
||
|
$call_data = json_decode($log->call_data, true) ?: array();
|
||
|
|
||
|
// Parse actions taken
|
||
|
if ($log->actions_taken) {
|
||
|
$actions = explode(';', $log->actions_taken);
|
||
|
foreach ($actions as $action) {
|
||
|
$action = trim($action);
|
||
|
if (preg_match('/\[(.*?)\] (.*)/', $action, $matches)) {
|
||
|
$timeline[] = array(
|
||
|
'time' => $matches[1],
|
||
|
'event' => $matches[2],
|
||
|
'type' => 'action'
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Add status changes from call data
|
||
|
if (isset($call_data['status_changes'])) {
|
||
|
foreach ($call_data['status_changes'] as $change) {
|
||
|
$timeline[] = array(
|
||
|
'time' => $change['timestamp'],
|
||
|
'event' => 'Call status changed to: ' . $change['status'],
|
||
|
'type' => 'status'
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Sort by time
|
||
|
usort($timeline, function($a, $b) {
|
||
|
return strtotime($a['time']) - strtotime($b['time']);
|
||
|
});
|
||
|
|
||
|
return $timeline;
|
||
|
}
|
||
|
}
|