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

Last change on this file was 118109, checked in by cedric@…, 2 months ago

Quand on cherche les infos d'un subscriber mais qu'il y a doublon en base, nettoyer la base en mettant l'obfusque a la poubelle et en reportant les subscriptions sur le valide

File size: 25.3 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 * Recuperer email et arg dans l'action confirm/subscribe/unsubscribe
13 * en gerant les cas foireux introduits par les urls coupees dans les mails
14 * ou par les services d'envoi+redirection qui abiment les URLs
15 *
16 * @param string $action
17 * @return array
18 *   email, $id_mailsubscribinglists
19 */
20function mailsubscribers_verifier_args_action($action) {
21        $email = _request('email');
22        $arg = _request('arg');
23
24        // reparer le arg ou le retrouver dans la QUERY_STRING si jamais il était coupé
25        if (is_null($arg) OR is_null($email)) {
26                $query = $_SERVER["QUERY_STRING"];
27                // cas du arg coupe
28                if (strpos($query, "arg%") !== false) {
29                        $query = str_replace("arg%", "arg=", $query);
30                }
31                // cas du & transorme en &amp;
32                if (strpos($query, '&amp;') !== false) {
33                        $query = str_replace("&amp;", "&", $query);
34                }
35                parse_str($query, $args);
36                $arg = strtolower($args['arg']);
37                $email = $args['email'];
38                if ($p = strpos($arg, '-') === false) {
39                        if (strlen($arg) > 40) {
40                                $arg = substr($arg, -40);
41                        }
42                }
43                else {
44                        // faisons un preg_match pour retrouver tous les elements malgre le caca qui a ete ajoute
45                        if (preg_match(",^(\d+-)+[0-9a-f]{40},", $arg, $m)) {
46                                $arg = $m[0];
47                        }
48                        else {
49                                $arg = null;
50                        }
51                }
52                // cas des urls qui ont ete triplement encodees : il faut encore urldecoder deux fois l'email
53                // %2540 = urlencode(urlencode('@'))
54                if (strpos($email, '%2540') !== false) {
55                        $email = urldecode($email);
56                }
57                // cas des urls qui ont ete doublement encodees : il faut encore urldecoder une fois l'email
58                // %40 = urlencode('@')
59                if (strpos($email, '%40') !== false) {
60                        $email = urldecode($email);
61                }
62                if ($arg AND $email) {
63                        spip_log("mailsubscriber : $email|$arg reconnus malgre la query_string mal formee (verifiez votre service d'envoi de mails) [" . $_SERVER["QUERY_STRING"] . "]", "mailsubscribers" . _LOG_INFO_IMPORTANTE);
64                }
65        }
66        if (!$email OR !$arg){
67                spip_log(_request('action')." : (email,arg)=($email,$arg) non trouves [" . $_SERVER["QUERY_STRING"] . "]", "mailsubscribers"._LOG_ERREUR);
68                return false;
69        }
70
71        if (!$email
72                OR !$row = sql_fetsel('id_mailsubscriber,email,jeton,lang,statut', 'spip_mailsubscribers', 'email=' . sql_quote($email) . ' OR email=' . sql_quote(mailsubscribers_obfusquer_email($email)))
73        ) {
74                spip_log(_request('action')." : email $email pas dans la base spip_mailsubscribers", "mailsubscribers"._LOG_INFO_IMPORTANTE);
75                return false;
76        } else {
77                include_spip("inc/lang");
78                changer_langue($row['lang']);
79               
80                $identifiants = array();
81                $jeton = $row['jeton'];
82                $id_mailsubscribinglists = explode('-', $arg);
83                array_pop($id_mailsubscribinglists); // le hash
84                if (!$id_mailsubscribinglists) {
85                        $id_mailsubscribinglists = null;
86                }
87                // verifier la cle telle quelle
88                // => soit une cle generique, applicable pour toutes les listes
89                // => soit une cle avec des id_mailsubscribinglists
90                $cle = mailsubscriber_cle_action($action, $email, $jeton, $id_mailsubscribinglists);
91                // si elle ne match pas et que arg ne contient aucun $id_mailsubscribinglists cherchons si c'est un hash ancien format
92                // avec juste une liste ajoute sous la forme jeton+id_mailsubscribinglist
93                if ($arg !== $cle and is_null($id_mailsubscribinglists)) {
94                        $id_mailsubscribinglists = array();
95                        // on ne cherche que dans les subscriptions connues pour cet inscrit, sinon rien a faire
96                        $subscriptions = sql_allfetsel('*', 'spip_mailsubscriptions', 'id_mailsubscriber=' . intval($row['id_mailsubscriber']));
97                        foreach ($subscriptions as $subscription){
98                                // verifier la cle pour cette liste
99                                $cle = mailsubscriber_cle_action($action, $email, $jeton . '+' . $subscription['id_mailsubscribinglist']);
100                                if ($arg == $cle) {
101                                        $id_mailsubscribinglists[] = $subscription['id_mailsubscribinglist'];
102                                        break;
103                                }
104                        }
105                        // pas de correspondance => cle incorrecte
106                        if (!$subscription['id_mailsubscribinglist']){
107                                spip_log(_request('action')." : cle $arg incorrecte pour email $email", "mailsubscribers"._LOG_INFO_IMPORTANTE);
108                                return false;
109                        }
110                }
111        }
112
113        return array($email, $id_mailsubscribinglists);
114}
115
116/**
117 * Normaliser le nom d'une liste de diffusion
118 *
119 * @param string $liste
120 * @param string $category
121 * @return string
122 */
123function mailsubscribers_normaliser_nom_liste($liste = '', $category = "newsletter") {
124        $category = strtolower(trim(preg_replace(",\W,", "", $category)));
125
126        if (!$liste) {
127                return "$category";
128        } // valeur fixe en cas de re-entrance
129
130        if (strpos($liste, "::") !== false) {
131                $liste = explode("::", $liste);
132
133                return mailsubscribers_normaliser_nom_liste($liste[1], $liste[0]);
134        }
135        include_spip("inc/charsets");
136        $liste = translitteration($liste);
137        $liste = strtolower($liste);
138
139        $liste = trim(preg_replace(",[^\w-],", "", $liste));
140
141        return $liste;
142}
143
144function mailsubscribers_obfusquer_email($email, $force = false) {
145    if (!$force and defined('_MAILSUBSCRIBERS_GARDER_EMAILENCLAIR') ) {
146            return $email;
147    }
148    // on ne double pas l'obfusquation
149    if (strpos($email, "@example.org") !== false) {
150        return $email;
151    }
152
153    return md5($email) . "@example.org";
154}
155
156function mailsubscribers_test_email_obfusque($email) {
157        return preg_match(",^[a-f0-9]+@example\.org$,", $email);
158}
159
160function mailsubscribers_obfusquer_mailsubscriber($id_mailsubscriber) {
161        $row = sql_fetsel('*', 'spip_mailsubscribers', 'id_mailsubscriber=' . intval($id_mailsubscriber));
162        if ($row
163                and in_array($row['statut'], array('refuse', 'poubelle'))
164                and !mailsubscribers_test_email_obfusque($row['email'])
165        ) {
166                include_spip('inc/autoriser');
167                include_spip('action/editer_objet');
168                autoriser_exception("modifier", "mailsubscriber", $id_mailsubscriber);
169                objet_modifier("mailsubscriber", $id_mailsubscriber,
170                        array('email' => mailsubscribers_obfusquer_email($row['email'])));
171                autoriser_exception("modifier", "mailsubscriber", $id_mailsubscriber, false);
172        }
173}
174
175/**
176 * Mise en forme de la trace des abonnements/desabonnements dans le champ optin
177 *
178 * @param string $actions
179 *   nouvelles actions tracees
180 * @param string $trace
181 *   trace existante
182 * @return string
183 */
184function mailsubscribers_trace_optin($actions, $trace) {
185        $trace = trim($trace);
186        $trace .=
187                "\n"
188                . trim($actions) . ' : '
189                . date('Y-m-d H:i:s') . " "
190                . _T('public:par_auteur') . ''
191                . (isset($GLOBALS['visiteur_session']['id_auteur']) ? "#" . $GLOBALS['visiteur_session']['id_auteur'] . ' ' : '')
192                . (isset($GLOBALS['visiteur_session']['nom']) ? $GLOBALS['visiteur_session']['nom'] . ' ' : '')
193                . (isset($GLOBALS['visiteur_session']['session_nom']) ? $GLOBALS['visiteur_session']['session_nom'] . ' ' : '')
194                . (isset($GLOBALS['visiteur_session']['session_email']) ? $GLOBALS['visiteur_session']['session_email'] . ' ' : '')
195                . '(' . $GLOBALS['ip'] . ')';
196
197        return $trace;
198}
199
200/**
201 * Compter les inscrits a une liste
202 *
203 * @param string $liste
204 * @param string $statut
205 * @param int $id_segment
206 * @return array|int
207 */
208function mailsubscribers_compte_inscrits($liste, $statut = 'valide', $id_segment=0) {
209        static $count = null;
210
211        if (is_null($count) OR isset($GLOBALS['mailsubscribers_recompte_inscrits'])) {
212                $count = array();
213                $rows = sql_allfetsel('id_mailsubscribinglist,statut,id_segment,count(id_mailsubscriber) as n', 'spip_mailsubscriptions', '',
214                        'id_mailsubscribinglist,statut,id_segment');
215
216                // recuperer les correspondance id_mailsubscribinglist <=> identifiant
217                $ids = array_map('reset', $rows);
218                $listes = sql_allfetsel('id_mailsubscribinglist,identifiant', 'spip_mailsubscribinglists',
219                        sql_in('id_mailsubscribinglist', $ids));
220                $ids = array();
221                foreach ($listes as $l) {
222                        $ids[$l['id_mailsubscribinglist']] = $l['identifiant'];
223                }
224
225                foreach ($rows as $row) {
226                        $l = $ids[$row['id_mailsubscribinglist']];
227                        if (!isset($count[$l])) {
228                                $count[$l] = array();
229                        }
230                        if (!isset($count[$l][$row['statut']])) {
231                                $count[$l][$row['statut']] = array();
232                        }
233                        if (!isset($count[$l][$row['statut']][$row['id_segment']])) {
234                                $count[$l][$row['statut']][$row['id_segment']] = 0;
235                        }
236                        $count[$l][$row['statut']][$row['id_segment']] += $row['n'];
237                }
238
239                // pour le compte sans liste, on prends le statut des mailsubscribers
240                $rows = sql_allfetsel('statut,count(id_mailsubscriber) as n', 'spip_mailsubscribers', '', 'statut');
241                foreach ($rows as $row) {
242                        if (!isset($count[''][$row['statut']])) {
243                                $count[''][$row['statut']] = array(0=>0);
244                        }
245                        $count[''][$row['statut']][0] += $row['n'];
246                }
247                // sauf pour statut en attente : on compte tous les subscribers qui ont une inscription en attente
248                $count['']['prop'][0] = sql_getfetsel('count(DISTINCT id_mailsubscriber)','spip_mailsubscriptions', 'statut='.sql_quote('prop').' AND id_segment=0');
249
250        }
251
252        if ($statut == 'all') {
253                if (isset($count[$liste])) {
254                        return $count[$liste];
255                }
256
257                return array();
258        }
259        if (isset($count[$liste][$statut][$id_segment])) {
260                return $count[$liste][$statut][$id_segment];
261        }
262
263        return 0;
264}
265
266/**
267 * Trouver une fonction de synchronisation pour une liste donnee
268 * mailsubscribers_synchro_list_xxxx
269 *
270 * @param $liste
271 * @return mixed|string
272 */
273function mailsubscribers_trouver_fonction_synchro($liste) {
274        $f = mailsubscribers_normaliser_nom_liste($liste);
275        $f = 'newsletter_' . $f;
276        include_spip("public/parametrer"); // fichier mes_fonctions.php
277        if (function_exists($f = "mailsubscribers_synchro_list_$f")) {
278                return $f;
279        }
280
281        return "";
282}
283
284/**
285 * Informer un subscriber : ici juste l'url unsubscribe a calculer
286 *
287 * @param array $infos
288 * @return array mixed
289 */
290function mailsubscribers_informe_subscriber($infos) {
291        static $identifiants;
292        $infos['listes'] = array();
293        $infos['subscriptions'] = array();
294        if (isset($infos['id_mailsubscriber'])) {
295                $infos['status'] = 'off';
296                if (is_null($identifiants)) {
297                        $identifiants = array();
298                        $rows = sql_allfetsel('id_mailsubscribinglist,identifiant', 'spip_mailsubscribinglists');
299                        foreach ($rows as $row) {
300                                $identifiants[$row['id_mailsubscribinglist']] = $row['identifiant'];
301                        }
302                }
303                $subs = sql_allfetsel('id_mailsubscribinglist,statut', 'spip_mailsubscriptions', 'id_mailsubscriber=' . intval($infos['id_mailsubscriber']));
304                foreach ($subs as $sub) {
305                        if (isset($identifiants[$sub['id_mailsubscribinglist']])) {
306                                $id = $identifiants[$sub['id_mailsubscribinglist']];
307                                $status = 'off';
308                                if ($sub['statut'] == 'valide') {
309                                        $infos['listes'][] = $id;
310                                        $status = 'on';
311                                        $infos['status'] = 'on';
312                                } elseif (in_array($sub['statut'], array('prepa', 'prop'))) {
313                                        $status = 'pending';
314                                        if ($infos['status'] == 'off') {
315                                                $infos['status'] = 'pending';
316                                        }
317                                }
318                                $url_unsubscribe = mailsubscriber_url_unsubscribe($infos['email'], $infos['jeton'] . "+" . $sub['id_mailsubscribinglist']);
319                                $infos['subscriptions'][$id] = array(
320                                        'id' => $id,
321                                        'status' => $status,
322                                        'url_unsubscribe' => $url_unsubscribe
323                                );
324                        }
325                }
326                unset($infos['id_mailsubscriber']);
327        }
328
329        // URL unscubscribe generale (a toutes les inscriptions)
330        $infos['url_unsubscribe'] = mailsubscriber_url_unsubscribe($infos['email'], $infos['jeton']);
331
332        unset($infos['jeton']);
333
334        return $infos;
335}
336
337
338/**
339 * Recuperer la declaration des informations liees
340 * prend nativement en charge
341 *   - les champs extras sur mailsubscribers
342 *   - les mots cles associes aux mailsubscribers
343 * @pipeline mailsubscriber_informations_liees
344 * @return array
345 */
346function mailsubscriber_declarer_informations_liees() {
347        static $declaration;
348        if (is_null($declaration)){
349
350                $infos = array(
351                        'lang' => array(
352                                'titre' => $s = _T('mailsubscriber:label_lang'),
353                                /* Optionnel : utile si on veut uniquement afficher mais pas fournir de saisie pour les segments
354                                'valeurs' => array(
355                                        'id' => 'titre'
356                                ),
357                                */
358                          // declaration de la saisie de cette info pour la creation de segments
359                          'saisie' => 'selection',
360                          'options' => array(
361                                  'label' => $s,
362                                  'nom' => 'lang',
363                                  'datas' => array()
364                          ),
365                                'auto_field' => true, // internal : pour remplissage automatique a partir de la table
366                        )
367                );
368                // les valeurs des langues
369                $langues = $GLOBALS['meta']['langues_proposees'];
370                $langues = explode(',',$langues);
371                foreach ($langues as $langue){
372                        $infos['lang']['options']['datas'][$langue] = traduire_nom_langue($langue);
373                }
374
375                // des champs extras ?
376                if (test_plugin_actif('cextras')) {
377                        $saisies_tables = pipeline('declarer_champs_extras', array());
378                        if (isset($saisies_tables['spip_mailsubscribers'])) {
379                                foreach ($saisies_tables['spip_mailsubscribers'] as $saisie){
380                                        $champ = array(
381                                                'titre' => $saisie['options']['label'],
382                                                'saisie' => $saisie['saisie'],
383                                                'options' => $saisie['options'],
384                                                'auto_field' => true, // internal : pour remplissage automatique a partir de la table
385                                        );
386                                        $id = $saisie['options']['nom'];
387                                        $infos[$id] = $champ;
388                                }
389                        }
390                }
391
392                // des groupes de mots ?
393                $groupes = sql_allfetsel('*','spip_groupes_mots','tables_liees like '.sql_quote('%mailsubscribers%'));
394                foreach ($groupes as $groupe) {
395                        $infos['groupemots_'.$groupe['id_groupe']] = array(
396                                'titre' => $groupe['titre'],
397                                'saisie' => 'mot',
398                                'options' => array(
399                                        'id_groupe' => $groupe['id_groupe'],
400                                        'forcer_select' => 'oui',
401                                        'nom' => 'groupemots_'.$groupe['id_groupe'],
402                                        'label' => $groupe['titre'],
403                                        'class' => 'chosen',
404                                ),
405                                'auto_mot' => true, // internal : pour remplissage automatique a partir de liens mots-mailsubscribers
406                        );
407                }
408
409                // Appeler le pipeline avec declarer=true
410                // data contient une entree par type d'information, avec les entrees titre et valeurs
411                // + la declaration de saisies si option saisable pour la definition d'un segment de liste
412                $flux = array(
413                        'args' => array(
414                                'declarer' => true,
415                        ),
416                        'data' => $infos
417                );
418                $declaration = pipeline('mailsubscriber_informations_liees', $flux);
419        }
420        return $declaration;
421}
422
423/**
424 * Recuperer les informations liees a un subscriber, utiles pour la segmentation
425 * @pipeline mailsubscriber_informations_liees
426 * @param $id_mailsubscriber
427 * @param $email
428 * @return array|mixed|null
429 */
430function mailsubscriber_recuperer_informations_liees($id_mailsubscriber, $email){
431        $infos = array();
432        if ($declaration = mailsubscriber_declarer_informations_liees()) {
433
434                $row = null;
435                foreach ($declaration as $nom => $champ){
436                        if (isset($champ['auto_field']) and $champ['auto_field']){
437                                if (is_null($row)) {
438                                        $row = sql_fetsel('*','spip_mailsubscribers','id_mailsubscriber='.intval($id_mailsubscriber));
439                                }
440                                $infos[$nom] = $row[$nom];
441                        }
442                        elseif (isset($champ['auto_mot']) and $champ['auto_mot']
443                          and strncmp($nom,'groupemots_',11)==0
444                          and $id_groupe = $champ['options']['id_groupe']){
445                                $mots = sql_allfetsel('M.id_mot','spip_mots as M JOIN spip_mots_liens as L on L.id_mot=M.id_mot','L.objet='.sql_quote('mailsubscriber').' AND L.id_objet='.intval($id_mailsubscriber).' AND M.id_groupe='.intval($id_groupe));
446                                foreach($mots as $mot) {
447                                        if (!isset($flux['data'][$nom])){
448                                                $infos[$nom] = array();
449                                        }
450                                        $infos[$nom][] = $mot['id_mot'];
451                                }
452                        }
453                }
454
455                // Appeler avec la reference du subscriber
456                $flux = array(
457                        'args' => array(
458                                'email' => $email,
459                                'id_mailsubscriber' => $id_mailsubscriber
460                        ),
461                        'data' => $infos
462                );
463
464                $infos = pipeline('mailsubscriber_informations_liees', $flux);
465        }
466        return $infos;
467}
468
469/**
470 * Filtrer une liste a partir de sa category
471 *
472 * @param $liste
473 * @param string $category
474 * @return string
475 *   chaine vide si la liste n'est pas dans la category
476 *   nom de la liste sans le prefix de la category si ok
477 */
478function mailsubscribers_filtre_liste($liste, $category = "newsletter") {
479        if (strncmp($liste, "$category::", $l = strlen("$category::")) == 0) {
480                return substr($liste, $l);
481        }
482
483        return '';
484}
485
486/**
487 * Renvoi les listes de diffusion disponibles avec leur status
488 * (open,close,?)
489 *
490 * Les listes à la poubelles sont exclues sauf si on filtre par statut.
491 *
492 * @param array $options
493 *   status : filtrer les listes sur le status
494 *            (array|string) tableau ou liste de status séparés par des virgules
495 *            ouverte | fermee | poubelle
496 *   id : filtrer les listes selon leurs identifiants
497 *        (array|string) tableau ou liste d'identifiants séparés par des virgules
498 *   segments : fournir le detail des segments avec un identifant de la forme xxxx+nn
499 * @return array
500 *   array
501 *     id : identifiant
502 *     titre : titre de la liste
503 *     descriptif : descriptif de la liste
504 *     status : status de la liste
505 *     from_name : nom de l'envoyeur (optionnel)
506 *     from_email : nom de l'envoyeur (optionnel)
507 */
508function mailsubscribers_listes($options = array()) {
509        // option : filtrer par statut
510        $filtrer_status = array();
511        if (!empty($options['status'])) {
512                $filtrer_status = is_array($options['status']) ? $options['status'] : explode(',', $options['status']);
513                // pour compatibilité descendante
514                foreach ($filtrer_status as $k => $status){
515                        if ($status == 'open') {
516                                $filtrer_status[$k] = 'ouverte';
517                        }
518                        if ($status == 'close') {
519                                $filtrer_status[$k] = 'fermee';
520                        }
521                }
522        }
523        // option : filtrer par identifiant
524        $filtrer_id = array();
525        if (!empty($options['id'])) {
526                $filtrer_id = is_array($options['id']) ? $options['id'] : explode(',', $options['id']);
527        }
528
529        $where = array();
530        if ($filtrer_status) {
531                $where[] = sql_in('statut', $filtrer_status);
532        } else {
533                $where[] = 'statut != ' . sql_quote('poubelle');
534        }
535        if ($filtrer_id) {
536                $where[] = sql_in('identifiant', $filtrer_id);
537        }
538        $rows = sql_allfetsel('identifiant as id,titre,descriptif,statut as status,adresse_envoi_nom as from_name,adresse_envoi_email as from_email,segments', 'spip_mailsubscribinglists', $where, '',
539                'statut DESC,0+titre,titre');
540        $listes = array();
541        foreach ($rows as $row) {
542                $segments = $row['segments'];
543                unset($row['segments']);
544                if ($row['status'] == 'ouverte') {
545                        $row['status'] = 'open';
546                }
547                if ($row['status'] == 'fermee') {
548                        $row['status'] = 'close';
549                }
550                $listes[$row['id']] = $row;
551                if (isset($options['segments']) AND $options['segments']){
552                        $segments = unserialize($segments);
553                        if ($segments AND count($segments)){
554                                $id = $row['id'];
555                                $t = $row['titre'];
556                                foreach ($segments as $id_segment=>$segment){
557                                        $row['id'] = $id . '+' . $id_segment;
558                                        $row['titre'] = '&nbsp;— '.$t . ' > ' . $segment['titre'];
559                                        $listes[$row['id']] = $row;
560                                }
561                        }
562                }
563        }
564
565        return $listes;
566}
567
568
569/**
570 * Lance la synchro avec une liste en appelant la fonction
571 * mailsubscribers_synchro_list_xxxx pour la liste des abonnes
572 * puis la fonction de synchronisation
573 *
574 * @param $liste
575 */
576function mailsubscribers_do_synchro_list($liste) {
577        if ($f = mailsubscribers_trouver_fonction_synchro($liste)) {
578                $abonnes = $f();
579                if (is_array($abonnes)
580                        AND (!count($abonnes) OR ($r = reset($abonnes) AND isset($r['email'])))
581                ) {
582                        $n = count($abonnes);
583                        spip_log("Synchronise liste $liste avec $n abonnes (fonction $f)", "mailsubscribers");
584                        if (!mailsubscribers_synchronise_liste($liste, $abonnes)) {
585                                job_queue_add(
586                                        "mailsubscribers_do_synchro_list",
587                                        "Synchro liste (poursuivre) " . $liste,
588                                        array($liste),
589                                        "inc/mailsubscribers"
590                                );
591                        }
592                } else {
593                        spip_log("Synchronise liste $liste : abonnes mal formes en retour de la fonction $f",
594                                "mailsubscribers" . _LOG_ERREUR);
595                }
596        }
597}
598
599
600/**
601 * Retourner la liste des abonnes qu'on veut voir dans la liste newsletter::0minirezo
602 *
603 * @return array
604 */
605function mailsubscribers_synchro_list_newsletter_0minirezo() {
606        $auteurs = sql_allfetsel("email,nom", "spip_auteurs", "statut=" . sql_quote("0minirezo"));
607
608        return $auteurs;
609}
610
611/**
612 * Retourner la liste des abonnes qu'on veut voir dans la liste newsletter::1comite
613 *
614 * @return array
615 */
616function mailsubscribers_synchro_list_newsletter_1comite() {
617        $auteurs = sql_allfetsel("email,nom", "spip_auteurs", "statut=" . sql_quote("1comite"));
618
619        return $auteurs;
620}
621
622/**
623 * Retourner la liste des abonnes qu'on veut voir dans la liste newsletter::6forum
624 *
625 * @return array
626 */
627function mailsubscribers_synchro_list_newsletter_6forum() {
628        $auteurs = sql_allfetsel("email,nom", "spip_auteurs", "statut=" . sql_quote("6forum"));
629
630        return $auteurs;
631}
632
633
634/**
635 * Synchroniser les abonnes d'une liste en base avec un tableau fourni
636 * TODO : permettre de fournir une resource SQL en entree et ne pas manipuler de gros tableau en memoire (robustesse)
637 *
638 * @param string $liste
639 *   liste avec laquelle on synchronise les abonnes
640 * @param array $abonnes
641 *   chaque abonne est un tableau avec l'entree 'email' et les entrees optionnelles 'nom' et 'prenom'
642 * @param array $options
643 *   bool addonly : pour ajouter uniquement les nouveaux abonnes, et ne desabonner personne
644 *   bool graceful : pour ne pas reabonner ceux qui se sont desabonnes manuellement
645 * @return bool
646 *   - true : indique que la synchronisation s’est terminée (ou qu’il n’y avait rien à faire)
647 *   - false : indique que la synchronisation ne s’est pas terminée à cause d’un timeout proche
648 */
649function mailsubscribers_synchronise_liste($liste, $abonnes, $options = array()) {
650        $listes = array($liste);
651        $id_mailsubscribinglist = sql_getfetsel('id_mailsubscribinglist', 'spip_mailsubscribinglists',
652                'identifiant=' . sql_quote($liste));
653        if (!$id_mailsubscribinglist) {
654                spip_log("Mailing liste $liste introuvable pour synchro", 'mailsubscribers');
655                return true;
656        }
657
658        $timeout = ini_get('max_execution_time');
659        // valeur conservatrice si on a pas reussi a lire le max_execution_time
660        if (!$timeout) {
661                $timeout = 30;
662        } // parions sur une valeur tellement courante ...
663        $max_time = time() + $timeout / 2;
664
665        if (is_bool($options)) {
666                $options = array('addonly' => $options);
667        }
668        $options = array_merge(array('addonly' => false, 'graceful' => true), $options);
669
670        $abonnes_emails = array();
671        while (count($abonnes)) {
672                $abonne = array_shift($abonnes);
673                if (isset($abonne['email'])
674                        AND strlen($e = trim($abonne['email']))
675                ) {
676                        $abonnes_emails[$e] = $abonne;
677                }
678        }
679
680        $subscribe = charger_fonction('subscribe', 'newsletter');
681        $unsubscribe = charger_fonction('unsubscribe', 'newsletter');
682
683        // d'abord on prend la liste de tous les abonnes en base
684        // -> on retire du tableau $abonnes ceux qui le sont deja
685        // -> on desabonne ceux qui ne sont plus dans le tableau $abonnes
686        $subs = sql_allfetsel('S.email',
687                'spip_mailsubscribers as S JOIN spip_mailsubscriptions as L ON S.id_mailsubscriber=L.id_mailsubscriber',
688                'L.id_mailsubscribinglist=' . intval($id_mailsubscribinglist) . ' AND L.id_segment=0 AND L.statut=' . sql_quote('valide'));
689        spip_log("mailsubscribers_synchronise_liste $liste: " . count($subs) . " abonnes deja dans la liste",
690                "mailsubscribers" . _LOG_DEBUG);
691        $i=0;
692        foreach ($subs as $sub) {
693                // OK il est toujours dans les abonnes
694                if (isset($abonnes_emails[$sub['email']])) {
695                        unset($abonnes_emails[$sub['email']]);
696                } // il n'est plus dans les abonnes on l'enleve sauf si flag $addonly==true
697                elseif (!$options['addonly']) {
698                        //echo "unsubscribe ".$sub['email']."<br />";
699                        $unsubscribe($sub['email'], array('listes' => $listes, 'notify' => false, 'remove' => true));
700                        $i++;
701                }
702                if (time() >= $max_time) {
703                        spip_log("mailsubscribers_synchronise_liste $liste: $i desabonnes de la liste mais temps ecoule", "mailsubscribers" . _LOG_DEBUG);
704                        return false;
705                }
706        }
707        spip_log("mailsubscribers_synchronise_liste $liste: $i desabonnes de la liste", "mailsubscribers" . _LOG_DEBUG);
708        unset($subs);
709
710        // on enleve de la liste ceux qui ont deja ete abonnes dans le passe mais se sont desinscrit car on ne les reabonnera pas
711        $obfusques = array_keys($abonnes_emails);
712        $obfusques = array_combine(array_map('mailsubscribers_obfusquer_email', $obfusques), $obfusques);
713        $unsubs = sql_allfetsel('S.email',
714                'spip_mailsubscribers as S JOIN spip_mailsubscriptions as L ON S.id_mailsubscriber=L.id_mailsubscriber',
715                'L.id_mailsubscribinglist=' . intval($id_mailsubscribinglist) . ' AND L.id_segment=0 AND L.statut=' . sql_quote('refuse') . ' AND ' . sql_in('S.email', array_merge(array_keys($obfusques), array_values($obfusques))));
716        spip_log("mailsubscribers_synchronise_liste $liste: " . count($unsubs) . " ne veulent pas etre reabonnes a la liste", "mailsubscribers" . _LOG_DEBUG);
717        foreach ($unsubs as $unsub) {
718                if (isset($abonnes_emails[$unsub['email']])) {
719                        unset($abonnes_emails[$unsub['email']]);
720                }
721                elseif (isset($obfusques[$unsub['email']]) and isset($abonnes_emails[$obfusques[$unsub['email']]])) {
722                        unset($abonnes_emails[$obfusques[$unsub['email']]]);
723                }
724        }
725
726        spip_log("mailsubscribers_synchronise_liste $liste: " . count($abonnes_emails) . " a abonner dans la liste", "mailsubscribers" . _LOG_DEBUG);
727        // si il reste du monde dans $abonnes, c'est ceux qui ne sont pas en base
728        // on les subscribe
729        $i=0;
730        foreach ($abonnes_emails as $email => $abonne) {
731                //echo "subscribe ".$email."<br />";
732                $nom = (isset($abonne['nom']) ? $abonne['nom'] . ' ' : '');
733                $nom .= (isset($abonne['prenom']) ? $abonne['prenom'] . ' ' : '');
734                $data_subscriber = array(
735                        'nom' => trim($nom),
736                        'listes' => $listes,
737                        'force' => true,
738                        'notify' => false,
739                        'graceful' => $options['graceful'],
740                );
741                if (isset($abonne['lang'])) {
742                        $data_subscriber['lang'] = $abonne['lang'];
743                }
744                $subscribe($email, $data_subscriber);
745                $i++;
746                if (time() >= $max_time) {
747                        spip_log("mailsubscribers_synchronise_liste $liste: $i/".count($abonnes_emails)." abonnes mais temps ecoule", 'mailsubscribers' . _LOG_DEBUG);
748                        return false;
749                }
750        }
751
752        // baisser les drapeaux edition de tout ce qu'on vient de faire
753        if (function_exists('debloquer_tous')) {
754                $id_a = (isset($GLOBALS['visiteur_session']['id_auteur']) ? $GLOBALS['visiteur_session']['id_auteur'] : $GLOBALS['ip']);
755                debloquer_tous($id_a);
756        }
757
758        return true;
759}
Note: See TracBrowser for help on using the repository browser.