You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

343 lines
11 KiB

<?php
/**
* Plugin Abonnements
* (c) 2012 Les Développements Durables
* Licence GNU/GPL v3
*/
if (!defined('_ECRIRE_INC_VERSION')) return;
/**
* Créer ou renouveler un abonnement
*
* Si l'utilisateur n'a rien de cette offre, on crée un nouvel abonnement.
* Si l'utilisateur a toujours ou avait précédemment un abonnement de cette offre, on le renouvelle.
*
* On s'assure d'avoir les droits pendant les modifs
* car ce n'est pas un humain avec des droits qui déclanche ça explicitement
*
* @param int $id_auteur
* Identifiant de l'utilisateur pour lequel on veut créer un abonnement
* @param int $id_abonnements_offre
* Identifiant de l'offre d'abonnement voulue
* @param bool $forcer_creation
* `true` si on veut forcer la création sans chercher à renouveler
* @return mixed
*/
function abonnements_creer_ou_renouveler($id_auteur, $id_abonnements_offre, $forcer_creation=false) {
// Si on a bien un auteur et une offre
if (
($id_auteur = intval($id_auteur)) > 0
and ($id_abonnements_offre = intval($id_abonnements_offre)) > 0
) {
include_spip('inc/config');
include_spip('inc/autoriser');
// On cherche la durée limite pour renouveler un abonnement
$heures_limite = lire_config('abonnements/renouvellement_heures_limite', 48);
// Si on trouve un abonnement de cette offre (le dernier en date)
// et qu'il n'est pas trop vieux, ou sans de date de fin
// et qu'on a pas forcé la création…
if (
!$forcer_creation
and $abonnement = sql_fetsel(
'id_abonnement, date_fin',
'spip_abonnements',
array(
'id_auteur = '.$id_auteur,
'id_abonnements_offre = '.$id_abonnements_offre,
'statut != "poubelle"'
),
'',
'statut asc, maj desc',
'0,1'
)
and (
$abonnement['date_fin'] >= date('Y-m-d H:i:s', strtotime('- '.$heures_limite.' hours'))
or $abonnement['date_fin'] == '0000-00-00 00:00:00'
)
and $id_abonnement = intval($abonnement['id_abonnement'])
) {
autoriser_exception('modifier', 'abonnement', $id_abonnement, true);
// On le renouvelle !
$renouveler = charger_fonction('renouveler_abonnement', 'action/');
$retour = $renouveler($id_abonnement);
autoriser_exception('modifier', 'abonnement', $id_abonnement, false);
return $retour;
}
// Sinon on en crée un nouveau
else {
include_spip('action/editer_objet');
autoriser_exception('creer', 'abonnement', '', true);
if ($id_abonnement = objet_inserer('abonnement')) {
autoriser_exception('creer', 'abonnement', '', false);
autoriser_exception('modifier', 'abonnement', $id_abonnement, true);
$erreur = objet_modifier(
'abonnement', $id_abonnement,
array(
'id_auteur' => $id_auteur,
'id_abonnements_offre' => $id_abonnements_offre,
)
);
autoriser_exception('modifier', 'abonnement', $id_abonnement, false);
return array($id_abonnement, $erreur);
}
}
}
return false;
}
/**
* Initialiser les dates d'échéance et de fin pour un abonnement créé
*
* @pipeline_appel abonnement_initialisation_dates
* @param array $abonnement
* Informations sur l'abonnement à initialiser
* @param array $offre
* Informations sur l'offre de l'abonnement à initialiser
* @return array
* Retourne les modifications de dates initialisées
**/
function abonnements_initialisation_dates($abonnement, $offre){
$modifs = array();
// De combien doit-on augmenter la date
$duree = $offre['duree'];
switch ($offre['periode']){
case 'heures':
$ajout = " + ${duree} hours";
break;
case 'jours':
$ajout = " + ${duree} days";
break;
case 'mois':
$ajout = " + ${duree} months";
break;
default:
$ajout = '';
break;
}
// S'il n'y a pas eu de date de début déjà forcée à la création, alors on démarre l'abonnement maintenant
if ($abonnement['date_debut'] == '0000-00-00 00:00:00') {
$modifs['date_debut'] = $abonnement['date_debut'] = date('Y-m-d H:i:s');
}
// Par défaut les dates de fin et de la prochaine échéance sont les mêmes
$modifs['date_echeance'] = date('Y-m-d H:i:s', strtotime($abonnement['date_debut'].$ajout));
$modifs['date_fin'] = $modifs['date_echeance'];
// Mais si c'est un renouvellement auto avec Commandes et Bank
if ($date_fin = abonnements_bank_date_fin($abonnement['id_abonnement'])) {
$modifs['date_fin'] = $date_fin;
}
$modifs = pipeline(
'abonnement_initialisation_dates',
array(
'args' => array('abonnement' => $abonnement, 'offre' => $offre),
'data' => $modifs
)
);
return $modifs;
}
/**
* Trouver la date de fin d'un renouvellement automatique éventuel
*
* @param int $id_abonnement
* Identifiant de l'abonnement dont on veut trouver la date de fin
* @param int $id_commande
* Possibilité de donner la commande pour éviter une requête SQL
* @return bool|datetime
* Retourne la date de fin du renouvellement si on trouve, sinon false pour ne rien faire
**/
function abonnements_bank_date_fin($id_abonnement, $id_commande=0){
$date_fin = false;
// On teste si on trouve un renouvellement auto
if (
defined('_DIR_PLUGIN_COMMANDES')
and defined('_DIR_PLUGIN_BANK')
and (
// Soit on a déjà une commande sous la main
(
$id_commande = intval($id_commande)
and $id_commande > 0
)
// Soit on va chercher une commande liée à l'abonnement
or
(
include_spip('action/editer_liens')
and $lien_commande = objet_trouver_liens(array('commande' => '*'), array('abonnement' => $id_abonnement))
and is_array($lien_commande)
// On prend juste la première commande qu'on trouve
and $id_commande = intval($lien_commande[0]['id_commande'])
)
)
// On cherche un paiement bien payé pour cette commande
and $transaction = sql_fetsel(
'*', 'spip_transactions', array('id_commande = '.$id_commande, 'statut = "ok"')
)
// Et que c'est un renouvellement auto !
and $transaction['abo_uid']
) {
// On a trouvé la transaction qui a activé la commande qui a activé l'abonnement
// Si on détecte un prélèvement SEPA, on annule la date de fin !
if ($refcb = $transaction['refcb'] and strpos($refcb, 'SEPA') === 0) {
$date_fin = '0000-00-00 00:00:00';
}
// Si ya une fin de validité de carte bleue on en déduit une fin d'abonnement !
elseif ($validite = $transaction['validite']) {
include_spip('inc/bank');
list($year, $month) = explode('-', $validite);
$date_fin = bank_date_fin_mois($year, $month);
}
}
return $date_fin;
}
/*
* Programmer la désactivation d'un abonnement lors de sa date de fin
*
* @param int $id_abonnement
* L'identifiant de l'abonnement
* @param datetime $date_fin
* Optionnellement la date de fin si on la connait déjà, ce qui évite une requête
*/
function abonnements_programmer_desactivation($id_abonnement, $date_fin=null){
include_spip('action/editer_liens');
$id_abonnement = intval($id_abonnement);
// Si on a pas de date, on va chercher
if (!$date_fin){
$date_fin = sql_getfetsel('date_fin', 'spip_abonnements', 'id_abonnement = '.$id_abonnement);
}
// Dans tous les cas on cherche s'il y des tâches liées à cet abonnement
$liens = objet_trouver_liens(array('job' => '*'), array('abonnement' => $id_abonnement));
if ($liens and is_array($liens)){
// Et on les supprime toutes !
foreach ($liens as $lien){
job_queue_remove($lien['id_job']);
}
}
// Seulement si on a bien une date de fin, on reprogramme, sans duplication possible
if ($date_fin and $date_fin != '0000-00-00 00:00:00'){
$id_job = job_queue_add(
'abonnements_desactiver',
_T('abonnement:job_desactivation', array('id'=>$id_abonnement)),
array($id_abonnement),
'inc/abonnements',
true,
strtotime($date_fin)
);
job_queue_link($id_job, array('objet'=>'abonnement', 'id_objet'=>$id_abonnement));
}
}
/*
* Désactiver un abonnement en utilisant l'API et sans autorisation
*/
function abonnements_desactiver($id_abonnement){
include_spip('inc/autoriser');
include_spip('action/editer_objet');
// On inhibe les autorisations
autoriser_exception('modifier', 'abonnement', $id_abonnement);
autoriser_exception('instituer', 'abonnement', $id_abonnement);
// On désactive l'abonnement
objet_modifier('abonnement', $id_abonnement, array('statut' => 'inactif'));
// On remet les autorisations
autoriser_exception('instituer', 'abonnement', $id_abonnement, false);
autoriser_exception('modifier', 'abonnement', $id_abonnement, false);
}
/**
* Envoyer un courriel à l'abonné pour lui rappeler une échéance.
*
* @example
* Échéances dans 15 jours, il y a 1 mois, et le jour même :
* ````
* abonnements_notifier_echeance(1, 'untel', 'x@email.ltd', 15, 'jours', 'avant');
* abonnements_notifier_echeance(1, 'untel', 'x@email.ltd', 1, 'mois', 'apres');
* abonnements_notifier_echeance(1, 'untel', 'x@email.ltd', 0, 'jours', 'pendant');
* ````
*
* @param int $id_abonnement
* Numéro de l'abonnement
* @param string $nom
* Nom de la personne à notifier
* @param string $email
* Email de la personne à notifier
* @param int $duree
* Durée de l'échéance
* @param string $periode
* Période de l'échéance : `jours` | `mois`
* @param string $quand
* Indique si on est avant, après, ou le jour même de l'échéance
* - `avant` : on est avant la fin de l'abonnement (par défaut pour rétro compat)
* - `après` : on est après la fin de l'abonnement
* - `pendant` : on est le jour même de la fin de l'abonnement
* @return void
*/
function abonnements_notifier_echeance($id_abonnement, $nom, $email, $duree, $periode, $quand = 'avant'){
// Assurons nous que le "quand" est cohérent
if ($duree === 0){
$quand = 'pendant';
}
$quoi = 'abonnement_echeance';
// envoyer la notif dans la langue de l'auteur, ou sinon dans la langue du site.
$langue = ($id_auteur = sql_getfetsel('id_auteur', 'spip_abonnements', 'id_abonnement=' . $id_abonnement) and $langue_auteur = sql_getfetsel('lang', 'spip_auteurs', 'id_auteur=' . $id_auteur)) ? $langue_auteur : $GLOBALS['meta']['langue_site'] ;
$options = array(
'email' => $email,
'nom' => $nom,
'email' => $email,
'duree' => $duree,
'periode' => $periode,
'quand' => $quand,
'lang' => $langue,
);
$notifications = charger_fonction('notifications', 'inc');
$notifications($quoi, $id_abonnement, $options);
}
/**
* Lister tous les abonnements d'un utilisateur, classés par statut
*
* @param int $id_auteur
* Identifiant de l'utilisateur dont on cherche les abonnements
* @return array
* Tableau des abonnements, rangés dans une clé pour chaque statut
*/
function abonnements_auteur_lister($id_auteur, $forcer=false) {
static $abonnements_auteurs = array();
$id_auteur = intval($id_auteur);
if ($forcer or is_null($abonnements_auteurs[$id_auteur])) {
$abonnements_auteurs[$id_auteur] = array();
if ($abonnements = sql_allfetsel('*', 'spip_abonnements', 'id_auteur ='.$id_auteur)) {
foreach($abonnements as $abonnement) {
$statut = $abonnement['statut'];
// Initialiser pour ce statut
if (!isset($abonnements_auteurs[$id_auteur][$statut])) {
$abonnements_auteurs[$id_auteur][$statut] = array();
}
// Ajouter l'abonnement à ce statut
$abonnements_auteurs[$id_auteur][$statut][] = $abonnement;
}
}
}
return $abonnements_auteurs[$id_auteur];
}