\r
include_spip('facteur_fonctions');\r
\r
+/**\r
+ * Wrapper de spip_log pour par PHPMailer\r
+ * @param $message\r
+ * @param $level\r
+ */\r
+function facteur_log_debug($message,$level){\r
+ spip_log("$level: ".trim($message),"facteur"._LOG_DEBUG);\r
+}\r
+\r
+\r
class Facteur extends PHPMailer {\r
+ /**\r
+ * From force si From pas dans le bon domaine\r
+ * @var string\r
+ */\r
+ public $ForceFrom = '';\r
+\r
+ /**\r
+ * FromName force si From pas dans le bon domaine\r
+ * @var string\r
+ */\r
+ public $ForceFromName = '';\r
\r
/**\r
* @param $email\r
* @param array $options\r
*\r
*/\r
- function Facteur($email, $objet, $message_html, $message_texte, $options = array()) {\r
- $defaut = array(\r
- 'adresse_envoi' => $GLOBALS['meta']['facteur_adresse_envoi'],\r
- 'adresse_envoi_email' => $GLOBALS['meta']['facteur_adresse_envoi_email'],\r
- 'adresse_envoi_nom' => $GLOBALS['meta']['facteur_adresse_envoi_nom'],\r
- 'cc' => $GLOBALS['meta']['facteur_cc'],\r
- 'bcc' => $GLOBALS['meta']['facteur_bcc'],\r
- 'smtp' => $GLOBALS['meta']['facteur_smtp'],\r
- 'smtp_host' => $GLOBALS['meta']['facteur_smtp_host'],\r
- 'smtp_port' => $GLOBALS['meta']['facteur_smtp_port'],\r
- 'smtp_auth' => $GLOBALS['meta']['facteur_smtp_auth'],\r
- 'smtp_username' => $GLOBALS['meta']['facteur_smtp_username'],\r
- 'smtp_password' => $GLOBALS['meta']['facteur_smtp_password'],\r
- 'smtp_secure' => $GLOBALS['meta']['facteur_smtp_secure'],\r
- 'smtp_sender' => $GLOBALS['meta']['facteur_smtp_sender'],\r
- 'filtre_images' => $GLOBALS['meta']['facteur_filtre_images'],\r
- 'filtre_iso_8859' => $GLOBALS['meta']['facteur_filtre_iso_8859'],\r
- );\r
+ public function __construct($email, $objet, $message_html, $message_texte, $options = array()) {\r
+ // On récupère toutes les options par défaut depuis le formulaire de config\r
+ $defaut = array();\r
+ foreach (array(\r
+ 'adresse_envoi', 'adresse_envoi_email', 'adresse_envoi_nom', 'forcer_from',\r
+ 'cc', 'bcc',\r
+ 'smtp', 'smtp_host', 'smtp_port', 'smtp_auth',\r
+ 'smtp_username', 'smtp_password', 'smtp_secure', 'smtp_sender',\r
+ 'filtre_images', 'filtre_iso_8859',\r
+ ) as $config) {\r
+ $defaut[$config] = isset($GLOBALS['meta']["facteur_$config"]) ? $GLOBALS['meta']["facteur_$config"] : '';\r
+ }\r
+ // On fusionne les options avec d'éventuelles surcharges lors de l'appel\r
$options = array_merge($defaut, $options);\r
\r
+ // par defaut on log rien car tres verbeux\r
+ // on utilise facteur_log_debug qui filtre log SPIP en _LOG_DEBUG\r
+ $this->SMTPDebug = 0;\r
+ $this->Debugoutput = "facteur_log_debug";\r
+ // Il est possible d'avoir beaucoup plus de logs avec 2, 3 ou 4, ce qui logs les échanges complets avec le serveur\r
+ // utiliser avec un define('_MAX_LOG',1000); car sinon on est limite a 100 lignes par hit et phpMailer est tres verbeux\r
if (defined('_FACTEUR_DEBUG_SMTP')) {\r
$this->SMTPDebug = _FACTEUR_DEBUG_SMTP ;\r
}\r
- if ($options['adresse_envoi'] == 'oui'\r
- AND $options['adresse_envoi_email'])\r
+ $this->exceptions = false;\r
+\r
+\r
+ if (\r
+ $options['adresse_envoi'] == 'oui'\r
+ and $options['adresse_envoi_email']\r
+ ) {\r
$this->From = $options['adresse_envoi_email'];\r
- else\r
- $this->From = (isset($GLOBALS['meta']["email_envoi"]) AND $GLOBALS['meta']["email_envoi"])?\r
+ }\r
+ else {\r
+ $this->From = (isset($GLOBALS['meta']["email_envoi"]) AND $GLOBALS['meta']["email_envoi"]) ?\r
$GLOBALS['meta']["email_envoi"]\r
- :$GLOBALS['meta']['email_webmaster'];\r
+ : $GLOBALS['meta']['email_webmaster'];\r
+ }\r
\r
// Si plusieurs emails dans le from, pas de Name !\r
- if (strpos($this->From,",")===false){\r
- if ($options['adresse_envoi'] == 'oui'\r
- AND $options['adresse_envoi_nom'])\r
+ if (strpos($this->From,",") === false) {\r
+ if (\r
+ $options['adresse_envoi'] == 'oui'\r
+ and $options['adresse_envoi_nom']\r
+ ) {\r
$this->FromName = $options['adresse_envoi_nom'];\r
- else\r
+ }\r
+ // Par défaut, l'envoyeur est le nom du site\r
+ else {\r
$this->FromName = strip_tags(extraire_multi($GLOBALS['meta']['nom_site']));\r
+ }\r
+ }\r
+\r
+ // si forcer_from, on sauvegarde le From et FromName par defaut, qui seront utilises\r
+ // si From n'est pas dans le meme domaine\r
+ // (utiliser le facteur avec un service externe qui necessite la validation des domaines d'envoi)\r
+ if ($options['forcer_from']=='oui'){\r
+ $this->ForceFrom = $this->From;\r
+ $this->ForceFromName = $this->FromName;\r
}\r
\r
$this->CharSet = "utf-8";\r
//Pour un envoi multiple de mail, $email doit être un tableau avec les adresses.\r
if (is_array($email)) {\r
foreach ($email as $cle => $adresseMail) {\r
- if (!$this->AddAddress($adresseMail))\r
- spip_log("Erreur AddAddress $adresseMail : ".print_r($this->ErrorInfo,true),'facteur');\r
+ if (!$this->AddAddress($adresseMail)) {\r
+ spip_log("Erreur AddAddress $adresseMail : ".print_r($this->ErrorInfo, true), 'facteur.'._LOG_ERREUR);\r
+ }\r
}\r
}\r
- else\r
- if (!$this->AddAddress($email))\r
- spip_log("Erreur AddAddress $email : ".print_r($this->ErrorInfo,true),'facteur');\r
+ elseif (!$this->AddAddress($email)) {\r
+ spip_log("Erreur AddAddress $email : ".print_r($this->ErrorInfo, true), 'facteur.'._LOG_ERREUR);\r
+ }\r
\r
+ // Retour des erreurs\r
if (!empty($options['smtp_sender'])) {\r
$this->Sender = $options['smtp_sender'];\r
$this->AddCustomHeader("Errors-To: ".$this->Sender);\r
}\r
\r
+ // Destinataires en copie, seulement s'il n'y a pas de destinataire de test\r
if (!defined('_TEST_EMAIL_DEST')){\r
if (!empty($options['cc'])) {\r
- $this->AddCC( $options['cc'] );\r
+ $this->AddCC($options['cc']);\r
}\r
if (!empty($options['bcc'])) {\r
- $this->AddBCC( $options['bcc'] );\r
+ $this->AddBCC($options['bcc']);\r
}\r
}\r
\r
+ // Si on envoie avec un SMTP explicite\r
if (isset($options['smtp']) AND $options['smtp'] == 'oui') {\r
$this->Mailer = 'smtp';\r
$this->Host = $options['smtp_host'];\r
$this->Port = $options['smtp_port'];\r
+\r
+ // SMTP authentifié\r
if ($options['smtp_auth'] == 'oui') {\r
$this->SMTPAuth = true;\r
$this->Username = $options['smtp_username'];\r
else {\r
$this->SMTPAuth = false;\r
}\r
- if (intval(phpversion()) == 5) {\r
- if ($options['smtp_secure'] == 'ssl')\r
+\r
+ if ($options['smtp_secure'] == 'ssl') {\r
$this->SMTPSecure = 'ssl';\r
- if ($options['smtp_secure'] == 'tls')\r
+ }\r
+ if ($options['smtp_secure'] == 'tls') {\r
$this->SMTPSecure = 'tls';\r
}\r
+\r
+ // Pour le moment on remet l'ancien fonctionnement :\r
+ // on ne doit pas tester les certificats si pas demandé explicitement avec l'option TLS !\r
+ $this->SMTPAutoTLS = false;\r
}\r
\r
+ // S'il y a un contenu HTML\r
if (!empty($message_html)) {\r
- $message_html = unicode_to_utf_8(charset2unicode($message_html,$GLOBALS['meta']['charset']));\r
+ $message_html = unicode_to_utf_8(charset2unicode($message_html, $GLOBALS['meta']['charset']));\r
+\r
$this->Body = $message_html;\r
$this->IsHTML(true);\r
- if ($options['filtre_images'])\r
+ if ($options['filtre_images']) {\r
$this->JoindreImagesHTML();\r
+ }\r
+\r
$this->UrlsAbsolues();\r
}\r
+\r
+ // S'il y a un contenu texte brut\r
if (!empty($message_texte)) {\r
- $message_texte = unicode_to_utf_8(charset2unicode($message_texte,$GLOBALS['meta']['charset']));\r
+ $message_texte = unicode_to_utf_8(charset2unicode($message_texte, $GLOBALS['meta']['charset']));\r
+\r
+ // Si pas de HTML on le remplace en tant que contenu principal\r
if (!$this->Body) {\r
$this->IsHTML(false);\r
$this->Body = $message_texte;\r
}\r
+ // Sinon on met le texte brut en contenu alternatif\r
else {\r
$this->AltBody = $message_texte;\r
}\r
}\r
\r
- if ($options['filtre_iso_8859'])\r
+ if ($options['filtre_iso_8859']) {\r
$this->ConvertirUtf8VersIso8859();\r
+ }\r
+ }\r
\r
+ /**\r
+ * @param bool $exceptions\r
+ */\r
+ public function SetExceptions($exceptions){\r
+ $this->exceptions = ($exceptions?true:false);\r
}\r
- \r
- /*\r
+\r
+ /**\r
* Transforme du HTML en texte brut, mais proprement\r
* utilise le filtre facteur_mail_html2text\r
* @uses facteur_mail_html2text()\r
*\r
* @param string $html Le HTML à transformer\r
+ * @param bool $advanced Inutilisé\r
* @return string Retourne un texte brut formaté correctement\r
*/\r
- function html2text($html){\r
+ public function html2text($html, $advanced = false){\r
return facteur_mail_html2text($html);\r
}\r
- \r
+\r
+ /**\r
+ * Compat ascendante, obsolete\r
+ * @deprecated\r
+ */\r
+ public function ConvertirStylesEnligne() {\r
+ $this->Body = facteur_convertir_styles_inline($this->Body);\r
+ }\r
+\r
/**\r
* Transformer les urls des liens et des images en url absolues\r
* sans toucher aux images embarquees de la forme "cid:..."\r
*/\r
- function UrlsAbsolues($base=null){\r
+ protected function UrlsAbsolues($base=null){\r
include_spip('inc/filtres_mini');\r
if (preg_match_all(',(<(a|link)[[:space:]]+[^<>]*href=["\']?)([^"\' ><[:space:]]+)([^<>]*>),imsS',\r
$this->Body, $liens, PREG_SET_ORDER)) {\r
}\r
}\r
\r
- function JoindreImagesHTML() {\r
+ /**\r
+ * Embed les images HTML dans l'email\r
+ */\r
+ protected function JoindreImagesHTML() {\r
$image_types = array(\r
'gif' => 'image/gif',\r
'jpg' => 'image/jpeg',\r
\r
$adresse_site = $GLOBALS['meta']['adresse_site'].'/';\r
foreach($images as $im){\r
+ $im = array_pad($im, 6, null);\r
$src_orig = $im[1].$im[4].$im[5];\r
if (!isset($src_found[$src_orig])){ // deja remplace ? rien a faire (ie la meme image presente plusieurs fois)\r
// examiner le src et voir si embedable\r
\r
\r
/**\r
- * Compat ascendante, obsolete\r
+ * Conversion safe d'un texte utf en isotruc\r
+ * @param string $text\r
+ * @param string $mode\r
+ * @return string\r
*/\r
- function ConvertirStylesEnligne() {\r
- $this->Body = facteur_convertir_styles_inline($this->Body);\r
- }\r
-\r
-\r
- function safe_utf8_decode($text,$mode='texte_brut') {\r
+ protected function safe_utf8_decode($text,$mode='texte_brut') {\r
if (!is_utf8($text))\r
return ($text);\r
\r
}\r
}\r
\r
- function ConvertirUtf8VersIso8859() {\r
+ /**\r
+ * Convertir tout le mail utf en isotruc\r
+ */\r
+ protected function ConvertirUtf8VersIso8859() {\r
$this->CharSet = 'iso-8859-1';\r
$this->Body = str_ireplace('charset=utf-8', 'charset=iso-8859-1', $this->Body);\r
$this->Body = $this->safe_utf8_decode($this->Body,'html');\r
$this->FromName = $this->safe_utf8_decode($this->FromName);\r
}\r
\r
- function ConvertirAccents() {\r
+ /**\r
+ * Convertir les accents du body en entites html\r
+ */\r
+ protected function ConvertirAccents() {\r
// tableau à compléter au fur et à mesure\r
$cor = array(\r
'à' => 'à',\r
\r
$this->Body = strtr($this->Body, $cor);\r
}\r
- public function Send() {\r
- ob_start();\r
- $retour = parent::Send();\r
- $error = ob_get_contents();\r
- ob_end_clean();\r
- if( !empty($error) ) {\r
- spip_log("Erreur Facteur->Send : $error",'facteur.err');\r
+\r
+\r
+ /**\r
+ * Une fonction wrapper pour appeler une methode de phpMailer\r
+ * en recuperant l'erreur eventuelle, en la loguant via SPIP et en lancant une exception si demandee\r
+ * @param string $function\r
+ * @param array $args\r
+ * @return bool\r
+ * @throws phpmailerException\r
+ */\r
+ protected function callWrapper($function,$args){\r
+ $exceptions = $this->exceptions;\r
+ $this->exceptions = true;\r
+ try {\r
+ $retour = call_user_func_array($function,$args);\r
+ $this->exceptions = $exceptions;\r
}\r
+ catch (phpmailerException $exc) {\r
+ spip_log((is_array($function)?implode('::',$function):$function)."() : ".$exc->getMessage(),'facteur.'._LOG_ERREUR);\r
+ $this->exceptions = $exceptions;\r
+ if ($this->exceptions) {\r
+ throw $exc;\r
+ }\r
+ return false;\r
+ }\r
+ if ($this->ErrorInfo){\r
+ spip_log($function."() : ".$this->ErrorInfo,'facteur.'._LOG_ERREUR);\r
+ }\r
+\r
return $retour;\r
}\r
- public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {\r
- ob_start();\r
- $retour = parent::AddAttachment($path, $name, $encoding, $type);\r
- $error = ob_get_contents();\r
- ob_end_clean();\r
- if( !empty($error) ) {\r
- spip_log("Erreur Facteur->AddAttachment : $error",'facteur.err');\r
+\r
+ /*\r
+ * Appel des fonctions parents via le callWrapper qui se charge de loger les erreurs\r
+ */\r
+\r
+ /**\r
+ * Avant le Send() on force le From si besoin\r
+ * @return bool\r
+ * @throws phpmailerException\r
+ */\r
+ public function Send() {\r
+ if ($this->ForceFrom\r
+ AND $this->From!==$this->ForceFrom){\r
+ $forcedomain = explode('@',$this->ForceFrom);\r
+ $forcedomain = end($forcedomain);\r
+ $domain = explode('@',$this->From);\r
+ $domain = end($domain);\r
+ if ($domain!==$forcedomain){\r
+ // le From passe en ReplyTo\r
+ $this->AddReplyTo($this->From,$this->FromName);\r
+ // on force le From\r
+ $this->From = $this->ForceFrom;\r
+ $this->FromName = $this->ForceFromName;\r
+ }\r
}\r
- return $retour;\r
+ $args = func_get_args();\r
+ return $this->callWrapper(array('parent','Send'),$args);\r
+ }\r
+ public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment') {\r
+ $args = func_get_args();\r
+ return $this->callWrapper(array('parent','AddAttachment'),$args);\r
}\r
public function AddReplyTo($address, $name = '') {\r
- ob_start();\r
- $retour = parent::AddReplyTo($address, $name);\r
- $error = ob_get_contents();\r
- ob_end_clean();\r
- if( !empty($error) ) {\r
- spip_log("Erreur Facteur->AddReplyTo : $error",'facteur.err');\r
- }\r
- return $retour;\r
+ $args = func_get_args();\r
+ return $this->callWrapper(array('parent','AddReplyTo'),$args);\r
}\r
public function AddBCC($address, $name = '') {\r
- ob_start();\r
- $retour = parent::AddBCC($address, $name);\r
- $error = ob_get_contents();\r
- ob_end_clean();\r
- if( !empty($error) ) {\r
- spip_log("Erreur Facteur->AddBCC : $error",'facteur.err');\r
- }\r
- return $retour;\r
+ $args = func_get_args();\r
+ return $this->callWrapper(array('parent','AddBCC'),$args);\r
}\r
public function AddCC($address, $name = '') {\r
- ob_start();\r
- $retour = parent::AddCC($address, $name);\r
- $error = ob_get_contents();\r
- ob_end_clean();\r
- if( !empty($error) ) {\r
- spip_log("Erreur Facteur->AddCC : $error",'facteur.err');\r
- }\r
- return $retour;\r
+ $args = func_get_args();\r
+ return $this->callWrapper(array('parent','AddCC'),$args);\r
}\r
}\r
-\r
-?>\r