Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 408 | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?php
/**
* Web service particulier pour photoflora, qui ne doitpas être installé sur tela botanica
* mais sur photoflora.free.fr
* Une redirection htaccess est à faire, redirigeant /service:eflore:0.1/photoflora/image
* vers le site photoflora à l'adresse ou seront installé les services web et le minimum
* nécessaire pour les faire fonctionner (framework + base de code eflore-projet ou peut-être moins)
*
* La table des metadonnées est, elle, stockée sur Tela Botanica
* Le service est dans le même dépot que les autres par souci de commodité
*
*/
class Images {

        const MIME_JPEG = 'image/jpeg';
        const MIME_PNG = 'image/png';
        const MIME_JSON = 'application/json';
        const MIME_XML = 'text/xml';

        //TODO déplacer ceci dans des parametres de config
        const BDD_PF = 'photoflora';
        private $efph_url_photo = 'http://photoflora.free.fr/photos/%s/max/%s';
        private $efph_url_photo_bb = 'http://photoflorabb.free.fr/max/%s';
        private $efph_url_photo_jlt = 'http://photoflorajlt.free.fr/max/%s';

        private $efph_url_photo_min = 'http://photoflora.free.fr/photos/%s/min/%s';
        private $efph_url_photo_bb_min = 'http://photoflora.free.fr/photos/bb/min/%s';
        private $efph_url_photo_jlt_min = 'http://photoflora.free.fr/photos/jlt/min/%s';

        private $parametres = array();
        private $ressources = array();
        private $Bdd;

        private $format = 'min';
        private $retour_mime = 'application/json';
        private $nbreImages = '0';

        public function __construct(Bdd $bdd = null, Array $config = null) {
                $this->config = is_null($config) ? Config::get('Images') : $config;
                $this->Bdd = is_null($bdd) ? new Bdd() : $bdd;
        }

        public function consulter($ressources, $parametres) {

                $this->parametres = $parametres;
                $this->ressources = $ressources;

                $this->definirValeurParDefautDesParametres();

                $this->format = (isset($this->parametres['retour.format']) && $this->parametres['retour.format'] != '') ?  $this->parametres['retour.format'] : $this->format;
                $this->retour_mime = (isset($this->parametres['retour']) && $this->parametres['retour'] != '') ?  $this->parametres['retour'] : $this->retour_mime;
                $photographies = $this->getResultatTest();
                if($this->retour_mime == self::MIME_JPEG) {
                        $photo = $this->obtenirPremiereImage();
                        $retour = $this->formaterRetourImageBinaire($photo);
                        echo $retour;
                } elseif($this->retour_mime == self::MIME_JSON) {
                        $photographies = $this->obtenirImages();
                        $this->nbreImages = count($photographies);
                        $photographies_formatees = $this->formaterRetourJson($photographies);
                        $resultat = $photographies_formatees;
                        $entete = $this->construireEntete();
                        return array('entete' => $entete, 'resultats' => $resultat);
                } elseif ($this->retour_mime == self::MIME_XML) {
                        $photographies = $this->obtenirImages();
                        $this->nbreImages = count($photographies);
                        $photographies_formatees = $this->formaterRetourXml($photographies);
                        header('Content-Type: '.self::MIME_XML);
                        echo $photographies_formatees;
                        exit;
                }
        }

        private function construireEntete() {
                $entete = array('masque' => '', 'depart' => 0, 'limite' => 100, 'total' => 0);

                $entete['masque'] = $this->recupererMasque();
                $entete['depart'] = (int) $this->parametres['navigation.depart'];
                $entete['limite'] = (int) $this->parametres['navigation.limite'];
                $entete['total'] = $this->nbreImages;

                return $entete;
        }

        private function recupererMasque() {
                $masqueEntete = '';
                foreach ($this->parametres as $param => $cle) {
                        if ($param == 'masque') {
                                $masqueEntete = 'masque='.$cle.',';
                        } elseif (substr($param, 0, 7) == 'masque.') {
                                $masqueEntete .= substr($param, 7).'='.$cle.',';
                        }
                }
                $masqueEntete = rtrim($masqueEntete,',');
                return $masqueEntete;
        }

