Compare commits

..

4 Commits
master ... v2

Author SHA1 Message Date
spip.franck@lien-d-amis.net bb645947f5 - Ce n'est plus http://trad.spip.org mais https://trad.spip.net 6 years ago
spip.franck@lien-d-amis.net cffe979b67 Contrib est en https, donc j'ajoute le "s", plus divers broutilles 6 years ago
spip.franck@lien-d-amis.net e759d95b2b Ce n'est plus spip-contrib, mais contrib.spip 8 years ago
cedric@yterium.com a5d34cda0a Branchons la v2 pour pouvoir faire des travaux sur la v3 10 years ago
  1. 63
      .gitattributes
  2. 15
      .gitignore
  3. 424
      classes/facteur.php
  4. 27
      composer.json
  5. 0
      emails/css.html
  6. 0
      emails/inc-bas.html
  7. 9
      emails/inc-button.html
  8. 0
      emails/inc-haut.html
  9. 51
      emails/test_email_html.html
  10. 8
      emails/test_email_texte.html
  11. 36
      emails/texte.html
  12. 42
      erreurs et exceptions.txt
  13. 12
      facteur-64.svg
  14. 111
      facteur_administrations.php
  15. 339
      facteur_fonctions.php
  16. 36
      facteur_ieconfig_metas.php
  17. 302
      formulaires/configurer_facteur.html
  18. 361
      formulaires/configurer_facteur.php
  19. 4
      formulaires/inc-config-facteur-mailer-mail.html
  20. 71
      formulaires/inc-config-facteur-mailer-smtp.html
  21. 71
      formulaires/tester_facteur.html
  22. 183
      formulaires/tester_facteur.php
  23. 628
      inc/Facteur/FacteurMail.php
  24. 68
      inc/Facteur/FacteurSMTP.php
  25. 293
      inc/envoyer_mail.php
  26. 620
      inc/facteur.php
  27. 17
      inc/facteur_classes.php
  28. 224
      inc/facteur_convertir_styles_inline.php
  29. 52
      inc/facteur_envoyer_alerte_fail.php
  30. 113
      inc/facteur_mail_html2text.php
  31. 65
      inc/facteur_mail_wrap_to_html.php
  32. 67
      lang/facteur.xml
  33. 79
      lang/facteur_de.php
  34. 57
      lang/facteur_en.php
  35. 86
      lang/facteur_eo.php
  36. 49
      lang/facteur_es.php
  37. 79
      lang/facteur_fa.php
  38. 91
      lang/facteur_fr.php
  39. 101
      lang/facteur_fr_tu.php
  40. 100
      lang/facteur_it.php
  41. 99
      lang/facteur_ja.php
  42. 100
      lang/facteur_nl.php
  43. 79
      lang/facteur_oc_ni_mis.php
  44. 83
      lang/facteur_pt.php
  45. 83
      lang/facteur_pt_br.php
  46. 100
      lang/facteur_ru.php
  47. 34
      lang/facteur_sk.php
  48. 101
      lang/facteur_uk.php
  49. 48
      lang/paquet-facteur.xml
  50. 16
      lang/paquet-facteur_de.php
  51. 6
      lang/paquet-facteur_en.php
  52. 16
      lang/paquet-facteur_eo.php
  53. 6
      lang/paquet-facteur_es.php
  54. 10
      lang/paquet-facteur_fr.php
  55. 16
      lang/paquet-facteur_fr_tu.php
  56. 16
      lang/paquet-facteur_it.php
  57. 16
      lang/paquet-facteur_ja.php
  58. 16
      lang/paquet-facteur_nl.php
  59. 16
      lang/paquet-facteur_pt.php
  60. 16
      lang/paquet-facteur_pt_br.php
  61. 16
      lang/paquet-facteur_ru.php
  62. 6
      lang/paquet-facteur_sk.php
  63. 16
      lang/paquet-facteur_uk.php
  64. 46
      lib/PHPMailer-6/COMMITMENT
  65. 502
      lib/PHPMailer-6/LICENSE
  66. 227
      lib/PHPMailer-6/README.md
  67. 37
      lib/PHPMailer-6/SECURITY.md
  68. 1
      lib/PHPMailer-6/VERSION
  69. 34
      lib/PHPMailer-6/autoload.php
  70. 71
      lib/PHPMailer-6/composer.json
  71. 26
      lib/PHPMailer-6/language/phpmailer.lang-af.php
  72. 26
      lib/PHPMailer-6/language/phpmailer.lang-am.php
  73. 27
      lib/PHPMailer-6/language/phpmailer.lang-ar.php
  74. 27
      lib/PHPMailer-6/language/phpmailer.lang-az.php
  75. 27
      lib/PHPMailer-6/language/phpmailer.lang-ba.php
  76. 27
      lib/PHPMailer-6/language/phpmailer.lang-be.php
  77. 27
      lib/PHPMailer-6/language/phpmailer.lang-bg.php
  78. 27
      lib/PHPMailer-6/language/phpmailer.lang-ca.php
  79. 27
      lib/PHPMailer-6/language/phpmailer.lang-ch.php
  80. 28
      lib/PHPMailer-6/language/phpmailer.lang-cs.php
  81. 29
      lib/PHPMailer-6/language/phpmailer.lang-da.php
  82. 28
      lib/PHPMailer-6/language/phpmailer.lang-de.php
  83. 26
      lib/PHPMailer-6/language/phpmailer.lang-el.php
  84. 26
      lib/PHPMailer-6/language/phpmailer.lang-eo.php
  85. 27
      lib/PHPMailer-6/language/phpmailer.lang-es.php
  86. 28
      lib/PHPMailer-6/language/phpmailer.lang-fa.php
  87. 38
      lib/PHPMailer-6/language/phpmailer.lang-fr.php
  88. 27
      lib/PHPMailer-6/language/phpmailer.lang-gl.php
  89. 27
      lib/PHPMailer-6/language/phpmailer.lang-he.php
  90. 27
      lib/PHPMailer-6/language/phpmailer.lang-hi.php
  91. 27
      lib/PHPMailer-6/language/phpmailer.lang-hr.php
  92. 27
      lib/PHPMailer-6/language/phpmailer.lang-hu.php
  93. 27
      lib/PHPMailer-6/language/phpmailer.lang-hy.php
  94. 31
      lib/PHPMailer-6/language/phpmailer.lang-id.php
  95. 28
      lib/PHPMailer-6/language/phpmailer.lang-it.php
  96. 29
      lib/PHPMailer-6/language/phpmailer.lang-ja.php
  97. 27
      lib/PHPMailer-6/language/phpmailer.lang-ka.php
  98. 27
      lib/PHPMailer-6/language/phpmailer.lang-ko.php
  99. 27
      lib/PHPMailer-6/language/phpmailer.lang-lt.php
  100. 27
      lib/PHPMailer-6/language/phpmailer.lang-lv.php
  101. Some files were not shown because too many files have changed in this diff Show More

63
.gitattributes vendored

@ -0,0 +1,63 @@
* text=auto !eol
classes/facteur.php -text
emails/css.html -text
emails/inc-bas.html -text
emails/inc-button.html -text
emails/inc-haut.html -text
emails/test_email_html.html -text
emails/test_email_texte.html -text
emails/texte.html -text
/erreurs[!!-~]et[!!-~]exceptions.txt -text
/facteur_administrations.php -text
/facteur_fonctions.php -text
/facteur_ieconfig_metas.php -text
formulaires/configurer_facteur.html -text
formulaires/configurer_facteur.php -text
inc/envoyer_mail.php -text
inc/facteur_classes.php -text
lang/facteur.xml -text
lang/facteur_de.php -text
lang/facteur_en.php -text
lang/facteur_es.php -text
lang/facteur_fr.php -text
lang/facteur_sk.php -text
lang/paquet-facteur.xml -text
lang/paquet-facteur_en.php -text
lang/paquet-facteur_es.php -text
lang/paquet-facteur_fr.php -text
lang/paquet-facteur_sk.php -text
/paquet.xml -text
phpmailer-php5/LICENSE -text
phpmailer-php5/README -text
phpmailer-php5/class.phpmailer.php -text
phpmailer-php5/class.pop3.php -text
phpmailer-php5/class.smtp.php -text
phpmailer-php5/language/phpmailer.lang-ar.php -text
phpmailer-php5/language/phpmailer.lang-br.php -text
phpmailer-php5/language/phpmailer.lang-ca.php -text
phpmailer-php5/language/phpmailer.lang-ch.php -text
phpmailer-php5/language/phpmailer.lang-cz.php -text
phpmailer-php5/language/phpmailer.lang-de.php -text
phpmailer-php5/language/phpmailer.lang-dk.php -text
phpmailer-php5/language/phpmailer.lang-en.php -text
phpmailer-php5/language/phpmailer.lang-es.php -text
phpmailer-php5/language/phpmailer.lang-et.php -text
phpmailer-php5/language/phpmailer.lang-fi.php -text
phpmailer-php5/language/phpmailer.lang-fo.php -text
phpmailer-php5/language/phpmailer.lang-fr.php -text
phpmailer-php5/language/phpmailer.lang-hu.php -text
phpmailer-php5/language/phpmailer.lang-it.php -text
phpmailer-php5/language/phpmailer.lang-ja.php -text svneol=unset#application/octet-stream
phpmailer-php5/language/phpmailer.lang-nl.php -text
phpmailer-php5/language/phpmailer.lang-no.php -text
phpmailer-php5/language/phpmailer.lang-pl.php -text
phpmailer-php5/language/phpmailer.lang-ro.php -text
phpmailer-php5/language/phpmailer.lang-ru.php -text
phpmailer-php5/language/phpmailer.lang-se.php -text
phpmailer-php5/language/phpmailer.lang-tr.php -text
phpmailer-php5/language/phpmailer.lang-zh.php -text
phpmailer-php5/language/phpmailer.lang-zh_cn.php -text
prive/squelettes/contenu/configurer_facteur.html -text
prive/themes/spip/images/facteur-16.png -text
prive/themes/spip/images/facteur-24.png -text
prive/themes/spip/images/facteur-32.png -text

