Subversion Repositories eFlore/Applications.cel

Rev

Rev 502 | 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 $format = null;
        private $service = null;
        private $parametres = null;
        private $squelette = null;
        private $squelette_dossier = null;
        private $flux = array();
        
        /**
         * Méthode appelée avec une requête de type GET.
         */
        public function getElement($params = array()) {
                // Initialisation des variables
                $info = array();
                $contenu = '';
                        
                // 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']['baseURLAbsoluDyn'], get_class($this).'/');
                return $url_base;
        }
        
        private function getUrlServiceBase() {
                $url_service = $this->getUrlBase().$this->service.'/'.$this->format;
                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 =      (($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' * '.
                        'FROM cel_inventory '.
                        'WHERE transmission = 1 '.
                        'ORDER BY '.((!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 getServicePourAdmin() {
                $contenu = '';
                if ($this->authentifier()) {
                        // Construction de la requête
                        $requete =      (($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' * '.
                                'FROM cel_inventory '.
                                'ORDER BY '.((!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 transmission = 1 '.
                                        'AND '.implode(" \nOR ", $requete_where).' '.
                                        'ORDER BY '.((!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 =      (($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' * '.
                                'FROM cel_inventory '.
                                'WHERE transmission = 1 '.
                                "AND location = $commune ".
                                'ORDER BY '.((!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 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']['celUrlAbsolu'];
                $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';
                preg_match('/([0-9]+)/', '$Revision$', $match);
                $donnees['generateur_version'] = $match[1];
                return $donnees; 
        }
        
        private function construireDonneesCommunesAuxItems($observation) {
                $item = array();
                $date_modification_timestamp = strtotime($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['description'] = $this->creerDescription($observation, $item);
                $item['categorie'] = $this->creerCategorie($item);
                $item['description_encodee'] = htmlspecialchars($item['description']);
                $item['modifier_par'] = $this->creerAuteur($observation['identifiant']);
                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']);
                $titre = "$nom_plante à $lieu par $utilisateur";
                $titre = $this->nettoyerTexte($titre);
                return $titre;
        }
        
        private function creerAuteur($courriel) {
                $auteur = ($this->etreFluxAdmin()) ? $courriel : $this->traiterCourriel($courriel);
                return $auteur;
        }
        
        private function traiterCourriel($courriel) {
                $courriel = preg_replace('/[^@]+$/i', '...', $courriel);
                return $courriel;
        }
        
        private function nettoyerTexte($txt) {
                $txt = preg_replace('/&(?!(a-z+|#0-9+|#x0-9a-f+);)/i', '&amp;', $txt);
                $txt = preg_replace('/000null/i', '', $txt);
                return $txt;
        }
        
        private function creerGuidItem($element) {
                $guid = sprintf($this->config['settings']['guidObsTpl'], 'obs'.$element['id']);
                return $guid;
        }
        
        private function creerLienItem($element) {
                $lien = sprintf($this->config['settings']['efloreUrlTpl'], urlencode($element['num_nom_sel']));
                return $lien;
        }
        
        private function creerDescription($obs, $item) {
                $lien_correction = sprintf($this->config['settings']['phpEditUrlTpl'], $obs['id']);
                $description = 
                        '<ul>'.
                        '       <li>Nom saisi : '.$obs['nom_sel'].'</li>'.
                        (($obs['nom_sel'] != $obs['nom_ret']) ? '       <li>Nom retenu : '.$obs['nom_ret'].'</li>' : '').
                        '       <li>Lieu : '.$obs['location'].' ('.$obs['id_location'].')</li>'.
                        ($this->etreNull($obs['station']) ? '': '       <li>Station : '.$obs['station'].'</li>').
                        ($this->etreNull($obs['milieu']) ? '': '        <li>Milieu : '.$obs['milieu'].'</li>').
                        ($this->etreNull($obs['commentaire']) ? '': '   <li>Commentaire : '.$obs['commentaire'].'</li>').
                        (($this->etreFluxAdmin()) ? '   <li>Transmis (= public) : '.($obs['transmission'] == 1 ? 'oui' : 'non').'</li>' : '').
                        '       <li>Modifiée le : '.$item['date_maj_simple'].'</li>'.
                        '       <li>Créée le : '.$item['date_creation_simple'].'</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 ($this->service == 'pour-admin') ? true : false;
        }
        
        private function etreNull($valeur) {
                $etre_null = false;
                if ($valeur == '' || $valeur == null || $valeur == '000null' || $valeur == 'null') {
                        $etre_null = true;
                }
                return $etre_null;
        }
        
        private function creerUrlService() {
                $url_service = $this->getUrlServiceBase();
                if (isset($this->start) || isset($this->limit)) {
                        $arguments = array();
                        if (isset($this->start) && isset($_GET['start'])) {
                                $arguments[] = 'start='.$this->start;
                        }
                        if (isset($this->limit) && isset($_GET['limit'])) {
                                $arguments[] = 'limit='.($this->limit);
                        }
                        if (count($arguments) > 0) {
                                $url_service .= '?'.implode('&', $arguments);
                        }
                }
                return $url_service;
        }
}