301 lines
9.7 KiB
PHP
301 lines
9.7 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Phone schedule management class
|
||
|
*/
|
||
|
class TWP_Scheduler {
|
||
|
|
||
|
/**
|
||
|
* Check active schedules
|
||
|
*/
|
||
|
public function check_active_schedules() {
|
||
|
global $wpdb;
|
||
|
$table_name = $wpdb->prefix . 'twp_phone_schedules';
|
||
|
|
||
|
$current_time = current_time('H:i:s');
|
||
|
$current_day = strtolower(date('l'));
|
||
|
|
||
|
$schedules = $wpdb->get_results($wpdb->prepare(
|
||
|
"SELECT * FROM $table_name
|
||
|
WHERE is_active = 1
|
||
|
AND days_of_week LIKE %s
|
||
|
AND start_time <= %s
|
||
|
AND end_time >= %s",
|
||
|
'%' . $current_day . '%',
|
||
|
$current_time,
|
||
|
$current_time
|
||
|
));
|
||
|
|
||
|
foreach ($schedules as $schedule) {
|
||
|
$this->apply_schedule($schedule);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Apply schedule to phone number
|
||
|
*/
|
||
|
private function apply_schedule($schedule) {
|
||
|
$twilio = new TWP_Twilio_API();
|
||
|
|
||
|
// Get phone numbers
|
||
|
$numbers = $twilio->get_phone_numbers();
|
||
|
|
||
|
if ($numbers['success']) {
|
||
|
foreach ($numbers['data']['incoming_phone_numbers'] as $number) {
|
||
|
if ($number['phone_number'] == $schedule->phone_number) {
|
||
|
// Configure webhook based on schedule
|
||
|
$webhook_url = home_url('/twilio-webhook/voice');
|
||
|
$webhook_url = add_query_arg('schedule_id', $schedule->id, $webhook_url);
|
||
|
|
||
|
$twilio->configure_phone_number(
|
||
|
$number['sid'],
|
||
|
$webhook_url
|
||
|
);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create schedule
|
||
|
*/
|
||
|
public static function create_schedule($data) {
|
||
|
global $wpdb;
|
||
|
$table_name = $wpdb->prefix . 'twp_phone_schedules';
|
||
|
|
||
|
$insert_data = array(
|
||
|
'schedule_name' => sanitize_text_field($data['schedule_name']),
|
||
|
'days_of_week' => sanitize_text_field($data['days_of_week']),
|
||
|
'start_time' => sanitize_text_field($data['start_time']),
|
||
|
'end_time' => sanitize_text_field($data['end_time']),
|
||
|
'workflow_id' => sanitize_text_field($data['workflow_id']),
|
||
|
'is_active' => isset($data['is_active']) ? 1 : 0
|
||
|
);
|
||
|
|
||
|
$format = array('%s', '%s', '%s', '%s', '%s', '%d');
|
||
|
|
||
|
// Add optional fields if provided
|
||
|
if (!empty($data['phone_number'])) {
|
||
|
$insert_data['phone_number'] = sanitize_text_field($data['phone_number']);
|
||
|
$format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (!empty($data['forward_number'])) {
|
||
|
$insert_data['forward_number'] = sanitize_text_field($data['forward_number']);
|
||
|
$format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (!empty($data['after_hours_action'])) {
|
||
|
$insert_data['after_hours_action'] = sanitize_text_field($data['after_hours_action']);
|
||
|
$format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (!empty($data['after_hours_workflow_id'])) {
|
||
|
$insert_data['after_hours_workflow_id'] = sanitize_text_field($data['after_hours_workflow_id']);
|
||
|
$format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (!empty($data['after_hours_forward_number'])) {
|
||
|
$insert_data['after_hours_forward_number'] = sanitize_text_field($data['after_hours_forward_number']);
|
||
|
$format[] = '%s';
|
||
|
}
|
||
|
|
||
|
$result = $wpdb->insert($table_name, $insert_data, $format);
|
||
|
|
||
|
return $result !== false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update schedule
|
||
|
*/
|
||
|
public static function update_schedule($id, $data) {
|
||
|
global $wpdb;
|
||
|
$table_name = $wpdb->prefix . 'twp_phone_schedules';
|
||
|
|
||
|
$update_data = array();
|
||
|
$update_format = array();
|
||
|
|
||
|
if (isset($data['phone_number'])) {
|
||
|
$update_data['phone_number'] = sanitize_text_field($data['phone_number']);
|
||
|
$update_format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($data['schedule_name'])) {
|
||
|
$update_data['schedule_name'] = sanitize_text_field($data['schedule_name']);
|
||
|
$update_format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($data['days_of_week'])) {
|
||
|
$update_data['days_of_week'] = sanitize_text_field($data['days_of_week']);
|
||
|
$update_format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($data['start_time'])) {
|
||
|
$update_data['start_time'] = sanitize_text_field($data['start_time']);
|
||
|
$update_format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($data['end_time'])) {
|
||
|
$update_data['end_time'] = sanitize_text_field($data['end_time']);
|
||
|
$update_format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($data['workflow_id'])) {
|
||
|
$update_data['workflow_id'] = sanitize_text_field($data['workflow_id']);
|
||
|
$update_format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($data['forward_number'])) {
|
||
|
$update_data['forward_number'] = sanitize_text_field($data['forward_number']);
|
||
|
$update_format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($data['after_hours_action'])) {
|
||
|
$update_data['after_hours_action'] = sanitize_text_field($data['after_hours_action']);
|
||
|
$update_format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($data['after_hours_workflow_id'])) {
|
||
|
$update_data['after_hours_workflow_id'] = sanitize_text_field($data['after_hours_workflow_id']);
|
||
|
$update_format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($data['after_hours_forward_number'])) {
|
||
|
$update_data['after_hours_forward_number'] = sanitize_text_field($data['after_hours_forward_number']);
|
||
|
$update_format[] = '%s';
|
||
|
}
|
||
|
|
||
|
if (isset($data['is_active'])) {
|
||
|
$update_data['is_active'] = $data['is_active'] ? 1 : 0;
|
||
|
$update_format[] = '%d';
|
||
|
}
|
||
|
|
||
|
$result = $wpdb->update(
|
||
|
$table_name,
|
||
|
$update_data,
|
||
|
array('id' => $id),
|
||
|
$update_format,
|
||
|
array('%d')
|
||
|
);
|
||
|
|
||
|
return $result !== false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Delete schedule
|
||
|
*/
|
||
|
public static function delete_schedule($id) {
|
||
|
global $wpdb;
|
||
|
$table_name = $wpdb->prefix . 'twp_phone_schedules';
|
||
|
|
||
|
return $wpdb->delete(
|
||
|
$table_name,
|
||
|
array('id' => $id),
|
||
|
array('%d')
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get schedules
|
||
|
*/
|
||
|
public static function get_schedules($phone_number = null) {
|
||
|
global $wpdb;
|
||
|
$table_name = $wpdb->prefix . 'twp_phone_schedules';
|
||
|
|
||
|
if ($phone_number) {
|
||
|
return $wpdb->get_results($wpdb->prepare(
|
||
|
"SELECT * FROM $table_name WHERE phone_number = %s ORDER BY created_at DESC",
|
||
|
$phone_number
|
||
|
));
|
||
|
} else {
|
||
|
return $wpdb->get_results("SELECT * FROM $table_name ORDER BY created_at DESC");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get schedule by ID
|
||
|
*/
|
||
|
public static function get_schedule($id) {
|
||
|
global $wpdb;
|
||
|
$table_name = $wpdb->prefix . 'twp_phone_schedules';
|
||
|
|
||
|
return $wpdb->get_row($wpdb->prepare(
|
||
|
"SELECT * FROM $table_name WHERE id = %d",
|
||
|
$id
|
||
|
));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if schedule is active now
|
||
|
*/
|
||
|
public static function is_schedule_active($schedule_id) {
|
||
|
$schedule = self::get_schedule($schedule_id);
|
||
|
|
||
|
if (!$schedule || !$schedule->is_active) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$current_time = current_time('H:i:s');
|
||
|
$current_day = strtolower(date('l'));
|
||
|
|
||
|
// Check if current day is in schedule
|
||
|
if (strpos($schedule->days_of_week, $current_day) === false) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Check if current time is within schedule
|
||
|
return $current_time >= $schedule->start_time && $current_time <= $schedule->end_time;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get appropriate routing for schedule
|
||
|
*/
|
||
|
public static function get_schedule_routing($schedule_id) {
|
||
|
$schedule = self::get_schedule($schedule_id);
|
||
|
|
||
|
if (!$schedule || !$schedule->is_active) {
|
||
|
return array(
|
||
|
'action' => 'default',
|
||
|
'data' => null
|
||
|
);
|
||
|
}
|
||
|
|
||
|
$is_within_hours = self::is_schedule_active($schedule_id);
|
||
|
|
||
|
if ($is_within_hours) {
|
||
|
// Within business hours - use main workflow
|
||
|
return array(
|
||
|
'action' => 'workflow',
|
||
|
'data' => array(
|
||
|
'workflow_id' => $schedule->workflow_id
|
||
|
)
|
||
|
);
|
||
|
} else {
|
||
|
// After hours - use after hours routing
|
||
|
if ($schedule->after_hours_action === 'forward' && $schedule->after_hours_forward_number) {
|
||
|
return array(
|
||
|
'action' => 'forward',
|
||
|
'data' => array(
|
||
|
'forward_number' => $schedule->after_hours_forward_number
|
||
|
)
|
||
|
);
|
||
|
} else if ($schedule->after_hours_action === 'workflow' && $schedule->after_hours_workflow_id) {
|
||
|
return array(
|
||
|
'action' => 'workflow',
|
||
|
'data' => array(
|
||
|
'workflow_id' => $schedule->after_hours_workflow_id
|
||
|
)
|
||
|
);
|
||
|
} else {
|
||
|
// Default to main workflow if no after hours action specified
|
||
|
return array(
|
||
|
'action' => 'workflow',
|
||
|
'data' => array(
|
||
|
'workflow_id' => $schedule->workflow_id
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|