limites=$infos["limites"]; unset($infos["limites"]); $erreur_ok=false; foreach ($infos 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 vérifiant que le paramètre fourni est bien une source existante * et lui attribuant l'origine du flux si c'est le cas * cet attribut ne peut être vide * * @param la valeur à contrôler * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function set_source($source) { if(!empty($source)) { if(!($source instanceof FclFlux_source)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } if(empty($source->id_source)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } $existe=FclFlux_source::recherche($source->id_source,"id_source"); if(empty($existe)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_ENREG_ABSENT)); return false; } } else $source=""; $this->source=$source; return true; } /** * Méthode vérifiant que le paramètre fourni est bien un utilisateur existant * et lui attribuant l'origine du flux si c'est le cas * cet attribut ne peut être vide * * @param la valeur à contrôler * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function set_auteur($auteur) { if(!($auteur instanceof FclFlux_utilisateur)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } if(empty($auteur->id_utilisateur)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } $existe=FclFlux_utilisateur::recherche($auteur->id_utilisateur,"id_utilisateur","id_utilisateur"); if(empty($existe)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_ENREG_ABSENT." >> ".intval($auteur->id_utilisateur))); return false; } $this->auteur=$auteur; return true; } /** * Méthode vérifiant le texte de description fourni * * @param la description à contôler * @return booléen suivant succès * @author Fabrice PENHOËT */ public function set_description($description) { if(empty($this->limites["description_long_max"])) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } $long_max=$this->limites["description_long_max"]; if(!is_int($long_max)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } $description=strip_tags(strval(trim($description))); if(empty($description)) $this->description=null; else $this->description=get_chaine_debut($description,$long_max," (...)"); return true; } /** * Méthode vérifiant que le paramètre fourni fait partie des valeurs possibles * et lui attribuant la fréquence de lecture du flux si c'est le cas * cet attribut ne peut être vide * * @param la valeur à contrôler * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function set_frequence_maj($frequence_maj) { $valeurs_ok=explode("|",FLUX_FREQUENCES); if(empty($valeurs_ok)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } if (!in_array($frequence_maj,$valeurs_ok)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES." >> ".htmlentities($frequence_maj,ENT_QUOTES))); return false; } $this->frequence_maj=$frequence_maj; return true; } /** * Méthode vérifiant que le paramètre fourni fait partie des valeurs possibles * et lui attribuant la langue principale du flux si c'est le cas * cet attribut ne peut être vide * * @param la valeur à contrôler * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function set_langue($langue) { $valeurs_ok=explode("|",FLUX_LANGUES); if(empty($valeurs_ok)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } if (!in_array($langue,$valeurs_ok)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES." >> ".htmlentities($langue,ENT_QUOTES))); return false; } $this->langue=$langue; return true; } /** * Méthode testant la validité du mémo saisi pour un flux * et l'attribuant à l'objet si ok * * @param le texte à contôler * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function set_memo($memo) { $long_min=(!empty($this->limites["memo_long_min"]))?$this->limites["memo_long_min"]:0; if(empty($this->limites["memo_long_max"])) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } $long_max=$this->limites["memo_long_max"]; if((($long_min!=0)&&(!is_int($long_min)))||(!is_int($long_max))||($long_max<$long_min)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } $memo=strip_tags(strval(trim($memo))); $longueur=strlen($memo); if(($longueur<$long_min)||($longueur>$long_max)) { $this->erreurs=array_merge($this->erreurs,(array) (str_replace("__MAX__",$long_max,ERREUR_FLUX_MEMO_LONG))); return false; } else { $this->memo=$memo; return true; } } /** * Méthode testant l'existence d'un flux dans le bd via son id_flux ou son url (seuls champs identifiant) * * @param 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($valeur,$champ_recherche="id_flux",$champ_sortie="*") { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if(strpos("id_flux,url",$champ_recherche)===false) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_CHAMP_RECHERCHE." >> ".htmlentities($champ_recherche,ENT_QUOTES))); return false; } $prepare=$Bd->prepare("SELECT $champ_sortie FROM flux 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 des flux dans le bd pour un (ou +sieurs) mots-clés. * * @param 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)."%";//qd espaces, cherchez plusieurs mots plutôt qu'une seule expression ??? $prepare=$Bd->prepare("SELECT $champ_sortie FROM flux WHERE id_flux=:cherche_id OR nom LIKE :recherche OR url LIKE :recherche OR description LIKE :recherche ORDER BY nom ASC;"); $recherche=$prepare->execute(array(":cherche_id"=>$recherche,":recherche"=>$recherche_like)); 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; } /** * Test si une valeur donnée pour un champ est déjà utilisée pour un autre flux * * @return true si valeur non trouvée * @author Fabrice PENHOËT **/ public function est_libre($champ="url") { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if(empty($this->id_flux))//nouveau flux non encore enregistré { $prepare=$Bd->prepare("SELECT id_flux FROM flux WHERE $champ=:$champ"); $recherche=$prepare->execute(array(":$champ"=>$this->$champ)); } else { $prepare=$Bd->prepare("SELECT id_flux FROM flux WHERE ($champ=:$champ and id_flux!=:id)"); $recherche=$prepare->execute(array(":$champ"=>$this->$champ,":id"=>$this->id_flux)); } 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 enregistrant un nouveau flux * * @param $hub dans lequel classé ce flux si on le connait. * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function ajout($hub=null) { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if((empty($this->designation))||(empty($this->url))||(empty($this->auteur))) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } if(!($this->est_libre())) { $this->erreurs=array_merge($this->erreurs,(array) ERREUR_FLUX_DOUBLON); return false; } if(empty($this->langue)) $this->langue="fr"; if(empty($this->frequence_maj)) $this->frequence_maj="J"; $this->time_crea=time(); // cas particulier de GG News $gg_news_ok=false; if((strpos($this->url,"https://news.google.com")!==false)&&(defined("SOURCE_GG_NEWS_ID"))) { $gg_news=new FclFlux_source(); $gg_news->id_source=SOURCE_GG_NEWS_ID; $this->set_source($gg_news); unset($gg_news); $gg_news_ok=true; } //le flux est-il à valider par un administrateur ? $est_admin=$this->auteur->est_admin(); if(($est_admin)||($gg_news_ok)) $this->time_maj=$this->time_crea; else $this->time_maj=0;//reste à valider if(empty($this->source)) {//si je n'ai pas de source fournie, j'en créé une, basée sur les infos du flux. $source=new FclFlux_source(); $max["url_long_max"]=SOURCE_MAX_URL; $max["designation_long_min"]=SOURCE_MIN_NOM; $max["designation_long_max"]=SOURCE_MAX_NOM; $max["description_long_max"]=SOURCE_MAX_DESCRIPTION; $source->limites=$max; if(!empty($this->source_url)) $source->set_url(get_chaine_debut($this->source_url,SOURCE_MAX_URL)); else $source->set_url(get_chaine_debut($this->url,SOURCE_MAX_URL)); $source->set_designation(get_chaine_debut($this->designation,SOURCE_MAX_NOM)); $source->set_description(get_chaine_debut($this->description,SOURCE_MAX_DESCRIPTION)); $source->set_auteur($this->auteur); $source->ajout(); if(empty($source->id_source)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_AJOUT." >> ".intval($this->auteur->id_utilisateur)." >> ".intval($flux->id_flux))); return false; } else { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,"Un nouveau source vient d'être créée par un utilisateur (".strval($this->auteur->id_utilisateur).") >> ".strval($source->id_source))); $this->source=$source; } } if(empty($this->description)) $this->description=null; $prepare=$Bd->prepare("INSERT INTO flux (nom,url,description,auteur_id,langue,frequence_maj,time_crea,time_maj,memo) VALUES (:nom,:url,:description,:auteur_id,:langue,:frequence_maj,:time_crea,:time_maj,:memo)"); $ajout=$prepare->execute(array(':nom'=>$this->designation,':url'=>$this->url,':description'=>$this->description,':auteur_id'=>$this->auteur->id_utilisateur,':langue'=>$this->langue,':frequence_maj'=>$this->frequence_maj,':time_crea'=>$this->time_crea,':time_maj'=>$this->time_maj,':memo'=>$this->memo)); if((test_requete(__FILE__,__LINE__,$ajout,$prepare)===false)) return false; $this->id_flux=$Bd->lastInsertId(); $prepare=null; $this->crea_cache(); $this->actualise_source(); // classement du flux dans son hub if(!empty($hub)) $this->ajout_hub($hub);//fait tous les tests nécessaires... elseif($est_admin===false) {//création d'un hub temporaire calqué sur le flux pour permette à l'utilisateur de s'y abonner. $hub=new FclFlux_hub(); $max["nom_long_min"]=HUB_MIN_NOM; $max["nom_long_max"]=HUB_MAX_NOM; $max["description_long_max"]=HUB_MAX_DESCRIPTION; $hub->limites=$max; $hub->set_nom(get_chaine_debut($this->designation,HUB_MAX_NOM)); $hub->set_description(get_chaine_debut($this->description,HUB_MAX_DESCRIPTION)); $hub->set_auteur($this->auteur); $hub->set_langue($this->langue); $hub->ajout(); if(empty($hub->id_hub)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_AJOUT." >> ".intval($this->auteur->id_utilisateur)." >> ".intval($flux->id_flux))); return false; } else { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,MSG_HUB_AJOUT." >> ".intval($this->auteur->id_utilisateur)." >> ".intval($hub->id_hub))); $this->ajout_hub($hub); unset($hub); } } return true; } /** * Méthode enregistrant une mise à jour des infos principales d'un flux * * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function actualise() { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if((empty($this->designation))||(empty($this->url))||(empty($this->id_flux))) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } if(!($this->est_libre())) { $this->erreurs=array_merge($this->erreurs,(array) ERREUR_FLUX_DOUBLON); return false; } $a_flux=self::recherche($this->id_flux,"id_flux","description,langue,frequence_maj,memo"); if(empty($a_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_ENREG_ABSENT.">>".intval($this->id_flux))); return false; } if(!isset($this->description)) $this->description=$a_flux["description"]; if(!isset($this->langue)) $this->langue=$a_flux["langue"]; if(!isset($this->frequence_maj)) $this->frequence_maj=$a_flux["frequence_maj"]; if(!isset($this->memo)) $this->memo=$a_flux["memo"]; $prepare=$Bd->prepare("UPDATE flux SET nom=:nom,url=:url,description=:description,langue=:langue,frequence_maj=:frequence_maj,time_maj=:date_actuelle,memo=:memo WHERE id_flux=:id_flux;"); $maj=$prepare->execute(array(':nom'=>$this->designation,':url'=>$this->url,':description'=>$this->description,':langue'=>$this->langue,':frequence_maj'=>$this->frequence_maj,':date_actuelle'=>time(),':memo'=>$this->memo,':id_flux'=>$this->id_flux)); if((test_requete(__FILE__,__LINE__,$maj,$prepare)===false)) return false; $prepare=null; $this->crea_cache(); $this->actualise_source(); return true; } /** * Méthode enregistrant l'association d'une source au flux * * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function actualise_source() { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if((empty($this->source))||(empty($this->id_flux))) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } $nouvelle_source=$this->source->id_source; $a_flux=self::recherche($this->id_flux,"id_flux","source_id"); if(empty($a_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_ENREG_ABSENT.">>".intval($this->id_flux))); return false; } $a_source=$a_flux["source_id"]; if($a_source==$nouvelle_source) return true;//rien ne change... $prepare=$Bd->prepare("UPDATE flux SET source_id=:source_id WHERE id_flux=:id_flux;"); $maj=$prepare->execute(array(':source_id'=>$nouvelle_source,':id_flux'=>$this->id_flux)); if((test_requete(__FILE__,__LINE__,$maj,$prepare)===false)) return false; $prepare=null; $this->crea_cache(); return true; } /** * Méthode testant l'existence d'un lien entre un flux et un hub. * * @param le hub à contrôler * @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 **/ public function est_dans_hub($hub) { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if(empty($this->id_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } if(!($hub instanceof FclFlux_hub)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } if(empty($hub->id_hub)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } $prepare=$Bd->prepare("SELECT * FROM hub_flux WHERE (id_hub=:id_hub AND id_flux=:id_flux)"); $recherche=$prepare->execute(array(":id_hub"=>$hub->id_hub,":id_flux"=>$this->id_flux)); 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 enregistrant le lien entre un flux et un hub. * * @param le $hub (objet) * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function ajout_hub($hub=null) { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if(empty($this->id_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } if(!($hub instanceof FclFlux_hub)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } if(empty($hub->id_hub)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } $existe=FclFlux_hub::recherche($hub->id_hub,"id_hub"); if(empty($existe)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_ENREG_ABSENT." >> ".intval($hub->id_hub))); return false; } $classement=$this->est_dans_hub($hub); if($classement) { $this->erreurs=array_merge($this->erreurs,(array) (ERREUR_SQL_DOUBLON." >> ".intval($this->id_flux)." >> ".intval($hub->id_hub))); return false; } $prepare=$Bd->prepare("INSERT INTO hub_flux(id_flux,id_hub) VALUES (:id_flux,:id_hub)"); $classement=$prepare->execute(array(':id_flux'=>$this->id_flux,':id_hub'=>$hub->id_hub)); if((test_requete(__FILE__,__LINE__,$classement,$prepare)===false)) return false; $prepare=null; $this->crea_cache(); return true; } /** * Méthode supprimant du lien entre un flux et un hub * * @param le $hub (objet) * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function suppr_hub($hub=null) { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if(empty($this->id_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } if(!($hub instanceof FclFlux_hub)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } if(empty($hub->id_hub)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } $classement=$this->est_dans_hub($hub); if(!$classement) return false; $prepare=$Bd->prepare("DELETE FROM hub_flux WHERE (id_hub=:id_hub AND id_flux=:id_flux) LIMIT 1;"); $classement=$prepare->execute(array(':id_flux'=>$this->id_flux,':id_hub'=>$hub->id_hub)); if((test_requete(__FILE__,__LINE__,$classement,$prepare)===false)) return false; $prepare=null; $this->crea_cache(); return true; } /** * Méthode cherchant si il y a des flux qu'un administrateur doit valider. * * @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_a_valider() { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; $get_flux=$Bd->query("SELECT id_flux,nom FROM flux WHERE time_maj=0"); if((test_requete(__FILE__,__LINE__,$get_flux)===false)) return false; $resultat=$get_flux->fetchAll(PDO::FETCH_ASSOC); $prepare=null; if(empty($resultat)) return false; else return $resultat; } /** * Méthode listant les hubs auxquels est lié un flux * * @return liste des id_hub dans un tableau si trouvé (peut être vide), false en cas d'erreur * @author Fabrice PENHOËT **/ public function get_hubs() { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if(empty($this->id_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } $prepare=$Bd->prepare("SELECT id_hub FROM hub_flux WHERE id_flux=:valeur"); $recherche=$prepare->execute(array(":valeur"=>$this->id_flux)); if((test_requete(__FILE__,__LINE__,$recherche,$prepare)===false)) return false; $resultat=$prepare->fetchAll(PDO::FETCH_ASSOC); $prepare=null; return $resultat; } /** * Méthode retournant la liste des abonnés actifs d'un flux (et donc leur nombre) * * @return les données dans un tableau php, false en cas d'erreur * @author Fabrice PENHOËT **/ public function get_liste_abonnes() { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if(empty($this->id_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } $stats=array(); $get_actifs=$Bd->query("SELECT DISTINCT auteur_id FROM abonnements as A,abonnements_hub as H,hub_flux as F WHERE ((H.id_abonnement=A.id_abonnement) AND (H.id_hub=F.id_hub) AND (F.id_flux=".$this->id_flux.") AND (A.jours_alerte!='') AND (A.actif_ok=1));"); if((test_requete(__FILE__,__LINE__,$get_actifs)===false)) return false; $stats["actifs"]=$get_actifs->fetchAll(); unset($get_actifs); $get_inactifs=$Bd->query("SELECT DISTINCT auteur_id FROM abonnements as A,abonnements_hub as H,hub_flux as F WHERE ((H.id_abonnement=A.id_abonnement) AND (H.id_hub=F.id_hub) AND (F.id_flux=".$this->id_flux.") AND (A.jours_alerte=''));"); if((test_requete(__FILE__,__LINE__,$get_inactifs)===false)) return false; $stats["inactifs"]=$get_inactifs->fetchAll(); unset($get_inactifs); $get_en_pause=$Bd->query("SELECT DISTINCT auteur_id FROM abonnements as A,abonnements_hub as H,hub_flux as F WHERE ((H.id_abonnement=A.id_abonnement) AND (H.id_hub=F.id_hub) AND (F.id_flux=".$this->id_flux.") AND (A.jours_alerte!='') AND (A.actif_ok=0));"); if((test_requete(__FILE__,__LINE__,$get_en_pause)===false)) return false; $stats["en_pause"]=$get_en_pause->fetchAll(); unset($get_en_pause); return $stats; } /** * Méthode créant le fichier cache contenant les infos utiles d'un flux * * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function crea_cache() { if(empty($this->id_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } $infos=self::recherche($this->id_flux,"id_flux","nom,url,source_id,description,langue"); if($infos===false) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_ENREG_ABSENT." >> ".intval($this->id_flux))); return false; } $hubs=$this->get_hubs(); if(!empty($hubs)) $infos=array_merge($infos,$hubs); $id=strval($this->id_flux); return crea_cache(CACHE_REP_FLUX."/".$id[0]."/$id.txt",$infos); } /** * Méthode ouvrant le fichier cache contenant les infos d'un flux * * @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 du flux 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_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } $id=strval($this->id_flux); $fichier=CACHE_REP."/".CACHE_REP_FLUX."/".$id[0]."/$id.txt"; $infos=array(); if(!file_exists($fichier)) { if($crea_cache) { if(empty($GLOBALS['Bd'])) 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)) //cela doit être l'id d'un des hubs liés au flux. $infos[$key]=stripslashes($value); } //+infos de la source if(!empty($t['source_id'])) { $source=new FclFlux_source(); $source->id_source=$t['source_id']; $source_infos=$source->get_infos_cache($crea_cache); if(!empty($source_infos)) $infos["source"]=$source_infos; unset($source); } } if(empty($infos)) return false; else return $infos; } /** * Méthode de suppression du fichier cache lié à un flux * id_flux doit être connu * * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function suppr_cache() { if(empty($this->id_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } $id=strval($this->id_flux); $chemin=CACHE_REP."/".CACHE_REP_FLUX."/".$id[0]."/$id.txt"; 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 vérifiant qu'un lien venant d'un flux donné n'a pas déjà été importé dans un hub. * raison : un même lien peut apparaître dans différents flux d'un même site ayant des abonnés différents * et les liens d'un même flux peuvent être importés dans plusieurs flux différents. * seuls les abonnés du premier flux importé (ou hub) verraient alors le lien * les doublons possibles sont à gérer à l'affichage de l'abonnement * * @param l'url du lien et les identifiants du flux et du hub à tester. Si un titre est fourni il est aussi testé. * @return booléen suivant si il s'agit d'un doublon ou pas * @author Fabrice PENHOËT **/ static function test_lien_doublon($url,$id_flux,$id_hub,$titre="") { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if((empty($url))||(empty($id_flux))||(empty($id_hub))) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } if(empty($titre)) { $prepare=$Bd->prepare("SELECT id_post FROM hub_post WHERE ((url=:url) AND (flux_id=:id_flux) AND (hub_id=:id_hub))"); $recherche=$prepare->execute(array(":url"=>$url,":id_flux"=>$id_flux,":id_hub"=>$id_hub)); } else { $prepare=$Bd->prepare("SELECT id_post FROM hub_post WHERE ((url=:url OR ancre=:titre) AND (flux_id=:id_flux) AND (hub_id=:id_hub))"); $recherche=$prepare->execute(array(":url"=>$url,":titre"=>$titre,":id_flux"=>$id_flux,":id_hub"=>$id_hub)); } 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 true; } /** * Méthode enregistrant les nouveaux liens trouvés lors de la lecture d'un flux * Chaque nouveau lien est enregistré dans le(s) hub(s) associés à ce flux * C'est aussi ici que je supprime les anciens liens provenant du flux dans le cas où il ne fournit pas dates pour ses items. * * @param $nb_max de liens à récupérés * @return nombre de nouveaux liens importés, false en cas d'erreur rencontrée * @author Fabrice PENHOËT **/ public function import_liens($nb_max=50) { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if(empty($this->id_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } if(empty($this->url)) { $cherche_url=SELF::recherche($this->id_flux,"id_flux","url"); if(empty($cherche_url)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_ENREG_ABSENT." >> ".$this->id_flux)); return false; } $this->url=$cherche_url["url"]; unset($cherche_url); } // même si la lecture se déroule pas bien, le flux est enregistré comme ayant été traité pour ne pas bloquer les autres... $date_actuelle=time(); $prepare_maj=$Bd->prepare("UPDATE flux SET time_lecture=:date_actuelle WHERE id_flux=:id"); $maj_flux=$prepare_maj->execute(array(":date_actuelle"=>$date_actuelle,":id"=>$this->id_flux)); if((test_requete(__FILE__,__LINE__,$maj_flux,$prepare_maj)===false)) return false; unset($prepare_maj); $liens=$this->lecture($nb_max); if($liens===false) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FLUX_LECTURE." >> ".htmlspecialchars($this->url))); return false; } elseif($liens==null) { //$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_FLUX_VIDE." >> ".htmlspecialchars($this->url))); return false; } $hubs=$this->get_hubs(); if(empty($hubs)) { if($hubs===false) $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_ENREG_ABSENT." >> ".$this->id_flux)); else $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_ENREG_ABSENT." >> ".$this->id_flux)); return false; } $nb_liens=0; if(!empty($liens)) { $timeS_limite=time()-3600*24*LIEN_IMPORT_MAX_JOURS;//je n'importe pas les liens trop anciens //je n'utilise pas la méthode ajout() de la classe FclFlux_post pouvoir optimiser sql en utilisant +sieurs fois les mêmes requêtes $prepare=$Bd->prepare("INSERT INTO hub_post (hub_id,flux_id,ancre,url,time_crea,time_flux,time_validation) VALUES (:hub_id,:flux_id,:ancre,:url,:date_actuelle,:time_flux,:date_actuelle)"); //$prepare_svg=$Bd->prepare("INSERT INTO hub_post_svg (id_post,hub_id,flux_id,time_crea) VALUES (:id,:hub_id,:flux_id,:date_actuelle)"); foreach ($liens as $infos_lien) { if((empty($infos_lien["designation"]))||(empty($infos_lien["url"]))) $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,"Lien non conforme dans le flux :".htmlentities($this->url,ENT_QUOTES))); elseif((empty($infos_lien["timeS"]))||($infos_lien["timeS"]>=$timeS_limite)) { $infos_lien["limites"]["url_long_max"]=POST_MAX_URL; $infos_lien["limites"]["ancre_long_min"]=POST_MIN_ANCRE; $infos_lien["limites"]["ancre_long_max"]=POST_MAX_ANCRE; $infos_lien["ancre"]=get_chaine_debut(affiche_utf8(strip_tags($infos_lien["designation"]),UTF8_OK),255," (...)"); unset($infos_lien["designation"]);//sinon bug dans classe Lien ... $post=new FclFlux_post($infos_lien); if(empty($post->erreurs)) { $lien_import=false; foreach($hubs as $hub_infos) { $doublon=self::test_lien_doublon($infos_lien["url"],$this->id_flux,$hub_infos["id_hub"],$infos_lien["ancre"]); if($doublon===false) { $time_flux=0; if(!empty($infos_lien["timeS"])) $time_flux=$infos_lien["timeS"]; $ajout=$prepare->execute(array(':hub_id'=>$hub_infos["id_hub"],':flux_id'=>$this->id_flux,':ancre'=>$infos_lien["ancre"],':url'=>$infos_lien["url"],':date_actuelle'=>$date_actuelle,':time_flux'=>$time_flux)); if((test_requete(__FILE__,__LINE__,$ajout,$prepare)===false)) return false; $lien_import=true;//j'ai enregistré au moins une fois le lien trouvé } } if($lien_import) $nb_liens++; } unset($post); } if(!empty($infos_lien["url"])) $urls_flux[]=$infos_lien["url"];//utile pour suppression + bas. } if(!empty($nb_liens)) { // il y a du nouveau donc je peux supprimer les liens obsolètes concernant ce flux. // il faut veiller à ne pas supprimer de liens toujours présents dans le flux pour éviter de les réimporter par la suite (si pas de date fournie). // la suppression dans stat_clics_posts se fait dans FclFlux_post->supprime_anciens_posts() $sql_in="'".implode("','",$urls_flux)."'"; if(!empty($sql_in)) $suppr=$Bd->query("DELETE FROM hub_post WHERE time_crea+(".POSTS_MAX_JOURS."*24*3600)<".$date_actuelle." AND flux_id=".$this->id_flux." AND url NOT IN($sql_in);");// je continue même si ça bug else $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); unset($suppr); foreach($hubs as $hub_infos) { // je mets à jour la liste des derniers posts de chaque hub recevant les liens de ce flux $hub_cache=new FclFlux_hub(); $hub_cache->id_hub=$hub_infos["id_hub"]; $crea_cache=$hub_cache->get_liste_posts(true); unset($hub_cache); } } } $prepare=null;$prepare_svg=null; $prepare_maj=null; return $nb_liens; } /** * Méthode supprimant l'enregistrement d'un flux * Le cache listant les flux de ses rubriques sera impacté + cache listant les flux de sa source * * @param si sauve_abo vaut true, je ne peux supprimer un flux ayant des abonnés (via les hubs) * sinon et si ce flux est l'unique source d'information d'un hub qui n'est pas ouvert aux publications, le hub et ses abonnements sont supprimés. * @return booléen suivant succès * @author Fabrice PENHOËT **/ public function supprime($sauve_abo=true) { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if(empty($this->id_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT)); return false; } $prepare=$Bd->prepare("SELECT DISTINCT id_abonnement FROM abonnements_hub as A,hub_flux as F WHERE ((A.id_hub=F.id_hub) AND (F.id_flux=:id));"); $recherche=$prepare->execute(array(':id'=>$this->id_flux)); if((test_requete(__FILE__,__LINE__,$recherche,$prepare)===false)) return false; $abonnements=$prepare->fetchAll(PDO::FETCH_ASSOC); $prepare=null; if((!empty($abonnements))&&($sauve_abo)) { $this->erreurs=array_merge($this->erreurs,(array) ERREUR_FLUX_SUPPR_ABO); unset($abonnements); return false; } // hubs dans lesquels le contenu de ce flux était importé $hubs=$this->get_hubs(); $prepare=$Bd->prepare("DELETE FROM flux WHERE id_flux=:id LIMIT 1;"); $suppr=$prepare->execute(array(':id'=>$this->id_flux)); if((test_requete(__FILE__,__LINE__,$suppr,$prepare)===false)) return false; $nb_enreg=$prepare->rowCount(); $prepare=null; if($nb_enreg==0) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_SQL_SUPPR." >> ".intval($this->id_flux))); return false; } $this->suppr_cache(); if(!empty($hubs)) { foreach($hubs as $hud_id) { // est-ce qu'il s'agissait du seul flux de ce hub ? // est si oui ce hub est-il ouvert à la publication $hub_test=new FclFlux_hub(); $hub_test->id_hub=$hud_id["id_hub"]; $flux_hub=$hub_test->get_flux(); $hub_infos=$hub_test->get_infos_cache(true); if((count($flux_hub)==1)&&($hub_infos["publication_ok"]===false)) $hub_test->supprime(false);//supprime en même temps les abonnements unset($hub_test);unset($hub_infos); } } return true; } /** * Affichage par défaut d'un objet * il semble que la méthode héritée ne prenne pas en compte les nouveaux attributs ? * * @return chaîne de caractères listant la valeur de chaque attribut * @author Fabrice PENHOËT **/ public function __toString() { $texte="

".__CLASS__."

"; foreach($this as $key => $value) { if(is_array($value)) $value=affiche_tableau($value,"
  • #valeur
  • ",""); $texte.="$key : $value\n"; } return $texte; } /** * Méthode effectuant périodiquement l'importation de nouveaux liens en provenance des flux * Seuls les flux importés dans un hub ayant au moins 1 abonné actif sont traités * On actualise le cache si aucun bug est rencontré * * @param $nb_flux : nombre limite de flux à importés, $periode : périodicité des flux concernés * @return nombre de flux importés avec succès. false en cas d'erreur. * @author Fabrice PENHOËT **/ static function importation($nb_flux=10,$periode="H") { global $Bd; if((isset_connexion(__FILE__,__LINE__)===false)) return false; if(!is_int($nb_flux)) { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_FORMAT)); return false; } if($periode=="H") $time_limite=time()-3600;//toutes les heures elseif($periode=="J") $time_limite=time()-3600*12;//2 fois / jours else { $ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_AUTORISES)); return false; } $prepare=$Bd->prepare("SELECT DISTINCT F.id_flux,F.url,F.time_lecture FROM flux AS F,hub_flux AS H,abonnements_hub AS AH,abonnements AS Abo WHERE ((F.id_flux=H.id_flux) AND (H.id_hub=AH.id_hub) AND (AH.id_abonnement=Abo.id_abonnement) AND ((F.frequence_maj=:periode) AND (F.time_lecture<=:limite) AND (Abo.jours_alerte!=''))) ORDER BY F.time_lecture ASC LIMIT 0,$nb_flux"); $recherche=$prepare->execute(array(":periode"=>$periode,":limite"=>$time_limite)); if((test_requete(__FILE__,__LINE__,$recherche,$prepare)===false)) return false; $flux=$prepare->fetchAll(PDO::FETCH_ASSOC); $prepare=null; $nb_import=0; if(!empty($flux)) { $date_actuelle=time(); foreach ($flux as $flux_infos) { $flux_infos["limites"]["url_long_max"]=FLUX_MAX_URL; $flux_import=new FclFlux_flux($flux_infos); if(empty($flux_import->erreurs)) { $retour=$flux_import->import_liens(); if($retour!==false) $nb_import++; } unset($flux_import); } } return $nb_import; } }//fin de la classe