Rev 1175 | 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://www.photoflora.fr/photos/%s/max/%s';
private $efph_url_photo_bb = 'http://photoflorabb.fr/max/%s';
private $efph_url_photo_jlt = 'http://photoflorajlt.fr/max/%s';
private $efph_url_photo_min = 'http://www.photoflora.fr/photos/%s/min/%s';
private $efph_url_photo_bb_min = 'http://www.photoflora.fr/photos/bb/min/%s';
private $efph_url_photo_jlt_min = 'http://www.photoflora.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(' & ', ' & ', $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é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é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';
}
}
}
?>