Rev 3923 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php
// declare(encoding='UTF-8');
/**
* Service fournissant permettant de visualiser ou télécharger des images du CEL
* Spécifiquement pour le format O (original) tout en supprimant les EXIF
* de façon à protéger les espèces protégées floutées
*
* @internal Mininum PHP version : 5.2
* @category CEL
* @package Services
* @subpackage Images
* @version 0.1
* @author Mathias CHOUET <mathias@tela-botanica.org>
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @author Aurelien PERONNET <aurelien@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>
* @copyright 1999-2014 Tela Botanica <accueil@tela-botanica.org>
*/
class CelImageFormatO {
private $config;
// @TODO tirer ça de la config
private $formats = array('O');
const METHODE_TELECHARGEMENT = 'telecharger';
const METHODE_AFFICHAGE = 'afficher';
// Pas besoin d'étendre Cel ici, surtout que le constructeur
// de la classe Cel instancie toujours une connexion à la bdd
// dont on a pas besoin ici. Ceci évite de planter le service
// quand la bdd est surchargée.
public function __construct($config) {
$this->config = $config;
}
public function getRessource() {
header('Content-Type: application/json');
echo json_encode($this->obtenirDescriptionService());
}
/**
* Méthode appelée avec une requête de type GET.
*/
public function getElement($params) {
// suppression des 0 non significatifs à gauche
$id = ltrim($params[0], '0');
$format = isset($_GET['format']) ? $_GET['format'] : 'M';
$methode_livraison = isset($_GET['methode']) ? $_GET['methode'] : self::METHODE_AFFICHAGE;
if($this->verifierParametres($id, $format, $methode_livraison)) {
$gestion_formats_images = new ImageRecreation($this->config);
$image_binaire = $gestion_formats_images->creerOuRenvoyerImage($params[0], $format);
if($image_binaire) {
$this->envoyerImage($id, $image_binaire, $format, $methode_livraison);
} else {
header("HTTP/1.0 404 Not Found");
echo 'Aucune image ne correspond à cet identifiant';
}
}
}
private function verifierParametres($id, $format, $methode_livraison) {
$ok = true;
$message = '';
if(!is_numeric($id)) {
$message .= "L'identifiant de format doit être un entier. ";
$ok = false;
}
if(!in_array($format, $this->formats)) {
$message .= "Le format d'image est inconnu, les formats acceptés sont ".implode(',', $this->formats).". ";
$ok = false;
}
$types_methode_livraison = array(self::METHODE_AFFICHAGE, self::METHODE_TELECHARGEMENT);
if (!in_array($methode_livraison, $types_methode_livraison)) {
$message .= "Le format de methode de livraison ".$methode_livraison." n'est pas acceptée par le service. ".
" Seuls les methodes suivantes sont gérés : ".implode(',', $types_methode_livraison);
$ok = false;
}
if(!empty($message)) {
header("HTTP/1.0 400 Bad Request");
echo $message;
}
return $ok;
}
private function envoyerImage($id, $image_binaire, $format, $methode) {
$gestion_formats_images = new ImageRecreation($this->config);
$dossier = $gestion_formats_images->obtenirDossierPourFormat($id, $format);
$nom_fichier = $gestion_formats_images->convertirIdBddVersNomFichier($id, $format);
$last_modified_time = filemtime($dossier.'/'.$nom_fichier);
// On génère l'ETAG faible
$etag = 'W/"' . md5($last_modified_time) . '"';
// On définit les bons headers
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $last_modified_time) . " GMT");
header('Cache-Control: public, max-age=604800'); // On peut ici changer la durée de validité du cache
header("Etag: $etag");
// On vérifie les headers envoyés dans la requête
if (
(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) === $last_modified_time) ||
(isset($_SERVER['HTTP_IF_NONE_MATCH']) && $etag === trim($_SERVER['HTTP_IF_NONE_MATCH']))
) {
// On renvoit une 304 si on n'a rien modifié depuis
header('HTTP/1.1 304 Not Modified');
exit();
}
if ($methode == self::METHODE_AFFICHAGE) {
header('Content-Type: image/jpeg');
} else {
$this->envoyerHeadersTelechargement($id, $image_binaire, $format);
}
echo $image_binaire;
exit();
}
private function envoyerHeadersTelechargement($id, $image_binaire, $format) {
if (function_exists('mb_strlen')) {
$taille = mb_strlen($image_binaire, '8bit');
} else {
$taille = strlen($image_binaire);
}
// creation du format original
$id_avec_zeros = sprintf('%09s', $id) ;
$id_avec_zeros_underscores = wordwrap($id_avec_zeros, 3 , '_', true) ;
$nom_fichier = $id_avec_zeros_underscores.'_'.$format.'.jpg';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$nom_fichier.'"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: '.$taille);
}
private function obtenirDescriptionService() {
$retour = array('description' => 'Ce service peut être appelé afin de visualiser ou bien télécharger les images du cel',
'formats' => $this->formats,
'utilisation' => 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']."/{id} où {id} est l'identifiant numérique de l'image désirée",
'parametres' => array(
'methode' => "Valeurs : afficher, telecharger. Permet de préciser si l'image doit être affichée ou téléchargée",
'format' => "Valeurs : voir la liste ci dessous. Permet de demander un format précis de l'image parmi ceux disponibles ")
);
// ^^ c'est marrant non ?
$format_formates = array();
foreach ($this->formats as $format) {
if ($format == "O") {
$format_formates["O"] = array("hauteur" => "dépend de l'image originale",
"largeur" => "dépend de l'image originale",
"notes" => "Image dans son ratio et sa résolution originale (elle peut éventuellement avoir été compressée en qualité)"
);
} else {
$description = array();
if (strpos($format, 'R') !== false) {
$description[] = "Format carré, rogné pour ne garder que le centre de l'image.";
}
if (strpos($format, 'C') !== false) {
$description[] = "Format carré, si le format contient R, il est rogné, sinon des bandes blanches sont ajoutées pour conserver le ratio.";
}
if (empty($description)) {
$description[] = "Format standard, le ratio original de l'image est conservé";
}
$resolution = $this->config['cel']['format_'.$format];
$resolution = explode("_", $resolution);
$format_formates[$format] = array("hauteur" => $resolution[0],
"largeur" => $resolution[1],
"notes" => implode(' ', $description)
);
}
}
$retour['resolutions'] = $format_formates;
return $retour;
}
}