Browse Source

Ajout d'une option graceful sur les envois qui evite d'envoyer la meme newsletter a un email qui l'a deja recue

Cela s'accompagne d'une option dans le formulaire d'envoi, sur les newsletters, decochee par defaut : [ ] Envoyer à nouveau aux destinataires qui l'ont déjà reçue
(par defaut donc, desormais, on n'envoie plus en double)
Techniquement il y a un champ graceful en base sur les mailshots.
Par contre quand on construit la liste des destinataires on enumere bien tous les destinataires comme avant, mais simplement pour chaque envoi on verifie d'abord si cet email a deja recu la newsletter et si oui on recupere directement le statut et la date du dernier envoi sans rien faire
(le destinataire apparait donc bien dans la liste, en sent ou read ou open, avec la date de l'envoi precedent)
A priori ca doit marcher, mais je n'ai pas encore teste en live
svn/root/tags/v1.27.7
cedric@yterium.com 4 years ago
parent
commit
669336e306
  1. 1
      base/mailshot.php
  2. 11
      formulaires/newsletter_send.html
  3. 4
      formulaires/newsletter_send.php
  4. 131
      inc/mailshot.php
  5. 1
      lang/mailshot_fr.php
  6. 1
      lang/newsletter_fr.php
  7. 3
      mailshot_administrations.php
  8. 4
      newsletter/bulkstart.php
  9. 4
      paquet.xml
  10. 7
      prive/objets/contenu/mailshot.html
  11. 11
      prive/style_prive_plugin_mailshot.html

1
base/mailshot.php

@ -39,6 +39,7 @@ function mailshot_declarer_tables_objets_sql($tables) {
"html" => "longtext NOT NULL DEFAULT ''",
"texte" => "longtext NOT NULL DEFAULT ''",
"listes" => "text NOT NULL DEFAULT ''",
"graceful" => "tinyint(1) NOT NULL DEFAULT 0",
"from_name" => "text NOT NULL DEFAULT ''",
"from_email" => "text NOT NULL DEFAULT ''",
"total" => "bigint(21) NOT NULL",

11
formulaires/newsletter_send.html

@ -33,6 +33,17 @@
</select>
<input type="submit" name="envoi" class="submit" value="<:newsletter:bouton_envoyer:>" name="test" />
</li>
#SET{name,resend}#SET{obli,''}#SET{defaut,''}#SET{erreurs,#ENV**{erreurs}|table_valeur{#GET{name}}}
<li class="editer pleine_largeur editer_[(#GET{name})][ (#GET{obli})][ (#GET{erreurs}|oui)erreur]">[
<span class='erreur_message'>(#GET{erreurs})</span>
]<div class="choix">
#SET{val,non}
<input type="hidden" name="#GET{name}" value="#GET{val}" />
#SET{val,oui}
<input type="checkbox" name="#GET{name}" class="checkbox" id="#GET{name}_#GET{val}" value="#GET{val}"[(#ENV{#GET{name},#GET{defaut}}|=={#GET{val}}|oui)checked="checked"] />
<label for="#GET{name}_#GET{val}">[(#GET{fl}|concat{':label_',#GET{name},'_',#GET{val}}|_T)]</label>
</div>
</li>
#SET{name,date_start}#SET{obli,''}#SET{defaut,''}#SET{erreurs,#ENV**{erreurs}|table_valeur{#GET{name}}}
<li class="editer editer_[(#GET{name})][ (#GET{obli})][ (#GET{erreurs}|oui)erreur]">
<label for="planifie">

4
formulaires/newsletter_send.php

@ -17,6 +17,7 @@ function formulaires_newsletter_send_charger_dist($id_newsletter,$mode_test=fals
'email_test' => $GLOBALS['visiteur_session']['email'],
'liste' => '',
'planifie' => '',
'resend' => 'non',
'date_start_jour' => '',
'date_start_heure' => '',
'_mode_test' => $mode_test?$mode_test:'',
@ -122,6 +123,9 @@ function formulaires_newsletter_send_traiter_dist($id_newsletter,$mode_test=fals
$h = dater_recuperer_heure_saisie(_request('date_start_heure'));
$options['date_start'] = sql_format_date($d[0], $d[1], $d[2], $h[0], $h[1]);
}
if (_request('resend')!=='oui'){
$options['graceful'] = true;
}
$bulkstart = charger_fonction("bulkstart","newsletter");
if ($id_mailshot = $bulkstart($id_newsletter, $listes, $options)){

131
inc/mailshot.php

@ -173,31 +173,67 @@ function mailshot_envoyer_lot($nb_max=5,$offset=0){
foreach($dests as $d){
if (time()>_MAILSHOT_MAX_TIME) return $nb_restant;
$s = $subscriber($d['email'],array('listes'=>$listes));
spip_log("mailshot_envoyer_lot #".$shoot['id_mailshot']."/".$d['email']." send","mailshot");
$erreur = $send($s, $corps, $options);
$try = $d['try']+1;
if ($erreur){
if ($try>=_MAILSHOT_MAX_TRY
OR preg_match(",@example\.org$,i",$s['email'])
OR defined('_TEST_EMAIL_DEST')){
sql_updateq("spip_mailshots_destinataires",array('statut'=>'fail','try'=>$try,'date'=>date('Y-m-d H:i:s')),"id_mailshot=".intval($shoot['id_mailshot'])." AND email=".sql_quote($d['email']));
sql_update("spip_mailshots",array("current"=>"current+1","failed"=>"failed+1"),"id_mailshot=".intval($shoot['id_mailshot']));
spip_log("mailshot_envoyer_lot #".$shoot['id_mailshot']."/".$d['email']." : Erreur [$erreur] / failed apres $try essais","mailshot"._LOG_ERREUR);
// si c'est un fail max_try verifier et desinscrire eventuellement
if ($try>1){
mailshot_verifier_email_fail($d['email']);
$done = false;
if (!$done = mailshot_verifier_email_envoi_bloque($d['email'], $s, $shoot)) {
spip_log("mailshot_envoyer_lot #".$shoot['id_mailshot']."/".$d['email']." send","mailshot");
$erreur = $send($s, $corps, $options);
$try = $d['try']+1;
if ($erreur){
if ($try>=_MAILSHOT_MAX_TRY
OR preg_match(",@example\.org$,i",$s['email'])
OR defined('_TEST_EMAIL_DEST')){
$done = array(
'fail' => true,
'statut' => 'fail',
'try' => $try,
'date'=>date('Y-m-d H:i:s'),
'log' => "ERREUR [$erreur] / failed apres $try essais",
);
// si c'est un fail max_try verifier et desinscrire eventuellement
if ($try>1){
mailshot_verifier_email_fail($d['email']);
}
}
else {
$done = array(
'try' => $try,
'date'=>date('Y-m-d H:i:s'),
'log' => "INFO Probleme [$erreur] (essai $try)",
);
}
}
else {
sql_updateq("spip_mailshots_destinataires",array('try'=>$try,'date'=>date('Y-m-d H:i:s')),"id_mailshot=".intval($shoot['id_mailshot'])." AND email=".sql_quote($d['email']));
spip_log("mailshot_envoyer_lot #".$shoot['id_mailshot']."/".$d['email']." : Probleme [$erreur] (essai $try)","mailshot"._LOG_INFO_IMPORTANTE);
$done = array(
'done' => true,
'statut'=>'sent',
'try'=>$try,
'date'=>date('Y-m-d H:i:s'),
'log' => "OK",
);
}
}
else {
$nb_restant--;
sql_updateq("spip_mailshots_destinataires",array('statut'=>'sent','try'=>$try,'date'=>date('Y-m-d H:i:s')),"id_mailshot=".intval($shoot['id_mailshot'])." AND email=".sql_quote($d['email']));
sql_update("spip_mailshots",array("current"=>"current+1"),"id_mailshot=".intval($shoot['id_mailshot']));
spip_log("mailshot_envoyer_lot #".$shoot['id_mailshot']."/".$d['email']." OK","mailshot");
if ($done) {
if (isset($done['done'])) {
$nb_restant--;
unset($done['done']);
sql_update("spip_mailshots",array("current"=>"current+1"),"id_mailshot=".intval($shoot['id_mailshot']));
}
if (isset($done['fail'])) {
unset($done['fail']);
sql_update("spip_mailshots",array("current"=>"current+1","failed"=>"failed+1"),"id_mailshot=".intval($shoot['id_mailshot']));
}
if (isset($done['log'])) {
$loglevel = '';
if (strncmp($done['log'], 'ERREUR', 6) == 0) {
$loglevel = _LOG_ERREUR;
}
elseif (strncmp($done['log'], 'INFO', 4) == 0) {
$loglevel = _LOG_INFO_IMPORTANTE;
}
spip_log("mailshot_envoyer_lot #".$shoot['id_mailshot']."/".$d['email']." : " . $done['log'], "mailshot" . $loglevel);
unset($done['log']);
}
sql_updateq("spip_mailshots_destinataires", $done,"id_mailshot=".intval($shoot['id_mailshot'])." AND email=".sql_quote($d['email']));
}
$nb_max--;
}
@ -222,6 +258,61 @@ function mailshot_envoyer_lot($nb_max=5,$offset=0){
return 0; // plus rien a envoyer sur ce lot
}
/**
* Verifie avant nouvel envoi un email et bloque un envoi si besoin
*
* @param string $email
* @param array $subscriber
* @param array $shoot
* @return array|bool
*/
function mailshot_verifier_email_envoi_bloque($email, $subscriber, $shoot) {
static $envois_idem = array();
if (preg_match(",@example\.org$,i",$subscriber['email'])) {
return array(
'fail' => true,
'statut' => 'fail',
'date' => date('Y-m-d H:i:s'),
'log' => "INFO Envoi BLOQUE Email obfusque ".$subscriber['email']."",
);
}
if (_TEST_EMAIL_DEST) {
$erreur = _T('mailshot:erreur_envoi_mail_force_debug',array('email'=>_TEST_EMAIL_DEST));
return array(
'fail' => true,
'statut' => 'fail',
'date' => date('Y-m-d H:i:s'),
'log' => "INFO Envoi BLOQUE $erreur",
);
}
if ($shoot['graceful']) {
// trouver tous les envois pour le meme id
if (!isset($envois_idem[$shoot['id_mailshot']])) {
$idem = sql_allfetsel('id_mailshot', 'spip_mailshots', 'id='.sql_quote($shoot['id'],'','text'));
$envois_idem[$shoot['id_mailshot']] = array_column($idem, 'id_mailshot');
}
if ($last = sql_fetsel('*', 'spip_mailshots_destinataires',
array(
'email=' . sql_quote($email),
sql_in('statut', array('todo', 'fail'), 'NOT'),
sql_in('id_mailshot', $envois_idem[$shoot['id_mailshot']]),
),'', 'date DESC', '0,1')) {
// on a trouve un envoi deja fait a la meme newsletter, on passe notre tour pout celui-ci
$done = array(
'done' => true,
'statut' => $last['statut'],
'date' => $last['date'],
'log' => "INFO Envoi BLOQUE newsletter #".$shoot['id']." deja envoyee a $email par mailshot#" . $last['id_mailshot'] . " / " . $last['date']
);
return $done;
}
}
return false;
}
/**
* Verifier un email en fail et si plus de N fails consecutifs le desabonner (email foireux)

1
lang/mailshot_fr.php

@ -64,6 +64,7 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'label_from' => 'Envoyeur',
'label_html' => 'Version HTML',
'label_listes' => 'Listes',
'label_graceful' => 'Uniquement les destinataires qui n\'ont pas déjà reçu ce contenu',
'label_mailer_defaut' => 'Utiliser le même service d’envoi que pour les autres mails',
'label_mailer_defaut_desactive' => 'Impossible : aucun service d’envoi d’email n’est configuré',
'label_mailer_mailjet' => 'Mailjet',

1
lang/newsletter_fr.php

@ -21,6 +21,7 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'label_email_test' => 'à l\'adresse email',
'label_liste' => 'aux abonnés de ',
'label_date_start' => 'Planifier l\'envoi',
'label_resend_oui' => 'Envoyer à nouveau aux destinataires qui l\'ont déjà reçue',
);

3
mailshot_administrations.php

@ -60,6 +60,9 @@ function mailshot_upgrade($nom_meta_base_version, $version_cible) {
$maj['0.3.5'] = array(
array('maj_tables', array('spip_mailshots')),
);
$maj['0.3.6'] = array(
array('maj_tables', array('spip_mailshots')), // option graceful
);
include_spip('base/upgrade');
maj_plugin($nom_meta_base_version, $version_cible, $maj);

4
newsletter/bulkstart.php

@ -22,13 +22,14 @@ include_spip("inc/config");
* @param array $options
* string statut : statut par defaut
* string date_start : date de debut d'envoi (dans le futur)
* bool graceful : ne pas envoyer aux destinataires qui on déjà reçu ce contenu
* @return int
* 0 si echec ou id de l'envoi sinon
*/
function newsletter_bulkstart_dist($corps,$listes = array(),$options=array()){
// TODO : recuperer la limite de rate d'apres la config
$now = date('Y-m-d H:i:s');
$defaut = array('statut'=>'processing','date_start'=>$now);
$defaut = array('statut'=>'processing','date_start'=>$now, 'graceful'=>0);
if (isset($options['date_start'])){
if (strtotime($options['date_start'])>time()) {
$defaut['statut'] = 'init';
@ -75,6 +76,7 @@ function newsletter_bulkstart_dist($corps,$listes = array(),$options=array()){
'html' => $corps['html'],
'texte' => $corps['texte'],
'listes' => implode(',',$listes),
'graceful' => $options['graceful'],
'from_name' => $from_name,
'from_email' => $from_email,
'total' => $count,

4
paquet.xml

@ -1,12 +1,12 @@
<paquet
prefix="mailshot"
categorie="communication"
version="1.26.1"
version="1.27.0"
etat="stable"
compatibilite="[3.0.5;3.2.*]"
logo="prive/themes/spip/images/mailshot-32.png"
documentation="https://contrib.spip.net/mailshot"
schema="0.3.5"
schema="0.3.6"
>
<nom>MailShot</nom>

7
prive/objets/contenu/mailshot.html

@ -16,10 +16,13 @@
</div>]
]
[<div class="champ contenu_listes[ (#LISTES*|strlen|?{'',vide})]">
[[(#BOITE_OUVRIR{#VAL{mailshot:label_listes}|_T|concat{' ',#GRACEFUL|?{<small class="graceful"><:mailshot:label_graceful:></small>}}})]
<div class="champ contenu_listes[ (#LISTES*|strlen|?{'',vide})]">
<div class='label'><:mailshot:label_listes:> : </div>
<span dir='#LANG_DIR' class='#EDIT{listes} listes'>(#LISTES|mailshot_affiche_nom_liste)</span>
</div>]
</div>
#BOITE_FERMER
]
<div class="champ contenu_from[ (#FROM_EMAIL*|strlen|?{'',vide})]">
<div class='label'><:mailshot:label_from:> : </div>

11
prive/style_prive_plugin_mailshot.html

@ -11,9 +11,13 @@
.formulaire_newsletter_send .editer_liste .select {width: 20em;}
.formulaire_newsletter_send .editer_liste .submit {float: #ENV{right}}
.formulaire_newsletter_send .editer_resend {padding-top: 0;}
.formulaire_newsletter_send .editer_resend .choix {padding: 0;background: none;border:0 !important;}
.formulaire_newsletter_send .editer_resend .choix label {margin-left: 0}
.formulaire_newsletter_send .editer_date_start {padding-top:0;}
.formulaire_newsletter_send .editer_date_start label {width: auto}
.formulaire_newsletter_send .editer_date_start label input.checkbox {margin-left:0;}
.formulaire_newsletter_send .editer_date_start label input.checkbox {}
.formulaire_newsletter_send .liste-objets.mailshots {margin:1em 0;}
.formulaire_newsletter_send .mailshots .sujet {display: none;}
@ -21,6 +25,11 @@
.mailshot #wysiwyg {margin-bottom: 2.0775em;padding:0;}
.mailshot #wysiwyg .label {display: inline;}
.mailshot #wysiwyg small.graceful {font-weight: normal}
.mailshot #wysiwyg small.graceful::before {content:'(';display: inline}
.mailshot #wysiwyg small.graceful::after {content:')';display: inline}
.mailshot #wysiwyg .contenu_listes .label {display: none;}
.mailshot #wysiwyg .contenu_avancement,
.mailshot #wysiwyg .contenu_html,
.mailshot #wysiwyg .contenu_texte {margin-bottom: 3em;}

Loading…
Cancel
Save