version 3.1.15 : ajout d'un formulaire pour envoyer des notifications ponctuellement aux abonnés d'une offre, en complément des notifications programmées donc. Par exemple, pour notifier les gens dont l'abonnement a expiré et qu'on ne pourrait pas inclure dans les notifications programmées.

Pas de doublon : si on envoie une notification et qu'elle est déjà programmée le même jour, elle ne partira qu'une seule fois.
On peut choisir les abonnements en fonction de leurs statuts et de leurs dates de création/fin.
Il y a une étape de vérification avant d'envoyer pour éviter les fausses manoeuvres.
svn/attic/shelves/BoOz/122940
tcharlss@bravecassine.com 7 years ago
parent 2b9dc17b36
commit dc6be3e4d5

3
.gitattributes vendored

@ -12,6 +12,8 @@ formulaires/editer_abonnements_offre.html -text
formulaires/editer_abonnements_offre.php -text
formulaires/editer_abonnements_offre_notifications.html -text
formulaires/editer_abonnements_offre_notifications.php -text
formulaires/notifier_echeances_abonnementsoffre.html -text
formulaires/notifier_echeances_abonnementsoffre.php -text
genie/abonnements_verifier_desactivation.php -text
genie/abonnements_verifier_echeances.php -text
genie/abonnements_verifier_notifications.php -text
@ -43,6 +45,7 @@ prive/squelettes/hierarchie/abonnement.html -text
prive/squelettes/hierarchie/abonnement_edit.html -text
prive/squelettes/inclure/abonnements_auteur.html -text
prive/squelettes/navigation/inc-abonnements_notifications.html -text
prive/style_prive_plugin_abonnements.html -text
prive/themes/spip/images/abonnement-16.png -text
prive/themes/spip/images/abonnement-24.png -text
prive/themes/spip/images/abonnement-32.png -text

