MagicWP Docs

Email

Complete email configuration and management guide for WordPress

Email Management

Configure and manage email functionality in WordPress. Learn to set up SMTP, handle email deliverability, and implement advanced email features for your website.

Email Configuration Basics

WordPress Default Email Settings

Default Configuration

// WordPress uses PHP mail() by default
// Server: localhost
// Port: 25 (or server's SMTP port)
// Authentication: None
// Encryption: None

Basic Email Settings

// Configure WordPress email settings
update_option('admin_email', 'admin@yourdomain.com');
update_option('blogname', 'Your Site Name');
update_option('blogdescription', 'Your site description');

// Set email charset
define('WP_MAIL_CHARSET', 'UTF-8');

SMTP Configuration

Manual SMTP Setup

// Configure SMTP in wp-config.php
define('SMTP_HOST', 'smtp.yourdomain.com');
define('SMTP_PORT', 587);
define('SMTP_SECURE', 'tls'); // tls or ssl
define('SMTP_AUTH', true);
define('SMTP_USER', 'your-email@yourdomain.com');
define('SMTP_PASS', 'your-email-password');
define('SMTP_FROM', 'noreply@yourdomain.com');
define('SMTP_FROM_NAME', 'Your Site Name');

Gmail SMTP Configuration

// Gmail SMTP settings
define('SMTP_HOST', 'smtp.gmail.com');
define('SMTP_PORT', 587);
define('SMTP_SECURE', 'tls');
define('SMTP_AUTH', true);
define('SMTP_USER', 'your-gmail@gmail.com');
define('SMTP_PASS', 'your-app-password'); // Use app password, not regular password

Outlook/Hotmail SMTP

// Outlook SMTP settings
define('SMTP_HOST', 'smtp-mail.outlook.com');
define('SMTP_PORT', 587);
define('SMTP_SECURE', 'tls');
define('SMTP_AUTH', true);
define('SMTP_USER', 'your-email@outlook.com');
define('SMTP_PASS', 'your-password');

Email Delivery Services

SendGrid Configuration

// SendGrid SMTP settings
define('SMTP_HOST', 'smtp.sendgrid.net');
define('SMTP_PORT', 587);
define('SMTP_SECURE', 'tls');
define('SMTP_AUTH', true);
define('SMTP_USER', 'apikey'); // SendGrid uses 'apikey' as username
define('SMTP_PASS', 'your-sendgrid-api-key');

Mailgun Setup

// Mailgun SMTP settings
define('SMTP_HOST', 'smtp.mailgun.org');
define('SMTP_PORT', 587);
define('SMTP_SECURE', 'tls');
define('SMTP_AUTH', true);
define('SMTP_USER', 'your-mailgun-smtp-username');
define('SMTP_PASS', 'your-mailgun-smtp-password');

Amazon SES

// Amazon SES SMTP settings
define('SMTP_HOST', 'email-smtp.us-east-1.amazonaws.com'); // Change region as needed
define('SMTP_PORT', 587);
define('SMTP_SECURE', 'tls');
define('SMTP_AUTH', true);
define('SMTP_USER', 'your-ses-smtp-username');
define('SMTP_PASS', 'your-ses-smtp-password');

API-Based Email Services

SendGrid API Integration

// SendGrid API configuration
define('SENDGRID_API_KEY', 'your-sendgrid-api-key');
define('SENDGRID_FROM_EMAIL', 'noreply@yourdomain.com');
define('SENDGRID_FROM_NAME', 'Your Site Name');

// SendGrid API function
function send_email_via_sendgrid($to, $subject, $message, $headers = array()) {
    $email = new \SendGrid\Mail\Mail();
    $email->setFrom(SENDGRID_FROM_EMAIL, SENDGRID_FROM_NAME);
    $email->setSubject($subject);
    $email->addTo($to);
    $email->addContent("text/html", $message);

    $sendgrid = new \SendGrid(SENDGRID_API_KEY);

    try {
        $response = $sendgrid->send($email);
        return array('success' => true, 'response' => $response);
    } catch (Exception $e) {
        return array('success' => false, 'error' => $e->getMessage());
    }
}

Email Testing and Debugging

Email Testing Tools

WordPress Email Testing

// Test email functionality
function test_wordpress_email() {
    $to = 'test@yourdomain.com';
    $subject = 'WordPress Email Test';
    $message = 'This is a test email from WordPress.';
    $headers = array('Content-Type: text/html; charset=UTF-8');

    $result = wp_mail($to, $subject, $message, $headers);

    if ($result) {
        error_log('Email test successful');
        return 'Email sent successfully';
    } else {
        error_log('Email test failed');
        return 'Email sending failed';
    }
}

