isSMTP(); $mail->Host = $MAILCFG['smtp']['host']; $mail->Port = (int)$MAILCFG['smtp']['port']; $mail->SMTPSecure = $MAILCFG['smtp']['secure'] ?? PHPMailer::ENCRYPTION_STARTTLS; $mail->SMTPAuth = (bool)$MAILCFG['smtp']['auth']; $mail->Username = $MAILCFG['smtp']['username'] ?? ''; $mail->Password = $MAILCFG['smtp']['password'] ?? ''; // 🔒 robustesse $mail->Timeout = 8; // seconds (SMTP) $mail->SMTPKeepAlive = false; $mail->SMTPAutoTLS = true; $mail->SMTPDebug = 0; $mail->CharSet = 'UTF-8'; $mail->Encoding = 'base64'; $mail->XMailer = ''; if (!empty($MAILCFG['bounce'])) $mail->Sender = $MAILCFG['bounce']; $from = $MAILCFG['from'] ?? ['contact@uslugi.fr', 'USLUGI.FR']; $rpto = $MAILCFG['reply_to'] ?? ['contact@uslugi.fr', 'USLUGI.FR']; $mail->setFrom($from[0], $from[1] ?? ''); if (!empty($rpto[0])) $mail->addReplyTo($rpto[0], $rpto[1] ?? ''); $mail->addAddress($toEmail, $toName); if (!empty($MAILCFG['suppress_auto'])) { $mail->addCustomHeader('Auto-Submitted', 'auto-generated'); $mail->addCustomHeader('X-Auto-Response-Suppress', 'All'); } $mail->isHTML(true); $mail->Subject = $subject; $mail->Body = $htmlBody; $mail->AltBody = $textBody; // 📎 Invitation iCalendar $mail->addStringAttachment( $ical, $filename, 'base64', 'text/calendar; method=REQUEST; charset=UTF-8' ); $mail->send(); return true; } catch (Throwable $e) { error_log('PHPMailer RDV send exception: '.$e->getMessage()); if (!empty($mail->ErrorInfo)) { error_log('PHPMailer RDV ErrorInfo: '.$mail->ErrorInfo); } return false; } } /* ================== Valeurs par défaut Online/Offline ================== */ if (!isset($c_online)) { $c_online = 'online'; } if (!isset($c_offline)) { $c_offline = 'offline'; } /* ================== CSRF pour l'appel AJAX ================== */ if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(16)); } $CSRF = $_SESSION['csrf_token']; /* ================== Helpers UI (inchangés) ================== */ function ui_head(string $title): void { ?>