hellofacteurV1/modele/FclFlux_flux.php

1080 lines
39 KiB
PHP
Executable File

<?php
/**
* classe dérivée de la classe Flux
* on va spécifier ici tout ce qui est propre à cette application :
* manipulation base de données, cache, attributs supplémentaires...
* on a besoin de la classe FclFlux_utilisateur pour définir les utilisateurs ayant enregistré les flux
* + FclFlux_source pour le classement
* + FclFlux_post & FclFlux_hub pour l'importation du contenu des flux
*
* @author Fabrice PENHOËT
**/
require_once("flux.php");
require_once("FclFlux_utilisateur.php");
require_once("FclFlux_source.php");
require_once("FclFlux_post.php");
require_once("FclFlux_hub.php");
require_once("FclFlux_abonnement.php");
class FclFlux_flux extends Flux
{
public $id_flux;
private $auteur; // objet de type FclFlux_utilisateur ou null (si utilisateur supprimé)
private $source; // objet de type FclFlux_source
protected $description;
private $langue; // langue principale du flux
private $frequence_maj; // à quelle fréquence ce flux est-il actualisé ?
private $time_crea; // timestamp d'enregistrement du flux
private $time_maj; // timestamp de la dernière mise à jour des infos du flux
private $time_lecture; // timestamp de la dernière tentative d'importation du flux
private $memo; // mémo interne, non destiné à être publié.
/**
* Constructeur qui initialise certains attributs en testant les valeurs fournies
* copier/ coller de la classe héritée du fait de méthodes contrôlant des attributs supplémentaires
*
* @param infos tableau contenant les différentes données correspondant aux attributs (supposés homonymes)
* @return null
* @author Fabrice PENHOËT
**/
public function __construct($infos=null)
{
if((!empty($infos))&&(is_array($infos)))
{
//les limites doivent être connues avant le reste
if(!empty($infos["limites"]))
$this->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="<h3>".__CLASS__."</h3>";
foreach($this as $key => $value)
{
if(is_array($value))
$value=affiche_tableau($value,"<li>#valeur</li>","<ul>","</ul>");
$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