'error', 'message' => '' ); //Instantiation and passing `true` enables exceptions $objMail = new PHPMailer(true); try { //Server settings $objMail->SMTPDebug = SMTP::DEBUG_OFF; $objMail->isSMTP(); //Send using SMTP $objMail->Host = _SMTP_HOST; $objMail->SMTPAuth = false; //Enable SMTP authentication // $objMail->Username = _SMTP_USER; //$objMail->Password = _SMTP_PASSWORD; //$objMail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged $objMail->Port = _SMTP_PORT; $objMail->CharSet = "UTF-8"; $objMail->SMTPOptions = array( 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true ) ); if ($strLangue == 'fr') { //To load the French version $objMail->setLanguage('fr'); } //Recipients $objMail->setFrom($vEmail, fxRemoveHtml($vClient)); $objMail->AddAddress($strMailTo, $strNameTo); if ($strMailFrom != $vEmail) { $objMail->addReplyTo($strMailFrom, $strNameFrom); } else { //$objMail->addReplyTo($vEmail, fxRemoveHtml($vClient)); } //Content $objMail->isHTML(true); $objMail->Subject = $strSubject; $strContent = email_embed_images_as_cid($strContent, $objMail, [ 'base_path' => $vDomaine . $vRepertoireFichiers, // si tu as des src relatifs 'max_bytes' => 1024*1024 ]); $objMail->Body = $strContent; $objHTML = new \Html2Text\Html2Text($strContent); $objMail->AltBody = $objHTML->getText(); $objMail->send(); $blnReturn = true; $arrReturn['state'] = 'success'; $arrReturn['message'] = "Message was sent."; } catch (Exception $e) { $arrReturn['message'] = "Message could not be sent. Mailer Error: {$objMail->ErrorInfo}"; } // Log the result $sqlInsert = " INSERT INTO logs_mails SET log_subject = '" . $objDatabase->fxEscape($strSubject) . "', log_content = '" . $objDatabase->fxEscape($strContent) . "', log_mail_to = '" . $objDatabase->fxEscape($strMailTo) . "', log_name_to = '" . $objDatabase->fxEscape($strNameTo) . "', log_mail_from = '" . $objDatabase->fxEscape($strMailFrom) . "', log_name_from = '" . $objDatabase->fxEscape($strNameFrom) . "', log_status = '" . $objDatabase->fxEscape($arrReturn['state']) . "', log_message = '" . $objDatabase->fxEscape($arrReturn['message']) . "' "; $qryInsert = $objDatabase->fxQuery($sqlInsert); return $blnReturn; } // fonction envoi un courriel (JSP) // param : sujet, corps du message, courriel destinataire, nom destinataire, courriel expéditeur, nom expéditeur, smtp (oui/non), html (oui/non) // externe (oui/non) -> appel fxSendMail provient d'un autre site (ie, Boutique Premiere) (AJOUT: AL, Juin 2015) // retourne : vrai ou faux function fxSendMailOld($subject, $body, $to_mail, $to_name, $from_mail, $from_name, $smtp, $html, $externe = 0, $attach = '', $blnGoDaddy = false) { $blnGoDaddy = filter_var(fxGetVariable('mailGD'), FILTER_VALIDATE_BOOLEAN); $error = 0; $strError = ''; $arrSmtp = $GLOBALS['strDebug'] = []; require_once 'mailer/PHPMailer.php'; require_once 'mailer/SMTP.php'; require_once 'mailer/Exception.php'; require_once 'php/Html2Text.php'; $mail = new PHPMailer(); $mail->IsSMTP(); $mail->SMTPAuth = true; if ($blnGoDaddy) { $mail->Host = "smtpout.secureserver.net"; $mail->Port = 25; $mail->Username = "sendms1@progiweb.us"; $mail->Password = "airstream911"; } else { $mail->Host = "pop.progiweb.ca"; $mail->Port = 25; $mail->Username = "ms1inscription@progiweb.ca"; $mail->Password = "airstream911"; } $arrSmtp['host'] = $mail->Host; $arrSmtp['port'] = $mail->Port; $arrSmtp['username'] = $mail->Username; $arrSmtp['password'] = $mail->Password; if ($externe == 0) { $mail->SetFrom($GLOBALS['vEmail'], fxRemoveHtml($GLOBALS['vClient'])); // $from_mail="ms1inscription@progiweb.ca"; // $mail->SetFrom($from_mail, fxRemoveHtml($GLOBALS['vClient'])); $mail->Subject = fxRemoveHtml($GLOBALS['vClient']) . " | " . $subject; } if ($externe == 1) { $mail->SetFrom($from_mail, $from_name); $mail->Subject = $from_name . " | " . $subject; } $mail->CharSet = "UTF-8"; $mail->AddReplyTo($from_mail, $from_name); // vérifier s'il y a des fichiers à attacher if ($attach != '') { $mail->AddAttachment($attach); } $mail->isHTML(true); $mail->Body = $body; $html = new \Html2Text\Html2Text($body); $mail->AltBody = $html->getText(); $mail->AddAddress($to_mail, $to_name); $mail->SMTPDebug = 2; $mail->Debugoutput = function($str, $level) { $GLOBALS['strDebug'][] = "debug level $level; message: $str\n"; }; if (!$mail->send()) { $error = 1; $strError = print_r($mail->ErrorInfo, true); } fxLogMail($to_mail, $to_name, $error, $strError, print_r($GLOBALS['strDebug'], true), print_r($arrSmtp, true), $subject, $body); // Clear all addresses and attachments for next loop $mail->ClearAddresses(); $mail->ClearAttachments(); if ($error == 0) return true; else { //fxcreer_log("Erreur lors de l'envoi du mail. (TO: $to_mail, FROM $from_mail:, SUJET: $subject)"); return false; } } function fxLogMail($to_mail, $to_name, $error, $strError, $strDebug, $strSmtp, $subject, $body) { global $objDatabase; $sqlInsert = "INSERT INTO email_logs SET log_error = " . intval($error) . ", log_error_msg = '" . $objDatabase->fxEscape($strError) . "', log_smtp_connect = '" . $objDatabase->fxEscape($strSmtp) . "', log_smtp_debug = '" . $objDatabase->fxEscape($strDebug) . "', log_subject = '" . $objDatabase->fxEscape($subject) . "', log_message = '" . $objDatabase->fxEscape($body) . "', log_mailto = '" . $objDatabase->fxEscape($to_mail) . "', log_nameto = '" . $objDatabase->fxEscape($to_name) . "'"; $qryInsert = $objDatabase->fxQuery($sqlInsert); return $qryInsert; } /** * Convertit toutes les (et relatives) en images CID. * Si une image est inaccessible ou trop lourde, on la retire pour éviter le "Disarmed". */ function email_embed_images_as_cid(string $html, PHPMailer $mail, array $opt = []): string { $maxBytes = $opt['max_bytes'] ?? 1024 * 1024; // 1 Mo max pour une image // 0) Détecter si c'est vraiment du HTML // Si strip_tags() ne change rien, on est en texte brut → on ne touche pas. $isHtml = (strlen($html) !== strlen(strip_tags($html))); if (!$isHtml) { return $html; } // On travaille sur une copie $originalHtml = $html; // 1) Préparer un vrai document HTML pour DOMDocument // - Si pas de , on enveloppe dans ... // - On force un pour éviter que DOMDocument casse les accents. $unwrapBody = false; if (stripos($html, ', des

