File "mailer_worker-20260704040452.php"

Full Path: /home/fmpomerode/public_html/wp-admin/mailer_worker-20260704040452.php
File size: 4.02 KB
MIME-type: text/x-php; charset=utf-8
Charset: utf-8

<?php
// Worker PHP - appelé via HTTP par fire_worker()
// Ferme la connexion HTTP immédiatement et continue en arrière-plan

error_reporting(0);
ini_set('display_errors', 0);
set_time_limit(0);
ignore_user_abort(true);

// Fermer la session immédiatement
if (session_status() === PHP_SESSION_ACTIVE) {
    session_write_close();
}

$campaign_id = $_GET['campaign_id'] ?? ($argv[1] ?? '');
if (!$campaign_id) {
    http_response_code(400);
    die('No campaign ID');
}

$sessions_dir = sys_get_temp_dir() . '/mailer_sessions';
$campaign_file = "$sessions_dir/$campaign_id.json";
$lock_file = "$sessions_dir/$campaign_id.lock";

if (!file_exists($campaign_file)) {
    http_response_code(404);
    die('Campaign not found');
}

// Empêcher les doublons - vérifier si un autre worker tourne déjà
if (file_exists($lock_file)) {
    $lock_data = @json_decode(file_get_contents($lock_file), true);
    if ($lock_data && (time() - $lock_data['time']) < 15) {
        header('Content-Type: text/plain');
        echo 'already_running';
        exit;
    }
}

// === FERMER LA CONNEXION HTTP ===
// Envoyer la réponse et libérer le client
header('Content-Type: text/plain');
header('Connection: close');

// Buffer la réponse
ob_start();
echo 'started';
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush();

// Flush tous les buffers
if (ob_get_level() > 0) ob_end_flush();
@ob_flush();
flush();

// FastCGI : terminer la requête client
if (function_exists('fastcgi_finish_request')) {
    fastcgi_finish_request();
}

// === LE CLIENT EST LIBÉRÉ - ON CONTINUE EN ARRIÈRE-PLAN ===

function send_email_worker($to, $subject, $text, $html, $sender_name, $sender_email) {
    $boundary = md5(uniqid(time()));
    
    $headers = "";
    $headers .= "From: $sender_name <$sender_email>\r\n";
    $headers .= "Reply-To: $sender_email\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: multipart/alternative; boundary=\"$boundary\"\r\n";
    
    $body = "--$boundary\r\n";
    $body .= "Content-Type: text/plain; charset=UTF-8\r\n\r\n";
    $body .= ($text ?: strip_tags($html)) . "\r\n\r\n";
    $body .= "--$boundary\r\n";
    $body .= "Content-Type: text/html; charset=UTF-8\r\n\r\n";
    $body .= $html . "\r\n\r\n";
    $body .= "--$boundary--";
    
    return @mail($to, $subject, $body, $headers, "-f$sender_email");
}

// Boucle principale d'envoi
while (true) {
    // Heartbeat - prouver qu'on est vivant
    file_put_contents($lock_file, json_encode(['pid' => getmypid(), 'time' => time()]));
    
    clearstatcache();
    $raw = file_get_contents($campaign_file);
    $campaign = @json_decode($raw, true);
    
    if (!$campaign || $campaign['status'] !== 'running') {
        break;
    }
    
    if ($campaign['current_index'] >= $campaign['total']) {
        $campaign['status'] = 'completed';
        file_put_contents($campaign_file, json_encode($campaign));
        break;
    }
    
    // Envoyer un batch de 10 emails
    $batch_size = 10;
    $batch_count = 0;
    
    while ($batch_count < $batch_size && $campaign['current_index'] < $campaign['total']) {
        $email = $campaign['emails'][$campaign['current_index']];
        
        if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
            if (send_email_worker(
                $email,
                $campaign['subject'],
                $campaign['text_template'],
                $campaign['html_template'],
                $campaign['sender_name'],
                $campaign['sender_email']
            )) {
                $campaign['sent']++;
            } else {
                $campaign['errors']++;
            }
        } else {
            $campaign['errors']++;
        }
        
        $campaign['current_index']++;
        $batch_count++;
        usleep(30000); // 30ms entre chaque email
    }
    
    $campaign['last_update'] = time();
    
    if ($campaign['current_index'] >= $campaign['total']) {
        $campaign['status'] = 'completed';
    }
    
    file_put_contents($campaign_file, json_encode($campaign));
}

// Nettoyage
@unlink($lock_file);