Implement multiple phone numbers per workflow feature
Database Changes: - Added twp_workflow_phones junction table for many-to-many relationship - Updated activator to create and manage new table - Maintained backward compatibility with existing phone_number field Workflow Management: - Added set_workflow_phone_numbers() and get_workflow_phone_numbers() methods - Updated get_workflow_by_phone_number() to check both old and new structures - Enhanced save/update handlers to support phone_numbers array - Added AJAX endpoint for retrieving workflow phone numbers User Interface: - Replaced single phone number select with dynamic multi-select interface - Added "Add Number" and "Remove" buttons for managing multiple numbers - Updated workflow listing to display all assigned phone numbers - Enhanced JavaScript for phone number management and validation The webhook routing already supports multiple numbers since get_workflow_by_phone_number() was updated to check both structures. This feature allows users to assign multiple Twilio phone numbers to trigger the same workflow. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1476,10 +1476,14 @@ class TWP_Admin {
|
||||
foreach ($workflows as $workflow) {
|
||||
$workflow_data = json_decode($workflow->workflow_data, true);
|
||||
$step_count = isset($workflow_data['steps']) ? count($workflow_data['steps']) : 0;
|
||||
|
||||
// Get phone numbers for this workflow
|
||||
$phone_numbers = TWP_Workflow::get_workflow_phone_numbers($workflow->id);
|
||||
$phone_display = !empty($phone_numbers) ? implode(', ', $phone_numbers) : $workflow->phone_number;
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo esc_html($workflow->workflow_name); ?></td>
|
||||
<td><?php echo esc_html($workflow->phone_number); ?></td>
|
||||
<td><?php echo esc_html($phone_display); ?></td>
|
||||
<td><?php echo $step_count; ?> steps</td>
|
||||
<td>
|
||||
<span class="twp-status <?php echo $workflow->is_active ? 'active' : 'inactive'; ?>">
|
||||
@@ -1510,11 +1514,17 @@ class TWP_Admin {
|
||||
<input type="text" id="workflow-name" name="workflow_name" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Phone Number:</label>
|
||||
<select id="workflow-phone" name="phone_number" required>
|
||||
<option value="">Select a phone number...</option>
|
||||
<!-- Will be populated via AJAX -->
|
||||
</select>
|
||||
<label>Phone Numbers:</label>
|
||||
<div id="workflow-phone-numbers">
|
||||
<div class="phone-number-row">
|
||||
<select name="phone_numbers[]" class="workflow-phone-select" required>
|
||||
<option value="">Select a phone number...</option>
|
||||
<!-- Will be populated via AJAX -->
|
||||
</select>
|
||||
<button type="button" class="button add-phone-number" style="margin-left: 10px;">Add Number</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="description">You can assign multiple phone numbers to this workflow. All selected numbers will trigger this workflow when called.</p>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
@@ -2913,9 +2923,27 @@ class TWP_Admin {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle phone numbers - can be a single number (legacy) or array (new)
|
||||
$phone_numbers = array();
|
||||
if (isset($_POST['phone_numbers']) && is_array($_POST['phone_numbers'])) {
|
||||
// New multi-number format
|
||||
foreach ($_POST['phone_numbers'] as $number) {
|
||||
$number = sanitize_text_field($number);
|
||||
if (!empty($number)) {
|
||||
$phone_numbers[] = $number;
|
||||
}
|
||||
}
|
||||
} elseif (isset($_POST['phone_number'])) {
|
||||
// Legacy single number format
|
||||
$number = sanitize_text_field($_POST['phone_number']);
|
||||
if (!empty($number)) {
|
||||
$phone_numbers[] = $number;
|
||||
}
|
||||
}
|
||||
|
||||
$data = array(
|
||||
'workflow_name' => sanitize_text_field($_POST['workflow_name']),
|
||||
'phone_number' => sanitize_text_field($_POST['phone_number']),
|
||||
'phone_number' => isset($phone_numbers[0]) ? $phone_numbers[0] : '', // Keep first number for backward compatibility
|
||||
'steps' => isset($workflow_data_parsed['steps']) ? $workflow_data_parsed['steps'] : array(),
|
||||
'conditions' => isset($workflow_data_parsed['conditions']) ? $workflow_data_parsed['conditions'] : array(),
|
||||
'actions' => isset($workflow_data_parsed['actions']) ? $workflow_data_parsed['actions'] : array(),
|
||||
@@ -2927,13 +2955,21 @@ class TWP_Admin {
|
||||
$result = TWP_Workflow::update_workflow($workflow_id, $data);
|
||||
} else {
|
||||
$result = TWP_Workflow::create_workflow($data);
|
||||
if ($result !== false) {
|
||||
global $wpdb;
|
||||
$workflow_id = $wpdb->insert_id;
|
||||
}
|
||||
}
|
||||
|
||||
// Save phone numbers to junction table
|
||||
if ($result !== false && !empty($phone_numbers)) {
|
||||
TWP_Workflow::set_workflow_phone_numbers($workflow_id, $phone_numbers);
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
wp_send_json_error('Failed to save workflow to database');
|
||||
} else {
|
||||
global $wpdb;
|
||||
wp_send_json_success(array('success' => true, 'workflow_id' => $workflow_id ?: $wpdb->insert_id));
|
||||
wp_send_json_success(array('success' => true, 'workflow_id' => $workflow_id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2953,6 +2989,23 @@ class TWP_Admin {
|
||||
wp_send_json_success($workflow);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for getting workflow phone numbers
|
||||
*/
|
||||
public function ajax_get_workflow_phone_numbers() {
|
||||
check_ajax_referer('twp_ajax_nonce', 'nonce');
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error('Unauthorized');
|
||||
return;
|
||||
}
|
||||
|
||||
$workflow_id = intval($_POST['workflow_id']);
|
||||
$phone_numbers = TWP_Workflow::get_workflow_phone_numbers($workflow_id);
|
||||
|
||||
wp_send_json_success($phone_numbers);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for deleting workflow
|
||||
*/
|
||||
|
Reference in New Issue
Block a user