        private function definirValeurParDefautDesParametres() {
                if (isset($this->parametres['retour']) == false) {
                        $this->parametres['retour'] = self::MIME_JSON;
                }
                if (isset($this->parametres['retour.format']) == false) {
                        $this->parametres['retour.format'] = 'min';
                }
                if (isset($this->parametres['navigation.depart']) == false) {
                        $this->parametres['navigation.depart'] = 0;
                }
                if (isset($this->parametres['navigation.limite']) == false) {
                        $this->parametres['navigation.limite'] = 100;
                }
        }

        public function obtenirPremiereImage() {
                $this->parametres['navigation.depart'] = 0;
                $this->parametres['navigation.limite'] = 1;
                $images = $this->obtenirImages();
                if (!is_array($images) || count($images) <= 0) {
                        $message = "Aucune image ne correspond au numéro numenclatural $refTax:$numNom";
                        $code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
                        throw new Exception($message, $code);
                } else {
                        return $images[0];
                }
        }

        public function obtenirImages() {
                //TODO: tri par date, mais les dates dans la bdd photoflora sont des chaines en entités HTML
                // donc un tri dessus n'a pas de sens
                $requete =      'SELECT photos.*, taxons.NumTaxon, taxons.NumNomen, taxons.Combinaison, photographes.Nom, '.
                        '       photographes.Prenom, photographes.Initiales, photographes.Mail '.
                        'FROM '.self::BDD_PF.'.photos, '.self::BDD_PF.'.photographes, '.self::BDD_PF.'.taxons '.
                        'WHERE '.
                        'photos.Auteur = photographes.ID '.
                        'AND photos.NumTaxon = taxons.NumTaxon '.
                        $this->construireWhereNumNom().' '.
                        $this->construireWhereNumTax().' '.
                        $this->construireWhereNomSci().' '.
                        $this->construireWhereAuteur().' '.
                        'ORDER BY photos.support LIMIT '.$this->parametres['navigation.depart'].','.$this->parametres['navigation.limite'];
                $resultat = $this->Bdd->recupererTous($requete);
                return $resultat;
        }

        private function construireWhereNumNom() {
                return (isset($this->parametres['masque.nn'])) ? 'AND taxons.NumNomen = '.$this->Bdd->proteger($this->parametres['masque.nn']).' ' : '';
        }

        private function construireWhereNumTax() {
                return (isset($this->parametres['masque.nt'])) ? 'AND taxons.NumTaxon = '.$this->Bdd->proteger($this->parametres['masque.nt']).' ' : '';
        }

        private function construireWhereNomSci() {
                return (isset($this->parametres['masque.ns'])) ? 'AND taxons.Combinaison LIKE '.$this->Bdd->proteger($this->parametres['masque.ns'].'%').' ' : '';
        }

        private function construireWhereAuteur() {
                $requete_auteur = '';
                if (isset($this->parametres['masque.auteur'])) {
                        $auteur_like = $this->Bdd->proteger($this->parametres['masque.auteur'].'%');
                        $requete_auteur = 'AND photos.auteur = '.
                                '(SELECT id FROM '.self::BDD_PF.'.photographes '.
                                'WHERE '.
                                'Nom LIKE '.$auteur_like.' OR '.
                                'Prenom LIKE '.$auteur_like.' OR '.
                                'Initiales LIKE '.$auteur_like.' OR '.
                                'Mail LIKE '.$auteur_like.') ';
                }
                return $requete_auteur;
        }

        private function formaterRetourImageBinaire($photo) {
                $image = '';
                $chemin = $url = $this->getUrlPhotoPourInitiales($photo['Initiales'], $photo['NumPhoto'], $this->format);
                $image = file_get_contents($chemin);
                if ($image === false) {
                        $message = "L'image demandée est introuvable sur le serveur : $chemin";
                        $code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
                        throw new Exception($message, $code);
                }
                return $image;
        }

        private function formaterRetourJson($photographies) {
                $resultat = array();
                if (is_array($photographies)) {
                        foreach ($photographies as $photo) {
                                $image = array();
                                $url = $this->getUrlPhotoPourInitiales($photo['Initiales'], $photo['NumPhoto'], $this->format);
                                $urlmax = $this->getUrlPhotoPourInitiales($photo['Initiales'], $photo['NumPhoto'], 'max');
                                $id = str_replace(array('.jpg','.jpeg', '.png'), '', $photo['NumPhoto']);

                                // Post-traitement des valeurs
                                $image['date'] = $this->donnerDate($this->formaterChaineEncodeeBddPhotoflora($photo['Date']));
                                $image['mime'] = $this->extraireMime($photo['NumPhoto']);
                                $image['auteur.libelle'] = $this->formaterChaineEncodeeBddPhotoflora($photo['Prenom'].' '.$photo['Nom']);
                                $image['binaire.href'] = $url;
                                $image['binaire.hrefmax'] = $urlmax;
                                $image['determination.libelle'] = $photo['Combinaison'].' ['.$photo['Prenom'].' '.$photo['Nom'].']';
                                $image['determination.nom_sci.libelle'] = $photo['Combinaison'];
                                $image['determination.nom_sci.code'] = "bdtfx.".$photo['NumNomen'];
                                $image['station.libelle'] = $this->formaterStation($photo['lieu']);

                                $resultat[$id] = $image;
                        }
                }
                return $resultat;
        }