15
.gitignore vendored

@ -1,15 +0,0 @@
/vendor/
/composer.phar
/composer.lock
/phpcs.xml
/phpstan.neon
/.php_cs.cache
/.php_cs.txt
/.phpunit.cache
/phpunit.xml
/var
!/var/tmp/file.unknown
!/var/tmp/test.zip
!/var/tmp/tar/test.tar
!/var/tmp/tgz/test.tar.gz
/rector.php

424
classes/facteur.php

@ -0,0 +1,424 @@
<?php
/*
* Plugin Facteur 2
* (c) 2009-2011 Collectif SPIP
* Distribue sous licence GPL
*
*/
if (!defined("_ECRIRE_INC_VERSION")) return;
include_spip('inc/charsets');
include_spip('inc/texte');
include_spip('inc/filtres');
if (!class_exists('PHPMailer')) {
include_spip('phpmailer-php5/class.phpmailer');
include_spip('phpmailer-php5/class.smtp');
}
include_spip('facteur_fonctions');
class Facteur extends PHPMailer {
/**
* @param $email
* @param $objet
* @param $message_html
* @param $message_texte
* @param array $options
*
*/
function Facteur($email, $objet, $message_html, $message_texte, $options = array()) {
$defaut = array(
'adresse_envoi' => $GLOBALS['meta']['facteur_adresse_envoi'],
'adresse_envoi_email' => $GLOBALS['meta']['facteur_adresse_envoi_email'],
'adresse_envoi_nom' => $GLOBALS['meta']['facteur_adresse_envoi_nom'],
'cc' => $GLOBALS['meta']['facteur_cc'],
'bcc' => $GLOBALS['meta']['facteur_bcc'],
'smtp' => $GLOBALS['meta']['facteur_smtp'],
'smtp_host' => $GLOBALS['meta']['facteur_smtp_host'],
'smtp_port' => $GLOBALS['meta']['facteur_smtp_port'],
'smtp_auth' => $GLOBALS['meta']['facteur_smtp_auth'],
'smtp_username' => $GLOBALS['meta']['facteur_smtp_username'],
'smtp_password' => $GLOBALS['meta']['facteur_smtp_password'],
'smtp_secure' => $GLOBALS['meta']['facteur_smtp_secure'],
'smtp_sender' => $GLOBALS['meta']['facteur_smtp_sender'],
'filtre_images' => $GLOBALS['meta']['facteur_filtre_images'],
'filtre_iso_8859' => $GLOBALS['meta']['facteur_filtre_iso_8859'],
);
$options = array_merge($defaut, $options);
if (defined('_FACTEUR_DEBUG_SMTP')) {
$this->SMTPDebug = _FACTEUR_DEBUG_SMTP ;
}
if ($options['adresse_envoi'] == 'oui'
AND $options['adresse_envoi_email'])
$this->From = $options['adresse_envoi_email'];
else
$this->From = (isset($GLOBALS['meta']["email_envoi"]) AND $GLOBALS['meta']["email_envoi"])?
$GLOBALS['meta']["email_envoi"]
:$GLOBALS['meta']['email_webmaster'];
// Si plusieurs emails dans le from, pas de Name !
if (strpos($this->From,",")===false){
if ($options['adresse_envoi'] == 'oui'
AND $options['adresse_envoi_nom'])
$this->FromName = $options['adresse_envoi_nom'];
else
$this->FromName = strip_tags(extraire_multi($GLOBALS['meta']['nom_site']));
}
$this->CharSet = "utf-8";
$this->Mailer = 'mail';
$this->Subject = unicode_to_utf_8(charset2unicode($objet,$GLOBALS['meta']['charset']));
//Pour un envoi multiple de mail, $email doit être un tableau avec les adresses.
if (is_array($email)) {
foreach ($email as $cle => $adresseMail) {
if (!$this->AddAddress($adresseMail))
spip_log("Erreur AddAddress $adresseMail : ".print_r($this->ErrorInfo,true),'facteur');
}
}
else
if (!$this->AddAddress($email))
spip_log("Erreur AddAddress $email : ".print_r($this->ErrorInfo,true),'facteur');
if (!empty($options['smtp_sender'])) {
$this->Sender = $options['smtp_sender'];
$this->AddCustomHeader("Errors-To: ".$this->Sender);
}
if (!empty($options['cc'])) {
$this->AddCC( $options['cc'] );
}
if (!empty($options['bcc'])) {
$this->AddBCC( $options['bcc'] );
}
if (isset($options['smtp']) AND $options['smtp'] == 'oui') {
$this->Mailer = 'smtp';
$this->Host = $options['smtp_host'];
$this->Port = $options['smtp_port'];
if ($options['smtp_auth'] == 'oui') {
$this->SMTPAuth = true;
$this->Username = $options['smtp_username'];
$this->Password = $options['smtp_password'];
}
else {
$this->SMTPAuth = false;
}
if (intval(phpversion()) == 5) {
if ($options['smtp_secure'] == 'ssl')
$this->SMTPSecure = 'ssl';
if ($options['smtp_secure'] == 'tls')
$this->SMTPSecure = 'tls';
}
}
if (!empty($message_html)) {
$message_html = unicode_to_utf_8(charset2unicode($message_html,$GLOBALS['meta']['charset']));
$this->Body = $message_html;
$this->IsHTML(true);
if ($options['filtre_images'])
$this->JoindreImagesHTML();
$this->UrlsAbsolues();
}
if (!empty($message_texte)) {
$message_texte = unicode_to_utf_8(charset2unicode($message_texte,$GLOBALS['meta']['charset']));
if (!$this->Body) {
$this->IsHTML(false);
$this->Body = $message_texte;
}
else {
$this->AltBody = $message_texte;
}
}
if ($options['filtre_iso_8859'])
$this->ConvertirUtf8VersIso8859();
}
/*
* Transforme du HTML en texte brut, mais proprement, c'est-à-dire en essayant
* de garder les titrages, les listes, etc
*
* @param string $html Le HTML à transformer
* @return string Retourne un texte brut formaté correctement
*/
function html2text($html){
// On remplace tous les sauts de lignes par un espace
$html = str_replace("\n", ' ', $html);
// Supprimer tous les liens internes
$texte = preg_replace("/\<a href=['\"]#(.*?)['\"][^>]*>(.*?)<\/a>/ims", "\\2", $html);
// Supprime feuille style
$texte = preg_replace(";<style[^>]*>[^<]*</style>;i", "", $texte);
// Remplace tous les liens
$texte = preg_replace("/\<a[^>]*href=['\"](.*?)['\"][^>]*>(.*?)<\/a>/ims", "\\2 (\\1)", $texte);
// Les titres
$texte = preg_replace(";<h1[^>]*>;i", "\n= ", $texte);
$texte = str_replace("</h1>", " =\n\n", $texte);
$texte = preg_replace(";<h2[^>]*>;i", "\n== ", $texte);
$texte = str_replace("</h2>", " ==\n\n", $texte);
$texte = preg_replace(";<h3[^>]*>;i", "\n=== ", $texte);
$texte = str_replace("</h3>", " ===\n\n", $texte);
// Une fin de liste
$texte = preg_replace(";</(u|o)l>;i", "\n\n", $texte);
// Une saut de ligne *après* le paragraphe
$texte = preg_replace(";<p[^>]*>;i", "\n", $texte);
$texte = preg_replace(";</p>;i", "\n\n", $texte);
// Les sauts de ligne interne
$texte = preg_replace(";<br[^>]*>;i", "\n", $texte);
//$texte = str_replace('<br /><img class=\'spip_puce\' src=\'puce.gif\' alt=\'-\' border=\'0\'>', "\n".'-', $texte);
$texte = preg_replace (';<li[^>]*>;i', "\n".'- ', $texte);
// accentuation du gras
// <b>texte</b> -> **texte**
$texte = preg_replace (';<b[^>]*>;i','**' ,$texte);
$texte = str_replace ('</b>','**' ,$texte);
// accentuation du gras
// <strong>texte</strong> -> **texte**
$texte = preg_replace (';<strong[^>]*>;i','**' ,$texte);
$texte = str_replace ('</strong>','**' ,$texte);
// accentuation de l'italique
// <em>texte</em> -> *texte*
$texte = preg_replace (';<em[^>]*>;i','/' ,$texte);
$texte = str_replace ('</em>','*' ,$texte);
// accentuation de l'italique
// <i>texte</i> -> *texte*
$texte = preg_replace (';<i[^>]*>;i','/' ,$texte);
$texte = str_replace ('</i>','*' ,$texte);
$texte = str_replace('&oelig;', 'oe', $texte);
$texte = str_replace("&nbsp;", " ", $texte);
$texte = filtrer_entites($texte);
// On supprime toutes les balises restantes
$texte = supprimer_tags($texte);
$texte = str_replace("\x0B", "", $texte);
$texte = str_replace("\t", "", $texte) ;
$texte = preg_replace(";[ ]{3,};", "", $texte);
// espace en debut de ligne
$texte = preg_replace("/(\r\n|\n|\r)[ ]+/", "\n", $texte);
//marche po
// Bring down number of empty lines to 4 max
$texte = preg_replace("/(\r\n|\n|\r){3,}/m", "\n\n", $texte);
//saut de lignes en debut de texte
$texte = preg_replace("/^(\r\n|\n|\r)*/", "\n\n", $texte);
//saut de lignes en debut ou fin de texte
$texte = preg_replace("/(\r\n|\n|\r)*$/", "\n\n", $texte);
// Faire des lignes de 75 caracteres maximum
//$texte = wordwrap($texte);
return $texte;
}
/**
* Transformer les urls des liens et des images en url absolues
* sans toucher aux images embarquees de la forme "cid:..."
*/
function UrlsAbsolues($base=null){
include_spip('inc/filtres_mini');
if (preg_match_all(',(<(a|link)[[:space:]]+[^<>]*href=["\']?)([^"\' ><[:space:]]+)([^<>]*>),imsS',
$this->Body, $liens, PREG_SET_ORDER)) {
foreach ($liens as $lien) {
if (strncmp($lien[3],"cid:",4)!==0){
$abs = url_absolue($lien[3], $base);
if ($abs <> $lien[3] and !preg_match('/^#/',$lien[3]))
$this->Body = str_replace($lien[0], $lien[1].$abs.$lien[4], $this->Body);
}
}
}
if (preg_match_all(',(<(img|script)[[:space:]]+[^<>]*src=["\']?)([^"\' ><[:space:]]+)([^<>]*>),imsS',
$this->Body, $liens, PREG_SET_ORDER)) {
foreach ($liens as $lien) {
if (strncmp($lien[3],"cid:",4)!==0){
$abs = url_absolue($lien[3], $base);
if ($abs <> $lien[3])
$this->Body = str_replace($lien[0], $lien[1].$abs.$lien[4], $this->Body);
}
}
}
}
function JoindreImagesHTML() {
$image_types = array(
'gif' => 'image/gif',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpe' => 'image/jpeg',
'bmp' => 'image/bmp',
'png' => 'image/png',
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
'swf' => 'application/x-shockwave-flash'
);
$src_found = array();
$images_embeded = array();
if (preg_match_all(
'/["\'](([^"\']+)\.('.implode('|', array_keys($image_types)).'))([?][^"\']+)?([#][^"\']+)?["\']/Uims',
$this->Body, $images, PREG_SET_ORDER)) {
$adresse_site = $GLOBALS['meta']['adresse_site'].'/';
foreach($images as $im){
$src_orig = $im[1].$im[4].$im[5];
if (!isset($src_found[$src_orig])){ // deja remplace ? rien a faire (ie la meme image presente plusieurs fois)
// examiner le src et voir si embedable
$src = $im[1];
if ($src AND strncmp($src,$adresse_site,strlen($adresse_site))==0)
$src = _DIR_RACINE . substr($src,strlen($adresse_site));
if ($src
AND !preg_match(",^[a-z0-9]+://,i",$src)
AND (
file_exists($f=$src) // l'image a ete generee depuis le meme cote que l'envoi
OR (_DIR_RACINE AND file_exists($f=_DIR_RACINE.$src)) // l'image a ete generee dans le public et on est dans le prive
OR (!_DIR_RACINE AND file_exists($f=_DIR_RESTREINT.$src)) // l'image a ete generee dans le prive et on est dans le public
)
){
if (!isset($images_embeded[$f])){
$extension = strtolower($im[3]);
$header_extension = $image_types[$extension];
$cid = md5($f); // un id unique pour un meme fichier
$images_embeded[$f] = $cid; // marquer l'image comme traitee, inutile d'y revenir
$this->AddEmbeddedImage($f, $cid, basename($f),'base64',$header_extension);
}
$this->Body = str_replace($src_orig, "cid:".$images_embeded[$f], $this->Body);
$src_found[$src_orig] = $f;
}
}
}
}
}
/**
* Compat ascendante, obsolete
*/
function ConvertirStylesEnligne() {
$this->Body = facteur_convertir_styles_inline($this->Body);
}
function safe_utf8_decode($text,$mode='texte_brut') {
if (!is_utf8($text))
return ($text);
if (function_exists('iconv') && $mode == 'texte_brut') {
$text = str_replace('’',"'",$text);
$text = iconv("UTF-8", "ISO-8859-1//TRANSLIT", $text);
return str_replace('&#8217;',"'",$text);
}
else {
if ($mode == 'texte_brut') {
$text = str_replace('’',"'",$text);
}
$text = unicode2charset(utf_8_to_unicode($text),'iso-8859-1');
return str_replace('&#8217;',"'",$text);
}
}
function ConvertirUtf8VersIso8859() {
$this->CharSet = 'iso-8859-1';
$this->Body = str_ireplace('charset=utf-8', 'charset=iso-8859-1', $this->Body);
$this->Body = $this->safe_utf8_decode($this->Body,'html');
$this->AltBody = $this->safe_utf8_decode($this->AltBody);
$this->Subject = $this->safe_utf8_decode($this->Subject);
$this->FromName = $this->safe_utf8_decode($this->FromName);
}
function ConvertirAccents() {
// tableau à compléter au fur et à mesure
$cor = array(
'à' => '&agrave;',
'â' => '&acirc;',
'ä' => '&auml;',
'ç' => '&ccedil;',
'é' => '&eacute;',
'è' => '&egrave;',
'ê' => '&ecirc;',
'ë' => '&euml;',
'î' => '&icirc;',
'ï' => '&iuml;',
'ò' => '&ograve;',
'ô' => '&ocirc;',
'ö' => '&ouml;',
'ù' => '&ugrave;',
'û' => '&ucirc;',
'œ' => '&oelig;',
'€' => '&euro;'
);
$this->Body = strtr($this->Body, $cor);
}
public function Send() {
ob_start();
$retour = parent::Send();
$error = ob_get_contents();
ob_end_clean();
if( !empty($error) ) {
spip_log("Erreur Facteur->Send : $error",'facteur.err');
}
return $retour;
}
public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
ob_start();
$retour = parent::AddAttachment($path, $name, $encoding, $type);
$error = ob_get_contents();
ob_end_clean();
if( !empty($error) ) {
spip_log("Erreur Facteur->AddAttachment : $error",'facteur.err');
}
return $retour;
}
public function AddReplyTo($address, $name = '') {
ob_start();
$retour = parent::AddReplyTo($address, $name);
$error = ob_get_contents();
ob_end_clean();
if( !empty($error) ) {
spip_log("Erreur Facteur->AddReplyTo : $error",'facteur.err');
}
return $retour;
}
public function AddBCC($address, $name = '') {
ob_start();
$retour = parent::AddBCC($address, $name);
$error = ob_get_contents();
ob_end_clean();
if( !empty($error) ) {
spip_log("Erreur Facteur->AddBCC : $error",'facteur.err');
}
return $retour;
}
public function AddCC($address, $name = '') {
ob_start();
$retour = parent::AddCC($address, $name);
$error = ob_get_contents();
ob_end_clean();
if( !empty($error) ) {
spip_log("Erreur Facteur->AddCC : $error",'facteur.err');
}
return $retour;
}
}
?>

