Rev 637 | Rev 742 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php
/**
* Service fournissant des informations concernant le CEL au format RSS1, RSS2 ou ATOM.
* Encodage en entrée : utf8
* Encodage en sortie : utf8
* Format du service :
* /CelSyndicationObservation/liste-des-flux
* /CelSyndicationObservation/opml
* /CelSyndicationObservation/par-defaut/(rss1|rss2|atom)?start=0&limit=150
* /CelSyndicationObservation/pour-admin/(rss1|rss2|atom)?start=0&limit=150
* /CelSyndicationObservation/par-mots-cles/(rss1|rss2|atom)/mot-cle?start=0&limit=150
* /CelSyndicationObservation/par-commune/(rss1|rss2|atom)/nom-commune?start=0&limit=150
*
* Les paramêtres :
* - "start" indique le numéro du premier item à afficher
* - "limit" nombre d'items à afficher
*
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
* @version $Id$
* @copyright 2010
*/
class CelSyndicationObservation extends Cel {
private $parametres_origines = null;
private $format = null;
private $service = null;
private $squelette = null;
private $squelette_dossier = null;
private $flux = array();
private $criteres = array(
'auteur' => 'identifiant',
'commune' => 'location',
'departement' => 'id_location',
'taxon' => 'nom_ret',
'commentaire' => 'commentaire',
'date' => 'date_observation',
'projet' => 'mots-cles');
/**
* 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->authentifierAdmin()) {
// Pré traitement des paramêtres
$pour_bdd = false;
$p = $this->traiterParametres(array('service', 'format'), $params, $pour_bdd);
extract($p);
$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 CEL 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 CEL 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 getUrlBase() {
$url_base = sprintf($this->config['settings']['baseURLAbsolu'], 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 publiques du CEL',
'Ce flux fournit des informations sur les observations du CEL.');
$this->setFlux('par-mots-cles', 'Flux de syndication des observations publiques du CEL filtrées par mots clés',
"Ce flux fournit des informations sur les observations du CEL filtrées par mots-clés. Il nécessite d'être
paramétré en indiquant en dernier position de l'url le mot-clé à rechercher.");
$this->setFlux('par-commune','Flux de syndication des observations publiques du CEL filtrées par commune',
"Ce flux fournit des informations sur les observations du CEL filtrées par commune. Il nécessite d'être
paramétré en indiquant en dernier position de l'url le nom de la commune à rechercher.");
}
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'] = "CEL - Obs - $flux_nom";
$info['description'] = $flux['description'];
$info['url_xml'] = $this->getUrlBase().$flux_nom.'/atom';
$info['url_html'] = $this->config['settings']['aideCelUrl'].'FluxSyndication';
$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 = (isset($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' * '.
'FROM cel_inventory '.
(($this->etreFluxAdmin()) ? '' : 'WHERE transmission = 1 ').
'ORDER BY '.(isset($this->orderby) && (!is_null($this->orderby)) ? $this->orderby : 'date_modification DESC').' '.
"LIMIT $this->start,$this->limit ";
$elements = $this->executerRequete($requete);
// Création du contenu
$contenu = $this->executerService($elements);
return $contenu;
}
private function getServiceParMotsCles() {
$contenu = '';
$mot_cle = $this->parametres[0];
if (isset($mot_cle)) {
$mot_cle_encode = $this->bdd->quote($this->encoderMotCle($mot_cle));
// Construction de la requête
$requete = 'SELECT * '.
'FROM cel_mots_cles_obs '.
"WHERE cmc_id_mot_cle_general = $mot_cle_encode ";
$elements = $this->executerRequete($requete);
if ($elements != false && count($elements) > 0) {
// Pré-construction du where de la requête
$tpl_where = '(mots_cles LIKE "%%%s%%" AND identifiant = %s )';
$requete_where = array();
foreach ($elements as $occurence) {
$requete_where[] = sprintf($tpl_where, $occurence['cmc_id_mot_cle_utilisateur'], $this->bdd->quote($occurence['cmc_id_proprietaire']));
}
// Construction de la requête
$requete = 'SELECT * '.
'FROM cel_inventory '.
'WHERE '.implode(" \nOR ", $requete_where).' '.
' '.(($this->etreFluxAdmin()) ? '' : 'AND transmission = 1 ').
'ORDER BY '.(isset($this->orderby) && (!is_null($this->orderby)) ? $this->orderby :
'date_modification, date_creation DESC').' '.
"LIMIT $this->start,$this->limit ";
$elements = $this->executerRequete($requete);
// Création du contenu
$contenu = $this->executerService($elements);
} else {
$this->messages[] = "Aucune observation ne correspond à ce mot clé.";
}
} else {
$this->messages[] = "Le service demandé nécessite d'indiquer un mot-clé en dernier paramêtre.";
}
return $contenu;
}
private function getServiceParCommune() {
$contenu = '';
$commune = $this->parametres[0];
if (isset($commune)) {
$commune = $this->bdd->quote($commune);
// Construction de la requête
$requete = (isset($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' * '.
'FROM cel_inventory '.
"WHERE location = $commune ".
' '.(($this->etreFluxAdmin()) ? '' : 'AND transmission = 1 ').
'ORDER BY '.(isset($this->orderby) && (!is_null($this->orderby)) ? $this->orderby : 'date_modification DESC, location ASC').' '.
"LIMIT $this->start,$this->limit ";
$elements = $this->executerRequete($requete);
// Création du contenu
$contenu = $this->executerService($elements);
} else {
$this->messages[] = "Le service demandé nécessite d'indiquer une nom de commune en dernier paramêtre.";
}
return $contenu;
}
private function getServiceMultiCriteres() {
$contenu = '';
if (isset($_GET['debut'])) $this->start = $_GET['debut'];
if (isset($_GET['limite'])) $this->limite = $_GET['limite'];
// Construction de la requête
$requete = (isset($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' * '.
'FROM cel_inventory '.
'WHERE transmission = 1 '.
' AND ';
if ($this->estUneRechercheGenerale()) {
$chaine_requete = $_GET['recherche'];
$requete .= $this->creerSousRequeteRechercheGenerale($chaine_requete);
} else {
$criteres = $this->traiterCriteresMultiples($_GET) ;
if (!empty($criteres)) {
$requete .= $this->creerSousRequeteRechercheParCriteres($criteres);
}
}
$requete = rtrim($requete, 'AND ');
$requete .= 'ORDER BY '.(isset($this->orderby) && (!is_null($this->orderby)) ? $this->orderby :
'date_modification DESC, location ASC').' '.
"LIMIT $this->start,$this->limit ";
$elements = $this->executerRequete($requete);//echo $requete;
// Création du contenu
if ($elements != false && count($elements) > 0) {
$contenu = $this->executerService($elements);
} else {
$this->messages[] = "Aucune observation disponible.";
}
return $contenu;
}
private function creerSousRequeteRechercheParCriteres($criteres) {
$requete = '';
foreach ($criteres as $pair) {
$nom_valeur = explode("=",$pair);
if (sizeof($nom_valeur) != 0) {
switch ($nom_valeur[0]) {
case "ci_limite" : $this->limite = $this->bdd->quote($nom_valeur[1]); break;
case "commentaire" : $mots_comment_liste = explode(" " , $nom_valeur[1]);
foreach($mots_comment_liste as $mot_comment) {
$mot_comment = trim($mot_comment) ;
$requete .= $nom_valeur[0].' LIKE '.$this->bdd->quote('%'.$mot_comment.'%').' AND ';
}
break;
case "date_observation" :
$nom_valeur[1] = str_replace('/', '-', $nom_valeur[1]);
if (preg_match('/(^[0-9]{2})-([0-9]{2})-([0-9]{4}$)/', $nom_valeur[1], $matches)) {
$nom_valeur[1] = $matches[3].'-'.$matches[2].'-'.$matches[1];
}
$requete .= $nom_valeur[0].'='.$this->bdd->quote($nom_valeur[1]).' AND '; break;
case "nom_ret" :
if ($nom_valeur[1] == "indetermine") $nom_valeur[1] = 'null';
$requete .= ' ('.$nom_valeur[0].' LIKE "%'.$nom_valeur[1].'%" OR nom_sel LIKE "%'.
$nom_valeur[1].'%") AND '; break;
case "mots-cles" : $requete .= $this->creerSousRequeteMotsCles($nom_valeur[1]); break;
default : $requete .= $nom_valeur[0].' = "'.$nom_valeur[1].'" AND '; break;
}
}
}
$requete = rtrim($requete,' AND ');
return $requete;
}
private function creerSousRequeteMotsCles($mot_cle) {
$requete = 'mots_cles like "inexistant" OR';
if (preg_match('/.*,.*/', $mot_cle)) {
$requete = $this->creerSousRequeteMotsClesOu($mot_cle);
} else if (preg_match('/.*ET.*/', $mot_cle)) {
$requete = $this->creerSousRequeteMotsClesEt($mot_cle);
} else {
// Construction de la requête
$prerequete = 'SELECT * '.
'FROM cel_mots_cles_obs '.
'WHERE cmc_id_mot_cle_general = '.$this->bdd->quote($this->encoderMotCle($mot_cle));
$elements = $this->executerRequete($prerequete);
if ($elements != false && count($elements) > 0) {
$requete = '';
foreach ($elements as $occurence) {
$requete .= '(mots_cles LIKE "%'.$occurence['cmc_id_mot_cle_utilisateur'].'%" AND identifiant = '.
$this->bdd->quote($occurence['cmc_id_proprietaire']).' ) OR ';
}
}
}
$requete = rtrim($requete,' OR ').' AND ';
return $requete;
}
private function creerSousRequeteMotsClesOu($mot_cle) {
$requete = 'mots_cles like "inexistant" OR';
$tab_mots_cles = explode(',', $mot_cle);
$where = '';
foreach ($tab_mots_cles as $mot) {
$where .= 'cmc_id_mot_cle_general = '.$this->bdd->quote($this->encoderMotCle($mot)).' OR ';
}
$where = rtrim($where,' OR ');
// Construction de la requête
$prerequete = "SELECT cmc_id_mot_cle_utilisateur, cmc_id_proprietaire FROM cel_mots_cles_obs WHERE $where ";
$elements = $this->executerRequete($prerequete);//print_r($elements);
if ($elements != false && count($elements) > 0) {
$requete = '';
foreach ($elements as $occurence) {
$requete .= '(mots_cles LIKE "%'.$occurence['cmc_id_mot_cle_utilisateur'].'%" AND identifiant = '.
$this->bdd->quote($occurence['cmc_id_proprietaire']).' ) OR ';
}
}
return $requete;
}
private function creerSousRequeteMotsClesEt($mot_cle) {
$requete = 'mots_cles like "inexistant" OR';
$where = '';
$champs = 'a.cmc_id_proprietaire , ';
$table = '';
$i = "a"; $j = "a";
$tab_mots_cles = explode("ET", $mot_cle);
foreach ($tab_mots_cles as $mot) {
$champs .= "$i.cmc_id_mot_cle_utilisateur as $i , ";
$table .= "cel_mots_cles_obs $i , ";
$where .= "$i.cmc_id_mot_cle_general = ".$this->bdd->quote($this->encoderMotCle($mot)).' AND ';
if ($i !== "a") {
$where .= " $i.cmc_id_proprietaire = ".$j.".cmc_id_proprietaire AND ";
$j++;
}
$i++;
}
$where = rtrim($where,' AND '); $champs = rtrim($champs,' , '); $table = rtrim($table,' , ');
// Construction de la requête
$prerequete = "SELECT $champs FROM $table WHERE $where ";
$elements = $this->executerRequete($prerequete);//print_r($elements);
if ($elements != false && count($elements) > 0) {
$requete = '';
foreach ($elements as $occurence) {
$requete = ' (';
for ($j = 'a'; $j < $i; $j++) {
$requete .= 'mots_cles like "%'.$occurence[$j].'%" AND ';
}
$requete .= ' identifiant = '.$this->bdd->quote($occurence['cmc_id_proprietaire']).' ) OR ';
}
}
return $requete;
}
private function traiterCriteresMultiples($tableau_criteres) {
$tableau_criteres_pour_bdd = array();
foreach($tableau_criteres as $nom_critere => $valeur_critere) {
if (isset($this->criteres[$nom_critere])) {
$tableau_criteres_pour_bdd[] = $this->criteres[$nom_critere].'='.$valeur_critere;
}
}
return $tableau_criteres_pour_bdd;
}
private function creerSousRequeteRechercheGenerale($chaine_requete) {
$requete = '';
if (trim($chaine_requete) != '') {
$chaine_requete = strtolower($chaine_requete);
$chaine_requete = str_replace(' ', '_', $chaine_requete);
$requete = ' ('.
'nom_ret LIKE "'.$chaine_requete.'%"'.
' OR '.
'nom_sel LIKE "'.$chaine_requete.'%"'.
' OR '.
'location LIKE "'.$chaine_requete.'%" '.
' OR '.
'id_location LIKE "'.$chaine_requete.'%" '.
' OR '.
'identifiant LIKE "'.$chaine_requete.'%" '.
') ';
}
return $requete;
}
private function estUneRechercheGenerale() {
return isset($_GET['recherche']);
}
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 = Cel::traiterSquelettePhp($this->squelette, $donnees);
}
}
return $contenu;
}
private function construireDonneesCommunesAuFlux($observations) {
$donnees = $this->getFlux($this->service);
$donnees['guid'] = $this->getUrlServiceBase();
$donnees['lien_service'] = $this->creerUrlService();
$donnees['lien_cel'] = $this->config['settings']['baseURLAbsolu'];
$donnees['editeur'] = $this->config['settings']['editeur'];
$derniere_info_en_date = reset($observations);
$date_modification_timestamp = strtotime($derniere_info_en_date['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'] = 'CEL - Jrest - CelSyndicationObservation';
$donnees['generateur_version'] = (preg_match('/([0-9]+)/', '$Revision$', $match)) ? $match[1] : '0';
return $donnees;
}
private function construireDonneesCommunesAuxItems($observation) {
$item = array();
$date_modification_timestamp = $this->convertirDateHeureMysqlEnTimestamp($observation['date_modification']);
$item['date_maj_simple'] = strftime('%A %d %B %Y à %H:%M', $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 à %H:%M', strtotime($observation['date_creation']));
$item['titre'] = $this->creerTitre($observation);
$item['guid'] = $this->creerGuidItem($observation);
$item['lien'] = $this->creerLienItem($observation);
$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['identifiant'], $this->etreFluxAdmin());
return $item;
}
private function creerTitre($obs) {
$nom_plante = $obs['nom_sel'].' [nn'.$obs['num_nom_sel'].']';
$lieu = $obs['location'].' ('.$obs['id_location'].')';
$utilisateur = $this->creerAuteur($obs['identifiant'], $this->etreFluxAdmin());
$titre = "$nom_plante à $lieu par $utilisateur";
$titre = $this->nettoyerTexte($titre);
return $titre;
}
private function creerGuidItem($element) {
$guid = sprintf($this->config['settings']['guidObsTpl'], 'obs'.$element['id']);
return $guid;
}
private function creerLienItem($element) {
$lien = null;
if ($element['num_nom_sel'] != 0) {
$lien = sprintf($this->config['settings']['efloreUrlTpl'], urlencode($element['num_nom_sel']), 'cel');
}
return $lien;
}
private function creerDescription($obs, $item) {
$id_obs = $obs['id'];
$famille = $obs['famille'];
$nom_saisi = $obs['nom_sel'];
$nom_retenu = $obs['nom_ret'];
$auteur = $this->creerAuteur($obs['identifiant'], $this->etreFluxAdmin());
$mots_cles_obs = $this->decoderMotsClesObs($obs['identifiant'], $obs['mots_cles']);
$lien_correction = sprintf($this->config['settings']['phpEditUrlTpl'], $obs['id']);
$lieu = $obs['location'].' ('.$obs['id_location'].') > '.$obs['lieudit'].' > '.$obs['station'];
$milieu = $obs['milieu'];
$coordonnees = ($this->etreNull($obs['coord_x']) && $this->etreNull($obs['coord_y'])) ? '' : $obs['coord_x'].'/'.$obs['coord_y'];
$commentaire = $obs['commentaire'];
$date_observation = $this->formaterDate($obs['date_observation'], '%A %d %B %Y');
$date_transmission = $this->formaterDate($obs['date_transmission']);
$date_modification = $this->formaterDate($obs['date_modification']);
$date_creation = $this->formaterDate($obs['date_creation']);
$transmission = $obs['transmission'] == 1 ? "oui ($date_transmission)" : 'non';
$description = '<h2>'."Observation #$id_obs de $nom_saisi".'</h2>'.
'<ul>'.
'<li>'.'Famille : '.$famille.'</li>'.
'<li>'.'Nom saisi : '.$nom_saisi.'</li>'.
'<li>'.'Nom retenu : '.$nom_retenu.'</li>'.
'<li>'.'Observée le : '.$date_observation.'</li>'.
'<li>'.'Lieu : '.$lieu.'</li>'.
'<li>'.'Milieu : '.$milieu.'</li>'.
(($this->etreFluxAdmin()) ? '<li>Coordonnées (Lat/Long) : '.$coordonnees.'</li>' : '').
'<li>'.'Commentaire : '.$commentaire.'</li>'.
'<li>'.'Mots-clés : '.implode(', ', $mots_cles_obs).'</li>'.
(($this->etreFluxAdmin()) ? '<li>Transmis (= public) : '.$transmission.'</li>' : '').
'<li>Modifiée le : '.$date_modification.'</li>'.
'<li>Créée le : '.$date_creation.'</li>'.
(($this->etreFluxAdmin()) ? '<li><a href="'.$lien_correction.'">Corriger cette observation</a></li>' : '').
'</ul>';
$description = $this->nettoyerTexte($description);
return $description;
}
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) {
$parametres_get = array();
foreach ($_GET as $cle => $valeur) {
$parametres_get[] = $cle.'='.$valeur;
}
$url_service .= '?'.implode('&', $parametres_get);
}
return $url_service;
}
}