source: spip-zone/_plugins_/abonnements/trunk/inc/abonnements.php @ 121564

Last change on this file since 121564 was 121564, checked in by rastapopoulos@…, 14 months ago

Permettre de forcer le rechargement de l'info, même si déjà calculé plus tôt dans la static

File size: 10.6 KB
Line 
1<?php
2/**
3 * Plugin Abonnements
4 * (c) 2012 Les Développements Durables
5 * Licence GNU/GPL v3
6 */
7
8if (!defined('_ECRIRE_INC_VERSION')) return;
9
10/**
11 * Créer ou renouveler un abonnement
12 *
13 * Si l'utilisateur n'a rien de cette offre, on crée un nouvel abonnement.
14 * Si l'utilisateur a toujours ou avait précédemment un abonnement de cette offre, on le renouvelle.
15 *
16 * On s'assure d'avoir les droits pendant les modifs
17 * car ce n'est pas un humain avec des droits qui déclanche ça explicitement
18 *
19 * @param int $id_auteur
20 *              Identifiant de l'utilisateur pour lequel on veut créer un abonnement
21 * @param int $id_abonnements_offre
22 *              Identifiant de l'offre d'abonnement voulue
23 * @param bool $forcer_creation
24 *              `true` si on veut forcer la création sans chercher à renouveler
25 * @return mixed
26 */
27function abonnements_creer_ou_renouveler($id_auteur, $id_abonnements_offre, $forcer_creation=false) {
28        // Si on a bien un auteur et une offre
29        if (
30                ($id_auteur = intval($id_auteur)) > 0
31                and ($id_abonnements_offre = intval($id_abonnements_offre)) > 0
32        ) {
33                include_spip('inc/config');
34                include_spip('inc/autoriser');
35               
36                // On cherche la durée limite pour renouveler un abonnement
37                $heures_limite = lire_config('abonnements/renouvellement_heures_limite', 48);
38               
39                // Si on trouve un abonnement de cette offre (le dernier en date)
40                // et qu'il n'est pas trop vieux, ou sans de date de fin
41                // et qu'on a pas forcé la création…
42                if (
43                        !$forcer_creation
44                        and $abonnement = sql_fetsel(
45                                'id_abonnement, date_fin',
46                                'spip_abonnements',
47                                array(
48                                        'id_auteur = '.$id_auteur,
49                                        'id_abonnements_offre = '.$id_abonnements_offre,
50                                        'statut != "poubelle"'
51                                ),
52                                '',
53                                'statut asc, maj desc',
54                                '0,1'
55                        )
56                        and (
57                                $abonnement['date_fin'] >= date('Y-m-d H:i:s', strtotime('- '.$heures_limite.' hours'))
58                                or $abonnement['date_fin'] == '0000-00-00 00:00:00'
59                        )
60                        and $id_abonnement = intval($abonnement['id_abonnement'])
61                ) {
62                        autoriser_exception('modifier', 'abonnement', $id_abonnement, true);
63                        // On le renouvelle !
64                        $renouveler = charger_fonction('renouveler_abonnement', 'action/');
65                        $retour = $renouveler($id_abonnement);
66                        autoriser_exception('modifier', 'abonnement', $id_abonnement, false);
67                        return $retour;
68                }
69                // Sinon on en crée un nouveau
70                else {
71                        include_spip('action/editer_objet');
72                        autoriser_exception('creer', 'abonnement', '', true);
73                        if ($id_abonnement = objet_inserer('abonnement')) {
74                                autoriser_exception('creer', 'abonnement', '', false);
75                                autoriser_exception('modifier', 'abonnement', $id_abonnement, true);
76                                $erreur = objet_modifier(
77                                        'abonnement', $id_abonnement,
78                                        array(
79                                                'id_auteur' => $id_auteur,
80                                                'id_abonnements_offre' => $id_abonnements_offre,
81                                        )
82                                );
83                                autoriser_exception('modifier', 'abonnement', $id_abonnement, false);
84                                return array($id_abonnement, $erreur);
85                        }
86                }
87        }
88       
89        return false;
90}
91
92/**
93 * Initialiser les dates d'échéance et de fin pour un abonnement créé
94 *
95 * @pipeline_appel abonnement_initialisation_dates
96 * @param array $abonnement
97 *              Informations sur l'abonnement à initialiser
98 * @param array $offre
99 *              Informations sur l'offre de l'abonnement à initialiser
100 * @return array
101 *              Retourne les modifications de dates initialisées
102 **/
103function abonnements_initialisation_dates($abonnement, $offre){
104        $modifs = array();
105       
106        // De combien doit-on augmenter la date
107        $duree = $offre['duree'];
108        switch ($offre['periode']){
109                case 'heures':
110                        $ajout = " + ${duree} hours";
111                        break;
112                case 'jours':
113                        $ajout = " + ${duree} days";
114                        break;
115                case 'mois':
116                        $ajout = " + ${duree} months";
117                        break;
118                default:
119                        $ajout = '';
120                        break;
121        }
122       
123        // Par défaut les dates de fin et de la prochaine échéance sont les mêmes
124        $modifs['date_echeance'] = date('Y-m-d H:i:s', strtotime($abonnement['date_debut'].$ajout));
125        $modifs['date_fin'] = $modifs['date_echeance'];
126       
127        // Mais si c'est un renouvellement auto avec Commandes et Bank
128        if ($date_fin = abonnements_bank_date_fin($abonnement['id_abonnement'])) {
129                $modifs['date_fin'] = $date_fin;
130        }
131       
132        $modifs = pipeline(
133                'abonnement_initialisation_dates',
134                array(
135                        'args' => array('abonnement' => $abonnement, 'offre' => $offre),
136                        'data' => $modifs
137                )
138        );
139       
140        return $modifs;
141}
142
143/**
144 * Trouver la date de fin d'un renouvellement automatique éventuel
145 *
146 * @param int $id_abonnement
147 *              Identifiant de l'abonnement dont on veut trouver la date de fin
148 * @param int $id_commande
149 *              Possibilité de donner la commande pour éviter une requête SQL
150 * @return bool|datetime
151 *              Retourne la date de fin du renouvellement si on trouve, sinon false pour ne rien faire
152 **/
153function abonnements_bank_date_fin($id_abonnement, $id_commande=0){
154        $date_fin = false;
155       
156        // On teste si on trouve un renouvellement auto
157        if (
158                defined('_DIR_PLUGIN_COMMANDES')
159                and defined('_DIR_PLUGIN_BANK')
160                and (
161                        // Soit on a déjà une commande sous la main
162                        (
163                                $id_commande = intval($id_commande)
164                                and $id_commande > 0
165                        )
166                        // Soit on va chercher une commande liée à l'abonnement
167                        or
168                        (
169                                include_spip('action/editer_liens')
170                                and $lien_commande = objet_trouver_liens(array('commande' => '*'), array('abonnement' => $id_abonnement))
171                                and is_array($lien_commande)
172                                // On prend juste la première commande qu'on trouve
173                                and $id_commande = intval($lien_commande[0]['id_commande'])
174                        )
175                )
176                // On cherche un paiement bien payé pour cette commande
177                and $transaction = sql_fetsel(
178                        '*', 'spip_transactions', array('id_commande = '.$id_commande, 'statut = "ok"')
179                )
180                // Et que c'est un renouvellement auto !
181                and $transaction['abo_uid']
182        ) {
183                // On a trouvé la transaction qui a activé la commande qui a activé l'abonnement
184                // Si on détecte un prélèvement SEPA, on annule la date de fin !
185                if ($refcb = $transaction['refcb'] and strpos($refcb, 'SEPA') === 0) {
186                        $date_fin = '0000-00-00 00:00:00';
187                }
188                // Si ya une fin de validité de carte bleue on en déduit une fin d'abonnement !
189                elseif ($validite = $transaction['validite']) {
190                        include_spip('inc/bank');
191                        list($year, $month) = explode('-', $validite);
192                        $date_fin = bank_date_fin_mois($year, $month);
193                }
194        }
195       
196        return $date_fin;
197}
198
199/*
200 * Programmer la désactivation d'un abonnement lors de sa date de fin
201 *
202 * @param int $id_abonnement
203 *      L'identifiant de l'abonnement
204 * @param datetime $date_fin
205 *      Optionnellement la date de fin si on la connait déjà, ce qui évite une requête
206 */
207function abonnements_programmer_desactivation($id_abonnement, $date_fin=null){
208        include_spip('action/editer_liens');
209        $id_abonnement = intval($id_abonnement);
210       
211        // Si on a pas de date, on va chercher
212        if (!$date_fin){
213                $date_fin = sql_getfetsel('date_fin', 'spip_abonnements', 'id_abonnement = '.$id_abonnement);
214        }
215       
216        // Dans tous les cas on cherche s'il y des tâches liées à cet abonnement
217        $liens = objet_trouver_liens(array('job' => '*'), array('abonnement' => $id_abonnement));
218        if ($liens and is_array($liens)){
219                // Et on les supprime toutes !
220                foreach ($liens as $lien){
221                        job_queue_remove($lien['id_job']);
222                }
223        }
224       
225        // Seulement si on a bien une date de fin, on reprogramme, sans duplication possible
226        if ($date_fin and $date_fin != '0000-00-00 00:00:00'){
227                $id_job = job_queue_add(
228                        'abonnements_desactiver',
229                        _T('abonnement:job_desactivation', array('id'=>$id_abonnement)),
230                        array($id_abonnement),
231                        'inc/abonnements',
232                        true,
233                        strtotime($date_fin)
234                );
235                job_queue_link($id_job, array('objet'=>'abonnement', 'id_objet'=>$id_abonnement));
236        }
237}
238
239/*
240 * Désactiver un abonnement en utilisant l'API et sans autorisation
241 */
242function abonnements_desactiver($id_abonnement){
243        include_spip('inc/autoriser');
244        include_spip('action/editer_objet');
245        // On inhibe les autorisations
246        autoriser_exception('modifier', 'abonnement', $id_abonnement);
247        autoriser_exception('instituer', 'abonnement', $id_abonnement);
248        // On désactive l'abonnement
249        objet_modifier('abonnement', $id_abonnement, array('statut' => 'inactif'));
250        // On remet les autorisations
251        autoriser_exception('instituer', 'abonnement', $id_abonnement, false);
252        autoriser_exception('modifier', 'abonnement', $id_abonnement, false);
253}
254
255/**
256 * Envoyer un courriel à l'abonné pour lui rappeler une échéance.
257 *
258 * @example
259 * Échéances dans 15 jours, il y a 1 mois, et le jour même :
260 * ````
261 * abonnements_notifier_echeance(1, 'untel', 'x@email.ltd', 15, 'jours', 'avant');
262 * abonnements_notifier_echeance(1, 'untel', 'x@email.ltd', 1, 'mois', 'apres');
263 * abonnements_notifier_echeance(1, 'untel', 'x@email.ltd', 0, 'jours', 'pendant');
264 * ````
265 *
266 * @param int $id_abonnement
267 *     Numéro de l'abonnement
268 * @param string $nom
269 *     Nom de la personne à notifier
270 * @param string $email
271 *     Email de la personne à notifier
272 * @param int $duree
273 *     Durée de l'échéance
274 * @param string $periode
275 *     Période de l'échéance : `jours` | `mois`
276 * @param string $quand
277 *     Indique si on est avant, après, ou le jour même de l'échéance
278 *     - `avant`   : on est avant la fin de l'abonnement (par défaut pour rétro compat)
279 *     - `après`   : on est après la fin de l'abonnement
280 *     - `pendant` : on est le jour même de la fin de l'abonnement
281 * @return void
282 */
283function abonnements_notifier_echeance($id_abonnement, $nom, $email, $duree, $periode, $quand = 'avant'){
284        // Assurons nous que le "quand" est cohérent
285        if ($duree === 0){
286                $quand = 'pendant';
287        }
288        $quoi    = 'abonnement_echeance';
289        $options = array(
290                'email'   => $email,
291                'nom'     => $nom,
292                'email'   => $email,
293                'duree'   => $duree,
294                'periode' => $periode,
295                'quand'   => $quand,
296        );
297        $notifications = charger_fonction('notifications', 'inc');
298        $notifications($quoi, $id_abonnement, $options);
299}
300
301/**
302 * Lister tous les abonnements d'un utilisateur, classés par statut
303 *
304 * @param int $id_auteur
305 *     Identifiant de l'utilisateur dont on cherche les abonnements
306 * @return array
307 *     Tableau des abonnements, rangés dans une clé pour chaque statut
308 */
309function abonnements_auteur_lister($id_auteur, $forcer=false) {
310        static $abonnements_auteurs = array();
311        $id_auteur = intval($id_auteur);
312       
313        if ($forcer or is_null($abonnements_auteurs[$id_auteur])) {
314                $abonnements_auteurs[$id_auteur] = array();
315               
316                if ($abonnements = sql_allfetsel('*', 'spip_abonnements', 'id_auteur ='.$id_auteur)) {
317                        foreach($abonnements as $abonnement) {
318                                $statut = $abonnement['statut'];
319                               
320                                // Initialiser pour ce statut
321                                if (!isset($abonnements_auteurs[$id_auteur][$statut])) {
322                                        $abonnements_auteurs[$id_auteur][$statut] = array();
323                                }
324                               
325                                // Ajouter l'abonnement à ce statut
326                                $abonnements_auteurs[$id_auteur][$statut][] = $abonnement;
327                        }
328                }
329        }
330       
331        return $abonnements_auteurs[$id_auteur];
332}
Note: See TracBrowser for help on using the repository browser.