* @license GPL v3 * @license CECILL v2 * @version $Id$ * @copyright 2010 */ class OdsSyndicationObservation extends OdsTriple { private $parametres_origines = null; private $format = null; private $service = null; private $squelette = null; private $squelette_dossier = null; private $flux = array(); private $tri = 'oo_date_modification'; private $tri_dir = "DESC"; private $mode = 'normal'; /** * Méthode appelée avec une requête de type GET. */ public function getElement($params = array()) { // Initialisation des variables $this->parametres_origines = $params; $info = array(); $contenu = ''; if (! $this->etreFluxAdmin() || $this->authentifier()) { // Pré traitement des paramêtres $pour_bdd = false; $p = $this->traiterParametres(array('service', 'format'), $params, $pour_bdd); extract($p); $this->traiterParametresTri(); $this->parametres = $params; $this->squelette_dossier = dirname(__FILE__).DIRECTORY_SEPARATOR.'squelettes'.DIRECTORY_SEPARATOR; // Récupération de la liste des flux $this->chargerListeDesFlux(); // Chargement du bon type de service demandé if (isset($service)) { $this->service = $this->traiterNomService($service); $methode = $this->getNomMethodeService(); if (method_exists($this, $methode)) { if (isset($format) && preg_match('/^(?:rss1|rss2|atom)$/i', $format)) { // Mise en minuscule de l'indication du format $this->format = strtolower($format); // Définition du fichier squelette demandé $this->squelette = $this->squelette_dossier.$this->format.'.tpl.xml'; } else if (isset($this->flux[$this->service])) { $this->format = ''; $this->messages[] = "Le service ODS Syndication nécessite d'indiquer en second paramètre le format : rss1, rss2 ou atom."; } if (!isset($this->flux[$this->service]) || isset($this->format)) { // Suppression des paramêtres inutile pour le reste des méthodes array_shift($this->parametres); array_shift($this->parametres); // Récupération du contenu à renvoyer $contenu = $this->$methode(); } } else { $this->messages[] = "Le type d'information demandé '$this->service' n'est pas disponible."; } } else { $this->messages[] = "Le service ODS Syndication Observation nécessite d'indiquer en premier paramètre le type d'information demandé."; } } // Envoie sur la sortie standard $encodage = 'utf-8'; $mime = $this->getTypeMime(); $formatage_json = $this->getFormatageJson(); $this->envoyer($contenu, $mime, $encodage, $formatage_json); } private function traiterParametresTri() { $tris_possibles = array('oo_date_modification', 'oo_date_saisie', 'oo_date'); $tris_dirs_possibles = array('ASC', 'DESC'); $this->tri = !empty($_GET['tri']) && in_array($_GET['tri'], $tris_possibles) ? $_GET['tri'] : 'oo_date_modification'; $this->tri_dir = !empty($_GET['tri_dir']) && in_array($_GET['tri_dir'], $tris_dirs_possibles) ? $_GET['tri_dir'] : 'DESC'; unset($_GET['tri']); unset($_GET['tri_dir']); } private function getUrlBase() { $url_base = sprintf($this->config['settings']['baseURLAbsoluDyn'], get_class($this).'/'); return $url_base; } private function getUrlServiceBase() { $url_service = $this->getUrlBase().implode('/', $this->parametres_origines); return $url_service; } private function traiterNomService($nom) { $nom = strtolower($nom); return $nom; } private function getNomMethodeService() { $methode = ''; $service_formate = str_replace(' ', '', ucwords(implode(' ', explode('-', $this->service)))); $methode = 'getService'.$service_formate; return $methode; } private function getTypeMime() { $mime = ''; $test = isset($this->format) ? $this->format : $this->service; switch ($test) { case 'atom' : $mime = 'application/atom+xml'; break; case 'rss1' : case 'rss2' : $mime = 'application/rss+xml'; break; case 'opml' : $mime = 'text/x-opml'; break; default: $mime = 'text/html'; } return $mime; } private function getFormatageJson() { $json = false; switch ($this->service) { case 'liste-des-flux' : $json = true; break; default: $json = false; } return $json; } private function getFlux($nom) { return isset($this->flux[$nom]) ? $this->flux[$nom] : array(); } private function setFlux($nom, $titre, $description) { $url_base = $this->getUrlBase(); $formats = array('atom', 'rss2', 'rss1'); $flux = array(); foreach ($formats as $format) { $url = $url_base.$nom.'/'.$format; $flux[$format] = $url; } $this->flux[$nom] = array('titre' => $titre, 'description' => $description, 'urls' => $flux); } private function chargerListeDesFlux() { $this->setFlux('par-defaut', 'Flux de syndication des observations d\'ODS', 'Ce flux fournit des informations sur les observations d\'ODS'); } private function getServiceListeDesFlux() { return $this->flux; } private function getServiceOpml() { $donnees = array(); $id = 1; foreach ($this->flux as $flux_nom => $flux){ $info = array(); $info['type'] = 'atom'; $info['titre'] = $flux['titre']; $info['texte'] = "ODS - Obs - $flux_nom"; $info['description'] = $flux['description']; $info['url_xml'] = $this->getUrlBase().$flux_nom.'/atom'; $donnees['liste_flux'][] = $info; } $this->squelette = $this->squelette_dossier.'opml.tpl.xml'; $contenu = Cel::traiterSquelettePhp($this->squelette, $donnees); return $contenu; } private function getServiceParDefaut() { // Construction de la requête $requete = 'SELECT oo.* '. 'FROM ods_observations oo '. 'INNER JOIN ods_individus oi '. 'ON oo.oo_ce_individu = oi.oi_id_individu '. 'INNER JOIN ods_especes oe '. 'ON oe.oe_espece_active = 1 '. 'AND oi.oi_ce_espece = oe.oe_id_espece '. 'WHERE oo_ce_participant != '.$this->config['appli']['id_participant_demo'].' '. 'AND oo_ce_participant != '.$this->config['appli']['id_participant_admin'].' '. 'AND DAY(oo_date) != "00" '. 'AND oo_absence_evenement = "0" '. 'ORDER BY '.$this->tri.' '.$this->tri_dir.' '. "LIMIT $this->start,$this->limit "; $elements = $this->executerRequete($requete); // Création du contenu $contenu = $this->executerService($elements); return $contenu; } private function getServiceModificationObservations() { $this->mode = 'admin'; // Construction de la requête $requete = 'SELECT * '. 'FROM ods_observations oo '. 'INNER JOIN ods_individus oi '. 'ON oo.oo_ce_individu = oi.oi_id_individu '. 'INNER JOIN ods_especes oe '. 'ON oe.oe_espece_active = 1 '. 'AND oi.oi_ce_espece = oe.oe_id_espece '. 'LEFT JOIN ods_stations os '. 'ON oi.oi_ce_station = os.os_id_station '. 'WHERE oo_ce_participant != '.$this->config['appli']['id_participant_demo'].' '. 'AND oo_ce_participant != '.$this->config['appli']['id_participant_admin'].' '. 'AND oo_date_saisie != oo_date_modification '. 'ORDER BY '.$this->tri.' '.$this->tri_dir.' '. "LIMIT $this->start,$this->limit "; $elements = $this->executerRequete($requete); // Création du contenu $contenu = $this->executerService($elements); return $contenu; } private function executerService($elements) { $contenu = ''; if (is_array($elements)) { // Prétraitement des données $donnees = $this->construireDonneesCommunesAuFlux($elements); foreach ($elements as $element) { $donnees['items'][] = $this->construireDonneesCommunesAuxItems($element); } // Création du contenu à partir d'un template PHP if (isset($this->squelette)) { $contenu = JrestService::traiterSquelettePhp($this->squelette, $donnees); } } return $contenu; } private function construireDonneesCommunesAuFlux($observations) { $donnees = $this->getFlux($this->service); $donnees['guid'] = $this->getUrlServiceBase(); $donnees['titre'] = $this->creerTitreService(); $donnees['description'] = $this->creerDescriptionService(); $donnees['lien_service'] = $this->creerUrlService(); $donnees['lien_ods'] = $this->config['settings']['odsSaisieUrlAbsolu']; $donnees['editeur'] = $this->config['settings']['editeur']; $derniere_info_en_date = reset($observations); $date_modification_timestamp = strtotime($derniere_info_en_date['oo_date_modification']); $donnees['date_maj_RSS'] = date(DATE_RSS, $date_modification_timestamp); $donnees['date_maj_ATOM'] = date(DATE_ATOM, $date_modification_timestamp); $donnees['date_maj_W3C'] = date(DATE_W3C, $date_modification_timestamp); $donnees['annee_courante'] = date('Y'); $donnees['generateur'] = 'ODS - Jrest - OdsSyndicationObservation'; preg_match('/([0-9]+)/', '$Revision$', $match); $donnees['generateur_version'] = isset($match[1]) ? $match[1] : 'Inconnue'; return $donnees; } private function construireDonneesCommunesAuxItems($observation) { $item = array(); $date_modification_timestamp = $this->convertirDateHeureMysqlEnTimestamp($observation['oo_date_modification']); $item['date_maj_simple'] = strftime('%A %d %B %Y', $date_modification_timestamp); $item['date_maj_RSS'] = date(DATE_RSS, $date_modification_timestamp); $item['date_maj_ATOM'] = date(DATE_ATOM, $date_modification_timestamp); $item['date_maj_W3C'] = date(DATE_W3C, $date_modification_timestamp); $item['date_creation_simple'] = strftime('%A %d %B %Y', strtotime($observation['oo_date_saisie'])); $item['titre'] = $this->creerTitre($observation); $item['guid'] = $this->creerGuidItem($observation); $item['lien'] = $this->creerUrlService(); $item['categorie'] = $this->creerCategorie($item); $item['description'] = $this->creerDescription($this->protegerCaracteresHtmlDansChamps($observation), $item); $item['description_encodee'] = htmlspecialchars($this->creerDescription($observation, $item)); $item['modifier_par'] = $this->creerAuteur($observation['oo_ce_participant'], $this->etreFluxAdmin()); return $item; } private function creerTitreService() { $titre = ''; switch($this->service) { case 'modification-observations': $titre = 'Flux rss des dernières modifications d\'observations de l\'observatoire des saisons'; break; default: $titre = 'Flux rss de l\'observatoire des saisons'; } return $titre; } private function creerDescriptionService() { $description = ''; switch($this->service) { case 'modification-observations': $description = 'Flux rss des dernières modifications d\'observations de l\'observatoire des saisons'; break; default: $description = 'Flux rss de l\'observatoire des saisons'; } return $description; } private function creerTitre($obs) { $date_saisie = date("d/m/Y", strtotime($obs['oo_date'])); $date_modif = date("d/m/Y", strtotime($obs['oo_date_modification'])); $stade_obs = $this->obtenirValeurTripleParId($obs['oo_ce_evenement']); $nom_plante = $this->obtenirNomEspecePourIdIndividu($obs['oo_ce_individu']); $utilisateur = $this->creerAuteur($obs['oo_ce_participant'], $this->etreFluxAdmin()); $titre = "$stade_obs pour $nom_plante par $utilisateur observée le $date_saisie"; $titre = $this->nettoyerTexte($titre); return $titre; } private function obtenirNomEspecePourIdIndividu($id_individu) { $requete_id_espece_individu = 'SELECT oi_ce_espece FROM ods_individus '. 'WHERE oi_id_individu = '.$this->proteger($id_individu); $resultat_id_espece = $this->executerRequete($requete_id_espece_individu); $id_espece = $resultat_id_espece[0]['oi_ce_espece']; $requete_nom_espece_individu = 'SELECT oe_nom_vernaculaire FROM ods_especes '. 'WHERE oe_id_espece = '.$this->proteger($id_espece); $resultat_nom_espece = $this->executerRequete($requete_nom_espece_individu); $nom_espece = $resultat_nom_espece[0]['oe_nom_vernaculaire']; return $nom_espece; } private function creerGuidItem($element) { $guid = sprintf($this->config['settings']['guidObsTpl'], 'obs'.$element['oo_id_observation']); return $guid; } private function creerLienItem($element) { return $this->config['settings']['odsSaisieUrlAbsolu']; } private function creerAuteur($element) { //TODO externaliser les champs dans le fichier de config $requete_selection_auteur = 'SELECT * FROM drupal_users '. 'WHERE uid = '.$this->proteger($element); $resultat_auteur = $this->executerRequete($requete_selection_auteur); $nom_auteur = !empty($resultat_auteur[0]['name']) ? $resultat_auteur[0]['name'] : ""; if($this->mode == 'admin') { $nom_auteur = $resultat_auteur[0]['mail']; } return $nom_auteur; } private function creerDescription($obs, $item) { $requete_commune_pour_station = 'SELECT os_ce_commune FROM ods_stations '. 'WHERE os_id_station = '. '(SELECT oi_ce_station FROM ods_individus '. 'WHERE oi_id_individu = '.$this->proteger($obs['oo_ce_individu']).')'; $resultat_commune = $this->executerRequete($requete_commune_pour_station); $commune = $resultat_commune[0]['os_ce_commune']; if(is_numeric($commune)) { $requete_lieu = 'SELECT * FROM ods_communes '. 'WHERE oc_code_insee = '.$this->proteger($commune); $resultat_lieu = $this->executerRequete($requete_lieu); if(!empty($resultat_lieu)) { $lieu = $resultat_lieu[0]['oc_nom']. ' ('.substr($commune,0,2).')'; } else { $lieu = $commune; } } else { $lieu = $commune; } $description = "Observé à $lieu".'
'; if($this->mode == 'admin') { $description .= ' Individu : '.$obs['oi_nom'].'
'; $description .= 'Station : '.$obs['os_nom'].'
'; if($this->estUneDateSqlInvalide($obs['oo_date'])) { $description .= ' Date d\'observation supprimée
'; } else { $description .= ' Date de l\'observation changée en : '.strftime('%A %d %B %Y', strtotime($obs['oo_date'])).'
'; } $description .= 'Saisi le : '.$item['date_creation_simple'].'
'; $description .= 'Modifié le : '.$item['date_maj_simple'].'
'; } $description = $this->nettoyerTexte($description); return $description; } private function estUneDateSqlInvalide($date) { $date_tab = explode('-', $date); return ($date_tab[2] == '00' || $date_tab[1] == '00' || $date_tab[0] == '0000'); } private function creerCategorie($element) { $categorie = ''; $categorie = 'Observation'; $categorie = $this->nettoyerTexte($categorie); return $categorie; } private function etreFluxAdmin() { return (isset($_GET['admin']) && $_GET['admin'] == '1') ? true : false; } private function creerUrlService() { $url_service = $this->getUrlServiceBase(); if (count($_GET) > 0) { $url_service .= '?'; $requete = ''; foreach($_GET as $cle => $valeur) { if($cle != '' && trim($valeur) != '') { $requete .= '&'.$cle.'='.$valeur; } } $url_service = $url_service.ltrim($requete, '&'); } return $url_service; } } ?>