source: spip-zone/_plugins_/facteur/trunk/classes/facteur.php @ 70528

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

Branche 3 de facteur, en dev :

  • on ajoute l'auto-detection des mails HTML dans envoyer_mail : si aucun Content-Type n'est fourni, et que le mail commence par un < finit par un > et contient bien un </html> on considère que c'est un mail HTML. Cette feature etait fournie pour les notifications uniquement (par inc/notifications) jusqu'ici
  • on recupere la fonction de conversion HTML->Texte du plugin Newsletter, qui s'appuie sur MarkDownify?
  • si aucune alternative texte n'est fournie à un mail HTML, on génère automatiquement une alternative texte dans envoyer_mail()

A tester et stabiliser.

  • Property svn:executable set to *
File size: 10.9 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('inc/charsets');
12include_spip('inc/texte');
13include_spip('inc/filtres');
14
15if (!class_exists('PHPMailer')) {
16        include_spip('phpmailer-php5/class.phpmailer');
17        include_spip('phpmailer-php5/class.smtp');
18}
19
20include_spip('facteur_fonctions');
21
22class Facteur extends PHPMailer {
23
24        /**
25         * @param $email
26         * @param $objet
27         * @param $message_html
28         * @param $message_texte
29         * @param array $options
30         *
31         */
32        function Facteur($email, $objet, $message_html, $message_texte, $options = array()) {
33                $defaut = array(
34                        'adresse_envoi' => $GLOBALS['meta']['facteur_adresse_envoi'],
35                        'adresse_envoi_email' => $GLOBALS['meta']['facteur_adresse_envoi_email'],
36                        'adresse_envoi_nom' => $GLOBALS['meta']['facteur_adresse_envoi_nom'],
37                        'cc' => $GLOBALS['meta']['facteur_cc'],
38                        'bcc' => $GLOBALS['meta']['facteur_bcc'],
39                        'smtp' => $GLOBALS['meta']['facteur_smtp'],
40                        'smtp_host' => $GLOBALS['meta']['facteur_smtp_host'],
41                        'smtp_port' => $GLOBALS['meta']['facteur_smtp_port'],
42                        'smtp_auth' => $GLOBALS['meta']['facteur_smtp_auth'],
43                        'smtp_username' => $GLOBALS['meta']['facteur_smtp_username'],
44                        'smtp_password' => $GLOBALS['meta']['facteur_smtp_password'],
45                        'smtp_secure' => $GLOBALS['meta']['facteur_smtp_secure'],
46                        'smtp_sender' => $GLOBALS['meta']['facteur_smtp_sender'],
47                        'filtre_images' => $GLOBALS['meta']['facteur_filtre_images'],
48                        'filtre_iso_8859' => $GLOBALS['meta']['facteur_filtre_iso_8859'],
49                );
50                $options = array_merge($defaut, $options);
51
52                if (defined('_FACTEUR_DEBUG_SMTP')) {
53                        $this->SMTPDebug = _FACTEUR_DEBUG_SMTP ;
54                }
55                if ($options['adresse_envoi'] == 'oui'
56                  AND $options['adresse_envoi_email'])
57                        $this->From = $options['adresse_envoi_email'];
58                else
59                        $this->From = (isset($GLOBALS['meta']["email_envoi"]) AND $GLOBALS['meta']["email_envoi"])?
60                                $GLOBALS['meta']["email_envoi"]
61                                :$GLOBALS['meta']['email_webmaster'];
62
63                // Si plusieurs emails dans le from, pas de Name !
64                if (strpos($this->From,",")===false){
65                        if ($options['adresse_envoi'] == 'oui'
66                          AND $options['adresse_envoi_nom'])
67                                $this->FromName = $options['adresse_envoi_nom'];
68                        else
69                                $this->FromName = strip_tags(extraire_multi($GLOBALS['meta']['nom_site']));
70                }
71
72                $this->CharSet = "utf-8";
73                $this->Mailer = 'mail';
74                $this->Subject = unicode_to_utf_8(charset2unicode($objet,$GLOBALS['meta']['charset']));
75
76                //Pour un envoi multiple de mail, $email doit être un tableau avec les adresses.
77                if (is_array($email)) {
78                        foreach ($email as $cle => $adresseMail) {
79                                if (!$this->AddAddress($adresseMail))
80                                        spip_log("Erreur AddAddress $adresseMail : ".print_r($this->ErrorInfo,true),'facteur');
81                        }
82                }
83                else
84                        if (!$this->AddAddress($email))
85                                spip_log("Erreur AddAddress $email : ".print_r($this->ErrorInfo,true),'facteur');
86
87                if (!empty($options['smtp_sender'])) {
88                        $this->Sender = $options['smtp_sender'];
89                        $this->AddCustomHeader("Errors-To: ".$this->Sender);
90                }
91
92                if (!empty($options['cc'])) {
93                        $this->AddCC( $options['cc'] );
94                }
95                if (!empty($options['bcc'])) {
96                        $this->AddBCC( $options['bcc'] );
97                }
98               
99                if (isset($options['smtp']) AND $options['smtp'] == 'oui') {
100                        $this->Mailer   = 'smtp';
101                        $this->Host     = $options['smtp_host'];
102                        $this->Port     = $options['smtp_port'];
103                        if ($options['smtp_auth'] == 'oui') {
104                                $this->SMTPAuth = true;
105                                $this->Username = $options['smtp_username'];
106                                $this->Password = $options['smtp_password'];
107                        }
108                        else {
109                                $this->SMTPAuth = false;
110                        }
111                        if (intval(phpversion()) == 5) {
112                        if ($options['smtp_secure'] == 'ssl')
113                                $this->SMTPSecure = 'ssl';
114                        if ($options['smtp_secure'] == 'tls')
115                                $this->SMTPSecure = 'tls';
116                        }
117                }
118
119                if (!empty($message_html)) {
120                        $message_html = unicode_to_utf_8(charset2unicode($message_html,$GLOBALS['meta']['charset']));
121                        $this->Body = $message_html;
122                        $this->IsHTML(true);
123                        if ($options['filtre_images'])
124                                $this->JoindreImagesHTML();
125                        $this->UrlsAbsolues();
126                }
127                if (!empty($message_texte)) {
128                        $message_texte = unicode_to_utf_8(charset2unicode($message_texte,$GLOBALS['meta']['charset']));
129                        if (!$this->Body) {
130                                $this->IsHTML(false);
131                                $this->Body = $message_texte;
132                        }
133                        else {
134                                $this->AltBody = $message_texte;
135                        }
136                }
137
138                if ($options['filtre_iso_8859'])
139                        $this->ConvertirUtf8VersIso8859();
140
141        }
142       
143        /*
144         * Transforme du HTML en texte brut, mais proprement
145         * utilise le filtre facteur_mail_html2text
146         * @uses facteur_mail_html2text()
147         *
148         * @param string $html Le HTML à transformer
149         * @return string Retourne un texte brut formaté correctement
150         */
151        function html2text($html){
152                return facteur_mail_html2text($html);
153        }
154       
155        /**
156         * Transformer les urls des liens et des images en url absolues
157         * sans toucher aux images embarquees de la forme "cid:..."
158         */
159        function UrlsAbsolues($base=null){
160                include_spip('inc/filtres_mini');
161                if (preg_match_all(',(<(a|link)[[:space:]]+[^<>]*href=["\']?)([^"\' ><[:space:]]+)([^<>]*>),imsS',
162                  $this->Body, $liens, PREG_SET_ORDER)) {
163                        foreach ($liens as $lien) {
164                                if (strncmp($lien[3],"cid:",4)!==0){
165                                        $abs = url_absolue($lien[3], $base);
166                                        if ($abs <> $lien[3] and !preg_match('/^#/',$lien[3]))
167                                                $this->Body = str_replace($lien[0], $lien[1].$abs.$lien[4], $this->Body);
168                                }
169                        }
170                }
171                if (preg_match_all(',(<(img|script)[[:space:]]+[^<>]*src=["\']?)([^"\' ><[:space:]]+)([^<>]*>),imsS',
172                  $this->Body, $liens, PREG_SET_ORDER)) {
173                        foreach ($liens as $lien) {
174                                if (strncmp($lien[3],"cid:",4)!==0){
175                                        $abs = url_absolue($lien[3], $base);
176                                        if ($abs <> $lien[3])
177                                                $this->Body = str_replace($lien[0], $lien[1].$abs.$lien[4], $this->Body);
178                                }
179                        }
180                }
181        }
182
183        function JoindreImagesHTML() {
184                $image_types = array(
185                                                        'gif'   => 'image/gif',
186                                                        'jpg'   => 'image/jpeg',
187                                                        'jpeg'  => 'image/jpeg',
188                                                        'jpe'   => 'image/jpeg',
189                                                        'bmp'   => 'image/bmp',
190                                                        'png'   => 'image/png',
191                                                        'tif'   => 'image/tiff',
192                                                        'tiff'  => 'image/tiff',
193                                                        'swf'   => 'application/x-shockwave-flash'
194                                                );
195                $src_found = array();
196                $images_embeded = array();
197                if (preg_match_all(
198                        '/["\'](([^"\']+)\.('.implode('|', array_keys($image_types)).'))([?][^"\']+)?([#][^"\']+)?["\']/Uims',
199                        $this->Body, $images, PREG_SET_ORDER)) {
200
201                        $adresse_site = $GLOBALS['meta']['adresse_site'].'/';
202                        foreach($images as $im){
203                                $src_orig = $im[1].$im[4].$im[5];
204                                if (!isset($src_found[$src_orig])){ // deja remplace ? rien a faire (ie la meme image presente plusieurs fois)
205                                        // examiner le src et voir si embedable
206                                        $src = $im[1];
207                                        if ($src AND strncmp($src,$adresse_site,strlen($adresse_site))==0)
208                                                $src = _DIR_RACINE . substr($src,strlen($adresse_site));
209                                        if ($src
210                                          AND !preg_match(",^[a-z0-9]+://,i",$src)
211                                          AND (
212                                              file_exists($f=$src) // l'image a ete generee depuis le meme cote que l'envoi
213                                              OR (_DIR_RACINE AND file_exists($f=_DIR_RACINE.$src)) // l'image a ete generee dans le public et on est dans le prive
214                                              OR (!_DIR_RACINE AND file_exists($f=_DIR_RESTREINT.$src)) // l'image a ete generee dans le prive et on est dans le public
215                                             )
216                                          ){
217                                                if (!isset($images_embeded[$f])){
218                                                        $extension = strtolower($im[3]);
219                                                        $header_extension = $image_types[$extension];
220                                                        $cid = md5($f); // un id unique pour un meme fichier
221                                                        $images_embeded[$f] = $cid; // marquer l'image comme traitee, inutile d'y revenir
222                                                        $this->AddEmbeddedImage($f, $cid, basename($f),'base64',$header_extension);
223                                                }
224
225                                                $this->Body = str_replace($src_orig, "cid:".$images_embeded[$f], $this->Body);
226                                                $src_found[$src_orig] = $f;
227                                        }
228                                }
229                        }
230                }
231        }
232
233
234        /**
235         * Compat ascendante, obsolete
236         */
237        function ConvertirStylesEnligne() {
238                $this->Body = facteur_convertir_styles_inline($this->Body);
239        }
240
241
242        function safe_utf8_decode($text,$mode='texte_brut') {
243                if (!is_utf8($text))
244                        return ($text);
245
246                if (function_exists('iconv') && $mode == 'texte_brut') {
247                        $text = str_replace('’',"'",$text);
248                        $text = iconv("UTF-8", "ISO-8859-1//TRANSLIT", $text);
249                        return str_replace('&#8217;',"'",$text);
250                }
251                else {
252                        if ($mode == 'texte_brut') {
253                                $text = str_replace('’',"'",$text);
254                        }
255                        $text = unicode2charset(utf_8_to_unicode($text),'iso-8859-1');
256                        return str_replace('&#8217;',"'",$text);
257                }
258        }
259
260        function ConvertirUtf8VersIso8859() {
261                $this->CharSet  = 'iso-8859-1';
262                $this->Body             = str_ireplace('charset=utf-8', 'charset=iso-8859-1', $this->Body);
263                $this->Body             = $this->safe_utf8_decode($this->Body,'html');
264                $this->AltBody  = $this->safe_utf8_decode($this->AltBody);
265                $this->Subject  = $this->safe_utf8_decode($this->Subject);
266                $this->FromName = $this->safe_utf8_decode($this->FromName);
267        }
268
269        function ConvertirAccents() {
270                // tableau à compléter au fur et à mesure
271                $cor = array(
272                                                'à' => '&agrave;',
273                                                'â' => '&acirc;',
274                                                'ä' => '&auml;',
275                                                'ç' => '&ccedil;',
276                                                'é' => '&eacute;',
277                                                'è' => '&egrave;',
278                                                'ê' => '&ecirc;',
279                                                'ë' => '&euml;',
280                                                'î' => '&icirc;',
281                                                'ï' => '&iuml;',
282                                                'ò' => '&ograve;',
283                                                'ô' => '&ocirc;',
284                                                'ö' => '&ouml;',
285                                                'ù' => '&ugrave;',
286                                                'û' => '&ucirc;',
287                                                'œ' => '&oelig;',
288                                                '€' => '&euro;'
289                                        );
290
291                $this->Body = strtr($this->Body, $cor);
292        }
293        public function Send() {
294                ob_start();
295                $retour = parent::Send();
296                $error = ob_get_contents();
297                ob_end_clean();
298                if( !empty($error) ) {
299                        spip_log("Erreur Facteur->Send : $error",'facteur.err');
300                }
301                return $retour;
302        }
303        public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
304                ob_start();
305                $retour = parent::AddAttachment($path, $name, $encoding, $type);
306                $error = ob_get_contents();
307                ob_end_clean();
308                if( !empty($error) ) {
309                        spip_log("Erreur Facteur->AddAttachment : $error",'facteur.err');
310                }
311                return $retour;
312        }
313        public function AddReplyTo($address, $name = '') {
314                ob_start();
315                $retour = parent::AddReplyTo($address, $name);
316                $error = ob_get_contents();
317                ob_end_clean();
318                if( !empty($error) ) {
319                        spip_log("Erreur Facteur->AddReplyTo : $error",'facteur.err');
320                }
321                return $retour;
322        }
323        public function AddBCC($address, $name = '') {
324                ob_start();
325                $retour = parent::AddBCC($address, $name);
326                $error = ob_get_contents();
327                ob_end_clean();
328                if( !empty($error) ) {
329                        spip_log("Erreur Facteur->AddBCC : $error",'facteur.err');
330                }
331                return $retour;
332        }
333        public function AddCC($address, $name = '') {
334                ob_start();
335                $retour = parent::AddCC($address, $name);
336                $error = ob_get_contents();
337                ob_end_clean();
338                if( !empty($error) ) {
339                        spip_log("Erreur Facteur->AddCC : $error",'facteur.err');
340                }
341                return $retour;
342        }
343}
344
345?>
Note: See TracBrowser for help on using the repository browser.