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

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

bugfix : reconnaitre et embarquer les images meme si elles ont une ancre ou une url absolue du site
evolution : permettre de passer un tableau d'option en 4e arg de Facteur. Les options non fournies sont piochees dans la config du plugin, mais cela permet d'utiliser la classe avec ses propres reglages sans devoir hacker les meta
Passage en 2.3.0

  • Property svn:executable set to *
File size: 13.7 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                        'smtp_sender' => $GLOBALS['meta']['facteur_smtp_sender'],
38                        'cc' => $GLOBALS['meta']['facteur_cc'],
39                        'bcc' => $GLOBALS['meta']['facteur_bcc'],
40                        'smtp' => $GLOBALS['meta']['facteur_smtp'],
41                        'smtp_host' => $GLOBALS['meta']['facteur_smtp_host'],
42                        'smtp_port' => $GLOBALS['meta']['facteur_smtp_port'],
43                        'smtp_auth' => $GLOBALS['meta']['facteur_smtp_auth'],
44                        'smtp_username' => $GLOBALS['meta']['facteur_smtp_username'],
45                        'smtp_password' => $GLOBALS['meta']['facteur_smtp_password'],
46                        'smtp_secure' => $GLOBALS['meta']['facteur_smtp_secure'],
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, c'est-à-dire en essayant
145         * de garder les titrages, les listes, etc
146         *
147         * @param string $html Le HTML à transformer
148         * @return string Retourne un texte brut formaté correctement
149         */
150        function html2text($html){
151                // On remplace tous les sauts de lignes par un espace
152                $html = str_replace("\n", ' ', $html);
153               
154                // Supprimer tous les liens internes
155                $texte = preg_replace("/\<a href=['\"]#(.*?)['\"][^>]*>(.*?)<\/a>/ims", "\\2", $html);
156       
157                // Supprime feuille style
158                $texte = preg_replace(";<style[^>]*>[^<]*</style>;i", "", $texte);
159       
160                // Remplace tous les liens     
161                $texte = preg_replace("/\<a[^>]*href=['\"](.*?)['\"][^>]*>(.*?)<\/a>/ims", "\\2 (\\1)", $texte);
162       
163                // Les titres
164                $texte = preg_replace(";<h1[^>]*>;i", "\n= ", $texte);
165                $texte = str_replace("</h1>", " =\n\n", $texte);
166                $texte = preg_replace(";<h2[^>]*>;i", "\n== ", $texte);
167                $texte = str_replace("</h2>", " ==\n\n", $texte);
168                $texte = preg_replace(";<h3[^>]*>;i", "\n=== ", $texte);
169                $texte = str_replace("</h3>", " ===\n\n", $texte);
170               
171                // Une fin de liste
172                $texte = preg_replace(";</(u|o)l>;i", "\n\n", $texte);
173               
174                // Une saut de ligne *après* le paragraphe
175                $texte = preg_replace(";<p[^>]*>;i", "\n", $texte);
176                $texte = preg_replace(";</p>;i", "\n\n", $texte);
177                // Les sauts de ligne interne
178                $texte = preg_replace(";<br[^>]*>;i", "\n", $texte);
179       
180                //$texte = str_replace('<br /><img class=\'spip_puce\' src=\'puce.gif\' alt=\'-\' border=\'0\'>', "\n".'-', $texte);
181                $texte = preg_replace (';<li[^>]*>;i', "\n".'- ', $texte);
182       
183       
184                // accentuation du gras
185                // <b>texte</b> -> **texte**
186                $texte = preg_replace (';<b[^>]*>;i','**' ,$texte);
187                $texte = str_replace ('</b>','**' ,$texte);
188       
189                // accentuation du gras
190                // <strong>texte</strong> -> **texte**
191                $texte = preg_replace (';<strong[^>]*>;i','**' ,$texte);
192                $texte = str_replace ('</strong>','**' ,$texte);
193       
194       
195                // accentuation de l'italique
196                // <em>texte</em> -> *texte*
197                $texte = preg_replace (';<em[^>]*>;i','/' ,$texte);
198                $texte = str_replace ('</em>','*' ,$texte);
199               
200                // accentuation de l'italique
201                // <i>texte</i> -> *texte*
202                $texte = preg_replace (';<i[^>]*>;i','/' ,$texte);
203                $texte = str_replace ('</i>','*' ,$texte);
204       
205                $texte = str_replace('&oelig;', 'oe', $texte);
206                $texte = str_replace("&nbsp;", " ", $texte);
207                $texte = filtrer_entites($texte);
208       
209                // On supprime toutes les balises restantes
210                $texte = supprimer_tags($texte);
211       
212                $texte = str_replace("\x0B", "", $texte); 
213                $texte = str_replace("\t", "", $texte) ;
214                $texte = preg_replace(";[ ]{3,};", "", $texte);
215       
216                // espace en debut de ligne
217                $texte = preg_replace("/(\r\n|\n|\r)[ ]+/", "\n", $texte);
218       
219                //marche po
220                // Bring down number of empty lines to 4 max
221                $texte = preg_replace("/(\r\n|\n|\r){3,}/m", "\n\n", $texte);
222       
223                //saut de lignes en debut de texte
224                $texte = preg_replace("/^(\r\n|\n|\r)*/", "\n\n", $texte);
225                //saut de lignes en debut ou fin de texte
226                $texte = preg_replace("/(\r\n|\n|\r)*$/", "\n\n", $texte);
227       
228                // Faire des lignes de 75 caracteres maximum
229                //$texte = wordwrap($texte);
230       
231                return $texte;
232        }
233       
234        /**
235         * Transformer les urls des liens et des images en url absolues
236         * sans toucher aux images embarquees de la forme "cid:..."
237         */
238        function UrlsAbsolues($base=null){
239                include_spip('inc/filtres_mini');
240                if (preg_match_all(',(<(a|link)[[:space:]]+[^<>]*href=["\']?)([^"\' ><[:space:]]+)([^<>]*>),imsS',
241                  $this->Body, $liens, PREG_SET_ORDER)) {
242                        foreach ($liens as $lien) {
243                                if (strncmp($lien[3],"cid:",4)!==0){
244                                        $abs = url_absolue($lien[3], $base);
245                                        if ($abs <> $lien[3] and !preg_match('/^#/',$lien[3]))
246                                                $this->Body = str_replace($lien[0], $lien[1].$abs.$lien[4], $this->Body);
247                                }
248                        }
249                }
250                if (preg_match_all(',(<(img|script)[[:space:]]+[^<>]*src=["\']?)([^"\' ><[:space:]]+)([^<>]*>),imsS',
251                  $this->Body, $liens, PREG_SET_ORDER)) {
252                        foreach ($liens as $lien) {
253                                if (strncmp($lien[3],"cid:",4)!==0){
254                                        $abs = url_absolue($lien[3], $base);
255                                        if ($abs <> $lien[3])
256                                                $this->Body = str_replace($lien[0], $lien[1].$abs.$lien[4], $this->Body);
257                                }
258                        }
259                }
260        }
261
262        function JoindreImagesHTML() {
263                $image_types = array(
264                                                        'gif'   => 'image/gif',
265                                                        'jpg'   => 'image/jpeg',
266                                                        'jpeg'  => 'image/jpeg',
267                                                        'jpe'   => 'image/jpeg',
268                                                        'bmp'   => 'image/bmp',
269                                                        'png'   => 'image/png',
270                                                        'tif'   => 'image/tiff',
271                                                        'tiff'  => 'image/tiff',
272                                                        'swf'   => 'application/x-shockwave-flash'
273                                                );
274                $src_found = array();
275                $images_embeded = array();
276                if (preg_match_all(
277                        '/["\'](([^"\']+)\.('.implode('|', array_keys($image_types)).'))([?][^"\']+)?([#][^"\']+)?["\']/Uims',
278                        $this->Body, $images, PREG_SET_ORDER)) {
279
280                        $adresse_site = $GLOBALS['meta']['adresse_site'].'/';
281                        foreach($images as $im){
282                                $src_orig = $im[1].$im[4].$im[5];
283                                if (!isset($src_found[$src_orig])){ // deja remplace ? rien a faire (ie la meme image presente plusieurs fois)
284                                        // examiner le src et voir si embedable
285                                        $src = $im[1];
286                                        if ($src AND strncmp($src,$adresse_site,strlen($adresse_site))==0)
287                                                $src = _DIR_RACINE . substr($src,strlen($adresse_site));
288                                        if ($src
289                                          AND !preg_match(",^[a-z0-9]+://,i",$src)
290                                          AND (
291                                              file_exists($f=$src) // l'image a ete generee depuis le meme cote que l'envoi
292                                              OR (_DIR_RACINE AND file_exists($f=_DIR_RACINE.$src)) // l'image a ete generee dans le public et on est dans le prive
293                                              OR (!_DIR_RACINE AND file_exists($f=_DIR_RESTREINT.$src)) // l'image a ete generee dans le prive et on est dans le public
294                                             )
295                                          ){
296                                                if (!isset($images_embeded[$f])){
297                                                        $extension = strtolower($im[3]);
298                                                        $header_extension = $image_types[$extension];
299                                                        $cid = md5($f); // un id unique pour un meme fichier
300                                                        $images_embeded[$f] = $cid; // marquer l'image comme traitee, inutile d'y revenir
301                                                        $this->AddEmbeddedImage($f, $cid, basename($f),'base64',$header_extension);
302                                                }
303
304                                                $this->Body = str_replace($src_orig, "cid:".$images_embeded[$f], $this->Body);
305                                                $src_found[$src_orig] = $f;
306                                        }
307                                }
308                        }
309                }
310        }
311
312
313        /**
314         * Compat ascendante, obsolete
315         */
316        function ConvertirStylesEnligne() {
317                $this->Body = facteur_convertir_styles_inline($this->Body);
318        }
319
320
321        function safe_utf8_decode($text,$mode='texte_brut') {
322                if (!is_utf8($text))
323                        return ($text);
324
325                if (function_exists('iconv') && $mode == 'texte_brut') {
326                        $text = str_replace('’',"'",$text);
327                        $text = iconv("UTF-8", "ISO-8859-1//TRANSLIT", $text);
328                        return str_replace('&#8217;',"'",$text);
329                }
330                else {
331                        if ($mode == 'texte_brut') {
332                                $text = str_replace('’',"'",$text);
333                        }
334                        $text = unicode2charset(utf_8_to_unicode($text),'iso-8859-1');
335                        return str_replace('&#8217;',"'",$text);
336                }
337        }
338
339        function ConvertirUtf8VersIso8859() {
340                $this->CharSet  = 'iso-8859-1';
341                $this->Body             = str_ireplace('charset=utf-8', 'charset=iso-8859-1', $this->Body);
342                $this->Body             = $this->safe_utf8_decode($this->Body,'html');
343                $this->AltBody  = $this->safe_utf8_decode($this->AltBody);
344                $this->Subject  = $this->safe_utf8_decode($this->Subject);
345                $this->FromName = $this->safe_utf8_decode($this->FromName);
346        }
347
348        function ConvertirAccents() {
349                // tableau à compléter au fur et à mesure
350                $cor = array(
351                                                'à' => '&agrave;',
352                                                'â' => '&acirc;',
353                                                'ä' => '&auml;',
354                                                'ç' => '&ccedil;',
355                                                'é' => '&eacute;',
356                                                'è' => '&egrave;',
357                                                'ê' => '&ecirc;',
358                                                'ë' => '&euml;',
359                                                'î' => '&icirc;',
360                                                'ï' => '&iuml;',
361                                                'ò' => '&ograve;',
362                                                'ô' => '&ocirc;',
363                                                'ö' => '&ouml;',
364                                                'ù' => '&ugrave;',
365                                                'û' => '&ucirc;',
366                                                'œ' => '&oelig;',
367                                                '€' => '&euro;'
368                                        );
369
370                $this->Body = strtr($this->Body, $cor);
371        }
372        public function Send() {
373                ob_start();
374                $retour = parent::Send();
375                $error = ob_get_contents();
376                ob_end_clean();
377                if( !empty($error) ) {
378                        spip_log("Erreur Facteur->Send : $error",'facteur.err');
379                }
380                return $retour;
381        }
382        public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
383                ob_start();
384                $retour = parent::AddAttachment($path, $name, $encoding, $type);
385                $error = ob_get_contents();
386                ob_end_clean();
387                if( !empty($error) ) {
388                        spip_log("Erreur Facteur->AddAttachment : $error",'facteur.err');
389                }
390                return $retour;
391        }
392        public function AddReplyTo($address, $name = '') {
393                ob_start();
394                $retour = parent::AddReplyTo($address, $name);
395                $error = ob_get_contents();
396                ob_end_clean();
397                if( !empty($error) ) {
398                        spip_log("Erreur Facteur->AddReplyTo : $error",'facteur.err');
399                }
400                return $retour;
401        }
402        public function AddBCC($address, $name = '') {
403                ob_start();
404                $retour = parent::AddBCC($address, $name);
405                $error = ob_get_contents();
406                ob_end_clean();
407                if( !empty($error) ) {
408                        spip_log("Erreur Facteur->AddBCC : $error",'facteur.err');
409                }
410                return $retour;
411        }
412        public function AddCC($address, $name = '') {
413                ob_start();
414                $retour = parent::AddCC($address, $name);
415                $error = ob_get_contents();
416                ob_end_clean();
417                if( !empty($error) ) {
418                        spip_log("Erreur Facteur->AddCC : $error",'facteur.err');
419                }
420                return $retour;
421        }
422}
423
424?>
Note: See TracBrowser for help on using the repository browser.