Email Logging

// Log all outgoing emails
function log_outgoing_email($mail) {
    $log_entry = array(
        'timestamp' => current_time('mysql'),
        'to' => is_array($mail['to']) ? implode(', ', $mail['to']) : $mail['to'],
        'subject' => $mail['subject'],
        'headers' => $mail['headers'],
        'message_length' => strlen($mail['message'])
    );

    // Log to file
    error_log('EMAIL LOG: ' . json_encode($log_entry));

    // Or store in database
    global $wpdb;
    $wpdb->insert('wp_email_logs', $log_entry);

    return $mail;
}
add_filter('wp_mail', 'log_outgoing_email');

Debug Email Issues

Common Email Problems

// Enable email debugging
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);

// Test SMTP connection
function test_smtp_connection() {
    $smtp_host = defined('SMTP_HOST') ? SMTP_HOST : 'localhost';
    $smtp_port = defined('SMTP_PORT') ? SMTP_PORT : 25;

    $connection = @fsockopen($smtp_host, $smtp_port, $errno, $errstr, 10);

    if ($connection) {
        fclose($connection);
        return "SMTP connection successful to {$smtp_host}:{$smtp_port}";
    } else {
        return "SMTP connection failed: {$errstr} ({$errno})";
    }
}

Email Template Management

Custom Email Templates

HTML Email Template

