hellofacteurV1/modele/FclFlux_utilisateur.php

2163 lines
89 KiB
PHP
Raw Permalink Normal View History

2021-11-02 11:23:49 +01:00
<?php
/**
* classe dérivée de la classe Utilisateurs
* on va spécifier ici tout ce qui est propre à cette application :
* manipulation base de données, cache, stockage des sessions, attributs supplémentaires...
*
* @author Fabrice PENHOËT
**/
require_once("utilisateur.php");
class FclFlux_utilisateur extends Utilisateur
{
protected $fuseau_horaire;// utile pour heure envoi des abonnements / email
/**
* Constructeur qui initialise certains attributs en testant les valeurs fournies
* Recopier de la classe héritée car attribut supplémentaire
*
* @param infos_utilisateur tableau contenant les différentes données correspondant aux attributs homonymes.
* @return null
* @author Fabrice PENHOËT
**/
public function __construct($info=null)
{
if((!empty($info))&&(is_array($info)))
{
$erreur_ok=false;
foreach ($info as $attribut => $valeur)
{
$methode="set_$attribut";
if(method_exists(__CLASS__,$methode))
{
if(!$this->$methode($valeur))
$erreur_ok=true;
}
else
$this->$attribut=$valeur;
}
if(($erreur_ok)&&(empty($this->erreurs)))
$this->erreurs=(array) ERREUR_IMPREVUE;
}
}
/**
* Méthode testant la validité du fuseau horaire et l'attribuant à l'objet si ok
*
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function set_fuseau_horaire($fuseau=null)
{
$fuseau_defaut=date_default_timezone_get();
if(empty($fuseau))
$fuseau=$fuseau_defaut;
else
{
$tz=new DateTimeZone($fuseau_defaut);
$zones=$tz->listIdentifiers();
if(!in_array($fuseau,$zones))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT." >> ".htmlentities($fuseau,ENT_QUOTES)));
return false;
}
}
$this->fuseau_horaire=$fuseau;
return true;
}
/**
* Test si une valeur donnée pour un champ est déjà utilisée par un autre utilisateur
* id_utilisateur doit être connu si il s'agit d'un utilisateur existant
*
* @param le champ recherché, l'attribut devant avoir le même nom
* @return true si valeur non trouvée
* @author Fabrice PENHOËT
**/
public function est_libre($champ="pseudo")
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(empty($this->$champ))//à ajouter aussi dans les autres classes
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT));
return false;
}
if(empty($this->id_utilisateur))//nouvel utilisateur non encore enregistré
{
$prepare=$Bd->prepare("SELECT id_utilisateur FROM utilisateurs WHERE $champ=:valeur");
$recherche=$prepare->execute(array(":valeur"=>$this->$champ));
}
else
{
$prepare=$Bd->prepare("SELECT id_utilisateur FROM utilisateurs WHERE ($champ=:valeur and id_utilisateur!=:id)");
$recherche=$prepare->execute(array(":valeur"=>$this->$champ,":id"=>$this->id_utilisateur));
}
if((test_requete(__FILE__,__LINE__,$recherche,$prepare)===false)) return false;
$resultat=$prepare->fetch();
$prepare=null;
if(empty($resultat))//pas de doublon
return true;
else
return false;
}
/**
* Méthode cherchant un utilisateur dans le bd via une valeur l'identifiant de manière unique
* champs acceptés : id_utilisateur,pseudo,email
*
* @param la valeur recherchée, le champ de recherche et les champs souhaités en sortie
* @return les données de la table dans un tableau si trouvé. false si pas trouvé ou en cas d'erreur
* @author Fabrice PENHOËT
**/
static function recherche($valeur,$champ_recherche="id_utilisateur",$champ_sortie="*")
{
global $Bd;
if(strpos("id_utilisateur,pseudo,email",$champ_recherche)===false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_CHAMP_RECHERCHE." >> ".htmlentities($champ_recherche,ENT_QUOTES)));
return false;
}
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
$prepare=$Bd->prepare("SELECT $champ_sortie FROM utilisateurs WHERE $champ_recherche=:valeur");
$recherche=$prepare->execute(array(":valeur"=>$valeur));
if((test_requete(__FILE__,__LINE__,$recherche,$prepare)===false)) return false;
$resultat=$prepare->fetch(PDO::FETCH_ASSOC);
$prepare=null;
if(empty($resultat))
return false;
else
return $resultat;
}
/**
* Méthode de recherche parmi les comptes utilisateur.
*
* @param l'expression recherchée + les champs souhaités en sortie
* @return les données de la table dans un tableau php si trouvé. false si pas trouvé ou en cas d'erreur.
* @author Fabrice PENHOËT
**/
static function recherche_globale($recherche,$champ_sortie="*")
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
$recherche=strip_tags(strval(trim($recherche)));
$recherche_like="%".str_replace(" ","%",$recherche)."%";
$prepare=$Bd->prepare("SELECT $champ_sortie FROM utilisateurs WHERE (pseudo LIKE :recherche_l OR email LIKE :recherche_l OR presentation LIKE :recherche_l OR id_utilisateur=:recherche) ORDER BY pseudo ASC;");
$recherche=$prepare->execute(array(":recherche_l"=>$recherche_like,":recherche"=>$recherche));
if((test_requete(__FILE__,__LINE__,$recherche,$prepare)===false)) return false;
$resultat=$prepare->fetchAll(PDO::FETCH_ASSOC);
$prepare=null;
if(empty($resultat))
return false;
else
return $resultat;
}
/**
* Méthode vérifiant que l'utilisateur est un administrateur
*
* @return booléen
* @author Fabrice PENHOËT
**/
public function est_admin()
{
global $Bd;
if(empty($this->id_utilisateur))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT));
return false;
}
$infos=self::recherche($this->id_utilisateur,"id_utilisateur","statut");
if(empty($infos))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_ENREG_ABSENT." >> ".intval($this->id_utilisateur)));
return false;
}
if($infos["statut"]=="administrateur")
return true;
else
return false;
}
/**
* Méthode créant le fichier cache contenant les infos d'un utilisateur
* id_utilisateur doit être connu
*
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function crea_cache()
{
if(empty($this->id_utilisateur))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT));
return false;
}
$info=self::recherche($this->id_utilisateur,"id_utilisateur","pseudo,email,statut,presentation,illustration,time_validation");
if($info===false)
return false;
/*if(empty($info["time_validation"]))-> à revoir, bug lors création compte
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_ACTION_NON_AUTORISEE." >> ".intval($this->id_utilisateur)));
return false;
}*/
$id=strval($this->id_utilisateur);
return crea_cache(CACHE_REP_UTILISATEURS."/".$id[0]."/$id.txt",$info);
}
/**
* Méthode de suppression du fichier cache contenant les infos utiles d'un utilisateur
* id_utilisateur doit être connu
*
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function suppr_cache()
{
if(empty($this->id_utilisateur))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT));
return false;
}
$fichier=$this->id_utilisateur.".txt";
$chemin=CACHE_REP."/".CACHE_REP_UTILISATEURS."/".$fichier[0]."/".$fichier;
if((file_exists($chemin))&&(!unlink($chemin)))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_SUPPR." >> ".htmlentities($chemin,ENT_QUOTES)));
return false;
}
//ses marque-pages
$chemin=CACHE_REP."/".CACHE_REP_UTILISATEURS."/".$fichier[0]."/MP-$fichier";
if((file_exists($chemin))&&(!unlink($chemin)))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_SUPPR." >> ".htmlentities($chemin,ENT_QUOTES)));
return false;
}
//ses abonnements
$chemin=CACHE_REP."/".CACHE_REP_UTILISATEURS."/".$fichier[0]."/abo-$fichier";
if((file_exists($chemin))&&(!unlink($chemin)))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_SUPPR." >> ".htmlentities($chemin,ENT_QUOTES)));
return false;
}
return true;
}
/**
* Méthode enregistrant un nouvel utilisateur lors de la création de son compte
* pseudo, email et origine doivent être fournis
*
* @param $crea_session à true si il faut créer une session à l'utilisateur en cas de succès,
* $validation=false si compte créé sans devoir valider l'email (compte créé par un administrateur)
* $validation=true si processus de validation classique
* $validation=ext si la suite est traitée par une méthode externe (ex.: publication d'une annonce)
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function ajout($crea_session=false,$validation=true)
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(empty($this->pseudo)||(empty($this->email))||(empty($this->origine)))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_CHAMPS_ABSENTS);
return false;
}
$pseudo_depart=$this->pseudo;
$i=2;$trouve=false;
while((strlen($this->pseudo)<=UTILISATEUR_MAX_PSEUDO)&&(!$trouve))
{
if(!($this->est_libre("pseudo")))
{//pour ne pas bloquer, on cherche un pseudo libre en incrémentant
$this->pseudo=$pseudo_depart.$i;
$i++;
}
else
$trouve=true;
}
if(!$trouve)//je suis sorti parce que trop de caractères...
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_PSEUDO_LIBRE);
return false;
}
if(!($this->est_libre("email")))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_EMAIL_LIBRE);
return false;
}
$ip=getIp();
if($ip===false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES));
return false;
}
if(empty($this->fuseau_horaire))
$this->fuseau_horaire=date_default_timezone_get();
$this->ip_crea=$ip;
$this->time_crea=time();
$this->statut="utilisateur";//toujours le cas lors d'une création de compte. Attribut nécessaire pour créer session + loin.
$prepare=$Bd->prepare("INSERT INTO utilisateurs (pseudo,email,ip_crea,time_crea,origine,fuseau_horaire) VALUES (:pseudo,:email,:ip_crea,:time_crea,:origine,:fuseau)");
$ajout=$prepare->execute(array(':pseudo'=>$this->pseudo,':email'=>$this->email,':ip_crea'=>$this->ip_crea,':time_crea'=>$this->time_crea,':origine'=>$this->origine,':fuseau'=>$this->fuseau_horaire));
if((test_requete(__FILE__,__LINE__,$ajout,$prepare)===false)) return false;
$this->id_utilisateur=$Bd->lastInsertId();
$prepare=null;
if(empty($this->id_utilisateur))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_AJOUT." >> ".htmlentities($this->email,ENT_QUOTES)));
return false;
}
// + sauvegardes
$prepare_svg=$Bd->prepare("INSERT INTO utilisateurs_svg (id_utilisateur,time_maj,pseudo,email,ip_crea,time_crea,origine,fuseau_horaire) VALUES (:id,:time_maj,:pseudo,:email,:ip_crea,:time_crea,:origine,:fuseau)");
$svg=$prepare_svg->execute(array(':id'=>$this->id_utilisateur,':time_maj'=>$this->time_crea,':pseudo'=>$this->pseudo,':email'=>$this->email,':ip_crea'=>$this->ip_crea,':time_crea'=>$this->time_crea,':origine'=>$this->origine,':fuseau'=>$this->fuseau_horaire));
if((test_requete(__FILE__,__LINE__,$svg,$prepare_svg)===false)) return false;
$prepare_svg=null;
$ticket=crea_ticket($this->id_utilisateur,TICKET_VALID_REP,"valid");
if($ticket===false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_CREA));
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_VALIDATION_MESSAGE);
}
else
{
$id=substr($ticket,(strrpos($ticket,"/"))+1);
if($validation===true)
{//l'utilisatdeur doit valider son compte
// + envoi du message avec PHPMailer
$Mail_expediteur_email=EMAIL_TRANSACTIONNEL_DE;
$Mail_expediteur_nom=SITE_NOM;
$Mail_destinataire_email=$this->email;
$Mail_destinataire_nom=$this->pseudo;
$Mail_sujet=COMPTE_VALIDATION_OBJET;
// message alternatif lorsque le html n'est pas lu :
$Mail_boby_txt=str_replace(array("__NOM_UTILISATEUR__","__ID__"),array($this->pseudo,$id),COMPTE_VALIDATION_CORPS);
//-- version html :
//texte invisible (sauf certains webmail ?) :
$Mail_html_sujet="Valider sans tarder votre inscription sur ".SITE_NOM.".";
//entête avant logo :
$Mail_html_header="<p>Valider sans tarder votre inscription sur ".SITE_NOM.".</p>";
//texte du message, hors liste de liens :
$Mail_html_intro=str_replace("__NOM_UTILISATEUR__",htmlentities($this->pseudo),COMPTE_VALIDATION_CORPS_HTML);
//liens sous forme de grands boutons. L'ancre ne doit donc pas être trop longue :
$Mail_html_liens_action[0]="<a href='".PAGE_VALIDATION_COMPTE.$id."'>Valider.</a>";
//footer du mail html :
$Mail_html_footer="<p><a href='".SITE_URL."'>".SITE_NOM."</a>, ".SITE_SLOGAN."</p>";
$Mail_boby_html="";
ob_start();
include(BASE_REP."../www/".TEMPLATE_REP."/mail/defaut.php");
$Mail_boby_html=ob_get_contents();
ob_end_clean();
$SMTP_CustomHeader["X-Mailin-Tag"]="inscription";
// connexion au serveur smtp si il y a lieu :
require(BASE_REP."../divers/phpmailer-initialise.php");
require(BASE_REP."../divers/phpmailer-envoi.php");
if(!$mail->Send())
{
sleep(2);// blocage temporaire smtp ???
if(!$mail->Send())
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_EMAIL_ENVOI.$mail->ErrorInfo));
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_VALIDATION_MESSAGE);
return false;
}
}
}
else if($validation=="ext")
$this->ticket=$id;
else//compte automatiquement validé
$this->valide($id,false);
}
if((empty($this->erreurs))&&($crea_session))
$this->crea_session(false,true);
return true;
}
/**
* Méthode appelée lors de la validation de son compte par un utilisateur
* On va notamment générer son mot de passe et l'enregister
*
* @param l'adresse du ticket contenant l'identifiant de l'utilisateur, $crea_session=true si on souhaite créer une session temporaire
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function valide($ticket,$crea_session=false)
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(strpos($ticket,"/")!==false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES));
return false;
}
if(!file_exists(TICKET_VALID_REP."/$ticket"))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_VALIDATION_LIEN);
return false;
}
$id_utilisateur=file_get_contents(TICKET_VALID_REP."/$ticket");
if(empty($id_utilisateur))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_EXISTE." >> ".htmlentities($ticket,ENT_QUOTES)));
return false;
}
unlink(TICKET_VALID_REP."/$ticket");
$info=self::recherche((int) $id_utilisateur);
if($info===false)
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_VALIDATION_EXPIRE);
return false;
}
if(!empty($info["time_validation"]))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_VALIDATION_DOUBLE);
return false;
}
$passe=crea_passe();
if($passe===false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_UTILISA_PASSE_CREA." >> ".intval($id_utilisateur)));
return false;
}
$this->set_passe($passe);
if(empty($this->erreurs))
{
$this->id_utilisateur=(int) $id_utilisateur;
$this->time_validation=time()+1;//+1 pour éviter bug clé primaire quand la validation suit l'enregistrement du compte
$prepare=$Bd->prepare("UPDATE utilisateurs SET passe=:passe,time_validation=:time where id_utilisateur=:id");
$maj=$prepare->execute(array(':passe'=>$this->chiffre,':time'=>$this->time_validation,':id'=>$this->id_utilisateur));
if((test_requete(__FILE__,__LINE__,$maj,$prepare)===false)) return false;
$nb_enreg=$prepare->rowCount();
$prepare=null;
if($nb_enreg==0)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_MAJ." >> ".intval($this->id_utilisateur)));
return false;
}
$prepare_svg=$Bd->prepare("INSERT INTO utilisateurs_svg (id_utilisateur,time_maj,passe,time_validation) VALUES (:id,:time_maj,:passe,:time)");
$svg=$prepare_svg->execute(array(':id'=>$this->id_utilisateur,':time_maj'=>$this->time_validation,':passe'=>$this->chiffre,':time'=>$this->time_validation));
if((test_requete(__FILE__,__LINE__,$svg,$prepare_svg)===false)) return false;
$prepare_svg=null;
$this->pseudo=$info["pseudo"];
$this->email=$info["email"];
// + envoi du message avec PHPMailer
$Mail_expediteur_email=EMAIL_TRANSACTIONNEL_DE;
$Mail_expediteur_nom=SITE_NOM;
$Mail_destinataire_email=$this->email;
$Mail_destinataire_nom=$this->pseudo;
$Mail_sujet=ENVOI_MOT_PASSE_OBJET;
// message alternatif lorsque le html n'est pas lu :
$Mail_boby_txt=str_replace(array("__NOM_UTILISATEUR__","__PASSE__"),array($this->pseudo,$this->passe),ENVOI_MOT_PASSE_CORPS);
//-- version html :
//texte invisible (sauf certains webmail ?) :
$Mail_html_sujet="Bienvenue sur ".SITE_NOM.". Voici votre mot de passe.";
//entête avant logo :
$Mail_html_header="<p>Bienvenue sur ".SITE_NOM.". Voici votre mot de passe.</p>";
//texte du message, hors liste de liens :
$Mail_html_intro=str_replace(array("__NOM_UTILISATEUR__","__PASSE__"),array($this->pseudo,$this->passe),ENVOI_MOT_PASSE_CORPS_HTML);
$Mail_html_items[0]="<p>Pour vous connecter, <a href='".PAGE_CONNEXION."'>cliquez-ici</a>.</p>";
$Mail_html_items[1]="<p>Pour modifier votre mot de passe ou votre email, <a href='".PAGE_MAJ_IDENTIFIANT."'>cliquez-ici</a>.</p>";
$Mail_html_items[2]="<p>Pour modifier vos autres informations (pseudo, ...), <a href='".PAGE_MAJ_INFOS_PERSO."'>cliquez-ici</a>.</p>";
$Mail_html_items[3]="<p>Pour gérer vos abonnements (sites, jours d'envoi...), <a href='".PAGE_ABO_LISTE."'>cliquez-ici</a>.</p>";
$Mail_html_items[4]="<p>Pour stopper temporairement l'envoi de vos abonnements (vacances...), <a href='".PAGE_ABSENCES_LISTE."'>cliquez-ici</a>.</p>";
$Mail_html_items[5]="<p>Pour proposer une actualité locale (spectacle, conférence, promo ...), <a href='".PAGE_AJOUT_POST."'>cliquez-ici</a>.</p>";
$Mail_html_complement="<p><b>Dernier conseil :</b> pour éviter que les messages de ".SITE_NOM." arrivent dans votre dossier \"spam\", ajoutez <a href='mailto:".EMAIL_MAILINGS."'>".EMAIL_MAILINGS."</a> à votre carnet d'adresses.</p>";
//footer du mail html :
$Mail_html_footer="<p><a href='".SITE_NOM."'>".SITE_NOM."</a>, ".SITE_SLOGAN."</p>";
$Mail_boby_html="";
ob_start();
include(BASE_REP."../www/".TEMPLATE_REP."/mail/defaut.php");
$Mail_boby_html=ob_get_contents();
ob_end_clean();
$SMTP_CustomHeader["X-Mailin-Tag"]="bienvenue";
// connexion au serveur smtp si il y a lieu :
require(BASE_REP."../divers/phpmailer-initialise.php");
require(BASE_REP."../divers/phpmailer-envoi.php");
if(!$mail->Send())
{
sleep(2);// blocage temporaire smtp ???
if(!$mail->Send())
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_EMAIL_ENVOI.$mail->ErrorInfo));
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_EMAIL_ENVOI);
}
}
$this->crea_cache();
$this->statut=$info["statut"];
if((empty($this->erreurs))&&($crea_session))
$this->crea_session(false);
return true;
}
else
return false;
}
/**
* Méthode enregistrant une mise à jour des informations de l'utilisateur
* l'email et le mot de passe nécessitent une procédure spéciale
* @param @suppr_illustration pour les demandes de suppression de l'image,
* $identifiants_ok si on peut changer l'email et le mot de passe sans passer par la procédure normale (doit être demandé par un administrateur)
*
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function actualise($suppr_illustration=false,$identifiants_ok=false)
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(!isset($this->id_utilisateur))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT));
return false;
}
if(!($this->est_libre("pseudo")))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_PSEUDO_LIBRE);
$this->suppr_illustration();
return false;
}
if($suppr_illustration)
$this->illustration="";//pour suppression réelle ci-dessous
if(isset($this->illustration))
{//je viens de télécharger une nouvelle illustration ou souhaite enregistrer une suppression
$ancien=self::recherche($this->id_utilisateur,"id_utilisateur","illustration");
if($ancien===false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_RECHERCHE." >> ".$this->id_utilisateur));
return false;
}
$ancien_illustration=$ancien["illustration"];
if(!empty($ancien_illustration))
unlink(UTILISATEUR_ILLUS_REP."/".$ancien_illustration[0]."/".$ancien_illustration);
$prepare=$Bd->prepare("UPDATE utilisateurs SET illustration=:illustration WHERE id_utilisateur=:id_utilisateur;");
$maj=$prepare->execute(array(':illustration'=>$this->illustration,':id_utilisateur'=>$this->id_utilisateur));
// + sauvegardes
$prepare_svg=$Bd->prepare("INSERT INTO utilisateurs_svg (id_utilisateur,time_maj,illustration) VALUES (:id,:time_maj,:illustration)");
$svg=$prepare_svg->execute(array(':id'=>$this->id_utilisateur,':time_maj'=>time()+1,':illustration'=>$this->illustration));//à revoir, +1 pour éviter doublon sql
}
elseif(($identifiants_ok)&&(!empty($this->email))&&($_SESSION["statut"]=="administrateur"))
{
if(!($this->est_libre("email")))//doit tout de même être unique...
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_EMAIL_LIBRE);
return false;
}
if(empty($this->passe))
{
$prepare=$Bd->prepare("UPDATE utilisateurs SET pseudo=:pseudo,presentation=:presentation,email=:email,fuseau_horaire=:fuseau WHERE id_utilisateur=:id_utilisateur;");
$maj=$prepare->execute(array(':pseudo'=>$this->pseudo,':presentation'=>$this->presentation,':id_utilisateur'=>$this->id_utilisateur,':email'=>$this->email,':fuseau'=>$this->fuseau_horaire));
// + sauvegardes
$prepare_svg=$Bd->prepare("INSERT INTO utilisateurs_svg (id_utilisateur,time_maj,pseudo,presentation,email,fuseau_horaire) VALUES (:id,:time_maj,:pseudo,:presentation,:email,:fuseau)");
$svg=$prepare_svg->execute(array(':id'=>$this->id_utilisateur,':time_maj'=>time(),':pseudo'=>$this->pseudo,':presentation'=>$this->presentation,':email'=>$this->email,':fuseau'=>$this->fuseau_horaire));
}
else
{
$prepare=$Bd->prepare("UPDATE utilisateurs SET pseudo=:pseudo,presentation=:presentation,email=:email,passe=:passe,fuseau_horaire=:fuseau WHERE id_utilisateur=:id_utilisateur;");
$maj=$prepare->execute(array(':pseudo'=>$this->pseudo,':presentation'=>$this->presentation,':id_utilisateur'=>$this->id_utilisateur,':email'=>$this->email,':passe'=>$this->chiffre,':fuseau'=>$this->fuseau_horaire));
// + sauvegardes
$prepare_svg=$Bd->prepare("INSERT INTO utilisateurs_svg (id_utilisateur,time_maj,pseudo,presentation,email,passe,fuseau_horaire) VALUES (:id,:time_maj,:pseudo,:presentation,:email,:passe,:fuseau)");
$svg=$prepare_svg->execute(array(':id'=>$this->id_utilisateur,':time_maj'=>time(),':pseudo'=>$this->pseudo,':presentation'=>$this->presentation,':email'=>$this->email,':passe'=>$this->chiffre,':fuseau'=>$this->fuseau_horaire));
}
}
else
{
$prepare=$Bd->prepare("UPDATE utilisateurs SET pseudo=:pseudo,presentation=:presentation,fuseau_horaire=:fuseau WHERE id_utilisateur=:id_utilisateur;");
$maj=$prepare->execute(array(':pseudo'=>$this->pseudo,':presentation'=>$this->presentation,':id_utilisateur'=>$this->id_utilisateur,':fuseau'=>$this->fuseau_horaire));
// + sauvegardes
$prepare_svg=$Bd->prepare("INSERT INTO utilisateurs_svg (id_utilisateur,time_maj,pseudo,presentation,fuseau_horaire) VALUES (:id,:time_maj,:pseudo,:presentation,:fuseau)");
$svg=$prepare_svg->execute(array(':id'=>$this->id_utilisateur,':time_maj'=>time(),':pseudo'=>$this->pseudo,':presentation'=>$this->presentation,':fuseau'=>$this->fuseau_horaire));
}
if((test_requete(__FILE__,__LINE__,$maj,$prepare)===false))
{
$this->suppr_illustration();
return false;
}
$prepare=null;
if((test_requete(__FILE__,__LINE__,$svg,$prepare_svg)===false)) return false;
$prepare_svg=null;
$this->crea_cache();
}
/**
* Méthode enregistrant une mise à jour des informations de connexion (email / mot de passe)
* l'ancien mot de passe doit nécessairement être fourni et contrôlé
* dans le cas d'un chgt d'email, un lien de vérification sera envoyé sur la nouvelle adresse
*
* @param le nouveau mot de passe si chgt
* @return false en cas d'erreur, null sinon.
* @author Fabrice PENHOËT
**/
public function actualise_infos_connexion($nouveau_passe="")
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if((empty($this->id_utilisateur))||(empty($this->email))||(empty($this->passe)))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT));
return false;
}
$resultat=self::recherche($this->id_utilisateur,"id_utilisateur","passe,email,pseudo");
if($resultat===false) return false;
if(!(password_verify($this->passe,$resultat["passe"])))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_PASSE_CORRECT);
return false;
}
if($this->email!=$resultat["email"])
{
if(!($this->est_libre("email")))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_EMAIL_LIBRE);
return false;
}
$ticket=crea_ticket($this->email."|".$this->id_utilisateur,TICKET_VALID_REP,"email");
if($ticket===false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_CREA));
return false;
}
else
{
// + envoi du message avec PHPMailer
$Mail_expediteur_email=EMAIL_TRANSACTIONNEL_DE;
$Mail_expediteur_nom=SITE_NOM;
$Mail_destinataire_email=$this->email;
$Mail_destinataire_nom=$this->pseudo;
$Mail_sujet=NOUVEL_EMAIL_VALIDATION_OBJET;
// message alternatif lorsque le html n'est pas lu :
$id=substr($ticket,(strrpos($ticket,"/"))+1);
$Mail_boby_txt=str_replace(array("__NOM_UTILISATEUR__","__ID__"),array($resultat["pseudo"],$id),NOUVEL_EMAIL_VALIDATION_CORPS);
//-- version html :
//texte invisible (sauf certains webmail ?) :
$Mail_html_sujet="Valider sans tarder votre nouvelle adresse email sur ".SITE_NOM.".";
//entête avant logo :
$Mail_html_sujet="Valider sans tarder votre nouvelle adresse email sur ".SITE_NOM.".";
//texte du message, hors liste de liens :
$Mail_html_intro=str_replace("__NOM_UTILISATEUR__",htmlentities($resultat["pseudo"]),NOUVEL_EMAIL_VALIDATION_CORPS_HTML);
//liens sous forme de grands boutons. L'ancre ne doit donc pas être trop longue :
$Mail_html_liens_action[0]="<a href='".PAGE_VALIDATION_EMAIL.$id."'>Valider.</a>";
//footer du mail html :
$Mail_html_footer="<p><a href='".SITE_NOM."'>".SITE_NOM."</a>, ".SITE_SLOGAN."</p>";
$Mail_boby_html="";
ob_start();
include(BASE_REP."../www/".TEMPLATE_REP."/mail/defaut.php");
$Mail_boby_html=ob_get_contents();
ob_end_clean();
$SMTP_CustomHeader["X-Mailin-Tag"]="nouvel_email";
// connexion au serveur smtp si il y a lieu :
require(BASE_REP."../divers/phpmailer-initialise.php");
require(BASE_REP."../divers/phpmailer-envoi.php");
if(!$mail->Send())
{
sleep(2);// blocage temporaire smtp ???
if(!$mail->Send())
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_EMAIL_ENVOI.$mail->ErrorInfo));
return false;
}
}
}
}
if(!empty($nouveau_passe))
{
if($this->set_passe($nouveau_passe)===true)
{
$prepare=$Bd->prepare("UPDATE utilisateurs SET passe=:passe WHERE id_utilisateur=:id_utilisateur;");
$maj=$prepare->execute(array(':passe'=>$this->chiffre,':id_utilisateur'=>$this->id_utilisateur));
if((test_requete(__FILE__,__LINE__,$maj,$prepare)===false)) return false;
$nb_enreg=$prepare->rowCount();
if($nb_enreg==0)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_MAJ." >> ".intval($this->id_utilisateur)));
return false;
}
$prepare=null;
// + sauvegardes
$prepare_svg=$Bd->prepare("INSERT INTO utilisateurs_svg (id_utilisateur,time_maj,passe) VALUES (:id,:time_maj,:passe)");
$svg=$prepare_svg->execute(array(':id'=>$this->id_utilisateur,':time_maj'=>time(),':passe'=>$this->chiffre));
if((test_requete(__FILE__,__LINE__,$svg,$prepare_svg)===false)) return false;
$prepare_svg=null;
}
else
return false;
}
return true;
}
/**
* Méthode enregistrant une mise à jour du fuseau horaire uniquement.
*
* @param
* @return booléen suivant succès.
* @author Fabrice PENHOËT
**/
public function actualise_fuseau_horaire()
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if((empty($this->id_utilisateur))||(empty($this->fuseau_horaire)))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT));
return false;
}
$prepare=$Bd->prepare("UPDATE utilisateurs SET fuseau_horaire=:fuseau WHERE id_utilisateur=:id_utilisateur;");
$maj=$prepare->execute(array(':fuseau'=>$this->fuseau_horaire,':id_utilisateur'=>$this->id_utilisateur));
if((test_requete(__FILE__,__LINE__,$maj,$prepare)===false)) return false;
$prepare=null;
// + sauvegardes
$timeS=time()+2;//time_maj doit être différent
$prepare_svg=$Bd->prepare("INSERT INTO utilisateurs_svg (id_utilisateur,time_maj,fuseau_horaire) VALUES (:id,:time_maj,:fuseau)");
$svg=$prepare_svg->execute(array(':id'=>$this->id_utilisateur,':time_maj'=>$timeS,':fuseau'=>$this->fuseau_horaire));
if((test_requete(__FILE__,__LINE__,$svg,$prepare_svg)===false)) return false;
$prepare_svg=null;
return true;
}
/**
* Méthode appelée lors de la validation de chgt d'adresse email
*
* @param $ticket l'adresse du ticket contenant l'identifiant de l'utilisateur + sa nouvelle adresse
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function valide_email($ticket)
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(strpos($ticket,"/")!==false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES));
return false;
}
if(!file_exists(TICKET_VALID_REP."/$ticket"))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_VALIDATION_EMAIL_LIEN);
return false;
}
$donnees_fichier=file_get_contents(TICKET_VALID_REP."/$ticket");
if(empty($donnees_fichier))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_EXISTE." >> ".htmlentities($ticket,ENT_QUOTES)));
return false;
}
unlink(TICKET_VALID_REP."/$ticket");
$donnees_fichier=explode("|",$donnees_fichier);
$info=self::recherche((int) $donnees_fichier[1],"id_utilisateur","id_utilisateur");
if($info===false) return false;
if($this->id_utilisateur!=(int) $donnees_fichier[1])//comparaison à l'id de l'utilisateur connecté
return false;
if($this->set_email($donnees_fichier[0])!==false)
{
$prepare=$Bd->prepare("UPDATE utilisateurs SET email=:email where id_utilisateur=:id");
$maj=$prepare->execute(array(':email'=>$this->email,':id'=>$this->id_utilisateur));
if((test_requete(__FILE__,__LINE__,$maj,$prepare)===false)) return false;
$nb_enreg=$prepare->rowCount();
if($nb_enreg==0)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_MAJ." >> ".intval($this->id_utilisateur)));
return false;
}
$prepare=null;
// + sauvegardes
$prepare_svg=$Bd->prepare("INSERT INTO utilisateurs_svg (id_utilisateur,time_maj,email) VALUES (:id,:time_maj,:email)");
$svg=$prepare_svg->execute(array(':id'=>$this->id_utilisateur,':time_maj'=>time(),':email'=>$this->email));
if((test_requete(__FILE__,__LINE__,$svg,$prepare_svg)===false)) return false;
$prepare_svg=null;
//+ le cache
$this->crea_cache();
return true;
}
else
return false;
}
/**
* Méthode envoyant un nouveau mot de passe à l'utilisateur bloqué
*
* @param null mais attribut doit être fourni
* @return booléen suivant réussite
* @author Fabrice PENHOËT
**/
public function get_nouveau_passe()
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
$resultat=self::recherche($this->email,"email","id_utilisateur,pseudo");
if($resultat===false)
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_PASSE_ENVOI);
return false;
}
$passe=crea_passe();
if($this->set_passe($passe)===false) return false;
$prepare=$Bd->prepare("UPDATE utilisateurs SET passe=:passe where email=:email");
$maj=$prepare->execute(array(':email'=>$this->email,':passe'=>$this->chiffre));
if((test_requete(__FILE__,__LINE__,$maj,$prepare)===false)) return false;
$nb_enreg=$prepare->rowCount();
if($nb_enreg==0)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_MAJ." >> ".intval($resultat["id_utilisateur"])));
return false;
}
$prepare=null;
// + sauvegardes
$prepare_svg=$Bd->prepare("INSERT INTO utilisateurs_svg (id_utilisateur,time_maj,passe) VALUES (:id,:time_maj,:passe)");
$svg=$prepare_svg->execute(array(':id'=>$resultat["id_utilisateur"],':time_maj'=>time(),':passe'=>$this->chiffre));
if((test_requete(__FILE__,__LINE__,$svg,$prepare_svg)===false)) return false;
$prepare_svg=null;
// + envoi du message avec PHPMailer
$Mail_expediteur_email=EMAIL_TRANSACTIONNEL_DE;
$Mail_expediteur_nom=SITE_NOM;
$Mail_destinataire_email=$this->email;
$Mail_destinataire_nom=$resultat["pseudo"];
$Mail_reponse_email=EMAIL_TRANSACTIONNEL_DE;
$Mail_sujet=ENVOI_NOUVEAU_MOT_PASSE_OBJET;
// message alternatif lorsque le html n'est pas lu :
$Mail_boby_txt=str_replace(array("__NOM_UTILISATEUR__","__PASSE__"),array($resultat["pseudo"],$this->passe),ENVOI_NOUVEAU_MOT_PASSE_CORPS);
//-- version html :
//texte invisible (sauf certains webmail ?) :
$Mail_html_sujet="Votre nouveau mot de passe ".SITE_NOM.".";
//entête avant logo :
$Mail_html_sujet="Votre nouveau mot de passe ".SITE_NOM.".";
//texte du message, hors liste de liens :
$Mail_html_intro=str_replace(array("__NOM_UTILISATEUR__","__PASSE__"),array($resultat["pseudo"],$this->passe),ENVOI_NOUVEAU_MOT_PASSE_CORPS_HTML);
//liens sous forme de grands boutons. L'ancre ne doit donc pas être trop longue :
$Mail_html_items[0]="<p>Pour vous connecter, <a href='".PAGE_CONNEXION."'>cliquez-ici</a>.</p>";
$Mail_html_items[1]="<p>Pour modifier votre mot de passe ou votre email, <a href='".PAGE_MAJ_IDENTIFIANT."'>cliquez-ici</a>.</p>";
$Mail_html_items[2]="<p>Pour modifier vos autres informations (pseudo,...), <a href='".PAGE_MAJ_INFOS_PERSO."'>cliquez-ici</a>.</p>";
$Mail_html_items[3]="<p>Pour gérer vos abonnements (sites, jours d'envoi...), <a href='".PAGE_ABO_LISTE."'>cliquez-ici</a>.</p>";
//footer du mail html :
$Mail_html_footer="<p><a href='".SITE_NOM."'>".SITE_NOM."</a>, ".SITE_SLOGAN."</p>";
$Mail_boby_html="";
ob_start();
include(BASE_REP."../www/".TEMPLATE_REP."/mail/defaut.php");
$Mail_boby_html=ob_get_contents();
ob_end_clean();
$SMTP_CustomHeader["X-Mailin-Tag"]="nouveau_passe";
// connexion au serveur smtp si il y a lieu :
require_once(BASE_REP."../divers/phpmailer-initialise.php");
require_once(BASE_REP."../divers/phpmailer-envoi.php");
if(!$mail->Send())
{
sleep(2);// blocage temporaire smtp ???
if(!$mail->Send())
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,$mail->ErrorInfo));
return false;
}
}
return true;
}
/**
* Méthode envoyant un lien par email permettant à un utilisateur de supprimer son compte
*
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function get_lien_suppression()
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(empty($this->email))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_CHAMPS_ABSENTS);
return false;
}
// est-ce qu'un compte existe pour cette email ?
$infos=FclFlux_utilisateur::recherche($this->email,"email","id_utilisateur,pseudo,statut");
if(empty($infos))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_RECHERCHE));
return false;
}
if($infos["statut"]=="administrateur")
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_ACTION_NON_AUTORISEE));
return false;
}
//tout semble ok et on peut créé le ticket qui va bien
$txt=$infos["id_utilisateur"]."|".time();
$ticket=crea_ticket($txt,TICKET_SUPPR_REP,"suppr");
if($ticket===false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_CREA));
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_CREA_LIEN_SUPPRESSION);
return false;
}
else
{
$id=substr($ticket,(strrpos($ticket,"/"))+1);
// envoi du message avec PHPMailer
$Mail_expediteur_email=EMAIL_TRANSACTIONNEL_DE;
$Mail_expediteur_nom=SITE_NOM;
$Mail_destinataire_email=$this->email;
$Mail_destinataire_nom=$infos["pseudo"];
$Mail_sujet=COMPTE_LIEN_SUPPRESSION_OBJET;
// message alternatif lorsque le html n'est pas lu :
$Mail_boby_txt=str_replace(array("__NOM_UTILISATEUR__","__ID__"),array($Mail_destinataire_nom,$id),COMPTE_LIEN_SUPPRESSION_CORPS);
//-- version html :
//texte invisible (sauf certains webmail ?) :
$Mail_html_sujet="Supprimez votre compte sur ".SITE_NOM." ?";
//entête avant logo :
$Mail_html_header="<p>Procédure de suppression de compte.</p>";
//texte du message, hors liste de liens :
$Mail_html_intro=str_replace("__NOM_UTILISATEUR__",htmlentities($Mail_destinataire_nom),COMPTE_LIEN_SUPPRESSION_CORPS_HTML);
//liens sous forme de grands boutons. L'ancre ne doit donc pas être trop longue :
$Mail_html_liens_action[0]="<a href='".PAGE_LIEN_SUPPRESSION_COMPTE.$id."'>Confirmer la suppression.</a>";
//footer du mail html :
$Mail_html_footer="<p><a href='".SITE_NOM."'>".SITE_NOM."</a>, ".SITE_SLOGAN."</p>";
$Mail_boby_html="";
ob_start();
include(BASE_REP."../www/".TEMPLATE_REP."/mail/defaut.php");
$Mail_boby_html=ob_get_contents();
ob_end_clean();
$SMTP_CustomHeader["X-Mailin-Tag"]="supprime_compte";
// connexion au serveur smtp si il y a lieu :
require(BASE_REP."../divers/phpmailer-initialise.php");
require(BASE_REP."../divers/phpmailer-envoi.php");
if(!$mail->Send())
{
sleep(2);// blocage temporaire smtp ???
if(!$mail->Send())
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_EMAIL_ENVOI.$mail->ErrorInfo));
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_CREA_LIEN_SUPPRESSION);
return false;
}
}
}
return true;
}
/**
* Méthode appelée lorsqu'un utilisateur clique sur le lien lui permettant de supprimer son compte
*
* @param l'adresse du ticket à contrôler
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function test_lien_suppression($ticket)
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(strpos($ticket,"/")!==false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES));
return false;
}
if(!file_exists(TICKET_SUPPR_REP."/$ticket"))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_LIEN_SUPPRESSION);
return false;
}
$donnees_fichier=explode("|",file_get_contents(TICKET_SUPPR_REP."/$ticket"));
unlink(TICKET_SUPPR_REP."/$ticket");
if(count($donnees_fichier)!=2)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES." >> ".htmlentities(implode("|",$donnees_fichier),ENT_QUOTES)));
return false;
}
if($donnees_fichier[1]<(time()-3600*COMPTE_LIEN_SUPPRESSION_MAX_DUREE))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_LIEN_SUPPRESSION);
return false;
}
$info=self::recherche((int) $donnees_fichier[0]);
if($info===false)
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_LIEN_SUPPRESSION);
return false;
}
if(empty($this->erreurs))
{
$this->id_utilisateur=(int) $donnees_fichier[0];
$this->supprime();
if(empty($this->erreurs))
return true;
else
return false;
}
else
return false;
}
/**
* Méthode supprimant les infos d'un utilisateur
* ne concerne pas la table des sauvegardes, ni celles des sessions ayant une durée de vie + longue
* je garde tout de même dans table sauvegardes la date de suppression du compte (pour stats)
* si tout se passe bien il faudra supprimer la session de l'utilisateur connecté (sauf si admin)
*
* @param $valide booléen pour savoir si il s'agit d'un utilisateur ayant validé son compte ou non
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function supprime($valide=true)
{
global $Bd;
if(!isset($this->id_utilisateur))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT));
return false;
}
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
$resultat=$this->recherche($this->id_utilisateur,"id_utilisateur","illustration");
if(empty($resultat))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_ENREG_ABSENT));
return false;
}
// je commence par supprimer tous les enregistrements dépendants (pour suppression des fichiers associés).
// -- les abonnements
require_once("FclFlux_abonnement.php");
$abos=FclFlux_abonnement::get_liste_abo_cache($this,true);//force la création du cache
if(!empty($abos))
{
$infos["proprietaire"]=$this;
foreach($abos as $abo_infos)
{
$infos["id_abonnement"]=$abo_infos["id_abonnement"];
$abo=new FclFlux_abonnement($infos);
$abo->supprime();
unset($abo);
}
}
$prepare=$Bd->prepare("DELETE FROM utilisateurs WHERE id_utilisateur=:id_utilisateur;");
$suppr=$prepare->execute(array(':id_utilisateur'=>$this->id_utilisateur));
if((test_requete(__FILE__,__LINE__,$suppr,$prepare)===false));
$nb_enreg=$prepare->rowCount();
if(empty($nb_enreg))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_SUPPR." >> ".intval($this->id_utilisateur)));
return false;
}
$prepare=null;
if($valide)
{
// + sauvegardes
$prepare_svg=$Bd->prepare("INSERT INTO utilisateurs_svg (id_utilisateur,time_maj,time_suppr) VALUES (:id,:time,:time)");
$svg=$prepare_svg->execute(array(':id'=>$this->id_utilisateur,':time'=>time()));
if((test_requete(__FILE__,__LINE__,$svg,$prepare_svg)===false)) return false;
$prepare_svg=null;
}
$this->illustration=$resultat["illustration"];
$this->suppr_illustration();
$this->suppr_cache();
if(($valide)&&((empty($_SESSION)||($_SESSION["statut"]!="administrateur"))))//c'est un admin qui supprime un compte
$this->supprime_session();
}
/**
* Méthode ouvrant le fichier cache contenant les infos d'un utilisateur
*
* @param crea_cache : un booléen pour savoir si il faut tester la création du fichier en cas d'absence
* @return tableau contenant les infos de l'utilisateur fournies par le fichier (si trouvé), false en cas d'erreur
* @author Fabrice PENHOËT
**/
public function get_infos_cache($crea_cache=false)
{
global $Bd;
if(empty($this->id_utilisateur))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT));
return false;
}
$id=strval($this->id_utilisateur);
$fichier=CACHE_REP."/".CACHE_REP_UTILISATEURS."/".$id[0]."/$id.txt";
$infos=array();
if(!file_exists($fichier))
{
if($crea_cache)
{
require("connexion-bd.php");
if(empty($GLOBALS['Bd'])) return false;
if(!$this->crea_cache())
return false;
}
else
return false;
}
include($fichier);
if(empty($t))
return false;
else
{
foreach($t as $key => $value)
{
if(!is_array($value))
$infos[$key]=stripslashes($value);
}
}
if(empty($infos))
return false;
else
return $infos;
}
/**
* Méthode contrôlant les données saisies lors d'une tentative de connexion
*
* @param persistence : booléen indiquant si souhait de créer une session persistante via cookies
* @return booléen suivant réussite
* @author Fabrice PENHOËT
**/
public function test_connexion($persistence=false)
{
global $Bd;
if((empty($this->email))||(empty($this->passe)))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_CHAMPS_ABSENTS);
return false;
}
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
$resultat=$this->recherche($this->email,"email","passe,id_utilisateur,pseudo,statut,time_validation");
if(($resultat===false)||(!(password_verify($this->passe,$resultat["passe"]))))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_CONNEXION);
return false;
}
//données utiles pour création session & co
$this->id_utilisateur=$resultat["id_utilisateur"];
$this->pseudo=$resultat["pseudo"];
$this->statut=$resultat["statut"];
//première connexion ok d'un utilisateur n'ayant pas validé son compte lors de l'inscription
//mais ayant demandé et reçu un nouveau mot de passe :
if($resultat["time_validation"]==0)
{
$prepare=$Bd->prepare("UPDATE utilisateurs SET time_validation=:time where id_utilisateur=:id");
$maj=$prepare->execute(array(':time'=>time(),':id'=>$this->id_utilisateur));
test_requete(__FILE__,__LINE__,$maj,$prepare);//on ne bloque pas même si c'est gênant...
}
if($this->crea_session($persistence,true)!==false)
return true;
else
return false;
}
/**
* Méthode contrôlant les données passées par l'url
* et créant une session à l'utilisateur si elles sont ok
*
* @param objet utilisateur pour le propriétaire de l'abonnement, le timestamp d'envoi du message + la clé générée lors du même envoi
* @return booléen suivant si les données sont ok et la session de l'utilisateur créé
* @author Fabrice PENHOËT
**/
public function crea_session_lien_abo($time_lien,$cle_lien)
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if((empty($time_lien))||(empty($cle_lien)))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT));
return false;
}
$prepare=$Bd->prepare("SELECT U.id_utilisateur,U.pseudo,U.statut FROM utilisateurs as U,abonnements_mail as A WHERE (U.id_utilisateur=A.utilisateur_id AND A.time_envoi=:time AND A.cle=:cle);");
$recherche=$prepare->execute(array(":time"=>$time_lien,":cle"=>$cle_lien));
if((test_requete(__FILE__,__LINE__,$recherche,$prepare)===false)) return false;
$abo_infos=$prepare->fetch(PDO::FETCH_ASSOC);
$prepare=null;
if(empty($abo_infos))
return false;
else
{
if($abo_infos["statut"]=="administrateur")
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,"Tentative de connexion non autorisée en tant qu'administrateur."));
return false;
}
$this->id_utilisateur=$abo_infos["id_utilisateur"];
$this->pseudo=$abo_infos["pseudo"];
$this->statut=$abo_infos["statut"];
$this->crea_session(false,false);
return $this->connexion_ok;
}
}
/**
* Méthode envoyant un lien par email permettant de se connecter sans mot de passe
*
* @param l'utilisateur a-t'il demandé une connexion persistente ?
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function get_lien_connexion($persistence=false)
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(empty($this->email))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_CHAMPS_ABSENTS);
return false;
}
// est-ce qu'un compte existe pour cette email ?
$infos=FclFlux_utilisateur::recherche($this->email,"email","id_utilisateur,pseudo,statut");
if(empty($infos))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_EMAIL_CONNEXION);
return false;
}
if($infos["statut"]=="administrateur")
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_ACTION_NON_AUTORISEE));
return false;
}
//tout semble ok et on peut créé le ticket qui va bien
$txt=$infos["id_utilisateur"]."|".time()."|".$persistence;
$ticket=crea_ticket($txt,TICKET_CONNECT_REP,"cnx");
if($ticket===false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_CREA));
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_CREA_LIEN_CONNEXION);
return false;
}
else
{
$id=substr($ticket,(strrpos($ticket,"/"))+1);
// envoi du message avec PHPMailer
// connexion au serveur smtp si il y a lieu :
$Mail_expediteur_email=EMAIL_TRANSACTIONNEL_DE;
$Mail_expediteur_nom=SITE_NOM;
$Mail_destinataire_email=$this->email;
$Mail_destinataire_nom=$infos["pseudo"];
$Mail_sujet=COMPTE_LIEN_CONNEXION_OBJET;
// message alternatif lorsque le html n'est pas lu :
$Mail_boby_txt=str_replace(array("__NOM_UTILISATEUR__","__ID__"),array($Mail_destinataire_nom,$id),COMPTE_LIEN_CONNEXION_CORPS);
//-- version html :
//texte invisible (sauf certains webmail ?) :
$Mail_html_sujet="Lien de connexion à ".SITE_NOM.".";
//entête avant logo :
$Mail_html_header="<p>Vous connecter à ".SITE_NOM.".</p>";
//texte du message, hors liste de liens :
$Mail_html_intro=str_replace("__NOM_UTILISATEUR__",htmlentities($Mail_destinataire_nom),COMPTE_LIEN_CONNEXION_CORPS_HTML);
//liens sous forme de grands boutons. L'ancre ne doit donc pas être trop longue :
$Mail_html_liens_action[0]="<a href='".PAGE_LIEN_CONNEXION_COMPTE.$id."'>Connexion.</a>";
//footer du mail html :
$Mail_html_footer="<p><a href='".SITE_URL."'>".SITE_NOM."</a>, ".SITE_SLOGAN."</p>";
$Mail_boby_html="";
ob_start();
include(BASE_REP."../www/".TEMPLATE_REP."/mail/defaut.php");
$Mail_boby_html=ob_get_contents();
ob_end_clean();
$SMTP_CustomHeader["X-Mailin-Tag"]="lien_connexion_sans_passe";
require(BASE_REP."../divers/phpmailer-initialise.php");
require(BASE_REP."../divers/phpmailer-envoi.php");
//echo var_dump($mail);
if(!$mail->Send())
{
sleep(2);// blocage temporaire smtp ???
if(!$mail->Send())
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_EMAIL_ENVOI.$mail->ErrorInfo));
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_CREA_LIEN_CONNEXION);
return false;
}
}
}
return true;
}
/**
* Méthode appelée lorsqu'un utilisateur clique sur un lien de connexion envoyé sur son email
*
* @param l'adresse du ticket à contrôler
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function crea_session_lien_connexion($ticket)
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(strpos($ticket,"/")!==false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES));
return false;
}
if(!file_exists(TICKET_CONNECT_REP."/$ticket"))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_LIEN_CONNEXION);
return false;
}
$donnees_fichier=explode("|",file_get_contents(TICKET_CONNECT_REP."/$ticket"));
unlink(TICKET_CONNECT_REP."/$ticket");
if(count($donnees_fichier)!=3)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES." >> ".htmlentities(implode("|",$donnees_fichier),ENT_QUOTES)));
return false;
}
if($donnees_fichier[1]<(time()-60*COMPTE_LIEN_CONNEXION_MAX_DUREE))
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_LIEN_CONNEXION);
return false;
}
$info=self::recherche((int) $donnees_fichier[0]);
if($info===false)
{
$this->erreurs=array_merge($this->erreurs,(array) ERREUR_UTILISA_LIEN_CONNEXION);
return false;
}
if(empty($this->erreurs))
{
$this->id_utilisateur=(int) $donnees_fichier[0];
$this->pseudo=$info["pseudo"];
$this->statut=$info["statut"];
if(empty($this->erreurs))
$this->crea_session($donnees_fichier[2]);
return true;
}
else
return false;
}
/**
* Méthode enregistrant une nouvelle session
* un fichier temporaire contiendra l'id de l'utilisateur + le timestamp et différentes infos pour les stats
* si connexion persistente demandée, on créé un cookie + un ticket pour les futurs contrôles du cookie
* mais connexion persistente interdite pour les administrateurs.
*
* @param persistence (booléen) souhait ou non d'une connexion persistente (cookies),
* initialise_session (booléen) : session déjà initialisée au préalable ?
* @return booléen suivant réussite
* @author Fabrice PENHOËT
**/
public function crea_session($persistence,$initialise_session=false)
{
if((empty($this->id_utilisateur))||(empty($this->pseudo))||(empty($this->statut))) return false;
if(!$initialise_session)
{
session_save_path(SESSIONS_REP);
ini_set("session.use_only_cookies",1);
session_regenerate_id(true);
session_start();
}
$ip_connexion=getIp();
$user_agent=$_SERVER["HTTP_USER_AGENT"];
if((empty($ip_connexion))||(empty($user_agent)))
return false;
$_SESSION["id_utilisateur"]=$this->id_utilisateur;
$_SESSION["pseudo"]=htmlspecialchars($this->pseudo);//donnée que j'affiche
$_SESSION["statut"]=$this->statut;
$_SESSION["controle"]=$user_agent;
$_SESSION["controle_ip"]=$ip_connexion;
$referer="";
if(!empty($_SERVER["HTTP_REFERER"]))
$referer=$_SERVER["HTTP_REFERER"];
if(!empty($_SESSION))
{
$this->connexion_ok=true;
$code=htmlentities($this->id_utilisateur)."##".time()."##".$ip_connexion."##".htmlentities($user_agent)."##".htmlentities($referer);
$ticket=crea_ticket($code,SESSIONS_TEMP_REP,"ses");
if($ticket===false)
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_CREA));
}
else
return false;
if(($persistence===true)&&($this->statut!="administrateur"))
{
$str_mois=strval(date("Y/m"));
$code=$this->id_utilisateur.",".$_SESSION["controle"].",".$_SESSION["controle_ip"];
$ticket=crea_ticket($code,COOKIES_REP."/".$str_mois,"cook");
if($ticket===false)
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_CREA));
else
{
$date_expire_cookie=time()+3600*24*180;//6 mois, durée max autorisée par la cnil...
setcookie("ctrl",str_replace("cook","",substr($ticket,(strrpos($ticket,"/"))+1)),$date_expire_cookie,"/",SITE_COOKIES_DOMAINE);
setcookie("mois",strval(date("Y-m")),$date_expire_cookie,"/",SITE_COOKIES_DOMAINE);
}
}
}
/**
* Méthode enregistrant un cookie éphémère
* dans le but de stocker une adresse vers laquelle rediriger l'utilisateur une fois qu'il sera connecté
*
* @param l'url vers laquelle rediriger le gus + la durée de vie en jours du cookie
* @return booléen suivant réussite
* @author Fabrice PENHOËT
**/
static function crea_cookie_redirection($url=SITE_URL,$duree=1)
{
if(strpos($url,SITE_COOKIES_DOMAINE)===false) return false;
$date_expire_cookie=time()+(3600*24)*$duree;
setcookie("rdg",$url,$date_expire_cookie,"/",SITE_COOKIES_DOMAINE);
}
/**
* Méthode testant les cookies de connexion
* si tout est ok, on créé des variables de session
* sinon on supprime les éventuels cookies
*
* @return booléen suivant réussite
* @author Fabrice PENHOËT
**/
public function test_cookies()
{
if((empty($_COOKIE["ctrl"]))||(empty($_COOKIE["mois"])))
return false;
if((strpos("/",$_COOKIE["ctrl"])!==false)||(strpos("/",$_COOKIE["mois"])!==false))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES));
setcookie("ctrl","",time()-42000,"/",SITE_COOKIES_DOMAINE);
setcookie("mois","",time()-42000,"/",SITE_COOKIES_DOMAINE);
return false;
}
$tab_mois=explode("-",$_COOKIE["mois"]);
$mois_ok=array("01","02","03","04","05","06","07","08","09","10","11","12");
if(!in_array($tab_mois[1],$mois_ok))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES));
setcookie("ctrl","",time()-42000,"/",SITE_COOKIES_DOMAINE);
setcookie("mois","",time()-42000,"/",SITE_COOKIES_DOMAINE);
return false;
}
$chemin_ticket=COOKIES_REP."/".intval($tab_mois[0])."/".$tab_mois[1]."/cook".$_COOKIE["ctrl"];
if(!file_exists($chemin_ticket))
{
$this->supprime_session();
return false;
}
$code=explode(",",file_get_contents($chemin_ticket));
/* bloque certains utilisateurs et ne protège pas de grand chose...
* $ip_connexion=getIp();
$user_agent=$_SERVER["HTTP_USER_AGENT"];
if((empty($ip_connexion))||(empty($user_agent)))
return false;
if(($code[1]!=$user_agent)&&($code[2]!=$ip_connexion))//il semble que le user-agent change parfois aussi en cours de route, les 2 c'est louche !
{
$this->supprime_session();
return false;
}*/
$this->id_utilisateur=intval($code[0]);
$infos=$this->get_infos_cache(true);//force la création du cache si nécessaire
if(empty($infos))
{
$this->id_utilisateur=null;
$this->supprime_session();
return false;
}
else
{
$this->pseudo=stripslashes($infos["pseudo"]);
$this->statut=stripslashes($infos["statut"]);
$this->crea_session(false,true);
}
return true;
}
/**
* Méthode testant si l'utilisateur est connecté ou non
* si oui l'objet courant se voit attribuer les données de la session
*
* @param $destroy, booléen suivant si je veux détruire ou non la variable de session, $admin à true si page uniquement pour les administrateurs
* @return booléen suivant si connexion active ou non
* @author Fabrice PENHOËT
**/
public function test_session($destroy=true,$admin=false)
{
if(MSG_MAINTENANCE!="")
return false;
session_save_path(SESSIONS_REP);
ini_set("session.use_only_cookies",1);
session_start();
if(empty($_SESSION))
$this->test_cookies();
/*
// bloque certains utilisateurs et ne sécurise pas grand chose..
// données servant à contrôler la session :
$ip_connexion=getIp();
$user_agent=$_SERVER["HTTP_USER_AGENT"];
if((empty($ip_connexion))||(empty($user_agent)))
return false;
if((!empty($_SESSION["id_utilisateur"]))&&(!empty($_SESSION["pseudo"]))&&(!empty($_SESSION["statut"]))&&(($_SESSION["controle"]==$user_agent)||($_SESSION["controle_ip"]==$ip_connexion)))//il semble que le user-agent change parfois aussi en cours de route mais les 2 c'est louche !*/
if((!empty($_SESSION["id_utilisateur"]))&&(!empty($_SESSION["pseudo"]))&&(!empty($_SESSION["statut"])))
{
$this->id_utilisateur=$_SESSION["id_utilisateur"];
$this->pseudo=strval($_SESSION["pseudo"]);//atttibut privé ne pouvant être utilisé en dehors de la classe. Du coup, voir si vraiment utile ?
$this->statut=strval($_SESSION["statut"]);//idem
$this->connexion_ok=true;
if(($admin)&&($_SESSION["statut"]!="administrateur"))
return false;
else
return true;
}
else
{
if(($destroy)&&(!empty($_SESSION)))
{
$_SESSION=array();
session_destroy();
}
}
}
/**
* Méthode supprimant tout ce qui est rapport avec une session
* cookies, fichiers de contrôle et variables de session
*
* @param null
* @return booléen suivant réussite
* @author Fabrice PENHOËT
**/
public function supprime_session()
{
if(!isset($_SESSION))
{
session_save_path(SESSIONS_REP);
session_start();
}
if((!empty($_COOKIE["ctrl"]))&&(!empty($_COOKIE["mois"])))
{
if((strpos("/",$_COOKIE["ctrl"])!==false)||(strpos("/",$_COOKIE["mois"])!==false))
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES));
else
{
$tab_mois=explode("-",$_COOKIE["mois"]);
$mois_ok=array("01","02","03","04","05","06","07","08","09","10","11","12");
if(!in_array($tab_mois[1],$mois_ok))
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES));
else
{
$chemin_ticket=COOKIES_REP."/".intval($tab_mois[0])."/".$tab_mois[1]."/cook".$_COOKIE["ctrl"];
unlink($chemin_ticket);
}
}
setcookie("ctrl","",time()-42000,"/",SITE_COOKIES_DOMAINE);
setcookie("mois","",time()-42000,"/",SITE_COOKIES_DOMAINE);
}
setcookie("rdg","",time()-42000,"/",SITE_COOKIES_DOMAINE);//peut exister si l'utilisateur a été redirigé lors de la connexion
$_SESSION=array();
if (ini_get("session.use_cookies"))
{
$params=session_get_cookie_params();
setcookie(session_name(),"",time()- 42000,$params["path"],$params["domain"],$params["secure"], $params["httponly"]);
}
session_destroy();
if(empty($_SESSION))
return true;
else
return false;
}
/**
* Méthode important dans la bd le contenu des fichiers temporaires de session
* puis supprimant les fichiers en question
*
* @param null
* @return booléen suivant réussite
* @author Fabrice PENHOËT
**/
static function sauve_sessions()
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(!is_dir(SESSIONS_TEMP_REP))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_REP_EXISTE." >> ".htmlentities(SESSIONS_REP,ENT_QUOTES)));
return false;
}
$rep=opendir(SESSIONS_TEMP_REP);
$tab=array();
while($fichier=readdir($rep))
{
if(!(is_dir(SESSIONS_TEMP_REP."/$fichier"))&&($fichier!=".")&&($fichier!=".."))
$tab[$fichier]=file_get_contents(SESSIONS_TEMP_REP."/$fichier");
}
closedir($rep);
$nb_import=0;
if(!empty($tab))
{
$prepare=$Bd->prepare("INSERT INTO utilisateurs_sessions (utilisateur_id,time_session,ip_session,config,referer) VALUES (:id,:time,:ip,:config,:referer)");
foreach ($tab as $fichier=>$contenu)
{
$tab2=explode("##",$contenu);
if(count($tab2)==5)
{
$ajout=$prepare->execute(array(':id'=>$tab2[0],':time'=>$tab2[1],':ip'=>$tab2[2],':config'=>$tab2[3],':referer'=>$tab2[4]));
test_requete(__FILE__,__LINE__,$ajout,$prepare);//pour infos mais je ne bloque pas sinon fichier non supprimé
$nb_import++;
}
unlink(SESSIONS_TEMP_REP."/$fichier");//contenu ok ou pas, le fichier est supprimé...
}
$prepare=null;
}
return $nb_import;
}
/**
* Méthode actualisant un journal comptabilisant les pages visitées par un abonné connecté
*
* @param $page affichée et $contexte de l'affichage (pour distinguer les mails)
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
public function ajout_journal_affichage($page=null,$contexte="site")
{
if(empty($this->id_utilisateur))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT));
return false;
}
if(empty($page) || (strpos($page,SITE_URL) === false && strpos($page,str_replace("https", "http", SITE_URL)) === false))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT));
return false;
}
else
$page=str_replace(SITE_URL,"",$page);
if(empty($page))
$page="accueil";
$contextes_ok=explode("|",ABO_AFFICHAGES_CONTEXTE);
if (!in_array($contexte,$contextes_ok))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES." >> ".htmlentities($contexte,ENT_QUOTES)));
return false;
}
$repertoire_fichier=CACHE_REP."/".CACHE_REP_UTILISATEURS."/affichages/";
$nom_fichier=strval(date('Y-m-d-H-i'));
$now=time();
if($contexte=="email")
$config=$_SERVER['HTTP_USER_AGENT'];
else
$config=null;//info déjà récupérée lors de la connexion au site
$code="\$a[$now]['c']='".$contexte."';\$a[$now]['u_id']='".$this->id_utilisateur."';\$a[$now]['page']=\"".htmlentities($page,ENT_QUOTES)."\";\$a[$now]['conf']=\"".htmlentities($config,ENT_QUOTES)."\";";
if(file_exists($repertoire_fichier.$nom_fichier))
{
if(!file_put_contents($repertoire_fichier.$nom_fichier,$code,FILE_APPEND | LOCK_EX))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_ECRITURE));
return false;
}
else
return true;
}
else
{
if(!file_exists($repertoire_fichier))
{
if(!mkdir($repertoire_fichier,CACHE_REP_CHMOD,true))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_REP_CREA));
return false;
}
}
if(!file_put_contents($repertoire_fichier.$nom_fichier,"<?php\n$code",LOCK_EX))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_ECRITURE));
return false;
}
else
return true;
}
}
/**
* Méthode retournant la liste des administrateurs du site
*
* @param null
* @return les données de la table dans un tableau si trouvé, false si pas trouvé ou en cas d'erreur
* @author Fabrice PENHOËT
**/
static function get_admins()
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
$get_admins=$Bd->query("SELECT id_utilisateur,pseudo,email FROM utilisateurs WHERE statut='administrateur';");
if((test_requete(__FILE__,__LINE__,$get_admins)===false)) return false;
$resultat=$get_admins->fetchAll(PDO::FETCH_ASSOC);
if(empty($resultat))
return false;
else
return $resultat;
}
/**
* Méthode enregistrant le contenu du journal des affichages
*
* @param null
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
static function sauve_journal_affichages()
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
$time_limite=time()-60;//un fichier est créé / minute, donc si fichier a + de 60 secondes, on peut l'importer
$repertoire_fichier=CACHE_REP."/".CACHE_REP_UTILISATEURS."/affichages/";
$rep=opendir($repertoire_fichier);
$affichages=array();
while($fichier=readdir($rep))
{
if(!(is_dir($repertoire_fichier.$fichier))&&($fichier!=".")&&($fichier!=".."))
{
$dates_fichier=explode("-",$fichier);
if(!checkdate($dates_fichier[1],$dates_fichier[2],$dates_fichier[0]))
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_DATE_VALIDE));
else
{
$time_fichier=filemtime($repertoire_fichier.$fichier);
if($time_fichier<$time_limite)
{
include($repertoire_fichier.$fichier);
if(is_array($a))
$affichages=$affichages+$a;
unlink($repertoire_fichier.$fichier);//dans tous les cas, le fichier est supprimé
unset($a);
}
}
}
}
closedir($rep);$nb_import=0;
if(count($affichages)!=0)
{
$prepare=$Bd->prepare("INSERT INTO utilisateurs_affichages (utilisateur_id,page,config,time_affichage,contexte) VALUES (:id,:page,:config,:time,:contexte)");
foreach ($affichages as $time_a=>$infos)
{
$test_utilisateur=FclFlux_utilisateur::recherche($infos["u_id"],"id_utilisateur","id_utilisateur");
if(!empty($test_utilisateur))
{
$ajout=$prepare->execute(array(':id'=>$infos["u_id"],':page'=>$infos["page"],':config'=>$infos["conf"],':time'=>$time_a,':contexte'=>$infos["c"]));
if((test_requete(__FILE__,__LINE__,$ajout,$prepare)===false)) return false;
$nb_import++;
}
}
$prepare=null;
}
return $nb_import;
}
/**
* Méthode vidant les valeurs anciennes de la table comptant les affichages
* tout en archivant certaines statistiques de configuration
*
* @param mois à archiver format YYYY-N, vide si c'est le mois précédent
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
static function nettoye_logs_affichages($mois=null)
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
//d'abord les affichages des utilisateurs connectés sur le site
$time_limite=time()-NB_JOURS_LOGS_AFFICHAGES*3600*24;
$suppr_log=$Bd->query("DELETE FROM utilisateurs_affichages WHERE contexte='site' AND time_affichage<$time_limite;");
if((test_requete(__FILE__,__LINE__,$suppr_log)===false)) return false;
unset($suppr_log);
//pour les logs d'email, soit le mois à traiter est fourni,
//soit je traite le mois précédent mais seulement si nous sommes le 1er du mois.
if(empty($mois)&&(date("j")==1))
{
$m=date("n");
if($m!=1)
{
$m=$m-1;
$mois=date("Y")."-$m";
}
else
{
$a=date("Y")-1;
$mois="$a-12";//décembre de l'année précédente
}
}
if(!empty($mois))
{
$Date_debut=explode("-",$mois);
$time_premier_jour=mktime(0,0,0,intval($Date_debut[1]),1,intval($Date_debut[0]));
if($time_premier_jour===false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT.$mois));
return false;
}
if($Date_debut[1]=="12")//chgt d'année
{
$Date_fin[1]=1;
$Date_fin[0]=$Date_debut[0]+1;
}
else
{
$Date_fin[1]=$Date_debut[1]+1;
$Date_fin[0]=$Date_debut[0];
}
$time_dernier_jour=mktime(0,0,0,$Date_fin[1],1,$Date_fin[0]);
if($time_dernier_jour===false)
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT.$Date_fin[0]."-".$Date_fin[1]));
return false;
}
$recherche_config=$Bd->query("SELECT config,count(DISTINCT utilisateur_id) AS nb FROM utilisateurs_affichages WHERE contexte='email' AND time_affichage>=$time_premier_jour AND time_affichage<$time_dernier_jour GROUP BY config;");
if((test_requete(__FILE__,__LINE__,$recherche_config)===false)) return false;
$resultats=$recherche_config->fetchAll(PDO::FETCH_ASSOC);
unset($recherche_config);
$prepare=$Bd->prepare("INSERT INTO utilisateurs_config_svg (config,mois,nb_utilisateurs) VALUES (:config,:mois,:nb)");
foreach($resultats as $config)
{
$ajout=$prepare->execute(array(':config'=>$config["config"],':mois'=>$mois,':nb'=>$config["nb"]));
if((test_requete(__FILE__,__LINE__,$ajout,$prepare)===false)) return false;
}
//pas de bug arrivé là, je peux supprimer les enregistrements du mois.
$suppr_log=$Bd->query("DELETE FROM utilisateurs_affichages WHERE contexte='email' AND time_affichage>=$time_premier_jour AND time_affichage<$time_dernier_jour;");
if((test_requete(__FILE__,__LINE__,$suppr_log)===false)) return false;
}
return true;
}
/**
* Méthode parcourant les répertoires contenant des fichiers temporaires pour supprimer ceux obsolètes
* concernés : tickets validation compte/nouvelle email, fichiers/session, fichiers ctrl des cookies, tickets de connexion
*
* @param null
* @return booléen suivant réussite
* @author Fabrice PENHOËT
**/
static function supprime_fichiers_temp()
{
if(is_dir(SESSIONS_REP))
{
$rep=opendir(SESSIONS_REP);
while($fichier=readdir($rep))
{
if(!(is_dir(SESSIONS_REP."/".$fichier))&&($fichier!=".")&&($fichier!=".."))
{
if(filemtime(SESSIONS_REP."/".$fichier)<(time()-3600*3))
{
if(!unlink(SESSIONS_REP."/".$fichier))
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_SUPPR." >> ".SESSIONS_REP."/".htmlentities($fichier,ENT_QUOTES)));
}
}
}
closedir($rep);
}
if(is_dir(COOKIES_REP))
{
$time_limite_cookies=time()-(180*24*3600);//durée max cnil
$date_limite=date("Y-m",$time_limite_cookies);
$dates_limite=explode("-",$date_limite);
$rep=opendir(COOKIES_REP);
while($fichier=readdir($rep))
{
if((is_dir(COOKIES_REP."/".$fichier))&&($fichier!=".")&&($fichier!=".."))
{
if(intval($fichier)<intval($dates_limite[0]))
supprime_repertoire(COOKIES_REP."/".$fichier);
else
{
$rep2=opendir(COOKIES_REP."/".$fichier);
while($fichier2=readdir($rep2))
{
if((is_dir(COOKIES_REP."/".$fichier."/".$fichier2))&&($fichier2!=".")&&($fichier2!=".."))
{
if(intval($fichier2)<intval($dates_limite[1]))
supprime_repertoire(COOKIES_REP."/".$fichier."/".$fichier2);
}
}
}
}
}
closedir($rep);
}
if(is_dir(TICKET_VALID_REP))
{
$rep=opendir(TICKET_VALID_REP);
while($fichier=readdir($rep))
{
if(!(is_dir(TICKET_VALID_REP."/$fichier"))&&($fichier!=".")&&($fichier!=".."))
{
if(strpos($fichier,"valid")!==false)
{
if(filemtime(TICKET_VALID_REP."/$fichier")<(time()-3600*24*COMPTE_VALIDATION_MAX_DUREE))
{
if(!unlink(TICKET_VALID_REP."/".$fichier))
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_SUPPR." >> ".TICKET_VALID_REP."/".htmlentities($fichier,ENT_QUOTES)));
}
}
else if(strpos($fichier,"email")!==false)
{
if(filemtime(TICKET_VALID_REP."/$fichier")<(time()-3600*24*NOUVEL_EMAIL_MAX_DUREE_VALIDATION))
{
if(!unlink(TICKET_VALID_REP."/".$fichier))
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_SUPPR." >> ".TICKET_VALID_REP."/".htmlentities($fichier,ENT_QUOTES)));
}
}
}
}
closedir($rep);
}
if(is_dir(TICKET_CONNECT_REP))
{
$rep=opendir(TICKET_CONNECT_REP);
while($fichier=readdir($rep))
{
if(!(is_dir(TICKET_CONNECT_REP."/".$fichier))&&($fichier!=".")&&($fichier!=".."))
{
if(filemtime(TICKET_CONNECT_REP."/".$fichier)<(time()-60*COMPTE_LIEN_CONNEXION_MAX_DUREE))
{
if(!unlink(TICKET_CONNECT_REP."/".$fichier))
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FICHIER_SUPPR." >> ".TICKET_CONNECT_REP."/".htmlentities($fichier,ENT_QUOTES)));
}
}
}
closedir($rep);
}
return true;
}
/**
* Méthode supprimant les données sauvegardées / anciens utilisateurs
* ceci inclus les données de leurs sessions
* on garde néanmoins une version anonymisée des enregistrements de création / suppresion de compte (pour stats) !!!
* supprime aussi les utilisateurs qui n'ont pas validé leur compte au-delà la date limite ou encore étant inactif depuis + d'un an
*
* @return booléen suivant succès
* @author Fabrice PENHOËT
**/
static function supprime_anciens_utilisateurs()
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
$time_limite=time()-DUREE_SVG_DONNEES*24*3600;
$cherche_anciens=$Bd->query("SELECT id_utilisateur,time_maj,time_crea,time_suppr FROM utilisateurs_svg WHERE (id_utilisateur NOT IN (SELECT id_utilisateur FROM utilisateurs)) and (id_utilisateur in (SELECT id_utilisateur FROM utilisateurs_svg GROUP BY id_utilisateur HAVING MAX(time_maj)<$time_limite));");
if((test_requete(__FILE__,__LINE__,$cherche_anciens)===false))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_RECHERCHE." >> ".$time_limite));
return false;
}
$resultats=$cherche_anciens->fetchAll(PDO::FETCH_ASSOC);
$cherche_anciens=null;
$prepare_suppr=$Bd->prepare("DELETE FROM utilisateurs_svg WHERE id_utilisateur=:id AND time_maj=:time;");
$prepare_anonyme=$Bd->prepare("UPDATE utilisateurs_svg SET pseudo=NULL,passe=NULL,email=NULL,presentation=NULL,illustration=NULL,ip_crea=NULL,fuseau_horaire=NULL WHERE id_utilisateur=:id AND time_maj=:time;");
$i=0;
while(isset($resultats[$i]))
{
if(($resultats[$i]["time_crea"]!=$resultats[$i]["time_maj"])&&(empty($resultats[$i]["time_suppr"])))
{
$suppr=$prepare_suppr->execute(array(':id'=>$resultats[$i]["id_utilisateur"],':time'=>$resultats[$i]["time_maj"]));
if((test_requete(__FILE__,__LINE__,$suppr,$prepare_suppr)===false))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_SUPPR." >> ".$resultats[$i]["id_utilisateur"]));
return false;
}
}
else
{// je garde les dates de création et suppression du compte mais sans données perso
$maj=$prepare_anonyme->execute(array(':id'=>$resultats[$i]["id_utilisateur"],':time'=>$resultats[$i]["time_maj"]));
if((test_requete(__FILE__,__LINE__,$maj,$prepare_anonyme)===false))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_MAJ." >> ".$resultats[$i]["id_utilisateur"]));
return false;
}
}
$i++;
}
$prepare_suppr=null;$prepare_anonyme=null;
$suppr_sessions=$Bd->query("DELETE FROM utilisateurs_sessions WHERE utilisateur_id IN (select id_utilisateur FROM utilisateurs_svg WHERE time_suppr< $time_limite);");
if((test_requete(__FILE__,__LINE__,$suppr_sessions)===false))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_SUPPR));
return false;
}
$suppr_sessions=null;
//les utilisateurs qui n'ont pas validé leur compte dans les temps sont supprimés des 2 tables
$suppr_sans_validation=$Bd->query("DELETE FROM utilisateurs_svg WHERE id_utilisateur IN (SELECT id_utilisateur FROM utilisateurs WHERE time_validation=0 and time_crea<".(time()-(3600*24*COMPTE_VALIDATION_MAX_DUREE)).");");
if((test_requete(__FILE__,__LINE__,$suppr_sans_validation)===false))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_SUPPR." >> ".$time_limite));
return false;
}
//l'utilisateur ayant pu s'abonner et modifier ses infos lors de la création de son compte, il faut lancer une suppression "normale" (fichiers cache, etc.)
//!!! peut-être garder des stats quelque part ???
$suppr_sans_validation=$Bd->query("SELECT id_utilisateur FROM utilisateurs WHERE time_validation=0 and time_crea<".(time()-(3600*24*COMPTE_VALIDATION_MAX_DUREE)).";");
if((test_requete(__FILE__,__LINE__,$suppr_sans_validation)===false))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_RECHERCHE));
return false;
}
$resultat_suppr=$suppr_sans_validation->fetchAll(PDO::FETCH_ASSOC);
$suppr_sans_validation=null;
foreach($resultat_suppr as $suppr)
{
$ancien=new FclFlux_utilisateur();
$ancien->id_utilisateur=$suppr["id_utilisateur"];
$ancien->supprime(false);
unset($ancien);
}
}
/**
* Méthode retournant les principales stats concernant les utilisateurs du site durant une période donnée :
* création comptes, email envoyés, clics, etc.
*
* @param timestamp de début et de fin de la période visée
* @return un tableau contenant les chiffres
* @author Fabrice PENHOËT
**/
static function get_stats_utilisateurs($time_debut=0,$time_fin=0)
{
global $Bd;global $hub_site;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(empty($time_fin))
$time_fin=time();
if((empty($time_debut))&&($time_debut!=0))
$time_debut=$time_fin-3600*24;
$statistiques=array();
// les comptes créés :
$get_stats=$Bd->query("SELECT id_utilisateur FROM utilisateurs WHERE time_crea>$time_debut AND time_crea<$time_fin;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_comptes"]=$get_stats->rowCount();
// les comptes validés :
$get_stats=$Bd->query("SELECT id_utilisateur FROM utilisateurs WHERE time_validation>$time_debut AND time_validation<$time_fin;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_comptes_valide"]=$get_stats->rowCount();
// tous les comptes de + de 6 mois :
$time_limite_6mois=time()-3600*24*180;
$get_stats=$Bd->query("SELECT DISTINCT id_utilisateur FROM utilisateurs_svg WHERE time_crea<$time_limite_6mois;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_comptes_6mois"]=$get_stats->rowCount();
// tous les comptes de + de 1 an :
$time_limite_1an=time()-3600*24*365;
$get_stats=$Bd->query("SELECT DISTINCT id_utilisateur FROM utilisateurs_svg WHERE time_crea<$time_limite_1an;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_comptes_1an"]=$get_stats->rowCount();
// les comptes supprimés :
$get_stats=$Bd->query("SELECT id_utilisateur FROM utilisateurs_svg WHERE time_suppr>$time_debut AND time_suppr<$time_fin;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_comptes_suppr"]=$get_stats->rowCount();
// pour toutes les stats sur les abonnements, on ne compte pas l'abonnement par défaut aux news du site :
$sup_sql="";
if(!empty($hub_site["id"]))
$sup_sql="AND id_abonnement NOT IN (SELECT DISTINCT id_abonnement FROM abonnements_hub WHERE id_hub=".$hub_site["id"].")";
// tous les abonnements :
$get_stats=$Bd->query("SELECT id_abonnement FROM abonnements WHERE time_crea>$time_debut AND time_crea<$time_fin $sup_sql;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_abo"]=$get_stats->rowCount();
// les abonnements avec envoi / mail :
$get_stats=$Bd->query("SELECT id_abonnement FROM abonnements WHERE time_crea>$time_debut AND time_crea<$time_fin AND jours_alerte!='' $sup_sql;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_abo_email"]=$get_stats->rowCount();
// tous les abonnés :
$get_stats=$Bd->query("SELECT distinct auteur_id FROM abonnements WHERE time_crea>$time_debut AND time_crea<$time_fin $sup_sql;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_abonnes"]=$get_stats->rowCount();
// tous les abonnés de + de 6 mois :
$get_stats=$Bd->query("SELECT distinct auteur_id FROM abonnements WHERE time_crea<$time_limite_6mois $sup_sql;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_abonnes_6mois"]=$get_stats->rowCount();
// tous les abonnés de + de 1an :
$get_stats=$Bd->query("SELECT distinct auteur_id FROM abonnements WHERE time_crea<$time_limite_1an $sup_sql;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_abonnes_1an"]=$get_stats->rowCount();
// les abonnés avec au moins un abonnement actif :
$get_stats=$Bd->query("SELECT distinct auteur_id FROM abonnements WHERE time_crea>$time_debut AND time_crea<$time_fin AND jours_alerte!='' $sup_sql;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_abonnes_email"]=$get_stats->rowCount();
// les abonnés toujours actifs au-delà de 6 mois :
$get_stats=$Bd->query("SELECT distinct auteur_id FROM abonnements WHERE time_crea<$time_limite_6mois AND jours_alerte!='' $sup_sql;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_abonnes_email_6mois"]=$get_stats->rowCount();
// les abonnés toujours actifs au-delà de 1 an :
$get_stats=$Bd->query("SELECT distinct auteur_id FROM abonnements WHERE time_crea<$time_limite_1an AND jours_alerte!='' $sup_sql;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_abonnes_email_1an"]=$get_stats->rowCount();
// tous les comptes sans abonnements :
$statistiques["nb_fantomes"]=$statistiques["nb_comptes_valide"]-$statistiques["nb_abonnes"];
// les comptes ayant au moins un abonnement mais aucun actif :
$statistiques["nb_abonnes_desactives"]=$statistiques["nb_abonnes"]-$statistiques["nb_abonnes_email"];
// tous les emails envoyés :
$get_stats=$Bd->query("SELECT abonnement_id FROM abonnements_mail WHERE time_envoi>$time_debut AND time_envoi<$time_fin;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_mail_envoyes"]=$get_stats->rowCount();
// les emails envoyés uniques :
$get_stats=$Bd->query("SELECT distinct utilisateur_id FROM abonnements_mail WHERE time_envoi>$time_debut AND time_envoi<$time_fin;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_mail_uniques_envoyes"]=$get_stats->rowCount();
// tous les clics dans les emails :
$get_stats=$Bd->query("SELECT id_clic FROM stat_clics_posts WHERE time_clic>$time_debut AND time_clic<$time_fin AND contexte='email';");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_clics_email"]=$get_stats->rowCount();
// les clics uniques dans les emails :
$get_stats=$Bd->query("SELECT distinct utilisateur_id FROM stat_clics_posts WHERE time_clic>$time_debut AND time_clic<$time_fin AND contexte='email';");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_clics_uniques_email"]=$get_stats->rowCount();
// tous les clics web sur le site :
$get_stats=$Bd->query("SELECT id_clic FROM stat_clics_posts WHERE time_clic>$time_debut AND time_clic<$time_fin AND contexte='site';");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_clics_site"]=$get_stats->rowCount();
// les clics uniques sur le site :
$get_stats=$Bd->query("SELECT distinct utilisateur_id FROM stat_clics_posts WHERE time_clic>$time_debut AND time_clic<$time_fin AND contexte='site';");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_clics_uniques_site"]=$get_stats->rowCount();
// tous les clics sur la période :
$statistiques["nb_clics"]=$statistiques["nb_clics_email"]+$statistiques["nb_clics_site"];
// tous les clics uniques :
$get_stats=$Bd->query("SELECT distinct utilisateur_id FROM stat_clics_posts WHERE time_clic>$time_debut AND time_clic<$time_fin;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["nb_clics_uniques"]=$get_stats->rowCount();
unset($get_stats);
unset($stats);
if(empty($statistiques))
return false;
else
return $statistiques;
}
/**
* Méthode retournant les principales stats concernant les adresses emails des utilisateurs du site durant une période donnée.
* Pour chaque domaine : nombre de comptes actifs, inactifs, cliqueurs...
*
* @param timestamp de début et de fin de la période visée, $nb_min nombre minimum d'utilisateur ayant une adresse de ce fournisseur.
* @return un tableau contenant les chiffres
* @author Fabrice PENHOËT
**/
static function get_stats_email($time_debut=0,$time_fin=0,$nb_min=2)
{
global $Bd;global $hub_site;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(empty($time_fin))
$time_fin=time();
if((empty($time_debut))&&($time_debut!=0))
$time_debut=$time_fin-3600*24;
$statistiques=array();
// les fournisseurs d'adresses email des comptes actifs ou non :
$get_stats=$Bd->query("SELECT SUBSTRING(email,(LOCATE(\"@\",email))+1) AS ndd,count(*) AS cpt FROM utilisateurs GROUP BY ndd HAVING cpt>$nb_min ORDER BY count(*) DESC;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["liste_emails_total"]=$get_stats->fetchAll();
// pour toutes les stats sur les abonnements, on ne compte pas l'abonnement par défaut aux news du site :
$sup_sql="";
if(!empty($hub_site["id"]))
$sup_sql="AND id_abonnement NOT IN (SELECT DISTINCT id_abonnement FROM abonnements_hub WHERE id_hub=".$hub_site["id"].")";
// les fournisseurs d'adresses email des comptes ayant encore au moins un abonnement actif :
$get_stats=$Bd->query("SELECT SUBSTRING(email,(LOCATE(\"@\",email))+1) AS ndd,count(*) AS cpt FROM utilisateurs WHERE (id_utilisateur in (SELECT distinct auteur_id FROM abonnements WHERE jours_alerte!='' $sup_sql)) GROUP BY ndd HAVING Cpt>$nb_min ORDER BY cpt DESC;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["liste_emails_actifs"]=$get_stats->fetchAll();
// les fournisseurs d'adresses email des cliqueurs sur la période demandée :
$get_stats=$Bd->query("SELECT SUBSTRING(email,(LOCATE(\"@\",email))+1) AS ndd,count(*) AS cpt FROM utilisateurs WHERE (id_utilisateur in (SELECT distinct utilisateur_id FROM stat_clics_posts WHERE time_clic>$time_debut AND time_clic<$time_fin)) GROUP BY ndd HAVING Cpt>$nb_min ORDER BY cpt DESC;");
if((test_requete(__FILE__,__LINE__,$get_stats)!==false))
$statistiques["liste_emails_cliqueur"]=$get_stats->fetchAll();
unset($get_stats);
if(empty($statistiques))
return false;
else
return $statistiques;
}
/**
* Méthode fournissant à un administrateur, certaines infos concernant l'utilisateur.
*
* @param
* @return tableaux avec les différentes données
* @author Fabrice PENHOËT
**/
public function get_infos_admin()
{
global $Bd;
if((isset_connexion(__FILE__,__LINE__)===false)) return false;
if(empty($this->id_utilisateur))
{
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT));
return false;
}
$id_utilisateur=$this->id_utilisateur;
$infos=array();
//ses abonnements.
$get_abos=$Bd->query("SELECT * FROM abonnements WHERE auteur_id=$id_utilisateur;");
if((test_requete(__FILE__,__LINE__,$get_abos)===false)) return false;
$abos=$get_abos->fetchAll(PDO::FETCH_ASSOC);
if(count($abos)!=0)
{
$i=0;
foreach ($abos as $abo)
{
$infos["abos"][$i]=$abo;
//dernier envoi réussi ?
$get_dernier_envoi=$Bd->query("SELECT time_envoi FROM abonnements_mail WHERE abonnement_id=".$abo["id_abonnement"]." ORDER BY time_envoi DESC LIMIT 0,1;");
if((test_requete(__FILE__,__LINE__,$get_dernier_envoi)===false)) return false;
$envoi=$get_dernier_envoi->fetchAll(PDO::FETCH_ASSOC);
if(!empty($envoi[0]["time_envoi"]))
$infos["abos"][$i]["time_dernier_envoi"]=$envoi[0]["time_envoi"];
//liste des hubs concernés par cet abonnement
$get_hubs=$Bd->query("SELECT H.nom,H.id_hub FROM hub AS H,abonnements_hub AS A WHERE ((H.id_hub=A.id_hub) AND (A.id_abonnement=".$abo["id_abonnement"]."));");
if((test_requete(__FILE__,__LINE__,$get_hubs)===false)) return false;
$hubs=$get_hubs->fetchAll(PDO::FETCH_ASSOC);
if(count($hubs)!=0)
$infos["abos"][$i]["hubs"]=$hubs;
$i++;
}
}
$get_dernier_envoi=null;$get_hubs=null;$get_abos=null;
// dernières activités du compte
$hier=time()-3600*24;
$semaine=time()-3600*24*7;
//les 10 dernières sessions enregistrées
$get_sessions=$Bd->query("SELECT * FROM utilisateurs_sessions WHERE utilisateur_id=$id_utilisateur AND time_session>$semaine ORDER BY time_session DESC LIMIT 0,10;");
$sessions=$get_sessions->fetchAll(PDO::FETCH_ASSOC);
if(count($sessions)!=0)
$infos["sessions"]=$sessions;
$get_sessions=null;
//les pages où il est passé
$get_pages=$Bd->query("SELECT page,time_affichage,contexte FROM utilisateurs_affichages WHERE utilisateur_id=$id_utilisateur AND time_affichage>$semaine ORDER BY time_affichage DESC;");
$pages=$get_pages->fetchAll(PDO::FETCH_ASSOC);
$nb_pages=count($pages);
if(count($pages)!=0)
$infos["pages"]=$pages;
return $infos;
}
}