feat: Add comprehensive email flow diagnostics and logging
🔍 Email Flow Diagnostic Tool: Created test-email-flow.php - comprehensive diagnostic dashboard: - System status (notification mode, email channel, Action Scheduler) - Event configuration checker - Email queue status (wp_options) - Action Scheduler queue status - Recent email logs viewer - Test actions (queue test email, process queue, test order email) - Troubleshooting guide 📝 Enhanced Debug Logging: Added detailed logging to EmailManager: - Hook trigger logging - Order validation logging - Event enabled/disabled logging - Email rendering status - wp_mail() call result - Full email flow traceability 🎯 Usage: 1. Visit: /wp-content/plugins/woonoow/test-email-flow.php 2. Check all system status indicators 3. Use test buttons to trigger emails 4. Monitor debug logs for detailed flow 📋 Logs to Watch: [EmailManager] send_order_processing_email triggered [EmailManager] order_processing email is disabled/enabled [EmailManager] Sending order_processing email [EmailManager] Email rendered successfully [EmailManager] wp_mail called - Result: success/failed [WooNooW MailQueue] Queued email ID [WooNooW MailQueue] Processing email_id [WooNooW MailQueue] Sent and deleted email ID 🚀 Troubleshooting Steps: 1. Check notification system mode (woonoow vs woocommerce) 2. Check email channel enabled 3. Check event-specific email enabled 4. Check Action Scheduler for failures 5. Check debug logs for flow 6. Test with diagnostic tool
This commit is contained in:
@@ -115,19 +115,33 @@ class EmailManager {
|
|||||||
* @param WC_Order $order
|
* @param WC_Order $order
|
||||||
*/
|
*/
|
||||||
public function send_order_processing_email($order_id, $order = null) {
|
public function send_order_processing_email($order_id, $order = null) {
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||||
|
error_log('[EmailManager] send_order_processing_email triggered for order #' . $order_id);
|
||||||
|
}
|
||||||
|
|
||||||
if (!$order) {
|
if (!$order) {
|
||||||
$order = wc_get_order($order_id);
|
$order = wc_get_order($order_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$order) {
|
if (!$order) {
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||||
|
error_log('[EmailManager] Order not found for ID: ' . $order_id);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if event is enabled
|
// Check if event is enabled
|
||||||
if (!$this->is_event_enabled('order_processing', 'email', 'customer')) {
|
if (!$this->is_event_enabled('order_processing', 'email', 'customer')) {
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||||
|
error_log('[EmailManager] order_processing email is disabled in settings');
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||||
|
error_log('[EmailManager] Sending order_processing email for order #' . $order_id);
|
||||||
|
}
|
||||||
|
|
||||||
// Send email
|
// Send email
|
||||||
$this->send_email('order_processing', 'customer', $order);
|
$this->send_email('order_processing', 'customer', $order);
|
||||||
}
|
}
|
||||||
@@ -364,6 +378,10 @@ class EmailManager {
|
|||||||
* @param array $extra_data
|
* @param array $extra_data
|
||||||
*/
|
*/
|
||||||
private function send_email($event_id, $recipient_type, $data, $extra_data = []) {
|
private function send_email($event_id, $recipient_type, $data, $extra_data = []) {
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||||
|
error_log('[EmailManager] send_email called - Event: ' . $event_id . ', Recipient: ' . $recipient_type);
|
||||||
|
}
|
||||||
|
|
||||||
// Get email renderer
|
// Get email renderer
|
||||||
$renderer = EmailRenderer::instance();
|
$renderer = EmailRenderer::instance();
|
||||||
|
|
||||||
@@ -371,16 +389,27 @@ class EmailManager {
|
|||||||
$email = $renderer->render($event_id, $recipient_type, $data, $extra_data);
|
$email = $renderer->render($event_id, $recipient_type, $data, $extra_data);
|
||||||
|
|
||||||
if (!$email) {
|
if (!$email) {
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||||
|
error_log('[EmailManager] Email rendering failed for event: ' . $event_id);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||||
|
error_log('[EmailManager] Email rendered successfully - To: ' . $email['to'] . ', Subject: ' . $email['subject']);
|
||||||
|
}
|
||||||
|
|
||||||
// Send email via wp_mail
|
// Send email via wp_mail
|
||||||
$headers = [
|
$headers = [
|
||||||
'Content-Type: text/html; charset=UTF-8',
|
'Content-Type: text/html; charset=UTF-8',
|
||||||
'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>',
|
'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>',
|
||||||
];
|
];
|
||||||
|
|
||||||
wp_mail($email['to'], $email['subject'], $email['body'], $headers);
|
$sent = wp_mail($email['to'], $email['subject'], $email['body'], $headers);
|
||||||
|
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||||
|
error_log('[EmailManager] wp_mail called - Result: ' . ($sent ? 'success' : 'failed'));
|
||||||
|
}
|
||||||
|
|
||||||
// Log email sent
|
// Log email sent
|
||||||
do_action('woonoow_email_sent', $event_id, $recipient_type, $email);
|
do_action('woonoow_email_sent', $event_id, $recipient_type, $email);
|
||||||
|
|||||||
255
test-email-flow.php
Normal file
255
test-email-flow.php
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Email Flow Diagnostic Tool
|
||||||
|
*
|
||||||
|
* Usage: Visit https://yoursite.com/wp-content/plugins/woonoow/test-email-flow.php
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Load WordPress
|
||||||
|
require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/wp-load.php';
|
||||||
|
|
||||||
|
if (!current_user_can('manage_options')) {
|
||||||
|
die('Access denied');
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Email Flow Diagnostic</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: monospace; padding: 20px; background: #1e1e1e; color: #d4d4d4; }
|
||||||
|
.pass { color: #4ec9b0; }
|
||||||
|
.fail { color: #f48771; }
|
||||||
|
.warn { color: #dcdcaa; }
|
||||||
|
h1 { color: #569cd6; }
|
||||||
|
h2 { color: #4ec9b0; margin-top: 30px; }
|
||||||
|
pre { background: #2d2d2d; padding: 10px; border-radius: 4px; overflow-x: auto; }
|
||||||
|
.status { display: inline-block; width: 60px; font-weight: bold; }
|
||||||
|
button { background: #0e639c; color: white; border: none; padding: 10px 20px; cursor: pointer; border-radius: 4px; margin: 10px 5px; }
|
||||||
|
button:hover { background: #1177bb; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Email Flow Diagnostic Tool</h1>
|
||||||
|
|
||||||
|
<h2>1. System Status</h2>
|
||||||
|
<?php
|
||||||
|
// Check notification system mode
|
||||||
|
$system_mode = get_option('woonoow_notification_system_mode', 'woonoow');
|
||||||
|
$status = ($system_mode === 'woonoow') ? '<span class="pass">✓ ENABLED</span>' : '<span class="fail">✗ DISABLED</span>';
|
||||||
|
echo "<div>$status - Notification System Mode: <strong>$system_mode</strong></div>";
|
||||||
|
|
||||||
|
// Check email channel
|
||||||
|
$email_enabled = get_option('woonoow_email_notifications_enabled', false);
|
||||||
|
$status = $email_enabled ? '<span class="pass">✓ ENABLED</span>' : '<span class="fail">✗ DISABLED</span>';
|
||||||
|
echo "<div>$status - Email Channel: <strong>" . ($email_enabled ? 'enabled' : 'disabled') . "</strong></div>";
|
||||||
|
|
||||||
|
// Check Action Scheduler
|
||||||
|
$as_exists = function_exists('as_enqueue_async_action');
|
||||||
|
$status = $as_exists ? '<span class="pass">✓ AVAILABLE</span>' : '<span class="warn">⚠ NOT AVAILABLE</span>';
|
||||||
|
echo "<div>$status - Action Scheduler: <strong>" . ($as_exists ? 'available' : 'not available (using wp-cron)') . "</strong></div>";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>2. Event Configuration</h2>
|
||||||
|
<?php
|
||||||
|
$settings = get_option('woonoow_notification_settings', []);
|
||||||
|
$events = $settings['events'] ?? [];
|
||||||
|
|
||||||
|
if (empty($events)) {
|
||||||
|
echo "<div><span class='fail'>✗ FAIL</span> - No events configured!</div>";
|
||||||
|
} else {
|
||||||
|
echo "<div><span class='pass'>✓ PASS</span> - " . count($events) . " events configured</div>";
|
||||||
|
echo "<pre>";
|
||||||
|
foreach ($events as $event_id => $event_data) {
|
||||||
|
$email_enabled = $event_data['channels']['email']['enabled'] ?? false;
|
||||||
|
$status_icon = $email_enabled ? '✓' : '✗';
|
||||||
|
echo "$status_icon $event_id: email " . ($email_enabled ? 'enabled' : 'disabled') . "\n";
|
||||||
|
}
|
||||||
|
echo "</pre>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>3. Email Queue Status</h2>
|
||||||
|
<?php
|
||||||
|
// Check for queued emails in wp_options
|
||||||
|
global $wpdb;
|
||||||
|
$queued_emails = $wpdb->get_results(
|
||||||
|
"SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name LIKE 'woonoow_mail_%' LIMIT 10"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (empty($queued_emails)) {
|
||||||
|
echo "<div><span class='warn'>⚠ INFO</span> - No emails currently queued</div>";
|
||||||
|
} else {
|
||||||
|
echo "<div><span class='pass'>✓ INFO</span> - " . count($queued_emails) . " emails in queue</div>";
|
||||||
|
echo "<pre>";
|
||||||
|
foreach ($queued_emails as $email) {
|
||||||
|
$payload = maybe_unserialize($email->option_value);
|
||||||
|
echo "ID: {$email->option_name}\n";
|
||||||
|
echo "To: " . ($payload['to'] ?? 'unknown') . "\n";
|
||||||
|
echo "Subject: " . ($payload['subject'] ?? 'unknown') . "\n";
|
||||||
|
echo "---\n";
|
||||||
|
}
|
||||||
|
echo "</pre>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>4. Action Scheduler Queue</h2>
|
||||||
|
<?php
|
||||||
|
if ($as_exists) {
|
||||||
|
$pending = $wpdb->get_var(
|
||||||
|
"SELECT COUNT(*) FROM {$wpdb->prefix}actionscheduler_actions
|
||||||
|
WHERE hook = 'woonoow/mail/send' AND status = 'pending'"
|
||||||
|
);
|
||||||
|
$failed = $wpdb->get_var(
|
||||||
|
"SELECT COUNT(*) FROM {$wpdb->prefix}actionscheduler_actions
|
||||||
|
WHERE hook = 'woonoow/mail/send' AND status = 'failed'"
|
||||||
|
);
|
||||||
|
$complete = $wpdb->get_var(
|
||||||
|
"SELECT COUNT(*) FROM {$wpdb->prefix}actionscheduler_actions
|
||||||
|
WHERE hook = 'woonoow/mail/send' AND status = 'complete'
|
||||||
|
ORDER BY action_id DESC LIMIT 10"
|
||||||
|
);
|
||||||
|
|
||||||
|
echo "<div><span class='pass'>✓ INFO</span> - Pending: <strong>$pending</strong></div>";
|
||||||
|
echo "<div><span class='pass'>✓ INFO</span> - Completed (last 10): <strong>$complete</strong></div>";
|
||||||
|
|
||||||
|
if ($failed > 0) {
|
||||||
|
echo "<div><span class='fail'>✗ WARN</span> - Failed: <strong>$failed</strong></div>";
|
||||||
|
|
||||||
|
// Show failed actions
|
||||||
|
$failed_actions = $wpdb->get_results(
|
||||||
|
"SELECT * FROM {$wpdb->prefix}actionscheduler_actions
|
||||||
|
WHERE hook = 'woonoow/mail/send' AND status = 'failed'
|
||||||
|
ORDER BY action_id DESC LIMIT 5"
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($failed_actions) {
|
||||||
|
echo "<pre>Recent failures:\n";
|
||||||
|
foreach ($failed_actions as $action) {
|
||||||
|
echo "ID: {$action->action_id}\n";
|
||||||
|
echo "Args: {$action->args}\n";
|
||||||
|
echo "Scheduled: {$action->scheduled_date_gmt}\n";
|
||||||
|
echo "---\n";
|
||||||
|
}
|
||||||
|
echo "</pre>";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "<div><span class='pass'>✓ PASS</span> - Failed: <strong>0</strong></div>";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "<div><span class='warn'>⚠ WARN</span> - Action Scheduler not available, using wp-cron</div>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>5. Recent Email Logs</h2>
|
||||||
|
<?php
|
||||||
|
// Check debug log for email activity
|
||||||
|
$debug_log = WP_CONTENT_DIR . '/debug.log';
|
||||||
|
if (file_exists($debug_log)) {
|
||||||
|
$log_lines = file($debug_log);
|
||||||
|
$email_logs = array_filter($log_lines, function($line) {
|
||||||
|
return strpos($line, '[WooNooW MailQueue]') !== false ||
|
||||||
|
strpos($line, 'woonoow_email_sent') !== false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (empty($email_logs)) {
|
||||||
|
echo "<div><span class='warn'>⚠ INFO</span> - No email logs found (enable WP_DEBUG to see logs)</div>";
|
||||||
|
} else {
|
||||||
|
echo "<div><span class='pass'>✓ INFO</span> - " . count($email_logs) . " email log entries found</div>";
|
||||||
|
echo "<pre>";
|
||||||
|
echo implode('', array_slice($email_logs, -10)); // Last 10 entries
|
||||||
|
echo "</pre>";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "<div><span class='warn'>⚠ INFO</span> - Debug log not found (enable WP_DEBUG_LOG)</div>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>6. Test Actions</h2>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if (isset($_GET['action'])) {
|
||||||
|
echo "<div style='margin: 20px 0; padding: 15px; background: #2d2d2d; border-left: 4px solid #4ec9b0;'>";
|
||||||
|
|
||||||
|
if ($_GET['action'] === 'test_email') {
|
||||||
|
echo "<h3>Testing Email Queue...</h3>";
|
||||||
|
|
||||||
|
// Queue a test email
|
||||||
|
$test_payload = [
|
||||||
|
'to' => get_option('admin_email'),
|
||||||
|
'subject' => 'WooNooW Test Email - ' . date('Y-m-d H:i:s'),
|
||||||
|
'html' => '<h1>Test Email</h1><p>This is a test email from WooNooW email queue system.</p><p>Time: ' . date('Y-m-d H:i:s') . '</p>',
|
||||||
|
'headers' => ['Content-Type: text/html; charset=UTF-8'],
|
||||||
|
'attachments' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
\WooNooW\Core\Mail\MailQueue::enqueue($test_payload);
|
||||||
|
|
||||||
|
echo "<p><span class='pass'>✓ SUCCESS</span> - Test email queued to: " . get_option('admin_email') . "</p>";
|
||||||
|
echo "<p>Check your inbox in a few moments. Also check Action Scheduler queue above.</p>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_GET['action'] === 'process_queue') {
|
||||||
|
echo "<h3>Processing Email Queue...</h3>";
|
||||||
|
|
||||||
|
if (function_exists('as_run_queue')) {
|
||||||
|
as_run_queue();
|
||||||
|
echo "<p><span class='pass'>✓ SUCCESS</span> - Action Scheduler queue processed</p>";
|
||||||
|
} else {
|
||||||
|
echo "<p><span class='warn'>⚠ WARN</span> - Action Scheduler not available</p>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_GET['action'] === 'test_order_email') {
|
||||||
|
echo "<h3>Testing Order Email...</h3>";
|
||||||
|
|
||||||
|
// Get a recent order
|
||||||
|
$orders = wc_get_orders(['limit' => 1, 'orderby' => 'date', 'order' => 'DESC']);
|
||||||
|
|
||||||
|
if (empty($orders)) {
|
||||||
|
echo "<p><span class='fail'>✗ FAIL</span> - No orders found. Create a test order first.</p>";
|
||||||
|
} else {
|
||||||
|
$order = $orders[0];
|
||||||
|
echo "<p>Using order #" . $order->get_id() . "</p>";
|
||||||
|
|
||||||
|
// Trigger order processing email
|
||||||
|
$email_manager = \WooNooW\Core\Notifications\EmailManager::instance();
|
||||||
|
$email_manager->send_order_processing_email($order->get_id(), $order);
|
||||||
|
|
||||||
|
echo "<p><span class='pass'>✓ SUCCESS</span> - Order processing email triggered</p>";
|
||||||
|
echo "<p>Check Action Scheduler queue and email logs above.</p>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</div>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div style="margin-top: 20px;">
|
||||||
|
<button onclick="window.location.href='?action=test_email'">Queue Test Email</button>
|
||||||
|
<button onclick="window.location.href='?action=process_queue'">Process Queue Now</button>
|
||||||
|
<button onclick="window.location.href='?action=test_order_email'">Test Order Email</button>
|
||||||
|
<button onclick="window.location.reload()">Refresh</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>7. Troubleshooting</h2>
|
||||||
|
<div>
|
||||||
|
<h3>If emails are not sending:</h3>
|
||||||
|
<ol>
|
||||||
|
<li>Check that "Notification System Mode" is set to "woonoow" (not "woocommerce")</li>
|
||||||
|
<li>Check that "Email Channel" is enabled</li>
|
||||||
|
<li>Check that specific events have email enabled in configuration</li>
|
||||||
|
<li>Check Action Scheduler for failed actions</li>
|
||||||
|
<li>Enable WP_DEBUG and WP_DEBUG_LOG to see detailed logs</li>
|
||||||
|
<li>Check your server's mail configuration (SMTP, sendmail, etc.)</li>
|
||||||
|
<li>Test with "Queue Test Email" button above</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 40px; padding-top: 20px; border-top: 1px solid #444; color: #888;">
|
||||||
|
Generated: <?php echo date('Y-m-d H:i:s'); ?>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user