1 | <?php |
---|
2 | /** |
---|
3 | * Plugin Abonnements |
---|
4 | * (c) 2012 Les Développements Durables |
---|
5 | * Licence GNU/GPL v3 |
---|
6 | */ |
---|
7 | |
---|
8 | if (!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 | */ |
---|
27 | function 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 | **/ |
---|
103 | function 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 | **/ |
---|
153 | function 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 | */ |
---|
207 | function 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 | */ |
---|
242 | function 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 | */ |
---|
283 | function 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 | */ |
---|
309 | function abonnements_auteur_lister($id_auteur) { |
---|
310 | static $abonnements_auteurs = array(); |
---|
311 | $id_auteur = intval($id_auteur); |
---|
312 | |
---|
313 | if (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 | } |
---|