hellofacteurV1/modele/FclFlux_flux.php

1080 lines
39 KiB
PHP
Raw Permalink Normal View History

2021-11-02 11:23:49 +01:00
<?php
/**
* classe d<EFBFBD>riv<EFBFBD>e de la classe Flux
* on va sp<EFBFBD>cifier ici tout ce qui est propre <EFBFBD> cette application :
* manipulation base de donn<EFBFBD>es, cache, attributs suppl<EFBFBD>mentaires...
* on a besoin de la classe FclFlux_utilisateur pour d<EFBFBD>finir les utilisateurs ayant enregistr<EFBFBD> les flux
* + FclFlux_source pour le classement
* + FclFlux_post & FclFlux_hub pour l'importation du contenu des flux
*
* @author Fabrice PENHO<EFBFBD>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<69>)
private $source; // objet de type FclFlux_source
protected $description;
private $langue; // langue principale du flux
private $frequence_maj; // <20> quelle fr<66>quence ce flux est-il actualis<69> ?
private $time_crea; // timestamp d'enregistrement du flux
private $time_maj; // timestamp de la derni<6E>re mise <20> jour des infos du flux
private $time_lecture; // timestamp de la derni<6E>re tentative d'importation du flux
private $memo; // m<>mo interne, non destin<69> <20> <20>tre publi<6C>.
/**
* Constructeur qui initialise certains attributs en testant les valeurs fournies
* copier/ coller de la classe h<EFBFBD>rit<EFBFBD>e du fait de m<EFBFBD>thodes contr<EFBFBD>lant des attributs suppl<EFBFBD>mentaires
*
* @param infos tableau contenant les diff<EFBFBD>rentes donn<EFBFBD>es correspondant aux attributs (suppos<EFBFBD>s homonymes)
* @return null
* @author Fabrice PENHO<EFBFBD>T
**/
public function __construct($infos=null)
{
if((!empty($infos))&&(is_array($infos)))
{
//les limites doivent <20>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<EFBFBD>thode v<EFBFBD>rifiant que le param<EFBFBD>tre fourni est bien une source existante
* et lui attribuant l'origine du flux si c'est le cas
* cet attribut ne peut <EFBFBD>tre vide
*
* @param la valeur <EFBFBD> contr<EFBFBD>ler
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode v<EFBFBD>rifiant que le param<EFBFBD>tre fourni est bien un utilisateur existant
* et lui attribuant l'origine du flux si c'est le cas
* cet attribut ne peut <EFBFBD>tre vide
*
* @param la valeur <EFBFBD> contr<EFBFBD>ler
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode v<EFBFBD>rifiant le texte de description fourni
*
* @param la description <EFBFBD> cont<EFBFBD>ler
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode v<EFBFBD>rifiant que le param<EFBFBD>tre fourni fait partie des valeurs possibles
* et lui attribuant la fr<EFBFBD>quence de lecture du flux si c'est le cas
* cet attribut ne peut <EFBFBD>tre vide
*
* @param la valeur <EFBFBD> contr<EFBFBD>ler
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode v<EFBFBD>rifiant que le param<EFBFBD>tre fourni fait partie des valeurs possibles
* et lui attribuant la langue principale du flux si c'est le cas
* cet attribut ne peut <EFBFBD>tre vide
*
* @param la valeur <EFBFBD> contr<EFBFBD>ler
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode testant la validit<EFBFBD> du m<EFBFBD>mo saisi pour un flux
* et l'attribuant <20> l'objet si ok
*
* @param le texte <EFBFBD> cont<EFBFBD>ler
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode testant l'existence d'un flux dans le bd via son id_flux ou son url (seuls champs identifiant)
*
* @param les champs souhait<EFBFBD>s en sortie
* @return les donn<EFBFBD>es de la table dans un tableau php si trouv<EFBFBD>. false si pas trouv<EFBFBD> ou en cas d'erreur.
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode de recherche des flux dans le bd pour un (ou +sieurs) mots-cl<EFBFBD>s.
*
* @param les champs souhait<EFBFBD>s en sortie
* @return les donn<EFBFBD>es de la table dans un tableau php si trouv<EFBFBD>. false si pas trouv<EFBFBD> ou en cas d'erreur.
* @author Fabrice PENHO<EFBFBD>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<75>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<EFBFBD>e pour un champ est d<EFBFBD>j<EFBFBD> utilis<EFBFBD>e pour un autre flux
*
* @return true si valeur non trouv<EFBFBD>e
* @author Fabrice PENHO<EFBFBD>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<74>
{
$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<EFBFBD>thode enregistrant un nouveau flux
*
* @param $hub dans lequel class<EFBFBD> ce flux si on le connait.
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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 <20> 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 <20> valider
if(empty($this->source))
{//si je n'ai pas de source fournie, j'en cr<63><72> une, bas<61>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'<27>tre cr<63><72>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<63>ation d'un hub temporaire calqu<71> sur le flux pour permette <20> 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<EFBFBD>thode enregistrant une mise <EFBFBD> jour des infos principales d'un flux
*
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode enregistrant l'association d'une source au flux
*
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode testant l'existence d'un lien entre un flux et un hub.
*
* @param le hub <EFBFBD> contr<EFBFBD>ler
* @return les donn<EFBFBD>es de la table dans un tableau php si trouv<EFBFBD>. false si pas trouv<EFBFBD> ou en cas d'erreur.
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode enregistrant le lien entre un flux et un hub.
*
* @param le $hub (objet)
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode supprimant du lien entre un flux et un hub
*
* @param le $hub (objet)
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode cherchant si il y a des flux qu'un administrateur doit valider.
*
* @param null
* @return les donn<EFBFBD>es de la table dans un tableau si trouv<EFBFBD>, false si pas trouv<EFBFBD> ou en cas d'erreur
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode listant les hubs auxquels est li<EFBFBD> un flux
*
* @return liste des id_hub dans un tableau si trouv<EFBFBD> (peut <EFBFBD>tre vide), false en cas d'erreur
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode retournant la liste des abonn<EFBFBD>s actifs d'un flux (et donc leur nombre)
*
* @return les donn<EFBFBD>es dans un tableau php, false en cas d'erreur
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode cr<EFBFBD>ant le fichier cache contenant les infos utiles d'un flux
*
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode ouvrant le fichier cache contenant les infos d'un flux
*
* @param crea_cache : un bool<EFBFBD>en pour savoir si il faut tester la cr<EFBFBD>ation du fichier en cas d'absence
* @return tableau contenant les infos du flux fournies par le fichier (si trouv<EFBFBD>), false en cas d'erreur
* @author Fabrice PENHO<EFBFBD>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 <20>tre l'id d'un des hubs li<6C>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<EFBFBD>thode de suppression du fichier cache li<EFBFBD> <EFBFBD> un flux
* id_flux doit <EFBFBD>tre connu
*
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode v<EFBFBD>rifiant qu'un lien venant d'un flux donn<EFBFBD> n'a pas d<EFBFBD>j<EFBFBD> <EFBFBD>t<EFBFBD> import<EFBFBD> dans un hub.
* raison : un m<EFBFBD>me lien peut appara<EFBFBD>tre dans diff<EFBFBD>rents flux d'un m<EFBFBD>me site ayant des abonn<EFBFBD>s diff<EFBFBD>rents
* et les liens d'un m<EFBFBD>me flux peuvent <EFBFBD>tre import<EFBFBD>s dans plusieurs flux diff<EFBFBD>rents.
* seuls les abonn<EFBFBD>s du premier flux import<EFBFBD> (ou hub) verraient alors le lien
* les doublons possibles sont <EFBFBD> g<EFBFBD>rer <EFBFBD> l'affichage de l'abonnement
*
* @param l'url du lien et les identifiants du flux et du hub <EFBFBD> tester. Si un titre est fourni il est aussi test<EFBFBD>.
* @return bool<EFBFBD>en suivant si il s'agit d'un doublon ou pas
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode enregistrant les nouveaux liens trouv<EFBFBD>s lors de la lecture d'un flux
* Chaque nouveau lien est enregistr<EFBFBD> dans le(s) hub(s) associ<EFBFBD>s <EFBFBD> ce flux
* C'est aussi ici que je supprime les anciens liens provenant du flux dans le cas o<EFBFBD> il ne fournit pas dates pour ses items.
*
* @param $nb_max de liens <EFBFBD> r<EFBFBD>cup<EFBFBD>r<EFBFBD>s
* @return nombre de nouveaux liens import<EFBFBD>s, false en cas d'erreur rencontr<EFBFBD>e
* @author Fabrice PENHO<EFBFBD>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<74> comme ayant <20>t<EFBFBD> trait<69> 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<71>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<74> au moins une fois le lien trouv<75>
}
}
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<6F>tes concernant ce flux.
// il faut veiller <20> ne pas supprimer de liens toujours pr<70>sents dans le flux pour <20>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 <20>a bug
else
$ajout_journal=new journal_erreurs(array(__FILE__,__LINE__,ERREUR_PARAM_MANQUANT));
unset($suppr);
foreach($hubs as $hub_infos)
{ // je mets <20> 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<EFBFBD>thode supprimant l'enregistrement d'un flux
* Le cache listant les flux de ses rubriques sera impact<EFBFBD> + cache listant les flux de sa source
*
* @param si sauve_abo vaut true, je ne peux supprimer un flux ayant des abonn<EFBFBD>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<EFBFBD>s.
* @return bool<EFBFBD>en suivant succ<EFBFBD>s
* @author Fabrice PENHO<EFBFBD>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 <20>tait import<72>
$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 <20> 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<EFBFBD>faut d'un objet
* il semble que la m<EFBFBD>thode h<EFBFBD>rit<EFBFBD>e ne prenne pas en compte les nouveaux attributs ?
*
* @return cha<EFBFBD>ne de caract<EFBFBD>res listant la valeur de chaque attribut
* @author Fabrice PENHO<EFBFBD>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<EFBFBD>thode effectuant p<EFBFBD>riodiquement l'importation de nouveaux liens en provenance des flux
* Seuls les flux import<EFBFBD>s dans un hub ayant au moins 1 abonn<EFBFBD> actif sont trait<EFBFBD>s
* On actualise le cache si aucun bug est rencontr<EFBFBD>
*
* @param $nb_flux : nombre limite de flux <EFBFBD> import<EFBFBD>s, $periode : p<EFBFBD>riodicit<EFBFBD> des flux concern<EFBFBD>s
* @return nombre de flux import<EFBFBD>s avec succ<EFBFBD>s. false en cas d'erreur.
* @author Fabrice PENHO<EFBFBD>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