- Add OpenAI integration for realistic email conversation generation - Enhance campaign timeline algorithm with natural distribution patterns - Improve message handling with Symfony Mailer components - Add conversation blueprint system for structured email threads - Implement visual timeline with heatmap for campaign tracking 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
247 lines
10 KiB
PHP
247 lines
10 KiB
PHP
<?php
|
|
|
|
add_action('admin_menu', function () {
|
|
add_menu_page(
|
|
__('Messages', 'rl-mailwarmer'), // Page title
|
|
__('Messages', 'rl-mailwarmer'), // Menu title
|
|
'manage_options', // Capability
|
|
'rl-mailwarmer-messages', // Menu slug
|
|
'rl_mailwarmer_render_messages_page', // Callback function
|
|
'dashicons-email-alt', // Icon
|
|
9 // Position
|
|
);
|
|
});
|
|
|
|
/**
|
|
* Render the Messages admin page with checkboxes and a Delete button.
|
|
*/
|
|
function rl_mailwarmer_render_messages_page() {
|
|
if (!current_user_can('manage_options')) {
|
|
return;
|
|
}
|
|
|
|
global $wpdb;
|
|
|
|
$conversation_table = $wpdb->prefix . 'rl_mailwarmer_conversations';
|
|
$message_table = $wpdb->prefix . 'rl_mailwarmer_messages';
|
|
|
|
// Fetch conversations with their messages
|
|
$conversations = $wpdb->get_results("
|
|
SELECT c.id as conversation_id, c.campaign_id, c.created_at, m.id as message_id, m.scheduled_for_timestamp, m.from_email, m.to_email, m.subject
|
|
FROM $conversation_table c
|
|
LEFT JOIN $message_table m ON c.id = m.conversation_id
|
|
WHERE m.status != 'scheduled'
|
|
ORDER BY c.created_at DESC, m.scheduled_for_timestamp ASC
|
|
");
|
|
|
|
?>
|
|
<div class="wrap">
|
|
<h1><?php esc_html_e('Messages', 'rl-mailwarmer'); ?></h1>
|
|
|
|
<?php if (empty($conversations)) : ?>
|
|
<p><?php esc_html_e('No messages found.', 'rl-mailwarmer'); ?></p>
|
|
<?php else : ?>
|
|
<form id="message-management-form" method="post">
|
|
<table class="widefat fixed striped">
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 50px;">
|
|
<input type="checkbox" id="check-all-messages">
|
|
</th>
|
|
<th><?php esc_html_e('Conversation ID', 'rl-mailwarmer'); ?></th>
|
|
<th><?php esc_html_e('Campaign ID', 'rl-mailwarmer'); ?></th>
|
|
<th><?php esc_html_e('Created At', 'rl-mailwarmer'); ?></th>
|
|
<th><?php esc_html_e('Message ID', 'rl-mailwarmer'); ?></th>
|
|
<th><?php esc_html_e('Scheduled For', 'rl-mailwarmer'); ?></th>
|
|
<th><?php esc_html_e('From', 'rl-mailwarmer'); ?></th>
|
|
<th><?php esc_html_e('To', 'rl-mailwarmer'); ?></th>
|
|
<th><?php esc_html_e('Subject', 'rl-mailwarmer'); ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($conversations as $conversation) : ?>
|
|
<tr>
|
|
<td>
|
|
<?php if ($conversation->message_id) : ?>
|
|
<input type="checkbox" name="selected_messages[]" value="<?php echo esc_attr($conversation->message_id); ?>">
|
|
<?php endif; ?>
|
|
</td>
|
|
<td><?php echo esc_html($conversation->conversation_id); ?></td>
|
|
<td><?php echo esc_html($conversation->campaign_id); ?></td>
|
|
<td><?php echo esc_html($conversation->created_at); ?></td>
|
|
<td><?php echo esc_html($conversation->message_id); ?></td>
|
|
<td><?php echo esc_html($conversation->scheduled_for_timestamp); ?></td>
|
|
<td><?php echo esc_html($conversation->from_email); ?></td>
|
|
<td><?php echo esc_html($conversation->to_email); ?></td>
|
|
<td><?php echo esc_html($conversation->subject); ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<p>
|
|
<button type="button" id="delete-selected-messages" class="button button-primary">
|
|
<?php esc_html_e('Delete Items', 'rl-mailwarmer'); ?>
|
|
</button>
|
|
</p>
|
|
</form>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
// Select all messages
|
|
const checkAll = document.getElementById('check-all-messages');
|
|
const checkboxes = document.querySelectorAll('input[name="selected_messages[]"]');
|
|
|
|
checkAll.addEventListener('change', function () {
|
|
checkboxes.forEach(checkbox => checkbox.checked = checkAll.checked);
|
|
});
|
|
|
|
// Handle delete button click
|
|
document.getElementById('delete-selected-messages').addEventListener('click', function () {
|
|
const selectedIds = Array.from(checkboxes)
|
|
.filter(checkbox => checkbox.checked)
|
|
.map(checkbox => checkbox.value);
|
|
|
|
if (selectedIds.length === 0) {
|
|
alert('<?php esc_html_e('Please select at least one message to delete.', 'rl-mailwarmer'); ?>');
|
|
return;
|
|
}
|
|
|
|
if (confirm('<?php esc_html_e('Are you sure you want to delete the selected messages?', 'rl-mailwarmer'); ?>')) {
|
|
jQuery.post(ajaxurl, {
|
|
action: 'rl_delete_messages',
|
|
message_ids: selectedIds,
|
|
}, function (response) {
|
|
if (response.success) {
|
|
alert('<?php esc_html_e('Selected messages deleted successfully.', 'rl-mailwarmer'); ?>');
|
|
location.reload(); // Reload the page to update the list
|
|
} else {
|
|
alert('<?php esc_html_e('Failed to delete messages.', 'rl-mailwarmer'); ?>');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
add_action('wp_ajax_rl_delete_messages', function () {
|
|
global $wpdb;
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(['message' => __('Permission denied.', 'rl-mailwarmer')]);
|
|
}
|
|
|
|
$message_ids = isset($_POST['message_ids']) ? array_map('intval', $_POST['message_ids']) : [];
|
|
|
|
if (empty($message_ids)) {
|
|
wp_send_json_error(['message' => __('No messages selected.', 'rl-mailwarmer')]);
|
|
}
|
|
|
|
$table_name = $wpdb->prefix . 'rl_mailwarmer_messages';
|
|
|
|
// Delete selected messages
|
|
$placeholders = implode(',', array_fill(0, count($message_ids), '%d'));
|
|
$query = "DELETE FROM $table_name WHERE id IN ($placeholders)";
|
|
$result = $wpdb->query($wpdb->prepare($query, $message_ids));
|
|
|
|
if ($result === false) {
|
|
wp_send_json_error(['message' => __('Failed to delete messages.', 'rl-mailwarmer')]);
|
|
}
|
|
|
|
wp_send_json_success(['message' => __('Messages deleted successfully.', 'rl-mailwarmer')]);
|
|
});
|
|
|
|
|
|
/**
|
|
* Add a metabox to the WP dashboard for monitoring and processing the message queue.
|
|
*/
|
|
add_action('wp_dashboard_setup', function () {
|
|
wp_add_dashboard_widget(
|
|
'rl_mailwarmer_message_queue',
|
|
__('Message Queue', 'rl-mailwarmer'),
|
|
'rl_mailwarmer_render_message_queue_widget'
|
|
);
|
|
});
|
|
|
|
/**
|
|
* Render the Message Queue dashboard widget.
|
|
*/
|
|
function rl_mailwarmer_render_message_queue_widget() {
|
|
global $wpdb;
|
|
|
|
// Count past-due messages
|
|
$table_name = $wpdb->prefix . 'rl_mailwarmer_messages';
|
|
$past_due_count = $wpdb->get_var(
|
|
$wpdb->prepare(
|
|
"SELECT COUNT(*) FROM $table_name WHERE status = %s AND scheduled_for_timestamp < %s",
|
|
'scheduled',
|
|
current_time('mysql')
|
|
)
|
|
);
|
|
|
|
?>
|
|
<div id="rl-mailwarmer-queue">
|
|
<p><strong><?php esc_html_e('Past-Due Messages:', 'rl-mailwarmer'); ?></strong> <?php echo esc_html($past_due_count); ?></p>
|
|
<button id="process-message-queue" class="button button-primary">
|
|
<?php esc_html_e('Process Message Queue', 'rl-mailwarmer'); ?>
|
|
</button>
|
|
<div id="message-queue-result" style="margin-top: 10px;"></div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const button = document.getElementById('process-message-queue');
|
|
const resultDiv = document.getElementById('message-queue-result');
|
|
|
|
button.addEventListener('click', function () {
|
|
button.disabled = true;
|
|
resultDiv.textContent = '<?php esc_html_e('Processing...', 'rl-mailwarmer'); ?>';
|
|
|
|
jQuery.post(ajaxurl, {
|
|
action: 'rl_mailwarmer_process_message_queue',
|
|
security: '<?php echo esc_js(wp_create_nonce('rl_mailwarmer_message_queue_nonce')); ?>'
|
|
}, function (response) {
|
|
button.disabled = false;
|
|
|
|
if (response.success) {
|
|
console.log("Success");
|
|
resultDiv.textContent = '<?php esc_html_e('Messages processed:', 'rl-mailwarmer'); ?> ' + response.data.success + ' with ' + response.data.failure + ' failures' ;
|
|
} else {
|
|
console.log("Failure");
|
|
resultDiv.textContent = '<?php esc_html_e('Error:', 'rl-mailwarmer'); ?> ' + response.data.message;
|
|
}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* AJAX handler to process the message queue.
|
|
*/
|
|
add_action('wp_ajax_rl_mailwarmer_process_message_queue', function () {
|
|
// log_to_file("wp_ajax_rl_mailwarmer_process_message_queue - Running");
|
|
// Verify nonce
|
|
if (!check_ajax_referer('rl_mailwarmer_message_queue_nonce', 'security', false)) {
|
|
wp_send_json_error(['message' => __('Invalid nonce.', 'rl-mailwarmer')]);
|
|
}
|
|
|
|
// Ensure the user has permission
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(['message' => __('Permission denied.', 'rl-mailwarmer')]);
|
|
}
|
|
|
|
try {
|
|
// Process pending messages
|
|
// log_to_file("wp_ajax_rl_mailwarmer_process_message_queue - Trying process_pending_messages()");
|
|
$results = RL_MailWarmer_Message_Handler::process_pending_messages();
|
|
|
|
wp_send_json_success($results);
|
|
} catch (Exception $e) {
|
|
wp_send_json_error(['message' => $e->getMessage()]);
|
|
}
|
|
});
|