        private function extraireMime($fichierImg) {
                $mime = '';
                if (strpos($fichierImg, '.jpg') || strpos($fichierImg, '.jpeg')) {
                        $mime = self::MIME_JPEG;
                } else if (strpos($fichierImg, '.png')) {
                        $mime = self::MIME_PNG;
                }
                return $mime;
        }

        private function formaterStation($station) {
                $station = $this->formaterChaineEncodeeBddPhotoflora($station);
                $station = preg_replace('/^ : /', '', $station);
                return $station;
        }

        private function callBackReplace($m) {
                return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES");
        }

        private function formaterChaineEncodeeBddPhotoflora($chaine) {
                return $chaine = preg_replace_callback("/(&#[0-9]+;)/", array($this, 'callBackReplace'), $chaine);
        }

        // TODO: garder ancien web service pour retour xml ou bien fusionner les deux ?
        private function formaterRetourXml($photographies) {
                // Formatage du xml
                $xml = '<?xml version="1.0" encoding="utf-8"?>'."\n";
                $xml .= '<rdf:RDF'."\n";
                $xml .= '       xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"'."\n";
                $xml .= '       xmlns:dc="http://purl.org/dc/elements/1.1/"'."\n";
                $xml .= '       xmlns:dcterms="http://purl.org/dc/terms">'."\n";
                foreach ($photographies as $photo) {

                        $url = $this->getUrlPhotoPourInitiales($photo['Initiales'], $photo['NumPhoto'], $this->format);

                        // Post-traitement des valeurs
                        $photo['lieu'] = preg_replace('/^[ ]*:[ ]*/', '', $photo['lieu']);

                        // Gestion du XML
                        $xml .= '       <rdf:Description about="'.$url.'"'."\n";
                        $xml .= '               dc:identifier="'.preg_replace('/\.\w+$/', '', $photo['NumPhoto']).'"'."\n";
                        $xml .= '               dc:title="'.$photo['Combinaison'].'"'."\n";
                        $xml .= '               dc:description="'.$photo['Objet'].'"'."\n";
                        $xml .= '               dc:creator="'.$photo['Prenom'].' '.$photo['Nom'].'"'."\n";
                        //      $xml .= '               dc:contributor="Daniel MATHIEU (Détermination)"'."\n";
                        $xml .= '               dc:publisher="Photoflora"'."\n";
                        $xml .= '               dc:type="'.$this->donnerTxtSupport($photo['Support']).'"'."\n";
                        $xml .= '               dc:format="'.$this->donnerTypeMime($photo['NumPhoto']).'"'."\n";
                        $xml .= '               dcterms:spatial="'.$photo['lieu'].'"'."\n";
                        $xml .= '               dcterms:created="'.$photo['Date'].'"'."\n";
                        //      $xml .= '               dcterms:dateSubmitted="2006-10-18 08:32:00"'."\n";
                        $xml .= '               dcterms:licence="Utilisation des photos non autorisée sans accord avec le gestionnaire du site et sous certaines conditions - Tous droits réservés - All rights reserved"/>'."\n";
                }
                $xml .= '</rdf:RDF>'."\n";

                return $xml;
        }

        private function getUrlPhotoPourInitiales($initiales, $num_photo, $format) {
                // Gestion des urls des photos
                $url = '';
                if ($initiales == 'bb') {
                        $base_url = ($format == 'max') ? $this->efph_url_photo_bb : $this->efph_url_photo_bb_min;
                        $url = sprintf($base_url, $num_photo);
                } else if ($initiales == 'jlt') {
                        $base_url = ($format == 'max') ? $this->efph_url_photo_jlt : $this->efph_url_photo_jlt_min;
                        $url = sprintf($base_url, $num_photo);
                } else {
                        $base_url = ($format == 'max') ? $this->efph_url_photo : $this->efph_url_photo_min;
                        $url = sprintf($base_url, $initiales, $num_photo);
                }

                return $url;
        }

