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

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

les headers de PHPMailer fonctionnent, on peut les utiliser avec un peu de discernement

File size: 8.3 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
43        // si $corps est un tableau -> fonctionnalites etendues
44        // avec entrees possible : html, texte, pieces_jointes, nom_envoyeur, ...
45        if (is_array($corps)) {
46                $message_html   = $corps['html'];
47                $message_texte  = nettoyer_caracteres_mail($corps['texte']);
48                $pieces_jointes = $corps['pieces_jointes'];
49                $nom_envoyeur = $corps['nom_envoyeur'];
50                $from = (isset($corps['from'])?$corps['from']:$from);
51                $cc = $corps['cc'];
52                $bcc = $corps['bcc'];
53                $repondre_a = $corps['repondre_a'];
54                $adresse_erreur = $corps['adresse_erreur'];
55                $headers = (isset($corps['headers'])?$corps['headers']:$headers);
56                if (is_string($headers))
57                        $headers = array_map('trim',explode("\n",$headers));
58        }
59        // si $corps est une chaine -> compat avec la fonction native SPIP
60        // gerer le cas ou le corps est du html avec un Content-Type: text/html dans les headers
61        else {
62                if (preg_match(',Content-Type:\s*text/html,ims',$headers)){
63                        $message_html   = $corps;
64                }
65                else {
66                        // Autodetection : tester si le mail est en HTML
67                        if (strpos($headers,"Content-Type:")===false
68                                AND strpos($corps,"<")!==false // eviter les tests suivants si possible
69                                AND $ttrim = trim($corps)
70                                AND substr($ttrim,0,1)=="<"
71                          AND substr($ttrim,-1,1)==">"
72                          AND stripos($ttrim,"</html>")!==false){
73
74                                if(!strlen($sujet)){
75                                        // dans ce cas on ruse un peu : extraire le sujet du title
76                                        if (preg_match(",<title>(.*)</title>,Uims",$corps,$m))
77                                                $sujet = $m[1];
78                                        else {
79                                                // fallback, on prend le body si on le trouve
80                                                if (preg_match(",<body[^>]*>(.*)</body>,Uims",$corps,$m))
81                                                        $ttrim = $m[1];
82
83                                                // et on extrait la premiere ligne de vrai texte...
84                                                // nettoyer le html et les retours chariots
85                                                $ttrim = textebrut($ttrim);
86                                                $ttrim = str_replace("\r\n", "\r", $ttrim);
87                                                $ttrim = str_replace("\r", "\n", $ttrim);
88                                                // decouper
89                                                $ttrim = explode("\n",trim($ttrim));
90                                                // extraire la premiere ligne de texte brut
91                                                $sujet = array_shift($ttrim);
92                                        }
93                                }
94                                $message_html   = $corps;
95                        }
96                        // c'est vraiment un message texte
97                        else
98                                $message_texte  = nettoyer_caracteres_mail($corps);
99                }
100                $headers = array_map('trim',explode("\n",$headers));
101        }
102        $sujet = nettoyer_titre_email($sujet);
103
104        // si le mail est en texte brut, on l'encapsule dans un modele surchargeable
105        // pour garder le texte brut, il suffit de faire un modele qui renvoie uniquement #ENV*{texte}
106        if ($message_texte AND ! $message_html){
107                $message_html = recuperer_fond("emails/texte",array('texte'=>$message_texte,'sujet'=>$sujet));
108        }
109        // si le mail est en HTML sans alternative, la generer
110        if ($message_html AND !$message_texte){
111                $message_texte = facteur_mail_html2text($message_html);
112        }
113
114        // mode TEST : forcer l'email
115        if (defined('_TEST_EMAIL_DEST')) {
116                if (!_TEST_EMAIL_DEST)
117                        return false;
118                else
119                        $destinataire = _TEST_EMAIL_DEST;
120        }
121
122        // plusieurs destinataires peuvent etre fournis separes par des virgules
123        // c'est un format standard dans l'envoi de mail
124        // les passer au format array pour phpMailer
125        // mais ne pas casser si on a deja un array en entree
126        if (is_array($destinataire))
127                $destinataire = implode(", ",$destinataire);
128        $destinataire = array_map('trim',explode(",",$destinataire));
129       
130        // On crée l'objet Facteur (PHPMailer) pour le manipuler ensuite
131        $facteur = new Facteur($destinataire, $sujet, $message_html, $message_texte);
132       
133        // On ajoute le courriel de l'envoyeur s'il est fournit par la fonction
134        if (empty($from) AND empty($facteur->From)) {
135                $from = $GLOBALS['meta']["email_envoi"];
136                if (empty($from) OR !email_valide($from)) {
137                        spip_log("Meta email_envoi invalide. Le mail sera probablement vu comme spam.");
138                        $from = $destinataire;
139                }
140        }
141
142        // "Marie Toto <Marie@toto.com>"
143        if (preg_match(",^([^<>\"]*)<([^<>\"]+)>$,i",$from,$m)){
144                $nom_envoyeur = trim($m[1]);
145                $from = trim($m[2]);
146        }
147        if (!empty($from)){
148                $facteur->From = $from;
149                // la valeur par défaut de la config n'est probablement pas valable pour ce mail,
150                // on l'écrase pour cet envoi
151                $facteur->FromName = $from;
152        }
153
154        // On ajoute le nom de l'envoyeur s'il fait partie des options
155        if ($nom_envoyeur)
156                $facteur->FromName = $nom_envoyeur;
157
158        // Si plusieurs emails dans le from, pas de Name !
159        if (strpos($facteur->From,",")!==false){
160                $facteur->FromName = "";
161        }
162
163        // S'il y a des copies à envoyer
164        if ($cc){
165                if (is_array($cc))
166                        foreach ($cc as $courriel)
167                                $facteur->AddCC($courriel);
168                else
169                        $facteur->AddCC($cc);
170        }
171       
172        // S'il y a des copies cachées à envoyer
173        if ($bcc){
174                if (is_array($bcc))
175                        foreach ($bcc as $courriel)
176                                $facteur->AddBCC($courriel);
177                else
178                        $facteur->AddBCC($bcc);
179        }
180       
181        // S'il y a des copies cachées à envoyer
182        if ($repondre_a){
183                if (is_array($repondre_a))
184                        foreach ($repondre_a as $courriel)
185                                $facteur->AddReplyTo($courriel);
186                else
187                        $facteur->AddReplyTo($repondre_a);
188        }
189       
190        // S'il y a des pièces jointes on les ajoute proprement
191        if (count($pieces_jointes)) {
192                foreach ($pieces_jointes as $piece) {
193                        $facteur->AddAttachment(
194                                $piece['chemin'],
195                                isset($piece['nom']) ? $piece['nom']:'',
196                                (isset($piece['encodage']) AND in_array($piece['encodage'],array('base64', '7bit', '8bit', 'binary', 'quoted-printable'))) ? $piece['encodage']:'base64',
197                                isset($piece['mime']) ? $piece['mime']:Facteur::_mime_types(pathinfo($piece['chemin'], PATHINFO_EXTENSION))
198                        );
199                }
200        }
201
202        // Si une adresse email a été spécifiée pour les retours en erreur, on l'ajoute
203        if (!empty($adresse_erreur))
204                $facteur->Sender = $adresse_erreur;
205
206        // si entetes personalises : les ajouter
207        // attention aux collisions : si on utilise l'option cc de $corps
208        // et qu'on envoie en meme temps un header Cc: xxx, yyy
209        // on aura 2 lignes Cc: dans les headers
210        if (!empty($headers)) {
211                foreach($headers as $h)
212                        $facteur->AddCustomHeader($h);
213        }
214       
215        // On passe dans un pipeline pour modifier tout le facteur avant l'envoi
216        $facteur = pipeline('facteur_pre_envoi', $facteur);
217       
218        // On génère les headers
219        $head = $facteur->CreateHeader();
220
221        // Et c'est parti on envoie enfin
222        spip_log("mail via facteur\n$head"."Destinataire:".print_r($destinataire,true),'mail');
223        spip_log("mail\n$head"."Destinataire:".print_r($destinataire,true),'facteur');
224        $retour = $facteur->Send();
225       
226        if (!$retour)
227                spip_log("Erreur Envoi mail via Facteur : ".print_r($facteur->ErrorInfo,true),'facteur');
228
229        return $retour ;
230}
231
232?>
Note: See TracBrowser for help on using the repository browser.