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 ) ); } } } }