source: spip-zone/_plugins_/facteur/trunk/inc/envoyer_mail.php @ 86770

Last change on this file since 86770 was 86770, checked in by kent1@…, 5 years ago

Sans log de m c'est mieux

File size: 9.5 KB
Line 
1<?php
2/*
3 * Plugin Facteur 2
4 * (c) 2009-2011 Collectif SPIP
5 * Distribue sous licence GPL
6 *
7 */
8
9if (!defined("_ECRIRE_INC_VERSION")) return;
10
11include_spip('classes/facteur');
12// inclure le fichier natif de SPIP, pour les fonctions annexes
13include_once _DIR_RESTREINT."inc/envoyer_mail.php";
14
15/**
16 * @param string $destinataire
17 * @param string $sujet
18 * @param string|array $corps
19 *   au format string, c'est un corps d'email au format texte, comme supporte nativement par le core
20 *   au format array, c'est un corps etendu qui peut contenir
21 *     string texte : le corps d'email au format texte
22 *     string html : le corps d'email au format html
23 *     string from : email de l'envoyeur (prioritaire sur argument $from de premier niveau, deprecie)
24 *     string nom_envoyeur : un nom d'envoyeur pour completer l'email from
25 *     string cc : destinataires en copie conforme
26 *     string bcc : destinataires en copie conforme cachee
27 *     string|array repondre_a : une ou plusieurs adresses à qui répondre
28 *     string adresse_erreur : addresse de retour en cas d'erreur d'envoi
29 *     array pieces_jointes : listes de pieces a embarquer dans l'email, chacune au format array :
30 *       string chemin : chemin file system pour trouver le fichier a embarquer
31 *       string nom : nom du document tel qu'apparaissant dans l'email
32 *       string encodage : encodage a utiliser, parmi 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
33 *       string mime : mime type du document
34 *     array headers : tableau d'en-tetes personalises, une entree par ligne d'en-tete
35 * @param string $from (deprecie, utiliser l'entree from de $corps)
36 * @param string $headers (deprecie, utiliser l'entree headers de $corps)
37 * @return bool
38 */
39function inc_envoyer_mail($destinataire, $sujet, $corps, $from = "", $headers = "") {
40        $message_html   = '';
41        $message_texte  = '';
42        $nom_envoyeur = $cc = $bcc = $repondre_a = '';
43        $pieces_jointes = array();
44
45        // si $corps est un tableau -> fonctionnalites etendues
46        // avec entrees possible : html, texte, pieces_jointes, nom_envoyeur, ...
47        if (is_array($corps)) {
48                $message_html   = $corps['html'];
49                $message_texte  = nettoyer_caracteres_mail($corps['texte']);
50                $pieces_jointes = $corps['pieces_jointes'];
51                $nom_envoyeur = $corps['nom_envoyeur'];
52                $from = (isset($corps['from'])?$corps['from']:$from);
53                $cc = $corps['cc'];
54                $bcc = $corps['bcc'];
55                $repondre_a = $corps['repondre_a'];
56                $adresse_erreur = $corps['adresse_erreur'];
57                $headers = (isset($corps['headers'])?$corps['headers']:$headers);
58                if (is_string($headers)){
59                        $headers = array_map('trim',explode("\n",$headers));
60                        $headers = array_filter($headers);
61                }
62        }
63        // si $corps est une chaine -> compat avec la fonction native SPIP
64        // gerer le cas ou le corps est du html avec un Content-Type: text/html dans les headers
65        else {
66                if (preg_match(',Content-Type:\s*text/html,ims',$headers)){
67                        $message_html   = $corps;
68                }
69                else {
70                        // Autodetection : tester si le mail est en HTML
71                        if (strpos($headers,"Content-Type:")===false
72                                AND strpos($corps,"<")!==false // eviter les tests suivants si possible
73                                AND $ttrim = trim($corps)
74                                AND substr($ttrim,0,1)=="<"
75                                AND substr($ttrim,-1,1)==">"
76                                AND stripos($ttrim,"</html>")!==false){
77
78                                if(!strlen($sujet)){
79                                        // dans ce cas on ruse un peu : extraire le sujet du title
80                                        if (preg_match(",<title>(.*)</title>,Uims",$corps,$m))
81                                                $sujet = $m[1];
82                                        else {
83                                                // fallback, on prend le body si on le trouve
84                                                if (preg_match(",<body[^>]*>(.*)</body>,Uims",$corps,$m))
85                                                        $ttrim = $m[1];
86
87                                                // et on extrait la premiere ligne de vrai texte...
88                                                // nettoyer le html et les retours chariots
89                                                $ttrim = textebrut($ttrim);
90                                                $ttrim = str_replace("\r\n", "\r", $ttrim);
91                                                $ttrim = str_replace("\r", "\n", $ttrim);
92                                                // decouper
93                                                $ttrim = explode("\n",trim($ttrim));
94                                                // extraire la premiere ligne de texte brut
95                                                $sujet = array_shift($ttrim);
96                                        }
97                                }
98                                $message_html   = $corps;
99                        }
100                        // c'est vraiment un message texte
101                        else
102                                $message_texte  = nettoyer_caracteres_mail($corps);
103                }
104                $headers = array_map('trim',explode("\n",$headers));
105                $headers = array_filter($headers);
106        }
107        $sujet = nettoyer_titre_email($sujet);
108
109        // si le mail est en texte brut, on l'encapsule dans un modele surchargeable
110        // pour garder le texte brut, il suffit de faire un modele qui renvoie uniquement #ENV*{texte}
111        if ($message_texte AND ! $message_html){
112                $message_html = recuperer_fond("emails/texte",array('texte'=>$message_texte,'sujet'=>$sujet));
113        }
114        // si le mail est en HTML sans alternative, la generer
115        if ($message_html AND !$message_texte){
116                $message_texte = facteur_mail_html2text($message_html);
117        }
118
119        // mode TEST : forcer l'email
120        if (defined('_TEST_EMAIL_DEST')) {
121                if (!_TEST_EMAIL_DEST)
122                        return false;
123                else
124                        $destinataire = _TEST_EMAIL_DEST;
125        }
126
127        // plusieurs destinataires peuvent etre fournis separes par des virgules
128        // c'est un format standard dans l'envoi de mail
129        // les passer au format array pour phpMailer
130        // mais ne pas casser si on a deja un array en entree
131        // si pas destinataire du courriel on renvoie false (eviter les warning PHP : ligne 464 de phpmailer-php5/class.phpmailer.php
132        // suppression des adresses de courriels invalides, si aucune valide, renvoyer false (eviter un warning PHP : ligne 464 de phpmailer-php5/class.phpmailer.php)
133        if (is_array($destinataire))
134                $destinataire = implode(", ",$destinataire);
135
136        if(strlen($destinataire) > 0){
137                $destinataire = array_map('trim',explode(",",$destinataire));
138                foreach ($destinataire as $key => $value) {
139                        if(!email_valide($value))
140                                unset($destinataire[$key]);
141                }
142                if(count($destinataire) == 0) {
143                        spip_log("Aucune adresse email de destination valable pour l'envoi du courriel.", 'mail.' . _LOG_ERREUR);
144                        return false;
145                }
146        }
147        else {
148                spip_log("Aucune adresse email de destination valable pour l'envoi du courriel.", 'mail.' . _LOG_ERREUR);
149                return false;
150        }
151
152        // On crée l'objet Facteur (PHPMailer) pour le manipuler ensuite
153        $facteur = new Facteur($destinataire, $sujet, $message_html, $message_texte);
154       
155        // On ajoute le courriel de l'envoyeur s'il est fournit par la fonction
156        if (empty($from) AND empty($facteur->From)) {
157                $from = $GLOBALS['meta']["email_envoi"];
158                if (empty($from) OR !email_valide($from)) {
159                        spip_log("Meta email_envoi invalide. Le mail sera probablement vu comme spam.", 'mail.' . _LOG_ERREUR);
160                        if(is_array($destinataire) && count($destinataire) > 0)
161                                $from = $destinataire[0];
162                        else
163                                $from = $destinataire;
164                }
165        }
166
167        // "Marie Toto <Marie@toto.com>"
168        if (preg_match(",^([^<>\"]*)<([^<>\"]+)>$,i",$from,$m)){
169                $nom_envoyeur = trim($m[1]);
170                $from = trim($m[2]);
171        }
172        if (!empty($from)){
173                $facteur->From = $from;
174                // la valeur par défaut de la config n'est probablement pas valable pour ce mail,
175                // on l'écrase pour cet envoi
176                $facteur->FromName = $from;
177        }
178
179        // On ajoute le nom de l'envoyeur s'il fait partie des options
180        if ($nom_envoyeur)
181                $facteur->FromName = $nom_envoyeur;
182
183        // Si plusieurs emails dans le from, pas de Name !
184        if (strpos($facteur->From,",")!==false){
185                $facteur->FromName = "";
186        }
187
188        // S'il y a des copies à envoyer
189        if ($cc){
190                if (is_array($cc))
191                        foreach ($cc as $courriel)
192                                $facteur->AddCC($courriel);
193                else
194                        $facteur->AddCC($cc);
195        }
196       
197        // S'il y a des copies cachées à envoyer
198        if ($bcc){
199                if (is_array($bcc))
200                        foreach ($bcc as $courriel)
201                                $facteur->AddBCC($courriel);
202                else
203                        $facteur->AddBCC($bcc);
204        }
205       
206        // S'il y a une adresse de reply-to
207        if ($repondre_a){
208                if (is_array($repondre_a))
209                        foreach ($repondre_a as $courriel)
210                                $facteur->AddReplyTo($courriel);
211                else
212                        $facteur->AddReplyTo($repondre_a);
213        }
214       
215        // S'il y a des pièces jointes on les ajoute proprement
216        if (count($pieces_jointes)) {
217                foreach ($pieces_jointes as $piece) {
218                        $facteur->AddAttachment(
219                                $piece['chemin'],
220                                isset($piece['nom']) ? $piece['nom']:'',
221                                (isset($piece['encodage']) AND in_array($piece['encodage'],array('base64', '7bit', '8bit', 'binary', 'quoted-printable'))) ? $piece['encodage']:'base64',
222                                isset($piece['mime']) ? $piece['mime']:Facteur::_mime_types(pathinfo($piece['chemin'], PATHINFO_EXTENSION))
223                        );
224                }
225        }
226
227        // Si une adresse email a été spécifiée pour les retours en erreur, on l'ajoute
228        if (!empty($adresse_erreur))
229                $facteur->Sender = $adresse_erreur;
230
231        // si entetes personalises : les ajouter
232        // attention aux collisions : si on utilise l'option cc de $corps
233        // et qu'on envoie en meme temps un header Cc: xxx, yyy
234        // on aura 2 lignes Cc: dans les headers
235        if (!empty($headers)) {
236                foreach($headers as $h){
237                        // verifions le format correct : il faut au moins un ":" dans le header
238                        // et on filtre le Content-Type: qui sera de toute facon fourni par facteur
239                        if (strpos($h,":")!==false
240                          AND strncmp($h,"Content-Type:",13)!==0)
241                                $facteur->AddCustomHeader($h);
242                }
243        }
244       
245        // On passe dans un pipeline pour modifier tout le facteur avant l'envoi
246        $facteur = pipeline('facteur_pre_envoi', $facteur);
247       
248        // On génère les headers
249        $head = $facteur->CreateHeader();
250
251        // Et c'est parti on envoie enfin
252        spip_log("mail via facteur\n$head"."Destinataire:".print_r($destinataire,true),'mail');
253        spip_log("mail\n$head"."Destinataire:".print_r($destinataire,true),'facteur');
254        $retour = $facteur->Send();
255       
256        if (!$retour)
257                spip_log("Erreur Envoi mail via Facteur : ".print_r($facteur->ErrorInfo,true),'facteur.'._LOG_ERREUR);
258
259        return $retour ;
260}
261
262?>
Note: See TracBrowser for help on using the repository browser.