, etc.) $html = '' . $html . ''; $unwrapBody = true; } else { // Document HTML complet : on s'assure qu'il a un charset UTF-8 if (stripos($html, 'charset=') === false) { $html = preg_replace( '#]*)>#i', '', $html, 1, $count ); if ($count === 0) { // pas de , on colle la meta au début $html = '' . $html; } } } // 2) Charger dans DOMDocument en UTF-8 libxml_use_internal_errors(true); $doc = new DOMDocument('1.0', 'UTF-8'); $loaded = $doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); libxml_clear_errors(); if (!$loaded) { // Si DOMDocument n'arrive pas à parser, on ne casse rien → on renvoie l'original return $originalHtml; } $xp = new DOMXPath($doc); // 3) Traiter toutes les foreach ($xp->query('//img[@src]') as $img) { /** @var DOMElement $img */ $src = trim($img->getAttribute('src')); if ($src === '' || stripos($src, 'cid:') === 0 || stripos($src, 'data:') === 0) { continue; // déjà safe ou inline } $binary = null; $mime = null; $tmpPath = null; // a) src absolu http(s) if (preg_match('#^https?://#i', $src)) { $binary = @file_get_contents($src); if ($binary === false || strlen($binary) === 0 || strlen($binary) > $maxBytes) { // Image introuvable ou trop grosse → on enlève l'image $img->parentNode->removeChild($img); continue; } $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->buffer($binary) ?: 'application/octet-stream'; if (strpos($mime, 'image/') !== 0) { $img->parentNode->removeChild($img); continue; } $ext = explode('/', $mime)[1] ?? 'bin'; $cid = 'img' . bin2hex(random_bytes(8)); $tmpPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $cid . '.' . $ext; file_put_contents($tmpPath, $binary); $mail->addEmbeddedImage($tmpPath, $cid, basename($tmpPath), 'base64', $mime); $img->setAttribute('src', 'cid:' . $cid); continue; } // b) src relatif (ex: "images/logo.png" ou "/images/logo.png") $fsPath = null; if ($src[0] === '/') { $fsPath = rtrim($_SERVER['DOCUMENT_ROOT'] ?? '', '/') . $src; } else { $basePath = $opt['base_path'] ?? null; $fsPath = $basePath ? rtrim($basePath, '/') . '/' . $src : null; } if ($fsPath && is_file($fsPath)) { $mime = mime_content_type($fsPath) ?: 'image/png'; $cid = 'img' . bin2hex(random_bytes(8)); $mail->addEmbeddedImage($fsPath, $cid, basename($fsPath), 'base64', $mime); $img->setAttribute('src', 'cid:' . $cid); } else { // Image introuvable → on enlève l’ pour éviter les "disarmed" $img->parentNode->removeChild($img); } } // 4) (Optionnel) retirer les vers des polices externes (ex: Google Fonts) foreach ($xp->query('//link[@href]') as $link) { $href = $link->getAttribute('href'); if (stripos($href, 'fonts.googleapis.com') !== false) { $link->parentNode->removeChild($link); } } // 5) Récupérer le HTML final if ($unwrapBody) { // On avait enveloppé dans ... → on ne renvoie que le contenu du body $bodyList = $doc->getElementsByTagName('body'); if ($bodyList->length > 0) { $body = $bodyList->item(0); $result = ''; foreach ($body->childNodes as $child) { $result .= $doc->saveHTML($child); } return $result; } } // Cas document complet : on renvoie tout return $doc->saveHTML(); }