Browse Source

Mieux preparer et compter les destinataires valides car une combinaison dest vide + bcc invalide passait a travers les mailles et declenchait une erreur facteur

pull/16/head
Cerdic 8 months ago committed by Gitea
parent
commit
33e4c2c000
  1. 21
      inc/Facteur/FacteurMail.php
  2. 195
      inc/facteur.php

21
inc/Facteur/FacteurMail.php

@ -197,21 +197,28 @@ class FacteurMail extends PHPMailer {
* clear tous les destinataires precedemment definis
*
* @param string | array $email
* @return int
* nombre d'adresses valides
* @throws Exception
*/
public function setDest($email) {
$this->clearAllRecipients();
if (!is_array($email)) {
$email = [$email];
}
$nb_dest = 0;
//Pour un envoi multiple de mail, $email doit être un tableau avec les adresses.
if (is_array($email)) {
foreach ($email as $cle => $adresseMail) {
if (!$this->AddAddress($adresseMail)) {
$this->log("Erreur AddAddress $adresseMail : " . print_r($this->ErrorInfo, true), _LOG_ERREUR);
}
foreach ($email as $adresseMail) {
if (!$this->AddAddress($adresseMail)) {
$this->log("Erreur AddAddress $adresseMail : " . print_r($this->ErrorInfo, true), _LOG_ERREUR);
}
else {
$nb_dest++;
}
} elseif (!$this->AddAddress($email)) {
$this->log("Erreur AddAddress $email : " . print_r($this->ErrorInfo, true), _LOG_ERREUR);
}
return $nb_dest;
}
/**

195
inc/facteur.php

@ -10,9 +10,9 @@
/**
* @param array|string $destinataire
* @param array|string $destinataires
* si array : un tableau de mails
* si string : un mail ou une liste de mails séparés par des virgules
* si string : un mail ou une liste de mails séparés par des virgules
* @param string $sujet
* @param array $message
* string $texte : le corps d'email au format texte
@ -21,11 +21,11 @@
* string $nom_envoyeur : un nom d'envoyeur pour completer l'email from
* string $cc : destinataires en copie conforme
* string $bcc : destinataires en copie conforme cachee
* string|array $repondre_a : une ou plusieurs adresses à qui répondre.
* string|array $repondre_a : une ou plusieurs adresses à qui répondre.
* On peut aussi donner une liste de tableaux du type :
* array('email' => 'test@exemple.com', 'nom' => 'Adresse de test')
* pour spécifier un nom d'envoyeur pour chaque adresse.
* string $nom_repondre_a : le nom d'envoyeur pour compléter l'email repondre_a
* pour spécifier un nom d'envoyeur pour chaque adresse.
* string $nom_repondre_a : le nom d'envoyeur pour compléter l'email repondre_a
* string $adresse_erreur : addresse de retour en cas d'erreur d'envoi
* array $pieces_jointes : listes de pieces a embarquer dans l'email, chacune au format array :
* string $chemin : chemin file system pour trouver le fichier a embarquer
@ -38,12 +38,7 @@
* @return bool
* @throws Exception
*/
function facteur_envoyer_mail($destinataire, string $sujet, array $message) {
$nom_repondre_a = null;
$message_html = '';
$message_texte = '';
$nom_envoyeur = $cc = $bcc = $repondre_a = '';
$pieces_jointes = [];
function facteur_envoyer_mail($destinataires, string $sujet, array $message) {
$important = false;
// si $message est un tableau -> fonctionnalites etendues
@ -55,8 +50,8 @@ function facteur_envoyer_mail($destinataire, string $sujet, array $message) {
$pieces_jointes = $message['pieces_jointes'] ?? [];
$nom_envoyeur = $message['nom_envoyeur'] ?? '';
$from = $message['from'];
$cc = $message['cc'] ?? '';
$bcc = $message['bcc'] ?? '';
$cc = $message['cc'] ?? [];
$bcc = $message['bcc'] ?? [];
$repondre_a = $message['repondre_a'] ?? '';
$nom_repondre_a = $message['nom_repondre_a'] ?? '';
$adresse_erreur = $message['adresse_erreur'] ?? '';
@ -90,64 +85,36 @@ function facteur_envoyer_mail($destinataire, string $sujet, array $message) {
$exceptions = $message['exceptions'];
}
// mode TEST : forcer l'email
if (defined('_TEST_EMAIL_DEST')) {
if (!_TEST_EMAIL_DEST) {
spip_log($e = _T('facteur:erreur_envoi_bloque_constante'), 'mail.' . _LOG_ERREUR);
if ($exceptions) {
throw new Exception($e);
}
return false;
} else {
$destinataire = _TEST_EMAIL_DEST;
}
// On crée l'objet Facteur (PHPMailer) pour le manipuler ensuite
$options = [];
if ($exceptions) {
$options['exceptions'] = $exceptions;
}
$facteur = facteur_factory($options);
// commençons par verifier les destinataires
// plusieurs destinataires peuvent etre fournis separes par des virgules
// c'est un format standard dans l'envoi de mail
// les passer au format array pour phpMailer
// mais ne pas casser si on a deja un array en entree
// si pas destinataire du courriel on renvoie false (eviter les warning PHP : ligne 464 de phpmailer-php5/class.phpmailer.php
// suppression des adresses de courriels invalides, si aucune valide, renvoyer false (eviter un warning PHP : ligne 464 de phpmailer-php5/class.phpmailer.php)
if (is_array($destinataire)) {
$destinataire = implode(', ', $destinataire);
}
if (strlen($destinataire) > 0) {
$destinataire = array_map('trim', explode(',', $destinataire));
foreach ($destinataire as $key => $value) {
if (!email_valide($value)) {
unset($destinataire[$key]);
}
}
if (count($destinataire) == 0) {
spip_log($e = "Aucune adresse email de destination valable pour l'envoi du courriel.", 'mail.' . _LOG_ERREUR);
if ($exceptions) {
throw new Exception($e);
}
return false;
}
} else {
if ($bcc) {
// On peut envoyer de mail que en bcc
$destinataire = '';
} else {
spip_log($e = "Aucune adresse email de destination valable pour l'envoi du courriel.", 'mail.' . _LOG_ERREUR);
if ($exceptions) {
throw new Exception($e);
}
return false;
// les passer au format array
if (is_string($destinataires)) {
$destinataires = explode(',', $destinataires);
}
if (is_string($cc)) {
$cc = explode(',', $cc);
}
if (is_string($bcc)) {
$bcc = explode(',', $bcc);
}
$erreur = facteur_destinataires($facteur, $destinataires, $cc, $bcc);
if ($erreur) {
spip_log($erreur, 'mail.' . _LOG_ERREUR);
if ($exceptions) {
throw new Exception($erreur);
}
return false;
}
// On crée l'objet Facteur (PHPMailer) pour le manipuler ensuite
$options = [];
if ($exceptions) {
$options['exceptions'] = $exceptions;
}
$facteur = facteur_factory($options);
$facteur->setDest($destinataire);
$facteur->setObjet($sujet);
$facteur->setMessage($message_html, $message_texte);
@ -156,10 +123,10 @@ function facteur_envoyer_mail($destinataire, string $sujet, array $message) {
$from = $GLOBALS['meta']['email_envoi'];
if (empty($from) or !email_valide($from)) {
spip_log('Meta email_envoi invalide. Le mail sera probablement vu comme spam.', 'mail.' . _LOG_ERREUR);
if (is_array($destinataire) && count($destinataire) > 0) {
$from = $destinataire[0];
if (is_array($destinataires) && count($destinataires) > 0) {
$from = $destinataires[0];
} else {
$from = $destinataire;
$from = $destinataires;
}
}
}
@ -171,8 +138,8 @@ function facteur_envoyer_mail($destinataire, string $sujet, array $message) {
}
if (!empty($from)) {
$facteur->From = $from;
// la valeur par défaut de la config n'est probablement pas valable pour ce mail,
// on l'écrase pour cet envoi
// la valeur par défaut de la config n'est probablement pas valable pour ce mail,
// on l'écrase pour cet envoi
$facteur->FromName = '';
}
@ -186,28 +153,6 @@ function facteur_envoyer_mail($destinataire, string $sujet, array $message) {
$facteur->FromName = '';
}
// S'il y a des copies à envoyer
if ($cc) {
if (is_array($cc)) {
foreach ($cc as $courriel) {
$facteur->AddCC($courriel);
}
} else {
$facteur->AddCC($cc);
}
}
// S'il y a des copies cachées à envoyer
if ($bcc) {
if (is_array($bcc)) {
foreach ($bcc as $courriel) {
$facteur->AddBCC($courriel);
}
} else {
$facteur->AddBCC($bcc);
}
}
// S'il y a une adresse de reply-to
if ($repondre_a) {
if (is_array($repondre_a)) {
@ -225,7 +170,7 @@ function facteur_envoyer_mail($destinataire, string $sujet, array $message) {
}
}
// S'il y a des pièces jointes on les ajoute proprement
// S'il y a des pièces jointes on les ajoute proprement
if (is_countable($pieces_jointes) ? count($pieces_jointes) : 0) {
foreach ($pieces_jointes as $piece) {
if (!empty($piece['chemin']) and file_exists($piece['chemin'])) {
@ -241,7 +186,7 @@ function facteur_envoyer_mail($destinataire, string $sujet, array $message) {
}
}
// Si une adresse email a été spécifiée pour les retours en erreur, on l'ajoute
// Si une adresse email a été spécifiée pour les retours en erreur, on l'ajoute
if (!empty($adresse_erreur)) {
$facteur->Sender = $adresse_erreur;
}
@ -280,7 +225,7 @@ function facteur_envoyer_mail($destinataire, string $sujet, array $message) {
// mais on delegue la gestion de cet envoi au facteur qui est le seul a savoir quoi faire
// en fonction de la reponse et du modus operandi pour connaitre le status du message
if ($important and $dest_alertes = $facteur->Sender) {
$dest = (is_array($destinataire) ? implode(', ', $destinataire) : $destinataire);
$dest = (is_array($destinataires) ? implode(', ', $destinataires) : $destinataires);
$sujet_alerte = _T('facteur:sujet_alerte_mail_fail', ['dest' => $dest, 'sujet' => $sujet]);
$args = func_get_args();
$args[0] = $dest_alertes;
@ -306,6 +251,66 @@ function facteur_envoyer_mail($destinataire, string $sujet, array $message) {
}
/**
* Initialiser les destinataires en s'assurant qu'il y en a au moins un valide
* @param \Spip\Facteur\FacteurMail $facteur
* @param array $to
* @param array $cc
* @param array $bcc
* @return string
* @throws \PHPMailer\PHPMailer\Exception
*/
function facteur_destinataires(Spip\Facteur\FacteurMail $facteur, array $to, array $cc, array $bcc): string {
// mode TEST : forcer l'email ou bloquer tout envoi
if (defined('_TEST_EMAIL_DEST')) {
if (!_TEST_EMAIL_DEST) {
return _T('facteur:erreur_envoi_bloque_constante');
} else {
$to = [_TEST_EMAIL_DEST];
$cc = [];
$bcc = [];
}
}
// verifier qu'on a au moins un destinataire, meme si c'est un bcc ou un cc
// suppression des adresses de courriels invalides, si aucune valide, renvoyer une erreur
$to = array_map('trim', $to);
foreach ($to as $key => $value) {
if (!email_valide($value)) {
unset($to[$key]);
}
}
// initialiser les destinataires
$nb_dest_valides = $facteur->setDest($to);
// S'il y a des copies à envoyer
if (!empty($cc)) {
foreach ($cc as $courriel) {
if ($facteur->AddCC(trim($courriel))) {
$nb_dest_valides++;
}
}
}
// S'il y a des copies cachées à envoyer
if (!empty($bcc)) {
foreach ($bcc as $courriel) {
if ($facteur->AddBCC(trim($courriel))) {
$nb_dest_valides++;
}
}
}
if (!$nb_dest_valides) {
return _L("Aucune adresse email de destination valable pour l'envoi du courriel.");
}
return '';
}
/**
* Generer le FacteurXXX selon la config par defaut/passee en options
* @param array $options
@ -330,7 +335,7 @@ function facteur_factory($options = []) {
) {
return new $FacteurClass($options);
} else {
spip_log("Impossible de trouver la medthode $config_mailer ou sa classe " . (empty($methodes[$config_mailer]) ? '' : $methodes[$config_mailer]), 'facteur' . _LOG_ERREUR);
spip_log("Impossible de trouver la methode $config_mailer ou sa classe " . (empty($methodes[$config_mailer]) ? '' : $methodes[$config_mailer]), 'facteur' . _LOG_ERREUR);
// fallback fonction mail()
include_spip('inc/Facteur/FacteurMail');
@ -466,7 +471,7 @@ function facteur_extraire_sujet($message_html, $message_texte = '') {
/**
* Retourne la pile de fonctions utilisée pour envoyer un mail
* Retourne la pile de fonctions utilisée pour envoyer un mail
*
* @note
* Ignore les fonctions `include_once`, `include_spip`, `find_in_path`

Loading…
Cancel
Save