4 * (c) 2009-2011 Collectif SPIP
5 * Distribue sous licence GPL
9 if (!defined("_ECRIRE_INC_VERSION")) return;
11 include_spip('inc/charsets');
12 include_spip('inc/texte');
13 include_spip('inc/filtres');
15 if (!class_exists('PHPMailer')) {
16 include_spip('phpmailer-php5/class.phpmailer');
17 include_spip('phpmailer-php5/class.smtp');
20 include_spip('facteur_fonctions');
22 class Facteur
extends PHPMailer
{
27 * @param $message_html
28 * @param $message_texte
29 * @param array $options
32 function Facteur($email, $objet, $message_html, $message_texte, $options = 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'],
50 $options = array_merge($defaut, $options);
52 if (defined('_FACTEUR_DEBUG_SMTP')) {
53 $this->SMTPDebug
= _FACTEUR_DEBUG_SMTP
;
55 if ($options['adresse_envoi'] == 'oui'
56 AND $options['adresse_envoi_email'])
57 $this->From
= $options['adresse_envoi_email'];
59 $this->From
= (isset($GLOBALS['meta']["email_envoi"]) AND $GLOBALS['meta']["email_envoi"])?
60 $GLOBALS['meta']["email_envoi"]
61 :$GLOBALS['meta']['email_webmaster'];
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'];
69 $this->FromName
= strip_tags(extraire_multi($GLOBALS['meta']['nom_site']));
72 $this->CharSet
= "utf-8";
73 $this->Mailer
= 'mail';
74 $this->Subject
= unicode_to_utf_8(charset2unicode($objet,$GLOBALS['meta']['charset']));
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');
84 if (!$this->AddAddress($email))
85 spip_log("Erreur AddAddress $email : ".print_r($this->ErrorInfo
,true),'facteur');
87 if (!empty($options['smtp_sender'])) {
88 $this->Sender
= $options['smtp_sender'];
89 $this->AddCustomHeader("Errors-To: ".$this->Sender
);
92 if (!defined('_TEST_EMAIL_DEST')){
93 if (!empty($options['cc'])) {
94 $this->AddCC( $options['cc'] );
96 if (!empty($options['bcc'])) {
97 $this->AddBCC( $options['bcc'] );
101 if (isset($options['smtp']) AND $options['smtp'] == 'oui') {
102 $this->Mailer
= 'smtp';
103 $this->Host
= $options['smtp_host'];
104 $this->Port
= $options['smtp_port'];
105 if ($options['smtp_auth'] == 'oui') {
106 $this->SMTPAuth
= true;
107 $this->Username
= $options['smtp_username'];
108 $this->Password
= $options['smtp_password'];
111 $this->SMTPAuth
= false;
113 if (intval(phpversion()) == 5) {
114 if ($options['smtp_secure'] == 'ssl')
115 $this->SMTPSecure
= 'ssl';
116 if ($options['smtp_secure'] == 'tls')
117 $this->SMTPSecure
= 'tls';
121 if (!empty($message_html)) {
122 $message_html = unicode_to_utf_8(charset2unicode($message_html,$GLOBALS['meta']['charset']));
123 $this->Body
= $message_html;
125 if ($options['filtre_images'])
126 $this->JoindreImagesHTML();
127 $this->UrlsAbsolues();
129 if (!empty($message_texte)) {
130 $message_texte = unicode_to_utf_8(charset2unicode($message_texte,$GLOBALS['meta']['charset']));
132 $this->IsHTML(false);
133 $this->Body
= $message_texte;
136 $this->AltBody
= $message_texte;
140 if ($options['filtre_iso_8859'])
141 $this->ConvertirUtf8VersIso8859();
146 * Transforme du HTML en texte brut, mais proprement
147 * utilise le filtre facteur_mail_html2text
148 * @uses facteur_mail_html2text()
150 * @param string $html Le HTML à transformer
151 * @return string Retourne un texte brut formaté correctement
153 function html2text($html){
154 return facteur_mail_html2text($html);
158 * Transformer les urls des liens et des images en url absolues
159 * sans toucher aux images embarquees de la forme "cid:..."
161 function UrlsAbsolues($base=null){
162 include_spip('inc/filtres_mini');
163 if (preg_match_all(',(<(a|link)[[:space:]]+[^<>]*href=["\']?)([^"\' ><[:space:]]+)([^<>]*>),imsS',
164 $this->Body
, $liens, PREG_SET_ORDER
)) {
165 foreach ($liens as $lien) {
166 if (strncmp($lien[3],"cid:",4)!==0){
167 $abs = url_absolue($lien[3], $base);
168 if ($abs <> $lien[3] and !preg_match('/^#/',$lien[3]))
169 $this->Body
= str_replace($lien[0], $lien[1].$abs.$lien[4], $this->Body
);
173 if (preg_match_all(',(<(img|script)[[:space:]]+[^<>]*src=["\']?)([^"\' ><[:space:]]+)([^<>]*>),imsS',
174 $this->Body
, $liens, PREG_SET_ORDER
)) {
175 foreach ($liens as $lien) {
176 if (strncmp($lien[3],"cid:",4)!==0){
177 $abs = url_absolue($lien[3], $base);
178 if ($abs <> $lien[3])
179 $this->Body
= str_replace($lien[0], $lien[1].$abs.$lien[4], $this->Body
);
185 function JoindreImagesHTML() {
186 $image_types = array(
187 'gif' => 'image/gif',
188 'jpg' => 'image/jpeg',
189 'jpeg' => 'image/jpeg',
190 'jpe' => 'image/jpeg',
191 'bmp' => 'image/bmp',
192 'png' => 'image/png',
193 'tif' => 'image/tiff',
194 'tiff' => 'image/tiff',
195 'swf' => 'application/x-shockwave-flash'
197 $src_found = array();
198 $images_embeded = array();
200 '/["\'](([^"\']+)\.('.implode('|', array_keys($image_types)).'))([?][^"\']+)?([#][^"\']+)?["\']/Uims',
201 $this->Body
, $images, PREG_SET_ORDER
)) {
203 $adresse_site = $GLOBALS['meta']['adresse_site'].'/';
204 foreach($images as $im){
205 $src_orig = $im[1].$im[4].$im[5];
206 if (!isset($src_found[$src_orig])){ // deja remplace ? rien a faire (ie la meme image presente plusieurs fois)
207 // examiner le src et voir si embedable
209 if ($src AND strncmp($src,$adresse_site,strlen($adresse_site))==0)
210 $src = _DIR_RACINE
. substr($src,strlen($adresse_site));
212 AND !preg_match(",^[a-z0-9]+://,i",$src)
214 file_exists($f=$src) // l'image a ete generee depuis le meme cote que l'envoi
215 OR (_DIR_RACINE
AND file_exists($f=_DIR_RACINE
.$src)) // l'image a ete generee dans le public et on est dans le prive
216 OR (!_DIR_RACINE
AND file_exists($f=_DIR_RESTREINT
.$src)) // l'image a ete generee dans le prive et on est dans le public
219 if (!isset($images_embeded[$f])){
220 $extension = strtolower($im[3]);
221 $header_extension = $image_types[$extension];
222 $cid = md5($f); // un id unique pour un meme fichier
223 $images_embeded[$f] = $cid; // marquer l'image comme traitee, inutile d'y revenir
224 $this->AddEmbeddedImage($f, $cid, basename($f),'base64',$header_extension);
227 $this->Body
= str_replace($src_orig, "cid:".$images_embeded[$f], $this->Body
);
228 $src_found[$src_orig] = $f;
237 * Compat ascendante, obsolete
239 function ConvertirStylesEnligne() {
240 $this->Body
= facteur_convertir_styles_inline($this->Body
);
244 function safe_utf8_decode($text,$mode='texte_brut') {
248 if (function_exists('iconv') && $mode == 'texte_brut') {
249 $text = str_replace('’',"'",$text);
250 $text = iconv("UTF-8", "ISO-8859-1//TRANSLIT", $text);
251 return str_replace('’',"'",$text);
254 if ($mode == 'texte_brut') {
255 $text = str_replace('’',"'",$text);
257 $text = unicode2charset(utf_8_to_unicode($text),'iso-8859-1');
258 return str_replace('’',"'",$text);
262 function ConvertirUtf8VersIso8859() {
263 $this->CharSet
= 'iso-8859-1';
264 $this->Body
= str_ireplace('charset=utf-8', 'charset=iso-8859-1', $this->Body
);
265 $this->Body
= $this->safe_utf8_decode($this->Body
,'html');
266 $this->AltBody
= $this->safe_utf8_decode($this->AltBody
);
267 $this->Subject
= $this->safe_utf8_decode($this->Subject
);
268 $this->FromName
= $this->safe_utf8_decode($this->FromName
);
271 function ConvertirAccents() {
272 // tableau à compléter au fur et à mesure
293 $this->Body
= strtr($this->Body
, $cor);
295 public function Send() {
297 $retour = parent
::Send();
298 $error = ob_get_contents();
300 if( !empty($error) ) {
301 spip_log("Erreur Facteur->Send : $error",'facteur.err');
305 public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
307 $retour = parent
::AddAttachment($path, $name, $encoding, $type);
308 $error = ob_get_contents();
310 if( !empty($error) ) {
311 spip_log("Erreur Facteur->AddAttachment : $error",'facteur.err');
315 public function AddReplyTo($address, $name = '') {
317 $retour = parent
::AddReplyTo($address, $name);
318 $error = ob_get_contents();
320 if( !empty($error) ) {
321 spip_log("Erreur Facteur->AddReplyTo : $error",'facteur.err');
325 public function AddBCC($address, $name = '') {
327 $retour = parent
::AddBCC($address, $name);
328 $error = ob_get_contents();
330 if( !empty($error) ) {
331 spip_log("Erreur Facteur->AddBCC : $error",'facteur.err');
335 public function AddCC($address, $name = '') {
337 $retour = parent
::AddCC($address, $name);
338 $error = ob_get_contents();
340 if( !empty($error) ) {
341 spip_log("Erreur Facteur->AddCC : $error",'facteur.err');