@ -187,14 +187,23 @@ function abonnements_taches_generales_cron($taches) {
return $taches;
}
/*
* Ajouter la config des notifications
/**
* Ajouter des choses dans la colonne de gauche
*
* Offres d'abonnements : config des notifications + notifications ponctuelles
*
* @param array $flux
* @return array
*/
function abonnements_affiche_gauche($flux) {
if ($flux['args']['exec'] == 'abonnements_offre') {
if (isset($flux['args']['exec'])
and $flux['args']['exec'] == 'abonnements_offre'
and isset($flux['args']['id_abonnements_offre'])
) {
$flux['data'] .= recuperer_fond(
'prive/squelettes/navigation/inc-abonnements_notifications', array('id_abonnements_offre' => $flux['args']['id_abonnements_offre'])
'prive/squelettes/navigation/inc-abonnements_notifications', array(
'id_abonnements_offre' => $flux['args']['id_abonnements_offre']
)
);
}

@ -1,5 +1,6 @@
<div class="formulaire_spip formulaire_editer formulaire_#ENV{form}[ formulaire_#ENV{form}-(#ENV{id,nouveau})]">
<h3 class="titrem">[(#CHEMIN_IMAGE{notifications-24}|balise_img{'','cadre-icone'})]<:abonnementsoffre:configurer_notifications:></h3>
<p class="explication"><:abonnementsoffre:explication_configurer_notifications_abonnementsoffre:></p>
[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]

@ -0,0 +1,39 @@
[(#REM)
Envoyer ponctuellement des notifications aux abonnés d'une offre
On peut restreindre la liste des gens à notifier selon certains critères : statut, dates, ...
]
<div class="formulaire_spip formulaire_#FORM formulaire_#FORM-#ENV{id_abonnements_offre}">
<h3 class="titrem">[(#CHEMIN_IMAGE{notifications-24}|balise_img{'','cadre-icone'})]<:abonnementsoffre:titre_notifier_abonnementsoffre:></h3>
<p class="explication"><:abonnementsoffre:explication_envoyer_notifications_abonnementsoffre:></p>
[<p class="reponse_formulaire reponse_formulaire_ok[ (#ENV{is_annule}|ou{#ENV{is_verifie}}|oui)hidden]">(#ENV**{message_ok})</p>]
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV**{message_erreur})</p>]
[(#ENV{confirmer_verifier}|oui)
<div class="notice"><:abonnementsoffre:message_notifier_verifier_abonnements:></div>
]
[(#ENV{editable})
<form method="post" action="#ENV{action}"><div>
#ACTION_FORMULAIRE{#ENV{action}}
<input type="hidden" name="is_verifie" value="#ENV{is_verifie}" />
<input type="hidden" name="is_annule" value="#ENV{is_annule}" />
<input type="hidden" name="confirmer_verifier" value="#ENV{confirmer_verifier}" />
<[(#DIV|sinon{ul}) ]class="editer-groupe[ (#ENV{is_verifie}|oui)hidden]">
#GENERER_SAISIES{#ENV{_saisies}}
</[(#DIV|sinon{ul})]>
[(#REM) ajouter les saisies supplementaires : extra et autre, a cet endroit ]
<!--extra-->
<p class="boutons">
[(#ENV{is_verifie}|non)
<input type="submit" class="submit" name="btn_verifier" value="<:bouton_valider:>" />
][(#ENV{is_verifie}|oui)
<input type="submit" class="submit link" name="btn_annuler" value="<:abonnementsoffre:bouton_annuler:>" />
<input type="submit" class="submit" name="btn_notifier" value="<:abonnementsoffre:bouton_notifier:>" />
]
</p>
</div></form>
]
</div>

@ -0,0 +1,304 @@
<?php
/**
* Envoyer ponctuellement les notifications aux abonnés d'une offre
*
* On restreindre la liste des gens à notifier selon certains critères : statut, dates, ...
*/
// Sécurité
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Déclaration des saisies du formulaire
*
* @param int id_abonnements_offre
* Numéro d'une offre d'abonnements
* @param string $retour
* URL de redirection
* @return array
*/
function formulaires_notifier_echeances_abonnementsoffre_saisies_dist($id_abonnements_offre, $retour = ''){
$saisies = array(
array(
'saisie' => 'selection',
'options' => array(
'nom' => 'statut',
'label' => _T('abonnement:champ_notifier_statut_label'),
'datas' => array(
'' => ucfirst(_T('abonnement:statut_tous')),
'actif' => ucfirst(_T('abonnement:statut_actifs')),
'inactif' => ucfirst(_T('abonnement:statut_inactifs')),
),
'cacher_option_intro' => 'oui',
),
),
array(
'saisie' => 'fieldset',
'options' => array(
'nom' => 'fieldset_date_debut',
'label' => _T('abonnement:champ_dates_debut_label'),
'pliable' => 'oui',
'plie' => 'oui',
),
'saisies' => array(
array(
'saisie' => 'date',
'options' => array(
'nom' => 'date_debut_du',
'label' => _T('abonnement:champ_date_du_label'),
'li_class' => 'date_inline',
),
),
array(
'saisie' => 'date',
'options' => array(
'nom' => 'date_debut_au',
'label' => _T('abonnement:champ_date_au_label'),
'li_class' => 'date_inline',
),
),
),
),
array(
'saisie' => 'fieldset',
'options' => array(
'nom' => 'fieldset_date_fin',
'label' => _T('abonnement:champ_dates_fin_label'),
'pliable' => 'oui',
'plie' => 'oui',
),
'saisies' => array(
array(
'saisie' => 'date',
'options' => array(
'nom' => 'date_fin_du',
'label' => _T('abonnement:champ_date_du_label'),
'li_class' => 'date_inline',
),
),
array(
'saisie' => 'date',
'options' => array(
'nom' => 'date_fin_au',
'label' => _T('abonnement:champ_date_au_label'),
'li_class' => 'date_inline',
),
),
),
),
);
return $saisies;
}
/**
* Charger les valeurs
*
* @param int id_abonnements_offre
* Numéro d'une offre d'abonnement
* @param string $retour
* URL de redirection
* @return array
*/
function formulaires_notifier_echeances_abonnementsoffre_charger_dist($id_abonnements_offre, $retour = ''){
$contexte = array(
'id_abonnements_offre' => $id_abonnements_offre,
'is_verifie' => false,
'is_annule' => false,
'confirmer_verifier' => false,
);
// Il faut obligatoirement un ID valide
if (!intval($id_abonnements_offre)){
$contexte['message_erreur'] = _T('erreur');
$contexte['editable'] = false;
}
return $contexte;
}
/**
* Vérifier les valeurs postées
*
* @param int id_abonnements_offre
* Numéro d'une offre d'abonnement
* @param string $retour
* URL de redirection
* @return array
*/
function formulaires_notifier_echeances_abonnementsoffre_verifier_dist($id_abonnements_offre, $retour = ''){
$erreurs = array();
return $erreurs;
}
/**
* Traitements
*
* @param int id_abonnements_offre
* Numéro d'une offre d'abonnement
* @param string $retour
* URL de redirection
* @return array
*/
function formulaires_notifier_echeances_abonnementsoffre_traiter_dist($id_abonnements_offre, $retour = ''){
$res = array();
$message_ok = '';
$message_erreur = '';
// Empêcher le traitement AJAX en cas de redirection
if ($retour) {
refuser_traiter_formulaire_ajax();
}
// Récupérer et normaliser les valeurs postées
$statut = _request('statut');
$date_debut_du = normaliser_date(str_replace('/', '-', _request('date_debut_du')));
$date_debut_au = _request('date_debut_au') ? normaliser_date(str_replace('/', '-', _request('date_debut_au')) . ' 23:59:59') : '';
$date_fin_du = normaliser_date(str_replace('/', '-', _request('date_fin_du')));
$date_fin_au = _request('date_fin_au') ? normaliser_date(str_replace('/', '-', _request('date_fin_au')) . ' 23:59:59') : '';
// Préparer la partie du WHERE conçernant les dates, utilisée dans le SQL et le JS
$where = array("date_fin > 0"); // Il faut forcément une date de fin
if ($date_debut_du and !$date_debut_au) {
$where[] = 'date_debut >= ' . sql_quote($date_debut_du);
} elseif (!$date_debut_du and $date_debut_au) {
$where[] = 'date_debut <= ' . sql_quote($date_debut_au);
} elseif ($date_debut_du and $date_debut_au) {
$where[] = '(date_debut BETWEEN ' . sql_quote($date_debut_du) . ' AND ' . sql_quote($date_debut_au) . ')';
}
if ($date_fin_du and !$date_fin_au) {
$where[] = 'date_fin >= ' . sql_quote($date_fin_du);
} elseif (!$date_fin_du and $date_fin_au) {
$where[] = 'date_fin <= ' . sql_quote($date_fin_au);
} elseif ($date_fin_du and $date_fin_au) {
$where[] = '(date_fin BETWEEN ' . sql_quote($date_fin_du) . ' AND ' . sql_quote($date_fin_au) . ')';
}
// Préparer le JS pour remettre les listes à zéro
$js_reset = '<script type="text/javascript">' .
'ajaxReload("abonnements_actifs", {args:{"statut":"actif","where":"","nb":"","sinon":"","titre_singulier":"abonnement:info_1_abonnement_actif","titre_pluriel":"abonnement:info_nb_abonnements_actifs","date_fin":""}});' .
'ajaxReload("abonnements_inactifs",{args:{"statut":"inactif"}});' .
'</script>';
// ========================================================
// Vérification des abonnements à notifier avant validation
// ========================================================
if (_request('btn_verifier')){
// Renvoyer du JS dans le squelette pour recharger la liste avec les abonnements à notifier
// On cache la 2ème liste en passant un statut inexistant
$params = array(
'"titre_singulier":"abonnement:info_1_abonnement_notifier"',
'"titre_pluriel":"abonnement:info_nb_abonnements_notifier"',
'"sinon":"' . _T('abonnement:info_aucun_abonnement_notifier') . '"',
'"nb":"50"',
'"where":"' . join(' AND ', $where) . '"',
'"statut":"' . $statut . '"',
);
$params = join(',', array_filter($params));
$js = '<script type="text/javascript">' .
'ajaxReload("abonnements_actifs",{args:{'. $params .'}});' .
'ajaxReload("abonnements_inactifs",{args:{"statut":"non","sinon":""}});' .
'</script>';
$res['editable'] = true;
set_request('is_verifie', true);
set_request('is_annule', false);
set_request('confirmer_verifier', true);
$message_ok = $js;
}
// =============================
// Annulation après vérification
// =============================
if (_request('btn_annuler')){
$res['editable'] = true;
set_request('is_verifie', false);
set_request('is_annule', true);
set_request('confirmer_verifier', false);
$message_ok = $js_reset;
}
// ============================
// OK : envoi des notifications
// ============================
// Récupérer tous les abonnements qui n'ont pas de job
if (_request('btn_notifier')){
$where[] = 'id_abonnements_offre = ' . intval($id_abonnements_offre);
$where[] = 'email IS NOT NULL';
$where[] = 'j.id_job IS NULL';
$where[] = $statut ? 'abo.statut = ' . sql_quote($statut) : '';
$where = array_filter($where);
if ($a_notifier = sql_allfetsel(
'id_abonnement, nom, email, date_fin',
'spip_abonnements as abo' .
' INNER JOIN spip_auteurs AS aut ON abo.id_auteur = aut.id_auteur' .
' LEFT JOIN spip_jobs_liens AS l ON abo.id_abonnement = l.id_objet AND l.objet = "abonnement"' .
' LEFT JOIN spip_jobs AS j ON l.id_job = j.id_job AND j.fonction = "abonnements_notifier_echeance"',
$where
)){
// Pour chacun on programme un envoi de mail
foreach ($a_notifier as $abonnement){
$aujourdhui = new DateTime('now');
$echeance = new DateTime($abonnement['date_fin']);
$difference = $aujourdhui->diff($echeance);
$duree = $difference->days;
$periode = 'jours';
$quand = $duree === 0 ?
('pendant') :
($aujourdhui > $echeance ? 'apres' : 'avant');
$id_job = job_queue_add(
'abonnements_notifier_echeance',
"Notifier manuellement {$abonnement['nom']} $duree $periode $quand l'échéance de son abonnement {$abonnement['id_abonnement']}",
array(
$abonnement['id_abonnement'],
$abonnement['nom'],
$abonnement['email'],
$duree,
$periode,
$quand,
),
'inc/abonnements',
true
);
job_queue_link(
$id_job,
array(
'objet' => 'abonnement',
'id_objet' => $abonnement['id_abonnement']
)
);
}
}
if (count($a_notifier) > 0) {
$message_ok = _T('abonnementsoffre:message_notifier_ok');
$message_ok .= $js_reset;
} else {
$message_erreur = _T('abonnement:info_aucun_abonnement_notifier');
$message_erreur .= $js_reset;
}
$res['editable'] = false;
set_request('is_annule', false);
set_request('is_verifie', false);
set_request('confirmer_verifier', false);
// Redirection éventuelle
if ($retour) {
$res['redirect'] = $retour;
}
}
// Messages de retour
if ($message_erreur) {
$res['message_erreur'] = $message_erreur;
} elseif ($message_ok) {
$res['message_ok'] = $message_ok;
}
return $res;
}

@ -59,7 +59,7 @@ function genie_abonnements_verifier_notifications_dist($time){
foreach ($a_notifier as $abonne){
$id_job = job_queue_add(
'abonnements_notifier_echeance',
"Notifier ${abonne['nom']} ${notification['duree']} ${notification['periode']} ${notification['quand']} l'échéance de son abonnement ${abonne['id_abonnement']}",
"Notifier automatiquement ${abonne['nom']} ${notification['duree']} ${notification['periode']} ${notification['quand']} l'échéance de son abonnement ${abonne['id_abonnement']}",
array(
$abonne['id_abonnement'],
$abonne['nom'],

@ -12,11 +12,16 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
// C
'champ_date_debut_label' => 'Début de labonnement',
'champ_dates_debut_label' => 'Débuts des abonnements',
'champ_date_echeance_label' => 'Prochaine échéance',
'champ_date_fin_allonger_label' => 'Vous pouvez modifier la date de fin',
'champ_date_fin_label' => 'Fin de labonnement',
'champ_dates_fin_label' => 'Fin des abonnements',
'champ_date_du_label' => 'Du',
'champ_date_au_label' => 'Au',
'champ_id_abonnements_offre_label' => 'Offre dabonnement',
'champ_id_auteur_label' => 'Utilisateur',
'champ_notifier_statut_label' => 'Status des abonnements',
// E
'erreur_id_abonnements_offre' => 'Vous devez créer un abonnement pour une offre existante.',
@ -28,13 +33,16 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'info_1_abonnement' => 'Un abonnement',
'info_1_abonnement_actif' => 'Un abonnement actif',
'info_1_abonnement_inactif' => 'Un abonnement inactif',
'info_1_abonnement_notifier' => 'Un abonnement à notifier',
'info_abonnements_auteur' => 'Les abonnements de cet auteur',
'info_aucun_abonnement' => 'Aucun abonnement',
'info_aucun_abonnement_actif' => 'Aucun abonnement actif',
'info_aucun_abonnement_inactif' => 'Aucun abonnement inactif',
'info_aucun_abonnement_notifier' => 'Aucun abonnement à notifier',
'info_nb_abonnements' => '@nb@ abonnements',
'info_nb_abonnements_actifs' => '@nb@ abonnements actifs',
'info_nb_abonnements_inactifs' => '@nb@ abonnements inactifs',
'info_nb_abonnements_notifier' => '@nb@ abonnements à notifier',
'info_numero_abbr' => 'n°',
'info_numero_abbr_maj' => 'N°',
@ -66,7 +74,10 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
// S
'statut_actif' => 'actif',
'statut_actifs' => 'actifs',
'statut_inactif' => 'désactivé',
'statut_inactifs' => 'désactivés',
'statut_tous' => 'tous',
// T
'texte_ajouter_abonnement' => 'Ajouter un abonnement',

@ -10,6 +10,11 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
// A
'ajouter_lien_abonnementsoffre' => 'Ajouter cette offre dabonnement',
// B
'bouton_notifier' => 'Notifier',
'bouton_verifier' => 'Vérifier',
'bouton_annuler' => 'Annuler',
// C
'champ_descriptif_label' => 'Descriptif',
'champ_duree_0' => 'Sans limite',
@ -36,6 +41,8 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
// E
'erreur_notification_doublon' => 'Cette notification est déjà enregistrée',
'explication_envoyer_notifications_abonnementsoffre' => 'Envoi immédiat de notifications.',
'explication_configurer_notifications_abonnementsoffre' => 'Envoi automatique de notifications.',
// I
'icone_creer_abonnementsoffre' => 'Créer une offre dabonnement',
@ -54,6 +61,10 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'info_nb_mois_avant' => '@nb@ mois avant',
'info_aucune_notification' => 'Aucune notification',
// M
'message_notifier_verifier_abonnements' => 'Vérifier les utilisateurs ci-contre avant de valider l\'envoi des notifications.',
'message_notifier_ok' => 'Les notifications ont bien été envoyées.',
// N
'nb_abonnements' => 'Nb. abo.',
@ -69,5 +80,6 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'titre_abonnementsoffres' => 'Offres dabonnement',
'titre_abonnementsoffres_rubrique' => 'Offres dabonnement de la rubrique',
'titre_langue_abonnementsoffre' => 'Langue de cette offre dabonnement',
'titre_logo_abonnementsoffre' => 'Logo de cette offre dabonnement'
'titre_logo_abonnementsoffre' => 'Logo de cette offre dabonnement',
'titre_notifier_abonnementsoffre' => 'Envoyer des notifications',
);

@ -1,7 +1,7 @@
<paquet
prefix="abonnements"
categorie="auteur"
version="3.1.14"
version="3.1.15"
schema="2.2.6"
etat="test"
compatibilite="[3.0.0;3.1.*]"

@ -1,4 +1,4 @@
<INCLURE{fond=prive/objets/liste/abonnements, env, ajax,
<INCLURE{fond=prive/objets/liste/abonnements, env, ajax=abonnements_actifs,
id_abonnements_offre=#ENV{id_abonnements_offre},
masquer_offre=oui,
par=date_fin, date_fin_sens=1,
@ -12,7 +12,7 @@
]
<div class="nettoyeur"></div>
<INCLURE{fond=prive/objets/liste/abonnements, env, ajax,
<INCLURE{fond=prive/objets/liste/abonnements, env, ajax=abonnements_inactifs,
id_abonnements_offre=#ENV{id_abonnements_offre},
masquer_offre=oui,
par=date_fin,

@ -48,9 +48,10 @@
{id_auteur?}
{statut?}
{recherche?}
{annee_debut?}{mois_debut?}
{annee_echeance?}{mois_echeance?}
{annee_fin?}{mois_fin?}
{where?}
{date_debut?} {annee_debut?} {mois_debut?}
{date_echeance?} {annee_echeance?} {mois_echeance?}
{date_fin?} {annee_fin?} {mois_fin?}
{tri #ENV{par,date_debut},#GET{defaut_tri}}{pagination #ENV{nb,10}}
>
<tr class="[(#COMPTEUR_BOUCLE|alterner{row_odd,row_even})]">

@ -1 +1,13 @@
<div class="ajax">#FORMULAIRE_EDITER_ABONNEMENTS_OFFRE_NOTIFICATIONS{#ENV{id_abonnements_offre}}</div>
[(#REM) Configurer les notifications automatiques ]
[(#ENV{masquer_configurer}|!={oui}|oui)
<div class="ajax">
#FORMULAIRE_EDITER_ABONNEMENTS_OFFRE_NOTIFICATIONS{#ENV{id_abonnements_offre}}
</div>
]
[(#REM) Envoyer ponctuellement des notifications ]
[(#ENV{masquer_notifier}|!={oui}|oui)
<div class="ajax">
#FORMULAIRE_NOTIFIER_ECHEANCES_ABONNEMENTSOFFRE{#ENV{id_abonnements_offre}}
</div>
]

@ -0,0 +1,27 @@
[(#REM)<style>
Ce squelette definit les styles de l'espace prive
Note: l'entete "Vary:" sert a repousser l'entete par
defaut "Vary: Cookie,Accept-Encoding", qui est (un peu)
genant en cas de "rotation du cookie de session" apres
un changement d'IP (effet de clignotement).
ATTENTION: il faut absolument le charset sinon Firefox croit que
c'est du text/html !
]
#CACHE{3600*100,cache-client}
#HTTP_HEADER{Content-Type: text/css; charset=iso-8859-15}
#HTTP_HEADER{Vary: Accept-Encoding}
#SET{claire,##ENV{couleur_claire,c5e41c}}
#SET{foncee,##ENV{couleur_foncee,9dba00}}
.formulaire_notifier_echeances_abonnementsoffre .hidden { display: none; }
.formulaire_notifier_echeances_abonnementsoffre .editer.date_inline label,
.formulaire_notifier_echeances_abonnementsoffre .editer.date_inline .date {
display: inline-block;
}
.formulaire_notifier_echeances_abonnementsoffre fieldset h3 {
margin-bottom: 0;
font-size: 1em;
}
Loading…
Cancel
Save