source: spip-zone/_plugins_/mailsubscribers/trunk/inc/mailsubscribers.php @ 86325

Last change on this file since 86325 was 86325, checked in by cedric@…, 5 years ago

Evolutions fonctionnelles :

  • on peut creer automatiquement une liste des Administrateurs, Redacteurs et/ou Visiteurs, en cochant une case, qui seront synchronisées automatiquement une fois par jour
  • par extension, on peut synchroniser facilement la liste de son choix avec toutes données externes en ecrivant la fonction mailsubscribers_synchro_list_newsletter_{$id}() qui devra retourner une liste des abonnes avec au moins le champs 'email' pour chaque et optionnellement les champs 'nom' et 'prenom'. Des que la fonction existe, un message informe que la liste est synchronisée automatiquement
  • fonction de synchronisation facile d'une liste avec un tableau d'abonnes. Pour le moment la fonction ne peut fonctionner qu'avec un tableau, ce qui limite aux listes raisonnables (quelques milliers, mais pas plusieurs centaines de millier)
File size: 10.2 KB
Line 
1<?php
2/**
3 * Plugin mailsubscribers
4 * (c) 2012 Cédric Morin
5 * Licence GNU/GPL v3
6 *
7 */
8
9if (!defined('_ECRIRE_INC_VERSION')) return;
10
11/**
12 * Normaliser le nom d'une liste de diffusion
13 *
14 * @param string $liste
15 * @param string $category
16 * @return string
17 */
18function mailsubscribers_normaliser_nom_liste($liste='', $category="newsletter"){
19        $category = strtolower(trim(preg_replace(",\W,","",$category)));
20
21        if (!$liste)
22                return "$category::$category"; // valeur fixe en cas de reantrance
23
24        if (strpos($liste,"::")!==false){
25                $liste = explode("::",$liste);
26                return mailsubscribers_normaliser_nom_liste($liste[1],$liste[0]);
27        }
28        include_spip("inc/charsets");
29        $liste = translitteration($liste);
30        $liste = strtolower($liste);
31
32        $liste = trim(preg_replace(",[^\w-],","",$liste));
33        $liste = "$category::$liste";
34        return $liste;
35}
36
37function mailsubscribers_obfusquer_email($email){
38        return md5($email)."@example.org";
39}
40
41function mailsubscribers_test_email_obfusque($email){
42        return preg_match(",^[a-f0-9]+@example\.org$,",$email);
43}
44
45/**
46 * Compter les inscrits a une liste
47 * @param $liste
48 * @return mixed
49 */
50function mailsubscribers_compte_inscrits($liste){
51        $subscribers = charger_fonction("subscribers","newsletter");
52        return $subscribers(array($liste),array('count'=>true));
53}
54
55/**
56 * Trouver une fonction de synchronisation pour une liste donnee
57 * @param $liste
58 * @return mixed|string
59 */
60function mailsubscribers_trouver_fonction_synchro($liste){
61        $f = mailsubscribers_normaliser_nom_liste($liste);
62        $f = str_replace("::","_",$f);
63        include_spip("public/parametrer"); // fichier mes_fonctions.php
64        if (function_exists($f="mailsubscribers_synchro_list_$f"))
65                return $f;
66        return "";
67}
68
69/**
70 * Informer un subscriber : ici juste l'url unsubscribe a calculer
71 * @param array $infos
72 * @return array mixed
73 */
74function mailsubscribers_informe_subscriber($infos){
75        $infos['listes'] = explode(',',$infos['listes']);
76        $infos['listes'] = array_map('mailsubscribers_filtre_liste',$infos['listes']);
77        $infos['listes'] = array_filter($infos['listes']);
78
79        $infos['url_unsubscribe'] = mailsubscriber_url_unsubscribe($infos['email'],$infos['jeton']);
80        unset($infos['jeton']);
81        return $infos;
82}
83
84/**
85 * Filtrer une liste a partir de sa category
86 * @param $liste
87 * @param string $category
88 * @return string
89 *   chaine vide si la liste n'est pas dans la category
90 *   nom de la liste sans le prefix de la category si ok
91 */
92function mailsubscribers_filtre_liste($liste,$category="newsletter"){
93        if (strncmp($liste,"$category::",$l=strlen("$category::"))==0){
94                return substr($liste,$l);
95        }
96        return '';
97}
98
99/**
100 * Renvoi les listes de diffusion disponibles avec leur status
101 * (open,close,?)
102 *
103 * @param array $options
104 *   category : filtrer les listes par category (dans ce cas la categorie est enlevee de l'id)
105 *   status : filtrer les listes sur le status
106 * @return array
107 *   array
108 *     id : identifiant
109 *     titre : titre de la liste
110 *     status : status de la liste
111 */
112function mailsubscribers_listes($options = array()){
113        $filtrer_status = $filtrer_category = false;
114        if (isset($options['status']))
115                $filtrer_status = $options['status'];
116        if (isset($options['category']))
117                $filtrer_category = $options['category'];
118
119        $listes = array();
120
121        // d'abord les listes connues en config
122        if (!function_exists('lire_config'))
123                include_spip('inc/config');
124        if ($known_lists = lire_config("mailsubscribers/lists",array())
125                AND is_array($known_lists)
126                AND count($known_lists)){
127
128                foreach ($known_lists as $kl){
129                        $id = $kl['id'];
130                        if (!$filtrer_category OR $id=mailsubscribers_filtre_liste($id,$filtrer_category)){
131                                $status = ($kl['status']=='open'?'open':'close');
132                                if (!$filtrer_status OR $filtrer_status==$status) {
133                                        $listes[$id] = array(
134                                                'id' => $id,
135                                                'titre' => $kl['titre'],
136                                                'status' => $status
137                                        );
138                                }
139                        }
140                }
141        }
142
143        // puis trouver toutes les listes qui existent en base et non connues en config
144        // pas la peine si on a demande de filtrer les listes open ou close
145        if ($filtrer_status!=='?') {
146                $rows = sql_allfetsel("DISTINCT listes","spip_mailsubscribers","statut!=".sql_quote('poubelle'));
147                foreach ($rows as $row){
148                        $ll = explode(",",$row['listes']);
149                        foreach($ll as $l){
150                                if ($id=$l
151                                        AND (
152                                                !$filtrer_category OR $id=mailsubscribers_filtre_liste($l,$filtrer_category)
153                                        )){
154                                        if (!isset($listes[$id]))
155                                                $listes[$id] = array('id'=>$id,'titre'=>$id,'status'=>'?');
156                                }
157                        }
158                }
159        }
160
161        return $listes;
162}
163
164/**
165 * Renomme un identifiant de liste dans la liste des abonnés
166 *
167 * @note
168 *   Si le nouveau nom est déjà un nom de liste existante, le renommage
169 *   est tout de même effectué, sans doublonner si l'abonné y est déjà inscrit.
170 *
171 * @param string $liste_ancienne
172 *   Identifiant de liste à renommer (exemple newsletter::1-truc)
173 * @param string $liste_nouvelle
174 *   Nouvel identifiant de la liste (exemple newsletter::infolettre)
175 * @return bool
176 *   True si l'opération a été réalisée.
177**/
178function mailsubscribers_renommer_identifiant_liste($liste_ancienne, $liste_nouvelle) {
179        spip_log("Renommer la liste '$liste_ancienne' en '$liste_nouvelle'", "mailsubscribers");
180
181        while ($subscribers = sql_allfetsel(
182                'id_mailsubscriber, listes',
183                'spip_mailsubscribers',
184                "listes REGEXP '(^|,)$liste_ancienne($|,)'",
185                "","","0,50"))
186        {
187                if (!$subscribers) break;
188
189                include_spip('action/editer_objet');
190                $liste_nouvelle = trim($liste_nouvelle);
191
192                foreach ($subscribers as $s) {
193                        $listes = explode(',', $s['listes']);
194                        $key = array_search($liste_ancienne, $listes);
195                        if ($key !== false) { // sait on jamais
196                                // si le nouveau nom existe déjà, pas la peine de le dupliquer !
197                                if (false === array_search($liste_nouvelle, $listes)) {
198                                        $listes[$key] = $liste_nouvelle;
199                                } else {
200                                        unset($listes[$key]);
201                                }
202                                $listes = implode(',', $listes);
203                                objet_modifier("mailsubscriber", $s['id_mailsubscriber'], array('listes' => $listes));
204                        }
205                }
206        }
207        return true;
208}
209
210
211/**
212 * Supprime un identifiant de liste dans la liste des abonnés
213 *
214 * Si un abonné n'est alors plus abonné à aucune liste,
215 * on le met à la poubelle !
216 *
217 * @param string $liste
218 *   Identifiant de liste à supprimer (exemple newsletter::infolettre)
219 * @return bool
220 *   True si l'opération a été réalisée.
221**/
222function mailsubscribers_supprimer_identifiant_liste($liste) {
223        spip_log("Supprimer la liste '$liste'", "mailsubscribers");
224        $GLOBALS['notification_instituermailsubscriber_status'] = false; // pas de notification ici
225
226        while ($subscribers = sql_allfetsel(
227                'id_mailsubscriber, listes',
228                'spip_mailsubscribers',
229                "listes REGEXP '(^|,)$liste($|,)'",
230                "","","0,50"))
231        {
232                if (!$subscribers) break;
233
234                include_spip('action/editer_objet');
235
236                foreach ($subscribers as $s) {
237                        $listes = explode(',', $s['listes']);
238                        $key = array_search($liste, $listes);
239                        if ($key !== false) { // sait on jamais
240                                unset($listes[$key]);
241                        }
242                        if (count($listes)) {
243                                $listes = implode(',', $listes);
244                                objet_modifier("mailsubscriber", $s['id_mailsubscriber'], array('listes' => $listes));
245                        } else {
246                                objet_modifier("mailsubscriber", $s['id_mailsubscriber'], array('listes' => '', 'statut' => 'poubelle'));
247                        }
248                }
249        }
250        return true;
251}
252
253
254function mailsubscribers_do_synchro_list($liste){
255        if ($f = mailsubscribers_trouver_fonction_synchro($liste)){
256                $abonnes = $f();
257                $n = count($abonnes);
258                spip_log("Synchronise liste $liste avec $n abonnes (fonction $f)","mailsubscribers");
259                mailsubscribers_synchronise_liste($liste,$abonnes);
260        }
261}
262
263
264/**
265 * Retourner la liste des abonnes qu'on veut voir dans la liste newsletter::0minirezo
266 * @return array
267 */
268function mailsubscribers_synchro_list_newsletter_0minirezo(){
269        $auteurs = sql_allfetsel("email,nom","spip_auteurs","statut=".sql_quote("0minirezo"));
270        return $auteurs;
271}
272
273/**
274 * Retourner la liste des abonnes qu'on veut voir dans la liste newsletter::1comite
275 * @return array
276 */
277function mailsubscribers_synchro_list_newsletter_1comite(){
278        $auteurs = sql_allfetsel("email,nom","spip_auteurs","statut=".sql_quote("1comite"));
279        return $auteurs;
280}
281
282/**
283 * Retourner la liste des abonnes qu'on veut voir dans la liste newsletter::6forum
284 * @return array
285 */
286function mailsubscribers_synchro_list_newsletter_6forum(){
287        $auteurs = sql_allfetsel("email,nom","spip_auteurs","statut=".sql_quote("6forum"));
288        return $auteurs;
289}
290
291
292/**
293 * Synchroniser les abonnes d'une liste en base avec un tableau fourni
294 * TODO : permettre de fournir une resource SQL en entree et ne pas manipuler de gros tableau en memoire (robustesse)
295 * @param string $liste
296 *   liste avec laquelle on synchronise les abonnes
297 * @param array $abonnes
298 *   chaque abonne est un tableau avec l'entree 'email' et les entrees optionnelles 'nom' et 'prenom'
299 */
300function mailsubscribers_synchronise_liste($liste,$abonnes){
301        $listes = array($liste);
302
303        // desactiver toutes les notifications pendant cette operation
304        // on ne veut pas envoyer de mail a ceux qu'on ajoute/retire de la liste
305        $GLOBALS['notification_instituermailsubscriber_status'] = false;
306
307        $abonnes_emails = array();
308        while(count($abonnes)){
309                $abonne = array_shift($abonnes);
310                if (isset($abonne['email'])
311                  AND strlen(trim($abonne['email']))){
312                        $abonnes_emails[$abonne['email']] = $abonne;
313                }
314        }
315
316        $subscribers = charger_fonction('subscribers','newsletter');
317        $subscribe = charger_fonction('subscribe','newsletter');
318        $unsubscribe = charger_fonction('unsubscribe','newsletter');
319
320        // d'abord on prend la liste de tous les abonnes en base
321        // et on retire ceux qui ne sont plus dans le tableau $abonnes
322        $subs = $subscribers($listes);
323        foreach($subs as $sub){
324                // OK il est toujours dans les abonnes
325                if (isset($abonnes_emails[$sub['email']])){
326                        unset($abonnes_emails[$sub['email']]);
327                }
328                // il n'est plus dans les abonnes on l'enleve
329                else {
330                        //echo "unsubscribe ".$sub['email']."<br />";
331                        $unsubscribe($sub['email'],array('listes'=>$listes));
332                }
333        }
334
335        // si il reste du monde dans $abonnes, c'est ceux qui ne sont pas en base
336        // on les subscribe
337        foreach($abonnes_emails as $email=>$abonne){
338                //echo "subscribe ".$email."<br />";
339                $nom = (isset($abonne['nom'])?$abonne['nom'].' ':'');
340                $nom .= (isset($abonne['prenom'])?$abonne['prenom'].' ':'');
341                $subscribe($email,array(
342                        'nom' => trim($nom),
343                        'listes' => $listes,
344                        'force' => true,
345                ));
346        }
347
348        $GLOBALS['notification_instituermailsubscriber_status'] = true;
349}
Note: See TracBrowser for help on using the repository browser.