27
composer.json

@ -1,27 +0,0 @@
{
"autoload": {
"psr-4": {
"SPIP\\Facteur\\": "inc/Facteur/"
}
},
"autoload-dev": {
},
"require": {
"php": "^7.4 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"spip/coding-standards": "^1.2",
"phpstan/phpstan": "^1.4",
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.1",
"rector/rector": "^0.12.13"
},
"config": {
"platform": {
"php": "7.4.27"
},
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}

0
emails/css.html

0
emails/inc-bas.html

9
emails/inc-button.html

@ -1,6 +1,6 @@
[(#REM)
Bulletproof button code for email html
from https://buttons.cm/
from http://emailbtn.net/
Arguments :
url
@ -12,13 +12,12 @@
width (200px par defaut)
height (40px par defaut)
bgurl (rien par defaut)
fontsize (13px par défaut)
]
<span style="display: inline-block;"><!--[if mso]>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="#ENV*{url}" style="height:#ENV{height,40px};v-text-anchor:middle;width:#ENV{width,200px};"[(#ENV{borderradius,4px}|intval|oui)arcsize="[(#ENV{borderradius,4px}|intval|mult{100}|div{#ENV{height,40px}|intval}|intval)%]"] strokecolor="#ENV{bordercolor,#1e3650}" [(#ENV{bgurl,''}|?{'fill="t"',[fillcolor="(#ENV{bgcolor,#556270})"]})]>
[<v:fill type="tile" src="(#ENV{bgurl,''})" color="#ENV{bgcolor,#556270}" />
]<w:anchorlock/>
<center style="color:#ENV{color,#ffffff};font-family:sans-serif;[font-size:(#ENV{fontsize,13px});]font-weight:bold;">#ENV*{label}</center>
<center style="color:#ENV{color,#ffffff};font-family:sans-serif;font-size:13px;font-weight:bold;">#ENV*{label}</center>
</v:roundrect>
<![endif]--><a href="#ENV*{url}"
style="background-color:#ENV{bgcolor,#556270};[background-image:url\((#ENV{bgurl,''})\);]border:1px solid #ENV{bordercolor,#1e3650};[border-radius:(#ENV{borderradius,4px});]color:#ENV{color,#ffffff};display:inline-block;font-family:sans-serif;[font-size:(#ENV{fontsize,13px});]font-weight:bold;line-height:#ENV{height,40px};text-align:center;text-decoration:none;width:#ENV{width,200px};-webkit-text-size-adjust:none;mso-hide:all;">#ENV*{label}</a></span>
<![endif]--><![if !mso]><a href="#ENV*{url}"
style="background-color:#ENV{bgcolor,#556270};[background-image:url\((#ENV{bgurl,''})\);]border:1px solid #ENV{bordercolor,#1e3650};[border-radius:(#ENV{borderradius,4px});]color:#ENV{color,#ffffff};display:inline-block;font-family:sans-serif;font-size:13px;font-weight:bold;line-height:#ENV{height,40px};text-align:center;text-decoration:none;width:#ENV{width,200px};-webkit-text-size-adjust:none;">#ENV*{label}</a><![endif]></span>

0
emails/inc-haut.html

51
emails/test_email_html.html

@ -1,35 +1,28 @@
#HTTP_HEADER{Content-Type:text/html}
<body>
<h2><:facteur:corps_email_de_test:></h2>
#INCLURE{fond=emails/inc-haut}
<p><:facteur:version_html:></p>
<h2><:facteur:corps_email_de_test:></h2>
<BOUCLE_art(ARTICLES){id_article}>
[(#TEXTE|image_reduire{550,0})]
<hr />
[(#NOTES|image_reduire{550,0})]
</BOUCLE_art>
<BOUCLE_art2(ARTICLES){0,1}>
[(#TEXTE|image_reduire{550,0})]
<hr />
[(#NOTES|image_reduire{550,0})]
</BOUCLE_art2>
<//B_art>
<p><:facteur:version_html:></p>
<BOUCLE_image(DOCUMENTS){extension IN jpg,png,gif}{0,1}{statut==.*}{brise=0}{largeur>300}{par taille}>
[(#MODELE{img}|image_reduire{550,0})]
</BOUCLE_image>
<BOUCLE_art(ARTICLES){texte==<img}{0,1}>
[(#TEXTE|image_reduire{550,0})]
<hr />
[(#NOTES|image_reduire{550,0})]
</BOUCLE_art>
<BOUCLE_art2(ARTICLES){0,1}>
[(#TEXTE|image_reduire{550,0})]
<hr />
[(#NOTES|image_reduire{550,0})]
</BOUCLE_art2>
<//B_art>
<BOUCLE_pdf(DOCUMENTS){extension=pdf}{0,1}{statut==.*}{brise=0}>
[(#MODELE{doc}|image_reduire{550,0})]
</BOUCLE_pdf>
<BOUCLE_image(DOCUMENTS){extension IN jpg,png,gif}{0,1}>
[(#MODELE{img}|image_reduire{550,0})]
</BOUCLE_image>
[(#ENV{piece_jointe}|oui)
<div>
<h3><:medias:titre_documents_joints:></h3>
[(#ENV{piece_jointe/chemin}|basename|unique{basename})][ - (#ENV{piece_jointe/nom}|unique{basename})]
</div>
]
</body>
#FILTRE{liens_absolus}
#FILTRE{facteur_email_wrap_to_html}
<BOUCLE_pdf(DOCUMENTS){extension=pdf}{0,1}>
[(#MODELE{doc}|image_reduire{550,0})]
</BOUCLE_pdf>
#INCLURE{fond=emails/inc-bas}

8
emails/test_email_texte.html

@ -3,16 +3,10 @@
<:facteur:version_texte:>
<BOUCLE_art(ARTICLES){id_article}>
<BOUCLE_art(ARTICLES){texte==<img}{0,1}>
[(#TEXTE|textebrut)]
</BOUCLE_art>
<BOUCLE_art2(ARTICLES){0,1}>
[(#TEXTE|textebrut)]
</BOUCLE_art2>
<//B_art>
[(#ENV{piece_jointe}|oui)
### <:medias:titre_documents_joints:>
[(#ENV{piece_jointe/chemin}|basename|unique{basename})][ - (#ENV{piece_jointe/nom}|unique{basename})]
]

36
emails/texte.html

@ -4,9 +4,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>[(#ENV*{sujet})]</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style type="text/css">[
(#SET{siteColor,[#(#LOGO_SITE_SPIP|couleur_extraire|couleur_foncer_si_claire{88}|couleur_eclaircir_si_foncee{168}|sinon{BBB})]})][
(#VAL{_COULEUR_EMAILS_HTML}|defined|oui)#SET{siteColor,#VAL{_COULEUR_EMAILS_HTML}|constant}]
<style type="text/css">
[(#SET{siteColor,[#(#LOGO_SITE_SPIP|couleur_extraire|couleur_eclaircir_si_foncee{168}|sinon{BBB})]})]
#outlook a {padding: 0;}
body {width: 100% !important;}
body {margin: 0;padding: 0;}
@ -18,18 +17,14 @@
#templateHeader {background-color: #FFFFFF;border-bottom: 0;}
#templateContainer, .bodyContent {background-color: #FFFFFF;margin-top: 40px;}
.bodyContent {padding:30px;border-bottom:10px solid #GET{siteColor};}
.bodyContent .text {max-width: 540px;}
.bodyContent div {color: #222222;font-family: Verdana, Geneva, sans-serif;line-height: 150%;text-align: left;}
.bodyContent div a:link, .bodyContent div a:visited {color: #336699;font-weight: normal;text-decoration: underline;}
.bodyContent img {display: inline;margin-bottom: 10px;max-width: 100%;}
.bodyContent img {display: inline;margin-bottom: 10px;}
.bodyContent img.puce {display: inline;margin-bottom: 0;}
.bodyContent .spip_documents {max-width: 100%;}
.bodyContent .spip_documents img {max-width: 100%;}
.bodyContent .spip_documents_center {margin-left: auto;margin-right: auto;}
hr { height: 1px; margin: 1.5em 0; border: 0; background: #222222; color: #222222; }
.spip_code, .spip_cadre {color: #606060;font-family: Courier,"Courier New",monospace;font-size: 1em;word-wrap:break-word;max-width: 100%;overflow: auto;}
.coloration_code ol {list-style: none;}
.spip_logo,.spip_logos {float: right;margin-left: 10px;}
.spip_logos {float: right;margin-left: 10px;}
.text {word-wrap:break-word;}
.header,.footer {padding: 20px 40px;margin-left: -40px;margin-right: -40px;}
.text > .header:first-child {margin-top: -40px;}
@ -39,9 +34,7 @@
@media only screen and (max-width: 600px) {
html,body {width: 100% !important;}
body, .backgroundTable {background-color: #ffffff !important;}
table,tbody,td,tr {display:block;max-width:100%;}
.bodyContent {padding:0 0 10px !important;border-top:0;border-bottom:0;}
.bodyContent .text {max-width: 100%;}
#templateHead {display: none}
#templateContainer {width: 100% !important;border: 0 !important;margin-top: 0}
#templateBody {width: 100% !important;}
@ -50,14 +43,23 @@
.header,.footer {padding: 10px;margin-left: -10px;margin-right: -10px;}
.text > .header:first-child {margin-top: -10px;}
}
@media only screen and (max-device-width: 480px) {
html,body {width: 320px !important;}
body, .backgroundTable {background-color: #ffffff !important;}
.bodyContent {padding: 0 0 10px !important;border-top:0;border-bottom:0;}
#templateContainer {width: 320px !important;border: 0 !important;margin-top: 0;}
#templateBody {width: 320px !important;}
.padding {padding-left:0 !important;padding-right:0 !important;}
.text {color: #101010 !important;}
}
</style>
</head>
<body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0"
style="margin: 0;padding: 0;width: 100% !important;background-color: #DDDDDD;">
style="margin: 0;padding: 0;width: 100% !important;">
<center>
[<div style="display:none;display:none !important;">(#ENV{intro,''})</div>]
<table border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="backgroundTable"
style="margin: 0;padding: 0;height: 100% !important;width: 100% !important;background-color: #DDDDDD;">
style="margin: 0;padding: 0;height: 100% !important;width: 100% !important;">
<tr>
<td align="center" valign="top">
<!-- // End Template Preheader \\ -->
@ -85,10 +87,10 @@
<tr>
<td align="left" valign="top"
style="color:#A39F9A !important;font-family: Verdana, Geneva, sans-serif; !important;font-size:90% !important;font-weight:normal !important;font-style:normal !important;text-decoration:none !important;vertical-align:top !important;text-align:left !important;">
<br />
<br />
&mdash; #SET{site,<a href="#URL_SITE_SPIP/">#NOM_SITE_SPIP</a>}<:facteur:email_envoye_par{site=#GET{site}}:>
<br />
<br/>
<br/>
&mdash; Envoyé par <a href="#URL_SITE_SPIP/">#NOM_SITE_SPIP</a>
<br/>
</td>
</tr>
</table>

42
erreurs et exceptions.txt

@ -0,0 +1,42 @@
Avril 2012
Yffic
Petit point sur la gestion des erreurs et les exceptions de phpMailer 5. "Parce que c'est pénible de ne pas savoir pourquoi ça ne marche pas"
Constat :
- Les problèmes de connexion smtp ne sont pas affichées dans l'interface privée de SPIP après un test d'envoi via la page de config de Facteur. On a juste le message "Erreur: consultez le fichier log pour plus de détails" dans un cadre rouge.
- Dans formulaires/configurer_facteur.php, facteur_envoyer_mail_test() renvoie true/false. Donc on n'a pas accès aux messages d'erreurs de phpMailer dans l'espace privé.
- La gestion des exceptions via la classe phpmailerException n'est pas activée par défaut dans phpMailer (Cf le constructeur). Elle sert surtout à faire remonter les messages d'erreur.
- Après avoir activé la gestion des exceptions et le mode debug de la classe smtp (qui ne fait que des echo), on peut remarquer que les messages d'erreurs affichés par les exceptions dans phpMailer ne reprennent pas les vraies causes d'erreurs relevées dans la classe smtp. Si par exemple, on n'active pas ssl dans php, le debug "echo" affiche "SMTP -> ERROR: Failed to connect to server: Unable to find the socket transport "ssl" - did you forget to enable it when you configured PHP?", mais l'exception se contente d'un "SMTP Error: Could not connect to SMTP host" dans le fichier log. C'est quand même dommage de ne pas avoir accès au premier message d'erreur.
- Voir aussi :
http://code.google.com/a/apache-extras.org/p/phpmailer/issues/detail?id=50
http://code.google.com/a/apache-extras.org/p/phpmailer/issues/detail?id=5
En attendant une éventuelle amélioration de phpMailer, on peut :
- Upgrader phpMailer 5.2.1. J'ai testé, ca ne change rien au niveau de la gestion des messages d'erreur, mais ça corrige d'autres trucs.
05/04/12 : Un cas foireux avec la version 5.2.1 : Si comme hôte on met un serveur ssl (ssl0.ovh.net), mais qu'on ne coche pas ssl au dessous, lors d'un test d'envoi, la roue Ajax tourne en rond indéfiniment... Pas de retour, aucune trace meme avec de simples echo... Je pense que ca tourne en rond au niveau de la fonction feof de get_lines. Cf les Notes de http://php.net/manual/fr/function.feof.php... Il n'est pas donc pas si urgent d'upgrader...
- Redéfinir dans la classe Facteur, les fonctions Send, AddAttachment, AddReplyTo, AddBCC, AddCC, de la classe PhpMailer de cette façon :
public function Send() {
ob_start();
parent::Send();
$error = ob_get_contents();
ob_end_clean();
if( !empty($error) ) {
spip_log("Erreur Facteur->Send : $error",'facteur.err');
}
}
Avec une constante pour activer ce mode et rajouter au début du constructeur de Facteur :
if (defined('_FACTEUR_DEBUG_SMTP')) {
$this->SMTPDebug = _FACTEUR_DEBUG_SMTP ;
}
Ajouter la ligne qui suit dans mes_options.php permet donc de retrouver les erreurs dans le fichier facteur.err.log.
define('_FACTEUR_DEBUG_SMTP','5'); // Le niveau peut varier de 1 à 5, 5 affichant tout le dialogue lors de la connexion smtp avec le serveur

12
facteur-64.svg

@ -1,12 +0,0 @@
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" width="64" height="64">
<path d="M384.7 342.8H437a30.2 30.2 0 0030.2-30.3v-3.7a30.2 30.2 0 00-30.2-30.3h-52.3z" fill="#f3e3e3"/>
<path d="M306 512H206a97.2 97.2 0 01-97.2-97.2v-185a97.2 97.2 0 0197.2-97.2h100a97.2 97.2 0 0197.2 97.2v185A97.2 97.2 0 01306 512z" fill="#f3e3e3"/>
<path d="M127.3 342.8H75a30.2 30.2 0 01-30.2-30.3v-3.7A30.2 30.2 0 0175 278.5h52.3v64.3z" fill="#f3e3e3"/>
<path d="M363.7 266.3H148.2a53 53 0 01-53-53v-21.4h321.6v21.4a53 53 0 01-53 53z" fill="#E895B7"/>
<path d="M304 0h-96A112.8 112.8 0 0095.2 112.8v79h321.6v-79C416.8 50.5 366.3 0 304 0z" fill="#F43737"/>
<g fill="#555">
<path d="M424.6 262.2h-15v-8c8-10.7 12.7-24 12.7-38.4V121C422.3 54.3 368 0 301.2 0h-90.4A121.3 121.3 0 0089.7 121.1v94.7c0 14.4 4.7 27.8 12.7 38.5v8h-15a45.3 45.3 0 000 90.4h15v47c0 62 50.3 112.3 112.2 112.3h82.8c61.9 0 112.2-50.3 112.2-112.2v-47.1h15a45.3 45.3 0 000-90.5zm-322.2 60.5h-15a15.2 15.2 0 010-30.5h15v30.5zm277.2 77a82.3 82.3 0 01-82.2 82.3h-82.8a82.3 82.3 0 01-82.2-82.2v-123c7 2.5 14.4 3.9 22.1 3.9h203c7.7 0 15.2-1.4 22.1-4zm12.7-184a35 35 0 01-34.9 35H154.5a35 35 0 01-34.8-35v-5h272.6zm0-35H119.7V121A91.3 91.3 0 01210.8 30h90.4a91.3 91.3 0 0191.1 91.1v59.5zm32.3 142h-15v-30.5h15a15.2 15.2 0 010 30.5z"/>
<path d="M306.3 397a15 15 0 00-20.3 6.3 33.8 33.8 0 01-60 0 15 15 0 00-26.6 14 63.7 63.7 0 00113.2 0 15 15 0 00-6.3-20.3z"/>
<path fill="#fff" d="M 286.135 143.566 C 280.466 120.887 256.872 123.265 253.123 107.993 C 250.471 97.202 257.695 88.972 268.486 86.229 C 275.753 84.42 283.425 86.777 288.422 92.356 L 288.513 92.447 L 288.97 92.996 L 289.245 93.361 L 289.519 93.819 L 289.61 93.91 C 290.616 95.19 291.165 96.105 291.988 95.922 C 292.72 95.739 293.085 94.093 293.268 92.904 C 297.087 62.926 269.531 38.506 240.229 45.9 C 217.244 51.788 203.265 75.06 208.862 98.117 C 216.452 129.117 245.624 134.33 261.445 142.194 C 270.371 146.374 271.425 158.648 263.343 164.288 C 262.023 165.209 260.542 165.873 258.975 166.245 L 258.793 166.245 L 258.152 166.428 C 256.781 166.794 256.415 166.611 256.415 167.16 C 256.415 167.525 257.329 167.983 257.878 168.257 C 272.892 174.319 288.838 161.854 286.58 145.821 C 286.473 145.062 286.325 144.31 286.135 143.566 Z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

111
facteur_administrations.php

@ -1,86 +1,46 @@
<?php
/**
* Plugin Facteur 4
* (c) 2009-2019 Collectif SPIP
/*
* Plugin Facteur 2
* (c) 2009-2011 Collectif SPIP
* Distribue sous licence GPL
*
* @package SPIP\Facteur\Administrations
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
if (!defined("_ECRIRE_INC_VERSION")) return;
function facteur_upgrade($nom_meta_base_version, $version_cible) {
$maj = array();
function facteur_upgrade($nom_meta_base_version, $version_cible){
include_spip('inc/config');
$maj = array();
$maj['create'] = array(
array('ecrire_config','facteur/mailer', 'mail'),
array('ecrire_config','facteur/smtp_auth', 'non'),
array('ecrire_config','facteur/smtp_secure', 'non'),
array('ecrire_config','facteur/smtp_sender', ''),
array('ecrire_config','facteur/filtre_images', 0),
array('ecrire_config','facteur/filtre_css', 0),
array('ecrire_config','facteur/filtre_iso_8859', 0),
array('ecrire_config','facteur/adresse_envoi', 'non'),
array('ecrire_meta','facteur_smtp', 'non'),
array('ecrire_meta','facteur_smtp_auth', 'non'),
array('ecrire_meta','facteur_smtp_secure', 'non'),
array('ecrire_meta','facteur_smtp_sender', ''),
array('ecrire_meta','facteur_filtre_images', 1),
array('ecrire_meta','facteur_filtre_css', 0),
array('ecrire_meta','facteur_filtre_iso_8859', 0),
array('ecrire_meta','facteur_adresse_envoi', 'non'),
array('facteur_vieil_upgrade'),
);
$maj['2.0.0'] = array(
array('facteur_migre_metas_to_config'),
);
include_spip('base/upgrade');
maj_plugin($nom_meta_base_version, $version_cible, $maj);
}
/**
* Migrer les N metas en une seule meta facteur que l'on accede via les fonctions lire_config/ecrire_config
*/
function facteur_migre_metas_to_config(){
include_spip('inc/config');
// ne pas migrer 2 fois
if (!isset($GLOBALS['meta']["facteur"]) or !@unserialize($GLOBALS['meta']["facteur"])) {
foreach (array(
'adresse_envoi', 'adresse_envoi_email', 'adresse_envoi_nom', 'forcer_from',
'cc', 'bcc',
'mailer',
'smtp_host', 'smtp_port', 'smtp_auth',
'smtp_username', 'smtp_password', 'smtp_secure', 'smtp_sender', 'smtp_tls_allow_self_signed',
'filtre_images', 'filtre_iso_8859',
) as $config) {
if (isset($GLOBALS['meta']["facteur_$config"])) {
ecrire_config("facteur/$config", $GLOBALS['meta']["facteur_$config"]);
effacer_meta("facteur_$config");
}
}
}
if (isset($GLOBALS['meta']["facteur_smtp"])) {
if (!lire_config("facteur/mailer",'')) {
ecrire_config("facteur/mailer", $GLOBALS['meta']["facteur_smtp"] === 'oui' ? 'smtp' : 'mail');
}
effacer_meta('facteur_smtp');
}
}
/**
* migration depuis tres ancienne version du plugin spip_notifications, a la main
*/
function facteur_vieil_upgrade() {
function facteur_vieil_upgrade(){
// migration depuis tres ancienne version, a la main
if (isset($GLOBALS['meta']['spip_notifications_version'])) {
ecrire_config('facteur/mailer', ($GLOBALS['meta']['spip_notifications_smtp'] === 'oui') ? 'smtp' : 'mail');
ecrire_config('facteur/smtp_auth', $GLOBALS['meta']['spip_notifications_smtp_auth']);
ecrire_config('facteur/smtp_secure', $GLOBALS['meta']['spip_notifications_smtp_secure']);
ecrire_config('facteur/smtp_sender', $GLOBALS['meta']['spip_notifications_smtp_sender']);
ecrire_config('facteur/filtre_images', $GLOBALS['meta']['spip_notifications_filtre_images']);
ecrire_config('facteur/filtre_css', $GLOBALS['meta']['spip_notifications_filtre_css']);
ecrire_config('facteur/filtre_iso_8859', $GLOBALS['meta']['spip_notifications_filtre_iso_8859']);
ecrire_config('facteur/adresse_envoi', $GLOBALS['meta']['spip_notifications_adresse_envoi']);
ecrire_config('facteur/adresse_envoi_nom', $GLOBALS['meta']['spip_notifications_adresse_envoi_nom']);
ecrire_config('facteur/adresse_envoi_email', $GLOBALS['meta']['spip_notifications_adresse_envoi_email']);
ecrire_meta('facteur_smtp', $GLOBALS['meta']['spip_notifications_smtp']);
ecrire_meta('facteur_smtp_auth', $GLOBALS['meta']['spip_notifications_smtp_auth']);
ecrire_meta('facteur_smtp_secure', $GLOBALS['meta']['spip_notifications_smtp_secure']);
ecrire_meta('facteur_smtp_sender', $GLOBALS['meta']['spip_notifications_smtp_sender']);
ecrire_meta('facteur_filtre_images', $GLOBALS['meta']['spip_notifications_filtre_images']);
ecrire_meta('facteur_filtre_css', $GLOBALS['meta']['spip_notifications_filtre_css']);
ecrire_meta('facteur_filtre_iso_8859', $GLOBALS['meta']['spip_notifications_filtre_iso_8859']);
ecrire_meta('facteur_adresse_envoi', $GLOBALS['meta']['spip_notifications_adresse_envoi']);
ecrire_meta('facteur_adresse_envoi_nom', $GLOBALS['meta']['spip_notifications_adresse_envoi_nom']);
ecrire_meta('facteur_adresse_envoi_email', $GLOBALS['meta']['spip_notifications_adresse_envoi_email']);
// supprimer l'ancien nommage
effacer_meta('spip_notifications_smtp');
effacer_meta('spip_notifications_smtp_auth');
@ -101,6 +61,23 @@ function facteur_vieil_upgrade() {
function facteur_vider_tables($nom_meta_base_version) {
effacer_meta('facteur');
// cfg la dessus, ca serait mieux !
effacer_meta('facteur_version');
effacer_meta('facteur_smtp');
effacer_meta('facteur_smtp_auth');
effacer_meta('facteur_smtp_secure');
effacer_meta('facteur_smtp_sender');
effacer_meta('facteur_filtre_images');
effacer_meta('facteur_filtre_css');
effacer_meta('facteur_filtre_iso_8859');
effacer_meta('facteur_adresse_envoi');
effacer_meta('facteur_adresse_envoi_nom');
effacer_meta('facteur_adresse_envoi_email');
effacer_meta('facteur_cc');
effacer_meta('facteur_bcc');
effacer_meta($nom_meta_base_version);
}
?>

339
facteur_fonctions.php

@ -1,128 +1,289 @@
<?php
/**
* Plugin Facteur 4
* (c) 2009-2019 Collectif SPIP
/*
* Plugin Facteur 2
* (c) 2009-2011 Collectif SPIP
* Distribue sous licence GPL
*
* @package SPIP\Facteur\Fonctions
*/
if (!defined("_ECRIRE_INC_VERSION")) return;
/**
* Afficher partiellement un mot de passe que l'on ne veut pas rendre lisible par un champ hidden
* @param string $passe
* @param bool $afficher_partiellement
* @param int|null $portion_pourcent
* Transformer un mail texte ou HTML simplifie en mail HTML complet avec le wrapper emails/texte.html
* Si le mail est un mail texte :
* la premiere ligne est le sujet
* le reste est le corps du mail
*
* Si le mail est un mail HTML simplifie :
* le sujet est entre <title></title>
* le corps est entre <body></body>
* une eventuelle intro peut etre fournie entre <intro></intro>
*
* @param string $texte_ou_html
* @return string
*/
function facteur_affiche_password_masque($passe, $afficher_partiellement = false, $portion_pourcent = null) {
if (function_exists('spip_affiche_mot_de_passe_masque')) {
return spip_affiche_mot_de_passe_masque($passe, $afficher_partiellement, $portion_pourcent);
}
$l = strlen($passe);
function facteur_email_wrap_to_html($texte_ou_html){
$texte_ou_html = trim($texte_ou_html);
// attention : si pas de contenu on renvoi du vide aussi (mail vide = mail vide)
if (!strlen(trim($texte_ou_html)))
return $texte_ou_html;
$contexte = array("sujet"=>"","texte"=>"","intro"=>"");
// tester si le mail est en html (simplifie)
if (substr($texte_ou_html,0,1)=="<"
AND substr($texte_ou_html,-1,1)==">"
AND stripos($texte_ou_html,"</body>")!==false){
if ($l<=8 or !$afficher_partiellement){
if (!$l) {
return ''; // montrer qu'il y a pas de mot de passe si il y en a pas
// dans ce cas on ruse un peu : extraire le sujet du title
$sujet = "";
if (preg_match(",<title>(.*)</title>,Uims",$texte_ou_html,$m)){
$contexte['sujet'] = $m[1];
$texte_ou_html = preg_replace(",<title>(.*)</title>,Uims","",$texte_ou_html,1);
$texte_ou_html = trim($texte_ou_html);
}
return str_pad('',$afficher_partiellement ? $l : 16,'*');
if (preg_match(",<intro>(.*)</intro>,Uims",$texte_ou_html,$m)){
$contexte['intro'] = $m[1];
$texte_ou_html = preg_replace(",<intro>(.*)</intro>,Uims","",$texte_ou_html,1);
$texte_ou_html = trim($texte_ou_html);
}
$contexte['html'] = preg_replace(",</?body>,ims","",$texte_ou_html);
}
else {
// la premiere ligne est toujours le sujet
$texte_ou_html = explode("\n",$texte_ou_html);
$contexte['sujet'] = trim(array_shift($texte_ou_html));
$contexte['texte'] = trim(implode("\n",$texte_ou_html));
}
if (is_null($portion_pourcent)) {
if (!defined('_SPIP_AFFICHE_MOT_DE_PASSE_MASQUE_PERCENT')) {
define('_SPIP_AFFICHE_MOT_DE_PASSE_MASQUE_PERCENT', 20); // 20%
// attention : si pas de contenu on renvoi du vide aussi (mail vide = mail vide)
if (!strlen(trim(implode("",$contexte))))
return "";
return recuperer_fond("emails/texte",$contexte);
}
/*
Written by Eric Dols - edols@auditavenue.com
You may freely use or modify this, provided
you leave credits to the original coder.
Feedback about (un)successfull uses, bugs and improvements done
are much appreciated, but don't expect actual support.
PURPOSE OF THIS FUNCTION
It is designed to process html emails relying
on a css stylesheet placed in the <head> for layout in
order to enhance compatibility with email clients,
including webmail services.
Provided you use minimal css, you can keep styling separate
from the content in your email template, and let this function
"inject" those styles inline in your email html tags on-the-fly,
just before sending.
Technically, it grabs the style declarations found in the
<head> section and inserts each declaration inline,
inside the corresponding html tags in the email message.
Supports both HTML and XHTML markup seamlessly. Thus
tolerant to email message writers using non-xhtml tag,
even when template is xhtml compliant (e.g. they would
add <img ...> instead of a xhtml compliant <img ... />).
NEW 10 dec. 2003:
- code revised, including a few regexp bugs fixed.
- multiple class for a tag are now allowed <p class="firstclass secondclass">
- all unsupported css styles are now moved to the body section (not just a:hover etc...)
USE
Add this function to a function library include, like "inline.inc"
and include it near the beginning of your php page:
require ("inline.inc");
load the html source of message into a variable
like $html_source and process it using:
$html_source = sheet2inline($html_source)
STYLE DEFINITIONS SUPPORTED
TAG { ... }
TAG1, TAG2, ... { ... }
TAG.class { ... }
.class { ...)
TAG:pseudo { ... }
CSS definitions may be freely formatted (spaces, tabs, linefeeds...),
they are converted to oneliners before inserting them inline in the html tags.
.class definitions are processed AFTER tag definitions,
thus appended inline after any existing tag styling to
preserve the normal css priority behavior.
Existing style="..." attributes in tags are NOT stripped. However they MUST
be with double quotes. If not, an addtional style="..." attribute will be added
KNOWN LIMITATIONS
- style info should be placed in <head> section. I believe
it shouldnt be too hard to modify to point to an external
stylesheet instead.
- no support (yet?):
* chains like P UL LI { .... } or P UL LI.class { .... }
* #divname p { ... } and <tag id="...">
* a:hover, a:visited {...} multiple class:pseudo
They require a significantly more complicated processing likely
based on stylesheet and document trees parsing.
Many email clients don't handle more than what is supported
by this script anyway.
- pseudo-classes like a:hover {...} can't be inserted inline
in the html tags: they are moved to a <style> declaration in
the <body> instead. This is a limitation from html, not this script.
- It is still up to you to check if target email clients render
your css styled templates correctly, especially webmail services
like Hotmail, in which the email becomes a sub-part of an html page,
with styles already in place.
*/
function facteur_convertir_styles_inline($body){
// variables to be accessed in the callback sub-function too
global $styledefinition, $styletag, $styleclass;
// Let's first load the stylesheet information in a $styles array using a regexp
preg_match_all ( "/^[ \t]*([.]?)([\w, #]+)([.:])?(\S*)\s+{([^}]+)}/mi", $body , $styles);
/*
$styles[1] = . or '' => .class or tag (empty)
$styles[2] = name of class or tag(s)
$styles[3] = : . or '' => followed by pseudo-element, class separator or nothing (empty)
$styles[4] = name of pseudo-element after a tag, if any
$styles[5] = the style definition itself, i.e. what's between the { }
*/
// Now loop through the styles found and act accordingly;
// process TAG {...} & TAG1, TAG2,... {...} definitions only first by order of appearance
foreach ($styles[1] as $i => $type) {
if ($type=="" && $styles[3][$i]=="") {
$styledefinition = trim($styles[5][$i]);
$styletag = preg_replace("/ *, */", "|", trim($styles[2][$i])); //echo $styletag."<br />";
$styleclass = "";
// process TAG {...} and TAG1, TAG2 {...} but not TAG1 TAG2 {...} or #divname styles
if (!preg_match("/ /", $styletag) && !preg_match("/#/", $styletag)) {
$pattern = "!<(".$styletag.")([^>]*(?= /)|[^>]*)( /)?>!mi";
$body = preg_replace_callback ($pattern, 'facteur_addstyle' , $body);
$styles[6][$i]=1; // mark as injected inline
}
}
$portion_pourcent = _SPIP_AFFICHE_MOT_DE_PASSE_MASQUE_PERCENT;
}
if ($portion_pourcent >= 100) {
return $passe;
// append additional .CLASS {...} and TAG.CLASS {...} styling by order of appearance
// important to do so after TAG {...} definitions, so that class attributes override TAG styles when needed
foreach ($styles[1] as $i => $type) {
if ($type!="." && $styles[3][$i]=="." ) { // class definition for a specific tag
$styledefinition = trim($styles[5][$i]);
$styletag = trim($styles[2][$i]);
$styleclass = trim($styles[4][$i]);
$pattern = "!<(".$styletag.")([^>]* class\=['\"][^'\"]*".$styleclass."[^'\"]*['\"][^>]*(?= /)|[^>]* class\=['\"][^'\"]*".$styleclass."[^'\"]*['\"][^>]*)( />)?>!mi";
$body = preg_replace_callback ($pattern, 'facteur_addstyle' , $body);
$styles[6][$i]=1; // mark as injected inline
}
elseif ($type=="." && $styles[3][$i]=="" ) { // general class definition for any tag
$styledefinition = trim($styles[5][$i]);
$styletag = "";
$styleclass = trim($styles[2][$i]);
$pattern = "!<(\w+)([^>]* class\=['\"]".$styleclass."['\"][^>]*(?= /)|[^>]* class\=['\"]".$styleclass."['\"][^>]*)( />)?>!mi";
$body = preg_replace_callback ($pattern, 'facteur_addstyle' , $body);
$styles[6][$i]=1; // mark as injected inline
}
}
$e = intval(ceil($l * $portion_pourcent / 100 / 2));
$e = max($e, 0);
$mid = str_pad('',$l-2*$e,'*');
if ($e>0 and strlen($mid)>8){
$mid = '***...***';
/* move all style declarations that weren't injected from <head> to a <body> <style> section,
including but not limited to:
- pseudo-classes like a:hover {...} as they can't be set inline
- declaration chains like UL LI {...}
- #divname {...}. These are not supported by email clients like Mac/Entourage anyway, it seems. */
foreach ($styles[1] as $i => $type) {
if ($styles[6][$i]=="") {
// add a <style type="text/css"> section after <body> if there's isn't one yet
if (preg_match ("!<body[^>]*>\s*<style!mi", $body)==0) {
$body = preg_replace ("/(<body[^>]*>)/i", "\n\$1\n".'<style type="text/css">'."\n<!--\n-->\n</style>\n", $body);
}
// append a copy of the pseudo-element declaration to that body style section
$styledefinition = trim($styles[5][$i]);
$styledefinition = preg_replace ("!\s+!mi", " ", $styledefinition ); // convert style definition to a one-liner (optional)
$declaration = $styles[1][$i].trim($styles[2][$i]).$styles[3][$i].trim($styles[4][$i])." { ".$styledefinition." }";
$body = preg_replace ("!(<body[^>]*>\s*<style[^>]*>\s*<\!\-\-[^>]*)"."(\s*\-\->\s*</style>)!si", "\$1".$declaration."\n\$2", $body);
$styles[6][$i]= 2; // mark as moved to <style> section in <body>
}
}
return substr($passe,0,$e) . $mid . ($e > 0 ? substr($passe,-$e) : '');
// remove stylesheet declaration(s) from <head> section (comment following line out if not wanted)
//$body = preg_replace ("!(<head>.*)<style type.*</style>(.*</head>)!si", "\$1\$2" , $body);
// check what styles have been injected
# print_r($styles);
return $body;
}
/**
* Un filtre pour transformer les retour ligne texte en br si besoin (si pas autobr actif)
* facteur_addstyle
* @author Eric Dols
*
* @param string $texte
* @param $matches
* @return string
*/
function facteur_nl2br_si_pas_autobr($texte){
if (_AUTOBR) return $texte;
include_spip("inc/filtres");
$texte = post_autobr($texte);
return $texte;
}
function facteur_addstyle($matches) {
// $matches[1]=tag, $matches[2]=tag attributes (if any), $matches[3]=xhtml closing (if any)
// variables values set in calling function
global $styledefinition, $styletag, $styleclass;
/**
* @see inc_facteur_mail_wrap_to_html_dist
*
* @param string $texte_ou_html
* @return string
*/
function facteur_email_wrap_to_html($texte_ou_html){
// convert the style definition to a one-liner
$styledefinition = preg_replace ("!\s+!mi", " ", $styledefinition );
// convert all double-quotes to single-quotes
$styledefinition = preg_replace ('/"/','\'', $styledefinition );
$facteur_mail_wrap_to_html = charger_fonction('facteur_mail_wrap_to_html', 'inc');
return $facteur_mail_wrap_to_html($texte_ou_html);
}
if (preg_match ("/style\=/i", $matches[2])) {
// add styles to existing style attribute if any already in the tag
$pattern = "!(.* style\=)[\"]([^\"]*)[\"](.*)!mi";
$replacement = "\$1".'"'."\$2 ".$styledefinition.'"'."\$3";
$attributes = preg_replace ($pattern, $replacement , $matches[2]);
} else {
// otherwise add new style attribute to tag (none was present)
$attributes = $matches[2].' style="'.$styledefinition.'"';
}
/**
* voir inc/facteur_convertir_styles_inline
*
* @param string $body
* @return string
*/
function facteur_convertir_styles_inline($body){
if ($styleclass!="") {
// if we were injecting a class style, remove the now useless class attribute from the html tag
$facteur_convertir_styles_inline = charger_fonction('facteur_convertir_styles_inline', 'inc');
return $facteur_convertir_styles_inline($body);
}
// Single class in tag case (class="classname"): remove class attribute altogether
$pattern = "!(.*) class\=['\"]".$styleclass."['\"](.*)!mi";
$replacement = "\$1\$2";
$attributes = preg_replace ( $pattern, $replacement, $attributes);
// Multiple classes in tag case (class="classname anotherclass..."): remove class name from class attribute.
// classes are injected inline and removed by order of appearance in <head> stylesheet
// exact same behavior as where last declared class attributes in <style> take over (IE6 tested only)
$pattern = "!(.* class\=['\"][^\"]*)(".$styleclass." | ".$styleclass.")([^\"]*['\"].*)!mi";
$replacement = "\$1\$3";
$attributes = preg_replace ( $pattern, $replacement, $attributes);
/**
* voir inc/facteur_mail_html2text
* @param string $html
* @return string
*/
function facteur_mail_html2text($html){
}
$facteur_mail_html2text = charger_fonction('facteur_mail_html2text', 'inc');
return $facteur_mail_html2text($html);
return "<".$matches[1].$attributes.$matches[3].">";
}
/**
* Insertion dans le pipeline formulaire_fond (SPIP)
*
* On indique dans le formulaire de configuration de l'identité du site
* que facteur surchargera l'email configuré ici pour envoyer les emails
* Un filtre pour transformer les retour ligne texte en br si besoin (si pas autobr actif)
*
* @param array $flux
* Le contexte du pipeline
* @return array $flux
* Le contexte du pipeline modifé
* @param string $texte
* @return string
*/
function facteur_formulaire_fond($flux) {
if ($flux['args']['form'] == 'configurer_identite'
and include_spip('inc/config')
and lire_config('facteur/adresse_envoi') === 'oui'
and strlen($email = lire_config('facteur/adresse_envoi_email', '')) ) {
$url = generer_url_ecrire('configurer_facteur');
$ajout = '<p class="notice" style="margin-top:0">'._T('facteur:message_identite_email', array('url' => $url, 'email' => $email)).'</p>';
if (preg_match(",<(div|li) [^>]*class=[\"']editer editer_email_webmaster.*>,Uims", $flux['data'], $match)) {
$p = strpos($flux['data'], (string) $match[0]);
$p = strpos($flux['data'], "<input", $p);
$p = strpos($flux['data'], "</".$match[1], $p);
$flux['data'] = substr_replace($flux['data'], $ajout, $p, 0);
}
}
return $flux;
function facteur_nl2br_si_pas_autobr($texte){
return (_AUTOBR?$texte:nl2br($texte));
}
?>

36
facteur_ieconfig_metas.php

@ -1,18 +1,18 @@
<?php
/**
* Plugin Facteur 4
* (c) 2009-2019 Collectif SPIP
* Distribue sous licence GPL
*
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
function facteur_ieconfig_metas($table) {
$table['facteur']['titre'] = _T('facteur:configuration_facteur');
$table['facteur']['icone'] = 'facteur-16.png';
$table['facteur']['metas_brutes'] = 'facteur_adresse_envoi,facteur_adresse_envoi_nom,facteur_adresse_envoi_email,facteur_mailer,facteur_smtp_host,facteur_smtp_port,facteur_smtp_auth,facteur_smtp_username,facteur_smtp_password,facteur_smtp_secure,facteur_smtp_sender,facteur_filtre_images,facteur_filtre_css,facteur_filtre_iso_8859';
return $table;
}
<?php
/*
* Plugin Facteur 2
* (c) 2009-2011 Collectif SPIP
* Distribue sous licence GPL
*
*/
if (!defined("_ECRIRE_INC_VERSION")) return;
function facteur_ieconfig_metas($table){
$table['facteur']['titre'] = _T('facteur:configuration_facteur');
$table['facteur']['icone'] = 'facteur-16.png';
$table['facteur']['metas_brutes'] = 'facteur_adresse_envoi,facteur_adresse_envoi_nom,facteur_adresse_envoi_email,facteur_smtp,facteur_smtp_host,facteur_smtp_port,facteur_smtp_auth,facteur_smtp_username,facteur_smtp_password,facteur_smtp_secure,facteur_smtp_sender,facteur_filtre_images,facteur_filtre_css,facteur_filtre_iso_8859';
return $table;
}
?>

302
formulaires/configurer_facteur.html

@ -1,141 +1,197 @@
<div class="formulaire_spip formulaire_configurer formulaire_#FORM">
<h3 class="titrem"><:facteur:titre_configurer_facteur:></h3>
[<div class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</div>]
[<div class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</div>]
[<div class="notice">(#ENV*{_message_warning})</div>]
[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
[(#ENV{tester,''}|oui)
<iframe style='width:95%;height:500px;margin:10px;' src='#URL_PAGE{emails/test_email_html,var_mode=calcul}'></iframe>
]
<form method="post" action="#ENV{action}"><div>
#ACTION_FORMULAIRE{#ENV{action}}
<fieldset>
<legend><:facteur:configuration_adresse_envoi:></legend>
<div class="editer-groupe">
<div class="editer pleine_largeur editer_adresse_envoi [ (#ENV**{erreurs}|table_valeur{adresse_envoi}|oui)erreur]">
[<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{adresse_envoi})</span>]
<div class="choix">
<input type="radio" name="adresse_envoi" class="radio" value="non" id="adresse_envoi_non"[(#ENV{adresse_envoi,'non'}|=={non}|oui)checked="checked"]/>
<label for="adresse_envoi_non"><:facteur:utiliser_reglages_site{from=#ENV{_from_defaut}}:></label>
<div class="suite editer-groupe"[(#ENV{adresse_envoi,'non'}|=={non}|non)style='display:none;']>
<div class="editer editer_from_defaut_nom">
<label for="from_defaut_nom"><:facteur:facteur_adresse_envoi_nom:></label>
<input type="text" disabled="disabled" class="text" value="#ENV**{_from_defaut_nom}" id="from_defaut_nom" />
<ul>
<li class="fieldset">
<fieldset>
<legend><:facteur:configuration_adresse_envoi:></legend>
<ul>
<li class="editer editer_facteur_adresse_envoi [ (#ENV**{erreurs}|table_valeur{facteur_adresse_envoi}|oui)erreur]">
[<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{facteur_adresse_envoi})</span>]
<div class="choix">
<input type="radio" name="facteur_adresse_envoi" class="radio" value="non" id="facteur_adresse_envoi_non"[(#ENV{facteur_adresse_envoi,'non'}|=={non}|oui)checked="checked"]/>
<label for="facteur_adresse_envoi_non"><:facteur:utiliser_reglages_site:></label>
</div>
<div class="editer editer_from_defaut_email">
<label for="from_defaut_email"><:facteur:facteur_adresse_envoi_email:></label>
<input type="text" disabled="disabled" class="text" value="#ENV**{_from_defaut_email}" id="from_defaut_email" />
<div class="choix">
<input type="radio" name="facteur_adresse_envoi" class="radio" value="oui" id="facteur_adresse_envoi_oui"[(#ENV{facteur_adresse_envoi,'non'}|=={oui}|oui)checked="checked"]/>
<label for="facteur_adresse_envoi_oui"><:facteur:personnaliser:></label>
</div>
</div>
</div>
<div class="choix">
<input type="radio" name="adresse_envoi" class="radio" value="oui" id="adresse_envoi_oui"[(#ENV{adresse_envoi,'non'}|=={oui}|oui)checked="checked"]/>
<label for="adresse_envoi_oui"><:facteur:personnaliser:></label>
<div class="suite editer-groupe"[(#ENV{adresse_envoi,'non'}|=={non}|oui)style='display:none;']>
<div class="editer editer_adresse_envoi_perso editer_adresse_envoi_nom [ (#ENV**{erreurs}|table_valeur{adresse_envoi_nom}|oui)erreur]">
<label for="adresse_envoi_nom"><:facteur:facteur_adresse_envoi_nom:></label>[
<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{adresse_envoi_nom})</span>]
<input type="text" name="adresse_envoi_nom" class="text" value="#ENV**{adresse_envoi_nom}" id="adresse_envoi_nom" />
</li>
<li class="editer editer_facteur_adresse_envoi_perso editer_facteur_adresse_envoi_nom [ (#ENV**{erreurs}|table_valeur{facteur_adresse_envoi_nom}|oui)erreur]"[(#ENV{facteur_adresse_envoi,'non'}|=={non}|oui)style='display:none;']>
<label for="facteur_adresse_envoi_nom"><:facteur:facteur_adresse_envoi_nom:></label>[
<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{facteur_adresse_envoi_nom})</span>]
<input type="text" name="facteur_adresse_envoi_nom" class="text" value="#ENV**{facteur_adresse_envoi_nom}" id="facteur_adresse_envoi_nom" />
</li>
<li class="editer editer_facteur_adresse_envoi_perso editer_facteur_adresse_envoi_email [ (#ENV**{erreurs}|table_valeur{facteur_adresse_envoi_email}|oui)erreur]"[(#ENV{facteur_adresse_envoi,'non'}|=={non}|oui)style='display:none;']>
<label for="facteur_adresse_envoi_email"><:facteur:facteur_adresse_envoi_email:></label>[
<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{facteur_adresse_envoi_email})</span>]
<input type="text" name="facteur_adresse_envoi_email" class="text" value="#ENV**{facteur_adresse_envoi_email}" id="facteur_adresse_envoi_email" />