Files
twilio-wp-plugin/includes/class-twp-activator.php

420 lines
17 KiB
PHP
Raw Normal View History

2025-08-06 15:25:47 -07:00
<?php
/**
* Fired during plugin activation
*/
class TWP_Activator {
/**
* Run activation tasks
*/
public static function activate() {
// Create database tables
self::create_tables();
// Set default options
self::set_default_options();
2025-08-12 09:54:32 -07:00
// Create custom user roles
self::create_user_roles();
2025-08-11 20:31:48 -07:00
// Set the database version
if (defined('TWP_DB_VERSION')) {
update_option('twp_db_version', TWP_DB_VERSION);
}
2025-08-06 15:25:47 -07:00
// Create webhook endpoints
flush_rewrite_rules();
}
/**
* Check if tables exist and create them if needed
*/
public static function ensure_tables_exist() {
global $wpdb;
$required_tables = array(
'twp_phone_schedules',
'twp_call_queues',
'twp_queued_calls',
'twp_workflows',
'twp_workflow_phones',
2025-08-06 15:25:47 -07:00
'twp_call_log',
'twp_sms_log',
'twp_voicemails',
'twp_agent_groups',
'twp_group_members',
'twp_agent_status',
'twp_callbacks'
);
$missing_tables = array();
foreach ($required_tables as $table) {
$table_name = $wpdb->prefix . $table;
$table_exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_name));
if (!$table_exists) {
$missing_tables[] = $table;
}
}
if (!empty($missing_tables)) {
error_log('TWP Plugin: Missing database tables: ' . implode(', ', $missing_tables) . '. Creating them now.');
self::create_tables();
return false; // Tables were missing
}
2025-08-11 20:31:48 -07:00
// Check for and perform any needed migrations
self::migrate_tables();
2025-08-06 15:25:47 -07:00
return true; // All tables exist
}
/**
* Create plugin database tables
*/
private static function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// Phone schedules table
$table_schedules = $wpdb->prefix . 'twp_phone_schedules';
$sql_schedules = "CREATE TABLE $table_schedules (
id int(11) NOT NULL AUTO_INCREMENT,
phone_number varchar(20),
schedule_name varchar(100) NOT NULL,
2025-08-11 20:31:48 -07:00
days_of_week varchar(100) NOT NULL,
2025-08-06 15:25:47 -07:00
start_time time NOT NULL,
end_time time NOT NULL,
workflow_id varchar(100),
forward_number varchar(20),
after_hours_action varchar(20) DEFAULT 'workflow',
after_hours_workflow_id varchar(100),
after_hours_forward_number varchar(20),
2025-08-11 20:31:48 -07:00
holiday_dates text,
2025-08-06 15:25:47 -07:00
is_active tinyint(1) DEFAULT 1,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY phone_number (phone_number)
) $charset_collate;";
// Call queues table
$table_queues = $wpdb->prefix . 'twp_call_queues';
$sql_queues = "CREATE TABLE $table_queues (
id int(11) NOT NULL AUTO_INCREMENT,
queue_name varchar(100) NOT NULL,
2025-08-12 09:12:54 -07:00
notification_number varchar(20),
2025-08-11 20:31:48 -07:00
agent_group_id int(11),
2025-08-06 15:25:47 -07:00
max_size int(11) DEFAULT 10,
wait_music_url varchar(255),
tts_message text,
timeout_seconds int(11) DEFAULT 300,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
2025-08-11 20:31:48 -07:00
PRIMARY KEY (id),
KEY agent_group_id (agent_group_id),
2025-08-12 09:12:54 -07:00
KEY notification_number (notification_number)
2025-08-06 15:25:47 -07:00
) $charset_collate;";
// Queued calls table
$table_queued_calls = $wpdb->prefix . 'twp_queued_calls';
$sql_queued_calls = "CREATE TABLE $table_queued_calls (
id int(11) NOT NULL AUTO_INCREMENT,
queue_id int(11) NOT NULL,
call_sid varchar(100) NOT NULL,
from_number varchar(20) NOT NULL,
to_number varchar(20) NOT NULL,
position int(11) NOT NULL,
status varchar(20) DEFAULT 'waiting',
2025-08-11 20:31:48 -07:00
agent_phone varchar(20),
agent_call_sid varchar(100),
2025-08-06 15:25:47 -07:00
joined_at datetime DEFAULT CURRENT_TIMESTAMP,
answered_at datetime,
ended_at datetime,
PRIMARY KEY (id),
KEY queue_id (queue_id),
2025-08-11 20:31:48 -07:00
KEY call_sid (call_sid),
KEY status (status)
2025-08-06 15:25:47 -07:00
) $charset_collate;";
// Workflows table (keeping phone_number for backward compatibility, will be deprecated)
2025-08-06 15:25:47 -07:00
$table_workflows = $wpdb->prefix . 'twp_workflows';
$sql_workflows = "CREATE TABLE $table_workflows (
id int(11) NOT NULL AUTO_INCREMENT,
workflow_name varchar(100) NOT NULL,
phone_number varchar(20) NOT NULL,
workflow_data longtext,
is_active tinyint(1) DEFAULT 1,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY phone_number (phone_number)
) $charset_collate;";
// Workflow phone numbers junction table
$table_workflow_phones = $wpdb->prefix . 'twp_workflow_phones';
$sql_workflow_phones = "CREATE TABLE $table_workflow_phones (
id int(11) NOT NULL AUTO_INCREMENT,
workflow_id int(11) NOT NULL,
phone_number varchar(20) NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY workflow_phone (workflow_id, phone_number),
KEY workflow_id (workflow_id),
KEY phone_number (phone_number)
) $charset_collate;";
2025-08-06 15:25:47 -07:00
// Call log table
$table_call_log = $wpdb->prefix . 'twp_call_log';
$sql_call_log = "CREATE TABLE $table_call_log (
id int(11) NOT NULL AUTO_INCREMENT,
call_sid varchar(100) NOT NULL,
from_number varchar(20),
to_number varchar(20),
status varchar(20) NOT NULL,
duration int(11) DEFAULT 0,
workflow_id int(11),
workflow_name varchar(100),
queue_time int(11) DEFAULT 0,
actions_taken text,
call_data longtext,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY call_sid (call_sid),
KEY from_number (from_number),
KEY status (status)
) $charset_collate;";
// SMS log table
$table_sms_log = $wpdb->prefix . 'twp_sms_log';
$sql_sms_log = "CREATE TABLE $table_sms_log (
id int(11) NOT NULL AUTO_INCREMENT,
message_sid varchar(100) NOT NULL,
from_number varchar(20) NOT NULL,
to_number varchar(20) NOT NULL,
body text,
received_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY message_sid (message_sid)
) $charset_collate;";
// Voicemails table
$table_voicemails = $wpdb->prefix . 'twp_voicemails';
$sql_voicemails = "CREATE TABLE $table_voicemails (
id int(11) NOT NULL AUTO_INCREMENT,
workflow_id int(11),
from_number varchar(20) NOT NULL,
recording_url varchar(255),
duration int(11) DEFAULT 0,
transcription text,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY workflow_id (workflow_id)
) $charset_collate;";
// Agent groups table
$table_agent_groups = $wpdb->prefix . 'twp_agent_groups';
$sql_agent_groups = "CREATE TABLE $table_agent_groups (
id int(11) NOT NULL AUTO_INCREMENT,
group_name varchar(100) NOT NULL,
description text,
ring_strategy varchar(20) DEFAULT 'simultaneous',
timeout_seconds int(11) DEFAULT 30,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY group_name (group_name)
) $charset_collate;";
// Group members table
$table_group_members = $wpdb->prefix . 'twp_group_members';
$sql_group_members = "CREATE TABLE $table_group_members (
id int(11) NOT NULL AUTO_INCREMENT,
group_id int(11) NOT NULL,
user_id bigint(20) NOT NULL,
priority int(11) DEFAULT 0,
is_active tinyint(1) DEFAULT 1,
added_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY group_id (group_id),
KEY user_id (user_id),
UNIQUE KEY group_user (group_id, user_id)
) $charset_collate;";
// Agent status table
$table_agent_status = $wpdb->prefix . 'twp_agent_status';
$sql_agent_status = "CREATE TABLE $table_agent_status (
id int(11) NOT NULL AUTO_INCREMENT,
user_id bigint(20) NOT NULL,
status varchar(20) DEFAULT 'offline',
current_call_sid varchar(100),
last_activity datetime DEFAULT CURRENT_TIMESTAMP,
available_for_queues tinyint(1) DEFAULT 1,
PRIMARY KEY (id),
UNIQUE KEY user_id (user_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_schedules);
dbDelta($sql_queues);
dbDelta($sql_queued_calls);
dbDelta($sql_workflows);
dbDelta($sql_call_log);
dbDelta($sql_sms_log);
dbDelta($sql_voicemails);
// Callbacks table
$table_callbacks = $wpdb->prefix . 'twp_callbacks';
$sql_callbacks = "CREATE TABLE $table_callbacks (
id int(11) NOT NULL AUTO_INCREMENT,
phone_number varchar(20) NOT NULL,
requested_at datetime DEFAULT CURRENT_TIMESTAMP,
status varchar(20) DEFAULT 'pending',
attempts int(11) DEFAULT 0,
last_attempt datetime,
completed_at datetime,
queue_id int(11),
original_call_sid varchar(100),
callback_call_sid varchar(100),
notes text,
PRIMARY KEY (id),
KEY phone_number (phone_number),
KEY status (status),
KEY queue_id (queue_id)
) $charset_collate;";
dbDelta($sql_schedules);
dbDelta($sql_queues);
dbDelta($sql_queued_calls);
dbDelta($sql_workflows);
dbDelta($sql_workflow_phones);
2025-08-06 15:25:47 -07:00
dbDelta($sql_call_log);
dbDelta($sql_sms_log);
dbDelta($sql_voicemails);
dbDelta($sql_agent_groups);
dbDelta($sql_group_members);
dbDelta($sql_agent_status);
dbDelta($sql_callbacks);
2025-08-11 20:31:48 -07:00
// Add missing columns for existing installations
self::add_missing_columns();
}
/**
* Add missing columns for existing installations
*/
private static function add_missing_columns() {
global $wpdb;
$table_schedules = $wpdb->prefix . 'twp_phone_schedules';
// Check if holiday_dates column exists
$column_exists = $wpdb->get_results("SHOW COLUMNS FROM $table_schedules LIKE 'holiday_dates'");
if (empty($column_exists)) {
$wpdb->query("ALTER TABLE $table_schedules ADD COLUMN holiday_dates text AFTER after_hours_forward_number");
}
// Check if days_of_week column needs to be expanded
$column_info = $wpdb->get_results("SHOW COLUMNS FROM $table_schedules LIKE 'days_of_week'");
if (!empty($column_info) && $column_info[0]->Type === 'varchar(20)') {
$wpdb->query("ALTER TABLE $table_schedules MODIFY COLUMN days_of_week varchar(100) NOT NULL");
}
2025-08-12 09:12:54 -07:00
// Add new columns to call queues table and migrate phone_number to notification_number
2025-08-11 20:31:48 -07:00
$table_queues = $wpdb->prefix . 'twp_call_queues';
2025-08-12 09:12:54 -07:00
// Check if phone_number column exists and notification_number doesn't - need migration
2025-08-11 20:31:48 -07:00
$phone_column_exists = $wpdb->get_results("SHOW COLUMNS FROM $table_queues LIKE 'phone_number'");
2025-08-12 09:12:54 -07:00
$notification_column_exists = $wpdb->get_results("SHOW COLUMNS FROM $table_queues LIKE 'notification_number'");
if (!empty($phone_column_exists) && empty($notification_column_exists)) {
// Migrate phone_number to notification_number
$wpdb->query("ALTER TABLE $table_queues CHANGE phone_number notification_number varchar(20)");
// Update the index name
$wpdb->query("ALTER TABLE $table_queues DROP INDEX phone_number");
$wpdb->query("ALTER TABLE $table_queues ADD INDEX notification_number (notification_number)");
} elseif (empty($phone_column_exists) && empty($notification_column_exists)) {
// Fresh installation - add notification_number column
$wpdb->query("ALTER TABLE $table_queues ADD COLUMN notification_number varchar(20) AFTER queue_name");
$wpdb->query("ALTER TABLE $table_queues ADD INDEX notification_number (notification_number)");
2025-08-11 20:31:48 -07:00
}
// Check if agent_group_id column exists in queues table
$group_column_exists = $wpdb->get_results("SHOW COLUMNS FROM $table_queues LIKE 'agent_group_id'");
if (empty($group_column_exists)) {
2025-08-12 09:12:54 -07:00
$wpdb->query("ALTER TABLE $table_queues ADD COLUMN agent_group_id int(11) AFTER notification_number");
2025-08-11 20:31:48 -07:00
$wpdb->query("ALTER TABLE $table_queues ADD INDEX agent_group_id (agent_group_id)");
}
// Add agent columns to queued_calls table if they don't exist
$table_queued_calls = $wpdb->prefix . 'twp_queued_calls';
$agent_phone_exists = $wpdb->get_results("SHOW COLUMNS FROM $table_queued_calls LIKE 'agent_phone'");
if (empty($agent_phone_exists)) {
$wpdb->query("ALTER TABLE $table_queued_calls ADD COLUMN agent_phone varchar(20) AFTER status");
}
$agent_call_sid_exists = $wpdb->get_results("SHOW COLUMNS FROM $table_queued_calls LIKE 'agent_call_sid'");
if (empty($agent_call_sid_exists)) {
$wpdb->query("ALTER TABLE $table_queued_calls ADD COLUMN agent_call_sid varchar(100) AFTER agent_phone");
}
// Add status index if it doesn't exist
$status_index_exists = $wpdb->get_results("SHOW INDEX FROM $table_queued_calls WHERE Key_name = 'status'");
if (empty($status_index_exists)) {
$wpdb->query("ALTER TABLE $table_queued_calls ADD INDEX status (status)");
}
}
/**
* Perform table migrations for existing installations
*/
private static function migrate_tables() {
// Call the existing add_missing_columns function which now includes queue columns
self::add_missing_columns();
2025-08-06 15:25:47 -07:00
}
/**
* Set default plugin options
*/
private static function set_default_options() {
add_option('twp_twilio_account_sid', '');
add_option('twp_twilio_auth_token', '');
add_option('twp_elevenlabs_api_key', '');
add_option('twp_elevenlabs_voice_id', '');
add_option('twp_elevenlabs_model_id', 'eleven_multilingual_v2');
add_option('twp_default_queue_timeout', 300);
add_option('twp_default_queue_size', 10);
add_option('twp_urgent_keywords', 'urgent,emergency,important,asap,help');
add_option('twp_sms_notification_number', '');
2025-08-11 20:31:48 -07:00
add_option('twp_default_sms_number', '');
2025-08-06 15:25:47 -07:00
}
2025-08-12 09:54:32 -07:00
/**
* Create custom user roles for the plugin
*/
private static function create_user_roles() {
// Remove role first if it exists to ensure clean setup
remove_role('phone_agent');
// Add Phone Agent role with limited capabilities
add_role('phone_agent', 'Phone Agent', array(
// Basic WordPress capabilities
'read' => true,
// Profile management
'edit_profile' => true,
// Phone agent specific capabilities
'twp_access_voicemails' => true,
'twp_access_call_log' => true,
'twp_access_agent_queue' => true,
'twp_access_outbound_calls' => true,
'twp_access_sms_inbox' => true,
'twp_access_browser_phone' => true,
2025-08-12 10:36:32 -07:00
'twp_access_phone_numbers' => true,
2025-08-12 09:54:32 -07:00
));
}
2025-08-06 15:25:47 -07:00
}