        private function getResultatTest() {
                $photographies = array();
                $photographies[] = array('Initiales' => 'bb',
                                'NumPhoto' => 'bb047230.jpg',
                                'NumNomen' => '182',
                                'lieu' => 'Ristolas - Hautes Alpes (05) [France]',
                                'Combinaison' => '',
                                'Objet' => 'Vue générale, en fleur cv Musik - Canon EOS 350D DIGITAL - Expo : 1/160 sec. - Ouv. : f8 - ISO : 100 - flash : non - foc. : 60 - pix. : 8 Mp.',
                                'Prenom' => 'Benoit',
                                'Nom' => 'BOCK',
                                'Support' => 'Photographie numérique',
                                'Date' => 'Mai 2006');

                return $photographies;
        }

        /**
        * Fonction remplaçant les caractères posant problème dans le xml
        *
        * @param string le texte à nettoyer
        * @return string le texte nettoyé
        */
        function nettoyerXml($xml) {
                // Remplacement des esperluettes
                $xml = str_replace(' & ', ' &#38; ', $xml);
                // Remplacement du caractère spécial de fin de ligne : VT
                $xml = preg_replace('//', "\n", $xml);
                return $xml;
        }

        /**
         * Fonction fournissant les intitulés des types de support des images
         *
         * @param integer identifiant du support
         * @return string le texte correspondant au type de support
         */
        function donnerTxtSupport($support) {
                switch ($support) {
                        case '0':
                                $support = 'Photographie num&#233;rique (6 mégapixels)';
                                break;
                        case '1':
                                $support = 'Diapositive';
                                break;
                        case '10':
                                $support = 'Scan de la flore de Coste';
                                break;
                        case '11':
                                $support = 'Scan de plante fraiche';
                                break;
                        default:
                                $support = 'Erreur code support : pr&#233;venir eflore_remarques@tela-botanica.org';
                }
                return $support;
        }

        /**
         * Fonction fournissant les types MIME des fichiers images
         *
         * @param string le nom du fichier
         * @return string le texte du type MIME du fichier
         */
        function donnerTypeMime($fichier) {
                if (preg_match('/\.(\w+)$/', $fichier, $match)) {
                        switch (strtolower($match[1])) {
                                case 'jpeg':
                                case 'jpg':
                                        $type = 'image/jpeg';
                                        break;
                                case 'png':
                                        $type = 'image/png';
                                        break;
                                default:
                                        $type = 'Erreur Mime : prévenir eflore_remarques@tela-botanica.org';
                        }
                } else {
                        $type = 'Erreur Mime : prévenir eflore_remarques@tela-botanica.org';
                }
                return $type;
        }

        /**
         * Fonction fournissant une date au format Mysql
         *
         * @param string la date composé du nom du mois en français et de l'année sous 4 chiffres
         * @return string la date dans le format Mysql
         */
        function donnerDate($chaine) {
                if (preg_match('/^(\w+) (\d{4})$/',$chaine, $match)) {
                        $mois = $match[1];
                        $annee = $match[2];
                        switch (strtolower($mois)) {
                                case 'janvier' :
                                        $mois_sortie = '01';
                                        break;
                                case 'février' :
                                        $mois_sortie = '02';
                                        break;
                                case 'mars' :
                                        $mois_sortie = '03';
                                        break;
                                case 'avril' :
                                        $mois_sortie = '04';
                                        break;
                                case 'mai' :
                                        $mois_sortie = '05';
                                        break;
                                case 'juin' :
                                        $mois_sortie = '06';
                                        break;
                                case 'juillet' :
                                        $mois_sortie = '07';
                                        break;
                                case 'aout' :
                                case 'août' :
                                        $mois_sortie = '08';
                                        break;
                                case 'septembre' :
                                        $mois_sortie = '09';
                                        break;
                                case 'octobre' :
                                        $mois_sortie = '10';
                                        break;
                                case 'novembre' :
                                        $mois_sortie = '11';
                                        break;
                                case 'decembre' :
                                        $mois_sortie = '12';
                                        break;
                        }
                        return $annee.'-'.$mois_sortie.'-01 01:01:01';
                } else {
                        return '1970-01-01 01:01:01';
                }
        }
}
?>