function create_html_email_template($subject, $content, $header_image = '') {
    $site_name = get_bloginfo('name');
    $site_url = get_bloginfo('url');

    $template = '
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>' . esc_html($subject) . '</title>
        <style>
            body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #f4f4f4; }
            .email-container { max-width: 600px; margin: 0 auto; background-color: #ffffff; }
            .email-header { background-color: #007cba; color: white; padding: 20px; text-align: center; }
            .email-content { padding: 30px; line-height: 1.6; }
            .email-footer { background-color: #f4f4f4; padding: 20px; text-align: center; font-size: 12px; color: #666; }
            .button { display: inline-block; background-color: #007cba; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; }
        </style>
    </head>
    <body>
        <div class="email-container">
            ' . ($header_image ? '<div class="email-header"><img src="' . esc_url($header_image) . '" alt="' . esc_attr($site_name) . '" style="max-width: 200px;"></div>' : '<div class="email-header"><h1>' . esc_html($site_name) . '</h1></div>') . '
            <div class="email-content">
                ' . $content . '
            </div>
            <div class="email-footer">
                <p>Sent from ' . esc_html($site_name) . '</p>
                <p><a href="' . esc_url($site_url) . '">' . esc_url($site_url) . '</a></p>
            </div>
        </div>
    </body>
    </html>';

    return $template;
}

Plain Text Email Template

function create_plain_text_email_template($subject, $content) {
    $site_name = get_bloginfo('name');
    $site_url = get_bloginfo('url');

    $template = $subject . "\n";
    $template .= str_repeat('=', strlen($subject)) . "\n\n";
    $template .= $content . "\n\n";
    $template .= "---\n";
    $template .= "Sent from {$site_name}\n";
    $template .= "{$site_url}\n";

    return $template;
}

Custom Email Headers

function add_custom_email_headers($headers) {
    // Add custom headers
    $headers[] = 'X-Mailer: WordPress/' . get_bloginfo('version');
    $headers[] = 'X-Site-Name: ' . get_bloginfo('name');
    $headers[] = 'X-Site-URL: ' . get_bloginfo('url');
    $headers[] = 'List-Unsubscribe: <' . get_bloginfo('admin_email') . '>';

    // Add anti-spam headers
    $headers[] = 'X-Anti-Abuse: This is a legitimate email from ' . get_bloginfo('name');

    return $headers;
}
add_filter('wp_mail', function($args) {
    $args['headers'] = add_custom_email_headers($args['headers'] ?? array());
    return $args;
});

Email Queue and Batch Processing

Email Queue System

Basic Email Queue

// Create email queue table on plugin activation
function create_email_queue_table() {
    global $wpdb;

    $table_name = $wpdb->prefix . 'email_queue';

    $sql = "CREATE TABLE $table_name (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        to_email varchar(255) NOT NULL,
        subject text NOT NULL,
        message longtext NOT NULL,
        headers text,
        status enum('queued','sent','failed') DEFAULT 'queued',
        priority tinyint(1) DEFAULT 5,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        sent_at datetime NULL,
        error_message text,
        PRIMARY KEY (id),
        KEY status (status),
        KEY priority (priority)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}
register_activation_hook(__FILE__, 'create_email_queue_table');

Queue Email Function

function queue_email($to, $subject, $message, $headers = array(), $priority = 5) {
    global $wpdb;

    $wpdb->insert(
        $wpdb->prefix . 'email_queue',
        array(
            'to_email' => $to,
            'subject' => $subject,
            'message' => $message,
            'headers' => serialize($headers),
            'priority' => $priority,
            'status' => 'queued'
        )
    );

    return $wpdb->insert_id;
}

Process Email Queue

function process_email_queue() {
    global $wpdb;

    $table_name = $wpdb->prefix . 'email_queue';

    // Get emails to process (limit to prevent timeout)
    $emails = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM $table_name
         WHERE status = 'queued'
         ORDER BY priority DESC, created_at ASC
         LIMIT %d",
        get_option('email_queue_batch_size', 10)
    ));

    foreach ($emails as $email) {
        $headers = unserialize($email->headers);
        $result = wp_mail($email->to_email, $email->subject, $email->message, $headers);

        if ($result) {
            // Mark as sent
            $wpdb->update(
                $table_name,
                array(
                    'status' => 'sent',
                    'sent_at' => current_time('mysql')
                ),
                array('id' => $email->id)
            );
        } else {
            // Mark as failed
            $wpdb->update(
                $table_name,
                array(
                    'status' => 'failed',
                    'error_message' => 'wp_mail() returned false'
                ),
                array('id' => $email->id)
            );
        }
    }
}

// Schedule queue processing
if (!wp_next_scheduled('process_email_queue')) {
    wp_schedule_event(time(), 'every_minute', 'process_email_queue');
}
add_action('process_email_queue', 'process_email_queue');

Email Analytics and Monitoring

Email Tracking

Open and Click Tracking

function add_email_tracking($message, $email_id) {
    $tracking_pixel = '<img src="' . get_site_url() . '/email-tracking/open.php?id=' . $email_id . '" width="1" height="1" style="display:none;">';
    $message .= $tracking_pixel;

    // Convert links to tracking links
    $message = preg_replace_callback(
        '/href=["\']([^"\']+)["\']/i',
        function($matches) use ($email_id) {
            $original_url = $matches[1];
            $tracking_url = get_site_url() . '/email-tracking/click.php?id=' . $email_id . '&url=' . urlencode($original_url);
            return 'href="' . $tracking_url . '"';
        },
        $message
    );

    return $message;
}

// Create tracking endpoints
function handle_email_open_tracking() {
    $email_id = intval($_GET['id']);

    // Log email open
    global $wpdb;
    $wpdb->insert(
        $wpdb->prefix . 'email_tracking',
        array(
            'email_id' => $email_id,
            'event_type' => 'open',
            'ip_address' => $_SERVER['REMOTE_ADDR'],
            'user_agent' => $_SERVER['HTTP_USER_AGENT'],
            'timestamp' => current_time('mysql')
        )
    );

    // Return 1x1 transparent pixel
    header('Content-Type: image/gif');
    echo base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
    exit;
}

function handle_email_click_tracking() {
    $email_id = intval($_GET['id']);
    $original_url = sanitize_text_field($_GET['url']);

    // Log email click
    global $wpdb;
    $wpdb->insert(
        $wpdb->prefix . 'email_tracking',
        array(
            'email_id' => $email_id,
            'event_type' => 'click',
            'ip_address' => $_SERVER['REMOTE_ADDR'],
            'user_agent' => $_SERVER['HTTP_USER_AGENT'],
            'clicked_url' => $original_url,
            'timestamp' => current_time('mysql')
        )
    );

    // Redirect to original URL
    wp_redirect($original_url);
    exit;
}

Email Performance Metrics

Delivery Statistics

function get_email_delivery_stats($date_range = 30) {
    global $wpdb;

    $start_date = date('Y-m-d H:i:s', strtotime("-{$date_range} days"));

    $stats = $wpdb->get_row($wpdb->prepare(
        "SELECT
            COUNT(*) as total_sent,
            SUM(CASE WHEN status = 'sent' THEN 1 ELSE 0 END) as delivered,
            SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed,
            AVG(TIMESTAMPDIFF(MINUTE, created_at, sent_at)) as avg_delivery_time
        FROM {$wpdb->prefix}email_queue
        WHERE created_at >= %s",
        $start_date
    ));

    if ($stats->total_sent > 0) {
        $stats->delivery_rate = ($stats->delivered / $stats->total_sent) * 100;
    } else {
        $stats->delivery_rate = 0;
    }

    return $stats;
}

Security and Compliance

Email Security Best Practices

SPF, DKIM, and DMARC Setup

// SPF Record Example
// Add to DNS: v=spf1 include:_spf.yourdomain.com include:_spf.google.com ~all

// DKIM Setup (example for cPanel)
function setup_dkim_keys() {
    $private_key_path = '/home/user/.dkim/private.key';
    $public_key_path = '/home/user/.dkim/public.key';

    // Generate DKIM keys
    $key_resource = openssl_pkey_new(array(
        'private_key_bits' => 2048,
        'private_key_type' => OPENSSL_KEYTYPE_RSA
    ));

    // Export keys
    openssl_pkey_export($key_resource, $private_key);
    $public_key_details = openssl_pkey_get_details($key_resource);

    file_put_contents($private_key_path, $private_key);
    file_put_contents($public_key_path, $public_key_details['key']);

    // Set permissions
    chmod($private_key_path, 0600);
    chmod($public_key_path, 0644);

    return array(
        'private_key' => $private_key,
        'public_key' => $public_key_details['key']
    );
}

GDPR Compliance

function manage_email_consent($user_id, $consent_type, $consent_given = true) {
    $consent_key = 'email_consent_' . $consent_type;

    update_user_meta($user_id, $consent_key, $consent_given ? 'yes' : 'no');
    update_user_meta($user_id, $consent_key . '_date', current_time('mysql'));

    // Log consent change
    global $wpdb;
    $wpdb->insert(
        $wpdb->prefix . 'email_consent_log',
        array(
            'user_id' => $user_id,
            'consent_type' => $consent_type,
            'consent_value' => $consent_given ? 'granted' : 'revoked',
            'ip_address' => $_SERVER['REMOTE_ADDR'],
            'timestamp' => current_time('mysql')
        )
    );
}

function check_email_consent($user_id, $consent_type) {
    $consent = get_user_meta($user_id, 'email_consent_' . $consent_type, true);
    return $consent === 'yes';
}

Advanced Email Features

Email Templates System

Template Management

class EmailTemplateManager {
    private $templates = array();

    public function __construct() {
        $this->load_default_templates();
    }

    private function load_default_templates() {
        $this->templates = array(
            'welcome' => array(
                'subject' => 'Welcome to {site_name}!',
                'body' => 'Welcome {user_name} to {site_name}...',
                'variables' => array('site_name', 'user_name', 'login_url')
            ),
            'password_reset' => array(
                'subject' => 'Password Reset - {site_name}',
                'body' => 'Reset your password...',
                'variables' => array('site_name', 'reset_url', 'user_name')
            ),
            'order_confirmation' => array(
                'subject' => 'Order Confirmation - {order_number}',
                'body' => 'Thank you for your order...',
                'variables' => array('order_number', 'customer_name', 'order_total')
            )
        );
    }

    public function get_template($template_name) {
        return isset($this->templates[$template_name]) ? $this->templates[$template_name] : null;
    }

    public function render_template($template_name, $variables = array()) {
        $template = $this->get_template($template_name);

        if (!$template) {
            return false;
        }

        $subject = $template['subject'];
        $body = $template['body'];

        // Replace variables
        foreach ($variables as $key => $value) {
            $subject = str_replace('{' . $key . '}', $value, $subject);
            $body = str_replace('{' . $key . '}', $value, $body);
        }

        return array(
            'subject' => $subject,
            'body' => $body
        );
    }
}

Automated Email Campaigns

Newsletter System

class EmailNewsletterSystem {
    private $subscribers_table;

    public function __construct() {
        global $wpdb;
        $this->subscribers_table = $wpdb->prefix . 'email_subscribers';
    }

    public function subscribe_user($email, $name = '') {
        global $wpdb;

        $wpdb->insert(
            $this->subscribers_table,
            array(
                'email' => $email,
                'name' => $name,
                'status' => 'active',
                'subscribed_at' => current_time('mysql')
            )
        );

        return $wpdb->insert_id;
    }

    public function send_newsletter($subject, $content, $subscriber_ids = array()) {
        global $wpdb;

        if (empty($subscriber_ids)) {
            // Get all active subscribers
            $subscriber_ids = $wpdb->get_col($wpdb->prepare(
                "SELECT id FROM {$this->subscribers_table} WHERE status = %s",
                'active'
            ));
        }

        $sent_count = 0;
        $failed_count = 0;

        foreach ($subscriber_ids as $subscriber_id) {
            $subscriber = $wpdb->get_row($wpdb->prepare(
                "SELECT * FROM {$this->subscribers_table} WHERE id = %d",
                $subscriber_id
            ));

            if ($subscriber) {
                $personalized_content = $this->personalize_content($content, $subscriber);
                $result = wp_mail($subscriber->email, $subject, $personalized_content);

                if ($result) {
                    $sent_count++;
                } else {
                    $failed_count++;
                    // Log failure
                    $this->log_send_failure($subscriber_id, 'wp_mail_failed');
                }
            }
        }

        return array(
            'sent' => $sent_count,
            'failed' => $failed_count
        );
    }

    private function personalize_content($content, $subscriber) {
        $replacements = array(
            '{name}' => $subscriber->name ?: 'Valued Subscriber',
            '{email}' => $subscriber->email,
            '{unsubscribe_url}' => $this->get_unsubscribe_url($subscriber->id)
        );

        return str_replace(array_keys($replacements), array_values($replacements), $content);
    }
}

Monitoring and Maintenance

Email Health Monitoring

Delivery Rate Tracking

function monitor_email_delivery_health() {
    $stats = get_email_delivery_stats(7); // Last 7 days

    $health_status = array(
        'delivery_rate' => $stats->delivery_rate,
        'total_sent' => $stats->total_sent,
        'status' => 'healthy'
    );

    // Check delivery rate
    if ($stats->delivery_rate < 90) {
        $health_status['status'] = 'warning';
        $health_status['issues'][] = 'Low delivery rate: ' . round($stats->delivery_rate, 2) . '%';
    }

    if ($stats->delivery_rate < 80) {
        $health_status['status'] = 'critical';
        $health_status['issues'][] = 'Critical: Delivery rate below 80%';
    }

    // Check for high failure rate
    if ($stats->total_sent > 0) {
        $failure_rate = ($stats->failed / $stats->total_sent) * 100;
        if ($failure_rate > 10) {
            $health_status['issues'][] = 'High failure rate: ' . round($failure_rate, 2) . '%';
        }
    }

    return $health_status;
}

Email Queue Maintenance

Cleanup Old Emails

function cleanup_email_queue() {
    global $wpdb;

    $retention_days = get_option('email_queue_retention_days', 30);
    $cutoff_date = date('Y-m-d H:i:s', strtotime("-{$retention_days} days"));

    // Delete old sent emails
    $deleted_sent = $wpdb->query($wpdb->prepare(
        "DELETE FROM {$wpdb->prefix}email_queue
         WHERE status = 'sent' AND created_at < %s",
        $cutoff_date
    ));

    // Keep failed emails longer (90 days)
    $failed_cutoff = date('Y-m-d H:i:s', strtotime("-90 days"));
    $deleted_failed = $wpdb->query($wpdb->prepare(
        "DELETE FROM {$wpdb->prefix}email_queue
         WHERE status = 'failed' AND created_at < %s",
        $failed_cutoff
    ));

    return array(
        'deleted_sent' => $deleted_sent,
        'deleted_failed' => $deleted_failed
    );
}

// Schedule cleanup
if (!wp_next_scheduled('cleanup_email_queue')) {
    wp_schedule_event(time(), 'daily', 'cleanup_email_queue');
}
add_action('cleanup_email_queue', 'cleanup_email_queue');

Best Practices

Email Configuration Best Practices

  1. Use SMTP: Always use SMTP instead of PHP mail()
  2. Authentication: Use proper authentication and encryption
  3. DKIM/SPF: Set up proper email authentication
  4. Monitoring: Monitor delivery rates and bounce rates
  5. Testing: Test emails before sending to users

Performance Best Practices

  1. Queue System: Use email queue for bulk sending
  2. Rate Limiting: Implement sending rate limits
  3. Batch Processing: Send emails in manageable batches
  4. Caching: Cache email templates and configurations
  5. Optimization: Optimize email content and attachments

Security Best Practices

  1. Encryption: Use TLS/SSL for email transmission
  2. Authentication: Implement proper sender authentication
  3. Validation: Validate email addresses and content
  4. Monitoring: Monitor for spam and abuse
  5. Compliance: Follow email regulations (CAN-SPAM, GDPR)

Complete WordPress email management and optimization guide.

On this page