Subversion Repositories eFlore/Applications.del

Compare Revisions

No changes between revisions

Ignore whitespace Rev 2089 → Rev 2094

/tags/v1.10-sodium/services/modules/0.1/images/ListeImages.php
New file
0,0 → 1,168
<?php
// declare(encoding='UTF-8');
/**
* Listes des images avec leurs infos liées.
*
* del/services/0.1/images?navigation.depart=0&navigation.limite=12&tri=votes&ordre=desc
* del/services/0.1/images?navigation.depart=0&navigation.limite=12&tri=votes&ordre=desc&masque=plop
* del/services/0.1/images?navigation.depart=0&navigation.limite=12&tri=votes&ordre=desc&protocole=3
* del/services/0.1/images?navigation.depart=0&navigation.limite=12&tri=votes&ordre=desc&protocole=3&masque=plop
*
* @category DEL
* @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>
*/
 
//restore_error_handler();
//restore_exception_handler();
//error_reporting(E_ALL);
class ListeImages {
 
private $conteneur;
private $bdd;
private $filtrage;
private $sql;
private $navigation;
private $paramsFiltres = array();
private $mappings = array();
private $idsImagesOrdonnees = array();
private $infosImages = array();
private $infosImagesOrdonnees = array();
 
public function __construct(Conteneur $conteneur) {
$this->conteneur = $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->filtrage = $this->conteneur->getParametresFiltrage();
$this->sql = $this->conteneur->getSql();
$this->navigation = $this->conteneur->getNavigation();
 
$this->mappings['observations'] = $this->conteneur->getParametreTableau('observations.mapping');
$this->mappings['images'] = $this->conteneur->getParametreTableau('images.mapping');
}
 
public function consulter($ressources, $parametres) {
$this->paramsFiltres = $this->filtrage->filtrerUrlParamsAppliImg();
$this->sql->setAppli(Sql::APPLI_IMG);
$this->sql->setParametres($this->paramsFiltres);
$this->sql->ajouterContraintes();
$this->sql->ajouterConstrainteAppliImg();
$this->sql->definirOrdreSqlAppliImg();
 
$this->idsImagesOrdonnees = $this->getIdImages();
$this->navigation->setTotal($this->sql->getTotalLignesTrouvees());
 
// Ce n'est pas la peine de continuer s'il n'y a pas eu de résultats
$resultat = new ResultatService();
$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => array());
if (count($this->idsImagesOrdonnees) > 0) {
$this->infosImages = $this->getInfosImages();
$this->infosImagesOrdonnees = $this->formaterImages();
 
// Chargement des votes pour ces images et pour *tous* les protocoles
$votes = $this->sql->getVotesDesImages($this->idsImagesOrdonnees);
if ($votes) {
// ATTENTION : $images est récupéré par référence !
$this->sql->ajouterInfosVotesProtocoles($votes, $this->infosImagesOrdonnees);
}
 
$resultat->corps = array(
'entete' => $this->navigation->getEntete(),
'resultats' => array_values($this->infosImagesOrdonnees));
}
return $resultat;
}
 
private function getIdImages() {
$requete = 'SELECT SQL_CALC_FOUND_ROWS DISTINCT di.id_image '.
'FROM del_image AS di '.
$this->sql->getJoin().
'WHERE '.$this->sql->getWhere().
$this->sql->getGroupBy().
$this->sql->getOrderBy().
$this->sql->getLimit().
' -- '.__FILE__.':'.__LINE__;
// TODO : si le DISCTINCT dans la requête pose des pb de perf, supprimer les doublons d'id à l'aide de PHP
//Debug::printr($requete);exit();
$resultats = $this->bdd->recupererTous($requete);
$idImgs = array();
if ($resultats !== false ) {
foreach ($resultats as $resultat) {
$idImgs[] = $resultat['id_image'];
}
}
return $idImgs;
}
 
private function getInfosImages() {
// Traitement du champ mots clés text à part pour éviter un écrasement des mots
// clés img par ceux de l'obs
// TODO: gérer ce problème pour tous les champs où ça peut arriver
$mot_cles_texte_concat = "di.mots_cles_texte as mots_cles_texte_img";
$obsChamps = $this->sql->getAliasDesChamps($this->mappings['observations'], null, 'do');
$imgChamps = $this->sql->getAliasDesChamps($this->mappings['images'], null, 'di');
$idImgsConcat = implode(',', $this->idsImagesOrdonnees);
 
$requete = "SELECT $obsChamps, $imgChamps, $mot_cles_texte_concat ".
'FROM del_image AS di '.
' LEFT JOIN del_observation AS do ON (di.ce_observation = do.id_observation) '.
"WHERE di.id_image IN ($idImgsConcat) ".
'-- '.__FILE__.':'.__LINE__;
//Debug::printr($requete);
return $this->bdd->recupererTous($requete);
}
 
// cf Observation::reformateObservationSimpleIndex() et ListeObservations::reformateObservation()
// (trop de variétés de formatage, à unifier côté client pour unifier côté backend ...)
private function formaterImages() {
$urlImgTpl = $this->conteneur->getParametre('cel_img_url_tpl');
$imageFormat = isset($this->paramsFiltres['format']) ? $this->paramsFiltres['format'] : 'XL';
$obsFormatees = array_flip($this->idsImagesOrdonnees);// Permet de garder l'ordre de sortie !
foreach ($this->infosImages as $infos) {
$id = $infos['id_image'];
// ainsi nous utilisons deux tableaux: le final, indexé par couple d'id(image-obs)
// et celui indexé par simple id_image qui est fort utile pour mapVotesToImages()
// mais tout deux partage leur référence à "protocole"
$image = array(
'id_image' => $id,
'binaire.href' => sprintf($urlImgTpl, $infos['id_image'], $imageFormat),
'mots_cles_texte' => isset($infos['mots_cles_texte_img']) ? $infos['mots_cles_texte_img'] : null,
);
unset($infos['id_image'], $infos['mots_cles_texte'], $infos['mots_cles_texte_img']);
 
$obsFormatees[$id] = $image;
$obsFormatees[$id]['observation'] = $infos;
$obsFormatees[$id]['protocoles_votes'] = array();
}
return $obsFormatees;
}
 
/**
* Supprime une image directement dans le CEL en faisant un appel à un web service du CEL.
* Utilisé uniquement par les admins.
*
* @param array $ressources tableau des informations contenues dans l'url après le nom du service
* @param array $parametres contenu du post
* @return mixed Chaine "OK" (en majuscule) en cas de succès, booléen "false" en cas d'échec
*/
public function supprimer($ressources) {
$gestionUtilisateurs = $this->conteneur->getUtilisateur();
$gestionUtilisateurs->etreUtilisateurAvecDroitAdmin();
 
$urlServiceBase = $this->conteneur->getParametre('urlServiceCelImage');
$idImage = $ressources[0];
$url = $urlServiceBase.$idImage;
 
$clientHttp = $this->conteneur->getRestClient();
$retourCel = $clientHttp->supprimer($url);
$retour = preg_match('/^OK$/i', $retourCel) ? 'OK' : false;
return $retour;
}
}
Property changes:
Added: svnkit:entry:sha1-checksum
+d84f6381a2c4b4dcdd4e3de6e7b10fb8ad8e334d
\ No newline at end of property
/tags/v1.10-sodium/services/modules/0.1/images/VotesImage.php
New file
0,0 → 1,307
<?php
// declare(encoding='UTF-8');
/**
* Le web service image récupère toutes les données de la table del_obs_images
* pour retourner une liste d'images associée à une observation
*
* @category DEL
* @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 VotesImage {
 
private $conteneur;
private $navigation;
private $bdd;
private $mapping = array();
private $ressources;
private $parametres;
 
public function __construct(Conteneur $conteneur) {
$this->conteneur = $conteneur;
$this->navigation = $conteneur->getNavigation();
$this->bdd = $this->conteneur->getBdd();
 
$this->mapping = $this->conteneur->getParametreTableau('votes.mapping');
}
 
/**
* Méthode principale de la classe.
* Lance la récupération des images dans la base et les place dans un objet ResultatService
* pour l'afficher.
* @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
* @param array $parametres les paramètres situés après le ? dans l'url
* */
public function consulter($ressources, $parametres) {
$this->ressources = $ressources;
$this->parametres = $parametres;
 
// Lancement du service
$votes = $this->chargerVotes();
$total = $this->compterVotes();
$this->navigation->setTotal($total);
 
// Mettre en forme le résultat et l'envoyer pour affichage
$resultat = new ResultatService();
$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => $votes);
return $resultat;
}
 
private function chargerVotes() {
$idImgP = $this->bdd->proteger($this->ressources[0]);
$idProtocoleP = isset($this->parametres['protocole']) ? $this->bdd->proteger($this->parametres['protocole']) : null;
$requete = 'SELECT * FROM del_image_vote '.
"WHERE ce_image = $idImgP ".
($idProtocoleP != null ? "AND ce_protocole = $idProtocoleP " : '').
' -- '.__FILE__.' : '.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
return $this->formaterVotes($resultats);
}
 
private function compterVotes() {
$requete = 'SELECT FOUND_ROWS() AS nbre -- '.__FILE__.' : '.__LINE__;
$resultats = $this->bdd->recuperer($requete);
return (int) $resultats['nbre'];
}
 
private function formaterVotes($votes) {
$retour = array();
foreach ($votes as $vote) {
foreach ($vote as $champ => $valeur) {
$attribut = $this->mapping[$champ];
$retour[$vote['id_vote']][$attribut] = $valeur;
}
}
return $retour;
}
 
public function ajouter($ressources, $parametres) {
$this->ressources = $ressources;
$this->parametres = $parametres;
 
$this->verifierParametresAjoutModif();
$idVote = $this->ajouterVote();
if ($idVote) {
self::updateStats($this->bdd, $this->ressources[0], $this->parametres['protocole']);
 
$resultat = new ResultatService();
$resultat->corps = array('id_vote' => $idVote);
return $resultat;
}
return false;
}
 
private function ajouterVote() {
$idImgP = $this->bdd->proteger($this->ressources[0]);
$idProtocoleP = $this->bdd->proteger($this->parametres['protocole']);
$idUtilisateurP = $this->bdd->proteger($this->parametres['utilisateur']);
$valeurP = $this->bdd->proteger($this->parametres['valeur']);
$this->verifierAutorisationProtocoleIdentifie($this->parametres['protocole'], $this->parametres['utilisateur']);
$requete = 'INSERT INTO del_image_vote (ce_image, ce_protocole, ce_utilisateur, valeur, date) '.
"VALUES ( $idImgP, $idProtocoleP, $idUtilisateurP, $valeurP, NOW()) ".
' -- '.__FILE__.' : '.__LINE__;
 
$resultat = $this->bdd->executer($requete);
if ($resultat === false) {
$msg = "Un problème est survenu lors de l'ajout d'un vote.";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
} else if ($resultat === 0) {
$msg = "Aucun vote ne correspond au critères fournis : ".
"idImg -> $idImgP, id_protocole -> $idProtocoleP et id_utilisateur -> $idUtilisateurP.";
throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
// ATTENTION : idVote doit être récupéré avant toute nouvelle requete !
$idVote = $this->bdd->recupererIdDernierAjout();
return $idVote;
}
 
public function verifierParametresAjoutModif() {
$erreurs = array();
if (!is_numeric($this->ressources[0])) {
$erreurs[] = "Le paramètre indiquant l'identifiant de l'image doit être numérique.";
}
 
if (!isset($this->parametres['utilisateur'])) {
$erreurs[] = "Paramètre 'utilisateur' manquant.";
}
 
if (!isset($this->parametres['protocole'])) {
$erreurs[] = "Paramètre 'id_protocole' manquant.";
} else {
if (!is_numeric($this->parametres['protocole'])) {
$erreurs[] = "Le paramètre 'protocole' doit être numérique.";
}
}
 
if (!isset($this->parametres['valeur'])) {
$erreurs[] = "Paramètre 'valeur' manquant.";
} else {
if (!is_numeric($this->parametres['valeur'])) {
$erreurs[] = "Le paramètre 'valeur' doit être numérique.";
}
}
 
if (!empty($erreurs)) {
$msg = "Erreur lors de la configuration : \n".implode("\n", $erreurs);
throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
}
 
public function modifier($ressources, $parametres) {
$this->ressources = $ressources;
$this->parametres = $parametres;
$this->verifierParametresAjoutModif();
$resultat = $this->modifierVote();
if ($resultat > 0) {
self::updateStats($this->bdd, $this->ressources[0],$this->parametres['protocole']);
return 'ok';
}
}
 
public function modifierVote() {
$valeurP = $this->bdd->proteger($this->parametres['valeur']);
$idImgP = $this->bdd->proteger($this->ressources[0]);
$idProtocoleP = $this->bdd->proteger($this->parametres['protocole']);
$idUtilisateurP = $this->bdd->proteger($this->parametres['utilisateur']);
 
$this->verifierAutorisationProtocoleIdentifie($this->parametres['protocole'], $this->parametres['utilisateur']);
$requete = 'UPDATE del_image_vote '.
"SET valeur = $valeurP, date = NOW() ".
"WHERE ce_image = $idImgP AND ce_protocole = $idProtocoleP AND ce_utilisateur = $idUtilisateurP ".
' -- '.__FILE__.' : '.__LINE__;
 
$resultat = $this->bdd->executer($requete);
if ($resultat === false) {
$msg = "Un erreur est survenu lors de la tentative de modification du vote.";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
} else if ($resultat === 0) {
$msg = "Aucun vote ne correspond au critères fournis : ".
"idImg -> $idImgP, id_protocole -> $idProtocoleP et id_utilisateur -> $idUtilisateurP.";
throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
return $resultat;
}
 
public function supprimer($ressources) {
$this->ressources = $ressources;
$this->verifierParametresSuppression();
$idVoteP = $this->bdd->proteger($this->ressources[2]);
 
$voteInfos = $this->recupererInfosVote($idVoteP);
$this->verifierAutorisationSuppression($voteInfos);
 
$resultat = $this->supprimerVote($idVoteP);
if ($resultat > 0) {
$idImg = $this->ressources[0];
self::updateStats($this->bdd, $idImg, $voteInfos['id_protocole']);
return 'ok';
}
}
 
public function verifierParametresSuppression() {
$erreurs = array();
if (!isset($this->ressources[0])) {
$erreurs[] = "Le paramètre indiquant l'identifiant de l'image est obligatoire.";
} else {
if (!is_numeric($this->ressources[0])) {
$erreurs[] = "Le paramètre indiquant l'identifiant de l'image doit être numérique.";
}
}
if (!isset($this->ressources[2])) {
$erreurs[] = "Le paramètre indiquant l'identifiant du vote est obligatoire.";
} else {
if (!is_numeric($this->ressources[2])) {
$erreurs[] = "Le paramètre indiquant l'identifiant du vote doit être numérique.";
}
}
 
if (!empty($erreurs)) {
$msg = 'Erreur lors de la configuration : '."\n".implode("\n", $erreurs);
throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
}
 
private function recupererInfosVote($idVoteP) {
$requete = 'SELECT id_vote, ce_protocole AS id_protocole, ce_utilisateur AS id_utilisateur '.
'FROM del_image_vote '.
"WHERE id_vote = $idVoteP ".
' -- '.__FILE__.' : '.__LINE__;
 
$infos = $this->bdd->recuperer($requete);
if ($infos === false) {
$msg = "Aucun vote ne correspond à l'identifiant $idVoteP.";
throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
return $infos;
}
private function verifierAutorisationProtocoleIdentifie($idProtocole, $idUtilisateur) {
$idProtocoleP = $this->bdd->proteger($idProtocole);
$gestion_utilisateur = $this->conteneur->getUtilisateur();
$utilisateur = $gestion_utilisateur->getUtilisateur();
$utilisateurAComparer = $gestion_utilisateur->getIdAnonymeTemporaire();
// Si l'utilisateur n'est pas identifié on vérifie que le protocole n'impose
// pas d'être connecté pour voter, et le cas échéant, on refuse le vote
if(!$utilisateur['connecte']) {
$requete_proto_identifie = 'SELECT identifie FROM del_image_protocole '.
'WHERE id_protocole = '.$idProtocoleP;
$proto_identifie = $this->bdd->recuperer($requete_proto_identifie);
if($proto_identifie['identifie'] == 1) {
$msg = "Ce protocole nécéssite d'être identifié pour voter.";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
} else {
$utilisateurAComparer = $utilisateur['id_utilisateur'];
}
// Sinon on vérifie tout de même que la personne identifiée est bien celle
// associée aux votes dans les paramètres
if($utilisateurAComparer != $idUtilisateur) {
$msg = "L'utilisateur identifié et l'utilisateur du vote ne correspondent pas.";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
}
 
private function verifierAutorisationSuppression($voteInfos) {
$gestion_utilisateur = $this->conteneur->getUtilisateur();
$utilisateur = $gestion_utilisateur->getUtilisateur();
// @SECURE vérifier que l'utilisateur qui modifie son vote est bien celui qui est connecté
if (isset($utilisateur['id_utilisateur']) &&
$utilisateur['id_utilisateur'] != $voteInfos['id_utilisateur'] &&
$gestion_utilisateur->getIdAnonymeTemporaire() != $voteInfos['id_utilisateur']) {
$message = "Vous n'êtes pas autorisé à supprimer le vote : {$voteInfos['id_vote']}";
throw new Exception($message, RestServeur::HTTP_CODE_ACCES_NON_AUTORISE);
}
}
 
private function supprimerVote($idVoteP) {
$requete = "DELETE FROM del_image_vote WHERE id_vote = $idVoteP ".' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->executer($requete);
if ($resultat === false) {
$msg = "Impossible de supprimer le vote $idVoteP.";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
return $resultat;
}
 
// intermédiaire pour la méthode contenue dans "Commun"
static function updateStats($db, $id_image, $id_protocole) {
return TelaBotanica\Del\Commun\Stats::updateStats($db, $id_image, $id_protocole);
}
}
/tags/v1.10-sodium/services/modules/0.1/nomstaxons/ListeTaxons.php
New file
0,0 → 1,71
<?php
// declare(encoding='UTF-8');
/**
* Web service récupèrant une liste de noms de taxons suivant un référentiel et un masque donné.
*
* @category DEL
* @package Services
* @subpackage NomsTaxons
* @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 ListeTaxons {
 
private $conteneur;
private $navigation;
private $bdd;
 
private $resultatsBruts = array();
private $resultats = array();
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->navigation = $this->conteneur->getNavigation();
$this->bdd = $this->conteneur->getBdd();
}
 
public function consulter() {
$this->chargerNoms();
$this->formaterResultats();
$this->mettreAJourEnteteResultats();
 
$resultat = new ResultatService();
$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => $this->resultats);
return $resultat;
}
 
private function chargerNoms() {
$referentiel = $this->navigation->getFiltre('masque.referentiel');
if ($referentiel != 'tous') {
$requete = urlencode($this->navigation->getFiltre('masque.nom'));
$url = sprintf($this->conteneur->getParametre('nomstaxons.url_autocompletion_tpl'), $referentiel, $requete);
$restClient = $this->conteneur->getRestClient();
$resultatJson = $restClient->consulter($url);
$this->resultatsBruts =(array) json_decode($resultatJson, true);
}
}
 
private function formaterResultats() {
if (isset($this->resultatsBruts['resultat'])) {
foreach ($this->resultatsBruts['resultat'] as $info) {
$this->resultats[] = array(
"nn" => $info['num_nom'],
"ns" => $info['nom_sci_complet'],
"retenu" => ($info['retenu'] === "true" ? true : false)
);
}
}
}
 
private function mettreAJourEnteteResultats() {
$total = count($this->resultats);
$this->navigation->setTotal($total);
$this->navigation->setSansLimite();
}
}
/tags/v1.10-sodium/services/modules/0.1/Syndication.php
New file
0,0 → 1,178
<?php
// declare(encoding='UTF-8');
/**
* Classe principale de chargement des sous-services de syndication.
*
* @category DEL
* @package Services
* @subpackage Syndication
* @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 Syndication extends RestService {
 
private $parametres = array();
private $ressources = array();
private $conteneur;
private $methode = null;
private $sousServiceNom = null;
private $cheminCourant = null;
 
private $serviceNom = 'syndication';
private $format = 'atom';
private $squelette_dossier = null;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->conteneur = new Conteneur();
$this->cheminCourant = dirname(__FILE__).DS;
$this->squelette_dossier = dirname(__FILE__).DS.$this->serviceNom.DS.'squelettes'.DS;
$this->formats_autorises = $this->conteneur->getParametreTableau('syndication.formats');
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->initialiserRessourcesEtParametres($ressources, $parametres);
$this->verifierRessourcesEtParametres();
$this->format = isset($this->parametres['format']) ? $this->parametres['format'] : $this->format;
return $this->executerService();
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres = array()) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function verifierRessourcesEtParametres() {
if (isset($this->parametres['format']) && !in_array($this->parametres['format'], $this->formats_autorises)) {
$msg = "Vous devez indiquer un format de flux valide.\n".$this->getDoc();
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
}
 
private function executerService() {
$reponseHttp = new ReponseHttp();
try {
$donnees = $this->traiterRessources();
$resultat = $this->creerResultatService($donnees);
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
$reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
}
 
private function traiterRessources() {
$this->analyserRessources();
$retour = $this->initialiserService();
return $retour;
}
 
private function analyserRessources() {
if ($this->methode == 'consulter' && isset($this->ressources[0])) {
if (preg_match('/^tags|votes-?-Par-?Tag|tags-?Par-?Protocole$/i', $this->ressources[0])) {
$this->sousServiceNom = 'tags';
} else if (preg_match('/^votes|votes-?Par-?Protocole$/i', $this->ressources[0])){
$this->sousServiceNom = 'votes';
} else if ($this->ressources[0] == 'commentaires') {
$this->sousServiceNom = 'commentaires';
}
}
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function lancerMessageErreurRessource() {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "La ressource demandée '$ressource' ".
"n'est pas disponible pour le service {$this->serviceNom} !\n".
$this->getDoc();
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
public function getDoc() {
$formatsAutorises = implode(', ', $this->formats_autorises);
return "Les URLs disponibles pour ce service sont :\n".
" * en GET :\n".
" - syndication/commentaires\n".
" - syndication/tags\n".
" - syndication/votes-par-protocole\n".
" Paramètres : \n".
" - format : $formatsAutorises";
}
 
private function initialiserService() {
$classe = $this->obtenirNomClasseService();
$chemins = array();
$chemins[] = $this->cheminCourant.$this->serviceNom.DS.$classe.'.php';
$chemins[] = $this->cheminCourant.'commun'.DS.$classe.'.php';
$retour = '';
$service = null;
 
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
if ($this->methode == 'consulter') {
$retour = $service->consulter();
} else {
$message = "Le sous-service '{$this->sousServiceNom}' du service '{$this->serviceNom}' ".
"ne possède pas de méthode '{$this->methode}' !";
$code = RestServeur::HTTP_NON_IMPLEMENTE;
throw new Exception($message, $code);
}
}
}
 
if (is_null($service)) {
$ressource = $this->serviceNom.'/'.implode('/', $this->ressources);
$message = "Le classe '$classe' correspondant à la ressource '$ressource' ".
"est introuvable par le service '{$this->serviceNom}' !\n".
$this->getDoc();
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $retour;
}
 
private function obtenirNomClasseService() {
return str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $this->sousServiceNom))));
}
 
private function creerResultatService($donnees) {
$resultat = new ResultatService();
$resultat->mime = $this->getTypeMime();
$resultat->corps = SquelettePhp::analyser($this->squelette_dossier.$this->format.'.tpl.xml', $donnees);
return $resultat;
}
 
private function getTypeMime() {
$mime = '';
switch ($this->format) {
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;
}
}
Property changes:
Added: svnkit:entry:sha1-checksum
+40211bf16084bd2d96250989c0bb58b4fa8dbe36
\ No newline at end of property
/tags/v1.10-sodium/services/modules/0.1/Determinations.php
New file
0,0 → 1,143
<?php
// declare(encoding='UTF-8');
/**
* Classe principale de chargement des sous-services concernant les "déterminations" dans DEL.
*
* URLs possibles :
* GET :
* http://localhost/del/services/0.1/determinations/images-determinations-probables =>
*
* POST :
* http://localhost/del/services/0.1/determinations/valider-determination/#idProposition => Permet d'accepter une proposition donnée
*
* @category DEL
* @package Services
* @subpackage Determinations
* @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 Determinations extends RestService {
 
private $parametres = array();
private $ressources = array();
private $methode = null;
private $serviceNom = 'determinations';
private $sousServiceNom = null;
private $cheminCourant = null;
 
private $conteneur;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->initialiserRessourcesEtParametres($ressources, $parametres);
return $this->executerService();
}
 
public function modifier($ressources, $requeteDonnees) {
$this->methode = 'modifier';
$this->initialiserRessourcesEtParametres($ressources, $requeteDonnees);
return $this->executerService();
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres = array()) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function executerService() {
$reponseHttp = new ReponseHttp();
try {
$this->conteneur = new Conteneur($this->parametres);
$resultat = $this->traiterRessources();
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
$reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
}
 
private function traiterRessources() {
$this->analyserRessources();
$retour = $this->initialiserService();
return $retour;
}
 
private function analyserRessources() {
if ($this->methode == 'consulter') {
if ($this->ressources[0] == 'images-determinations-probables') {
$this->sousServiceNom = 'liste-images-determinations-probables';
}
} else if ($this->methode == 'modifier') {
if ($this->ressources[0] == 'valider-determination') {
$this->sousServiceNom = 'valider-determination';
}
}
 
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function lancerMessageErreurRessource() {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "La ressource demandée '$ressource' ".
"n'est pas disponible pour le service ".$this->serviceNom." !\n".
"Les URLs disponibles sont : \n".
" - en GET : determinations/images-determinations-probables \n".
" - en POST : determinations/valider-determination";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
private function initialiserService() {
$classe = $this->obtenirNomClasseService($this->sousServiceNom);
$chemins = array();
$chemins[] = $this->cheminCourant.$this->serviceNom.DS.$classe.'.php';
$chemins[] = $this->cheminCourant.'commun'.DS.$classe.'.php';
$retour = '';
$service = null;
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
if ($this->methode == 'consulter') {
$retour = $service->consulter($this->parametres);
} elseif ($this->methode == 'ajouter') {
$retour = $service->ajouter($this->ressources, $this->parametres);
} elseif ($this->methode == 'modifier') {
$retour = $service->modifier($this->ressources, $this->parametres);
} elseif ($this->methode == 'supprimer') {
$retour = $service->supprimer($this->ressources);
}
}
}
 
if (is_null($service)) {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "Le classe '$classe' correspondant à la ressource '$ressource' ".
"n'existe pas dans le service '{$this->serviceNom}' !";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $retour;
}
 
private function obtenirNomClasseService($mot) {
$classeNom = str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
}
/tags/v1.10-sodium/services/modules/0.1/Plantnet.php
New file
0,0 → 1,83
<?php
// declare(encoding='UTF-8');
/**
* Classe principale de chargement des sous-services de Plantnet.
*
* @category DEL
* @package Services
* @subpackage Plantnet
* @version 0.1
* @author Mathias CHOUET <mathias@tela-botanica.org>
* @author Samuel DUFOUR-KOWALSKI <samuel.dufour@cirad.fr>
* @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 PlantNet extends RestService {
 
private $parametres = array();
private $ressources = array();
private $methode = null;
private $projetNom = 'plantnet';
private $serviceNom = 'changements';
private $cheminCourant = null;
 
private $conteneur;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$reponseHttp = new ReponseHttp();
try {
$this->ressources = $ressources;
$this->parametres = $parametres;
 
$this->conteneur = new Conteneur($this->parametres);
 
$resultat = $this->initialiserService();
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
$reponseHttp->emettreLesEntetes();
return $reponseHttp->getCorps();
}
 
/*------------------------------------------------------------------------------------------------------------------
CONFIGURATION DU SERVICE
------------------------------------------------------------------------------------------------------------------*/
private function initialiserService() {
$classe = $this->obtenirNomClasseService($this->serviceNom);
$chemins = array();
$chemins[] = $this->cheminCourant.$this->projetNom.DS.$classe.'.php';
$retour = '';
$service = null;
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
$retour = $service->consulter($this->ressources, $this->parametres);
}
}
 
if (is_null($service)) {
$message = "Le service demandé '{$this->serviceNom}' n'existe pas dans le projet {$this->projetNom} !";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $retour;
}
 
private function obtenirNomClasseService($mot) {
$classeNom = str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
}
/tags/v1.10-sodium/services/modules/0.1/Commentaires.php
New file
0,0 → 1,168
<?php
// declare(encoding='UTF-8');
/**
* Classe principale de chargement des sous-services concernant les commentaires.
*
* URLs possibles :
*
* GET :
* http://localhost/del/services/0.1/commentaires => liste tous les commentaires
* http://localhost/del/services/0.1/commentaires/#id => retourne le contenu d'un commentaire d'id #id
*
* PUT :
* http://localhost/del/services/0.1/commentaires => Ajoute un nouveau commentaire
*
* DELETE :
* http://localhost/del/services/0.1/commentaires/#id => supprime le commentaire d'id #id
*
* @category DEL
* @package Services
* @subpackage Commentaires
* @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 Commentaires extends RestService {
 
private $parametres = array();
private $ressources = array();
private $methode = null;
private $serviceNom = 'commentaires';
private $sousServiceNom = null;
private $cheminCourant = null;
private $erreur = null;
 
private $conteneur;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->initialiserRessourcesEtParametres($ressources, $parametres);
return $this->executerService();
}
 
public function ajouter($ressources, $requeteDonnees) {
$this->methode = 'ajouter';
$this->initialiserRessourcesEtParametres($ressources, $requeteDonnees);
return $this->executerService();
}
 
public function supprimer($ressources) {
$this->methode = 'supprimer';
$this->initialiserRessourcesEtParametres($ressources);
return $this->executerService();
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres = array()) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function executerService() {
$reponseHttp = new ReponseHttp();
try {
$this->conteneur = new Conteneur($this->parametres);
$resultat = $this->traiterRessources();
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
$reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
}
 
private function traiterRessources() {
$this->analyserRessources();
$retour = $this->initialiserService();
return $retour;
}
 
private function analyserRessources() {
if ($this->methode == 'consulter') {
if (!isset($this->ressources) || empty($this->ressources)) {
$this->sousServiceNom = 'liste-commentaires';
} else if (isset($this->ressources[0]) && count($this->ressources) == 1 && is_numeric($this->ressources[0])) {
$this->sousServiceNom = 'commentaire-details';
}
} else if ($this->methode == 'ajouter') {
$this->sousServiceNom = 'ajouter-commentaire';
} else if ($this->methode == 'supprimer') {
if (isset($this->ressources[0]) && count($this->ressources) == 1 && is_numeric($this->ressources[0])) {
$this->sousServiceNom = 'supprimer-commentaire';
} else {
$this->erreur = "L'identifiant du commentaire est obligatoire et doit être un entier.";
}
}
 
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function lancerMessageErreurRessource() {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
if ($this->erreur != null) {
$message = $this->erreur;
} else {
$message = "La ressource demandée '$ressource' ".
"n'est pas disponible pour le service ".$this->serviceNom." !\n".
"Les URLs disponibles sont : \n".
" - en GET : commentaires, commentaires/#id \n".
" - en PUT : commentaires".
" - en DELETE : commentaires/#id\n".
"#id représente un nombre entier identifiant un commentaire.";
}
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
private function initialiserService() {
$classe = $this->obtenirNomClasseService($this->sousServiceNom);
//echo $this->sousServiceNom.':'.$classe."\n";
//echo 'Ressources :'.print_r($this->ressources, true);
//echo 'Parametres :'.print_r($this->parametres, true);
$chemins = array();
$chemins[] = $this->cheminCourant.$this->serviceNom.DS.$classe.'.php';
$chemins[] = $this->cheminCourant.'commun'.DS.$classe.'.php';
$retour = '';
$service = null;
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
if ($this->methode == 'consulter') {
$retour = $service->consulter($this->ressources);
} elseif ($this->methode == 'ajouter') {
$retour = $service->ajouter($this->parametres);
} elseif ($this->methode == 'supprimer') {
$retour = $service->supprimer($this->ressources);
}
}
}
 
if (is_null($service)) {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "Le classe '$classe' correspondant à la ressource '$ressource' ".
"n'existe pas dans le service '{$this->serviceNom}' !";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $retour;
}
 
private function obtenirNomClasseService($mot) {
$classeNom = str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
}
/tags/v1.10-sodium/services/modules/0.1/Communes.php
New file
0,0 → 1,133
<?php
// declare(encoding='UTF-8');
/**
* Classe principale de chargement des sous-services d'accès aux infos sur les communes.
*
* @category DEL
* @package Services
* @subpackage Communes
* @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 Communes extends RestService {
 
private $parametres = array();
private $ressources = array();
private $methode = null;
private $serviceNom = 'communes';
private $sousServiceNom = null;
private $cheminCourant = null;
 
private $conteneur;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->initialiserRessourcesEtParametres($ressources, $parametres);
return $this->executerService();
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres = array()) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function executerService() {
$reponseHttp = new ReponseHttp();
try {
$this->conteneur = new Conteneur($this->parametres);
$resultat = $this->traiterRessources();
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
$reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
}
 
private function traiterRessources() {
$this->analyserRessources();
$retour = $this->initialiserService();
return $retour;
}
 
private function analyserRessources() {
if ($this->methode == 'consulter') {
if (count($this->ressources) == 0 && $this->verifierPresenceParametre('masque.nom')) {
$this->sousServiceNom = 'liste-communes';
}
}
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function verifierPresenceParametre($cle) {
if (isset($this->parametres[$cle]) && trim($this->parametres[$cle]) == '') {
$message = "Le service demandé '{$this->serviceNom}' ".
"nécessite l'utilisation d'un paramètre (non vide) : masque.nom \n";
throw new Exception($message, RestServeur::HTTP_CODE_ECHEC_CONDITION);
}
return true;
}
 
private function lancerMessageErreurRessource() {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "La ressource demandée '$ressource' ".
"n'est pas disponible pour le service ".$this->serviceNom." !\n".
"Les URLs disponibles sont : \n".
" - en GET : communes (paramètres : masque.nom) \n";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
private function initialiserService() {
$classe = $this->obtenirNomClasseService($this->sousServiceNom);
$chemins = array();
$chemins[] = $this->cheminCourant.$this->serviceNom.DS.$classe.'.php';
$chemins[] = $this->cheminCourant.'commun'.DS.$classe.'.php';
$retour = '';
$service = null;
 
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
if ($this->methode == 'consulter') {
$retour = $service->consulter();
} else {
$message = "Le sous-service '{$this->sousServiceNom}' du service '{$this->serviceNom}' ".
"ne possède pas de méthode '{$this->methode}' !";
$code = RestServeur::HTTP_NON_IMPLEMENTE;
throw new Exception($message, $code);
}
}
}
 
if (is_null($service)) {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "Le classe '$classe' correspondant à la ressource '$ressource' ".
"est introuvable par le service '{$this->serviceNom}' !";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $retour;
}
 
private function obtenirNomClasseService($mot) {
$classeNom = str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
}
/tags/v1.10-sodium/services/modules/0.1/observations/VoteObservation.php
New file
0,0 → 1,248
<?php
// declare(encoding='UTF-8');
/**
* Web service permetant d'ajouter ou de modifier les votes associés aux propositions d'une observation.
*
* @category DEL
* @package Services
* @subpackage Observations
* @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 VoteObservation {
private $conteneur;
private $bdd;
private $navigation;
private $mapping;
private $ressources;
private $parametres;
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->navigation = $conteneur->getNavigation();
 
$this->mapping = $this->conteneur->getParametreTableau('votes.mapping');
}
 
public function consulter($ressources, $parametres) {
$this->ressources = $ressources;
$this->parametres = $parametres;
 
$votes = $this->chargerVotes();
$this->conteneur->getNavigation()->setTotal(count($votes));
// Mettre en forme le résultat et l'envoyer pour affichage
$resultat = new ResultatService();
$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => $votes);
return $resultat;
}
 
private function chargerVotes() {
$idCommentaireP = $this->bdd->proteger($this->ressources[1]);
$requete = 'SELECT * '.
'FROM del_commentaire_vote '.
"WHERE ce_proposition = $idCommentaireP ";
' -- '.__FILE__.':'.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
$votes = array();
foreach ($resultats as $vote) {
$votes[$vote['id_vote']] = $this->formaterVotes($vote);
$utilisateur = $this->chercherUtilisateur($vote['ce_utilisateur']);
if (count($utilisateur) > 0) {
$votes[$vote['id_vote']] = array_merge($votes[$vote['id_vote']], $utilisateur);
}
}
return $votes;
}
 
private function formaterVotes($vote) {
$retour = array();
foreach ($vote as $param => $valeur) {
$retour[$this->mapping[$param]] = $valeur;
}
return $retour;
}
 
private function chercherUtilisateur($id) {
// par défaut, pas d'info
$utilisateur = array();
// Si l'id utilisateur est un hash de session, on ne cherche rien
if (is_numeric($id)) {
$idUtilisateurP = $this->bdd->proteger($id);
$requete = "SELECT id_utilisateur AS 'auteur.id', nom AS 'auteur.nom', prenom AS 'auteur.prenom', ".
"courriel AS 'auteur.courriel' ".
'FROM del_utilisateur '.
"WHERE id_utilisateur = $idUtilisateurP ".
' -- '.__FILE__.':'.__LINE__;
$utilisateur = $this->bdd->recuperer($requete);
}
return $utilisateur;
}
 
public function ajouter($ressources, $parametres) {
$this->ressources = $ressources;
$this->parametres = $parametres;
$this->verifierParametresAjoutModif();
$idVote = $this->ajouterVote();
if ($idVote) {
$resultat = new ResultatService();
$resultat->corps = array('id_vote' => $idVote);
return $resultat;
}
return false;
}
 
private function ajouterVote() {
$idProposition = $this->creerPropositionDeterminationInitiale();
 
$idObsP = $this->bdd->proteger($this->ressources[0]);
$idPropositionP = $this->bdd->proteger($idProposition);
$idUtilisateurP = $this->bdd->proteger($this->parametres['utilisateur']);
$valeurP = $this->bdd->proteger($this->parametres['valeur']);
$requete = 'INSERT INTO del_commentaire_vote (ce_proposition , ce_utilisateur , valeur , date) '.
"VALUES ($idPropositionP, $idUtilisateurP, $valeurP, NOW()) ".
' -- '.__FILE__.' : '.__LINE__;
 
$resultat = $this->bdd->executer($requete);
if ($resultat === false) {
$msg = "Un problème est survenu lors de l'ajout d'un vote.";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
} else if ($resultat === 0) {
$msg = "Aucun vote ne correspond au critères fournis : ".
"idObs -> $idObsP, idProposition -> $idPropositionP et id_utilisateur -> $idUtilisateurP.";
throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
// ATTENTION : idVote doit être récupéré avant toute nouvelle requete !
$idVote = $this->bdd->recupererIdDernierAjout();
return $idVote;
}
 
/** Si l'identifiant de proposition vaut 0, c'est un vote sur une proposition
* fabriquée à partir de l'observation originale, dont on doit obtenir l'id
* (cas où l'on vient de voter pour celle et cela a créé la proposition, puis
* on revote pour celle ci en changeant d'avis sans recharger la page)
*/
private function creerPropositionDeterminationInitiale() {
$idProposition = $this->ressources[1];
if ($idProposition == 0) {
$propositionExiste = $this->verifierExistencePropositionInitiale();
if ($propositionExiste === false) {
$idProposition = $this->creerPropositionInitiale();
} else {
$idProposition = $this->getIdPropositionInitiale();
}
}
return $idProposition;
}
 
private function verifierExistencePropositionInitiale() {
$idObservationP = $this->bdd->proteger($this->ressources[0]);
$requete = 'SELECT COUNT(*) >= 1 AS existe '.
'FROM del_commentaire '.
"WHERE ce_observation = $idObservationP ".
'AND proposition_initiale = 1 '.
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recuperer($requete);
return $resultat['existe'] == 1;
}
 
private function creerPropositionInitiale() {
$idObservationP = $this->bdd->proteger($this->ressources[0]);
$requete = 'INSERT IGNORE INTO del_commentaire '.
'(ce_observation, ce_utilisateur, utilisateur_prenom, utilisateur_nom, utilisateur_courriel, '.
'nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, nt, famille, nom_referentiel, date, proposition_initiale) '.
'SELECT id_observation, ce_utilisateur, prenom, nom, '.
' courriel, nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, '.
" nt, famille, nom_referentiel, NOW(), '1' ".
'FROM del_observation do '.
' LEFT JOIN del_utilisateur du ON (do.ce_utilisateur = du.id_utilisateur) '.
"WHERE id_observation = $idObservationP ".
' -- '.__FILE__.' : '.__LINE__;
 
$this->bdd->executer($requete);
$id = $this->bdd->recupererIdDernierAjout();
return $id;
}
 
private function getIdPropositionInitiale() {
$idObservationP = $this->bdd->proteger($this->ressources[0]);
$requete = 'SELECT id_commentaire '.
'FROM del_commentaire '.
"WHERE ce_observation = $idObservationP ".
'AND proposition_initiale = 1 '.
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recuperer($requete);
return $resultat['id_commentaire'];
}
 
public function modifier($ressources, $parametres) {
$this->ressources = $ressources;
$this->parametres = $parametres;
$this->verifierParametresAjoutModif();
$resultat = $this->modifierVote();
if ($resultat > 0) {
return 'ok';
}
}
 
private function modifierVote() {
$idProposition = $this->creerPropositionDeterminationInitiale();
if ($idProposition == null) {
$msg = "Aucun identifiant de proposition n'est lié à cette observation.";
throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
// protection anti-usurpateurs
/*$idUtilisateur = $this->parametres['utilisateur'];
$gestionUtilisateurs = $this->conteneur->getUtilisateur();
$gestionUtilisateurs->controleUtilisateurIdentifie($idUtilisateur);*/
 
$idObsP = $this->bdd->proteger($this->ressources[0]);
$idPropositionP = $this->bdd->proteger($idProposition);
$idUtilisateurP = $this->bdd->proteger($idUtilisateur);
$valeurP = $this->bdd->proteger($this->parametres['valeur']);
$requete = 'UPDATE del_commentaire_vote '.
"SET valeur = $valeurP, date = NOW() ".
"WHERE ce_proposition = $idPropositionP AND ce_utilisateur = $idUtilisateurP ".
' -- '.__FILE__.' : '.__LINE__;
 
$resultat = $this->bdd->executer($requete);
if ($resultat === false) {
$msg = "Une erreur est survenue lors de la tentative de modification du vote.";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
} else if ($resultat === 0) {
$msg = "Aucun vote ne correspond au critères fournis : ".
"idObs -> $idObsP, idProposition -> $idPropositionP et id_utilisateur -> $idUtilisateurP.";
throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
return $resultat;
}
 
private function verifierParametresAjoutModif() {
$erreurs = array();
 
if (!isset($this->parametres['utilisateur'])) {
$erreurs[] = 'Paramètre "utilisateur" manquant.';
}
 
if (!isset($this->parametres['valeur'])) {
$erreurs[] = 'Paramètre "valeur" manquant.';
} else {
if (!is_numeric($this->parametres['valeur'])) {
$erreurs[] = 'Le paramètre "valeur" doit être numérique.';
} elseif($this->parametres['valeur'] != 0 && $this->parametres['valeur'] != 1) {
$erreurs[] = 'Le paramètre "valeur" ne peut prendre que la valeur 0 ou 1.';
}
}
 
if (!empty($erreurs)) {
$msg = "Erreur lors de la configuration : \n".implode("\n", $erreurs);
throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
}
}
/tags/v1.10-sodium/services/modules/0.1/observations/ListeObservations.php
New file
0,0 → 1,385
<?php
// declare(encoding='UTF-8');
/**
* Web service récupèrant toutes les observations et, pour chacune d'elle, les images qui lui sont associées.
*
* ATTENTION : le web service commence par récupérer seulement les id des obs (1er requete SQL), puis dans une
* deuxième requête SQL récupère les informations complémentaires. Il s'avère qu'en procédant ainsi le web service
* est 3 fois plus rapide !
*
* @category DEL
* @package Services
* @subpackage Observations
* @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 ListeObservations {
 
private $conteneur;
private $bdd;
private $navigation;
private $filtrage;
private $sql;
 
private $mappings = array();
private $paramsFiltres = array();
 
private $idsObsOrdonnees = array();
private $infosObs = array();
private $infosObsOrdonnee = array();
private $evenementsObs = array();
 
 
public function __construct(Conteneur $conteneur) {
$this->conteneur = $conteneur;
$this->conteneur->chargerConfiguration('config_departements_bruts.ini');
 
$this->bdd = $this->conteneur->getBdd();
$this->filtrage = $this->conteneur->getParametresFiltrage();
$this->sql = $this->conteneur->getSql();
$this->navigation = $this->conteneur->getNavigation();
 
$this->mappings['votes'] = $this->conteneur->getParametreTableau('votes.mapping');
$this->mappings['commentaires'] = $this->conteneur->getParametreTableau('commentaires.mapping');
}
 
public function consulter($ressources, $parametres) {
$this->paramsFiltres = $this->filtrage->filtrerUrlParamsAppliObs();
$this->sql->setAppli(Sql::APPLI_OBS);
$this->sql->setParametres($this->paramsFiltres);
$this->sql->ajouterContraintes();
$this->sql->ajouterConstrainteAppliObs();
$this->sql->definirOrdreSqlAppliObs();
 
$this->idsObsOrdonnees = $this->getIdObs();
$this->navigation->setTotal($this->sql->getTotalLignesTrouvees());
 
// Ce n'est pas la peine de continuer s'il n'y a pas eu de résultats
$resultat = new ResultatService();
$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => array());
if (count($this->idsObsOrdonnees) > 0) {
 
// 2) récupération des données nécessaires pour ces observations (obs + images)
$this->infosObs = $this->getInfosObs();
// 3) suppression, merge des données en tableau assez représentatif du futur JSON en output
$this->infosObsOrdonnees = $this->formaterObservations();
// 4) Ajouter commentaires + votes à $this->infosObsOrdonnees
$this->chargerDeterminations();
 
$resultat->corps = array(
'entete' => $this->navigation->getEntete(),
// 5) Applatissage du tableau afin de garder l'ordre de tri
// (qui n'est pas garanti dans un objet json)
'resultats' => array_values($this->infosObsOrdonnees));
}
return $resultat;
}
 
// SQL helpers
/*
* Retourne une liste ordonnée d'id d'observation correspondant aux critères
* passés dans p et aux clauses where/join présentes dans le tableau $req
*
* @param p: $params (filtrés sauf escape-string)
* @param req: le tableau représentant les composants de la requete SQL
* @param db: l'instance de db
*/
private function getIdObs() {
$requete = $this->renvoyerRequeteSelonType();
//Debug::printr($requete);
$resultats = $this->bdd->recupererTous($requete);
 
$idObs = array();
if ($resultats !== false ) {
foreach ($resultats as $resultat) {
$idObs[] = $resultat['id_observation'];
}
}
return $idObs;
}
private function renvoyerRequeteSelonType() {
if($this->monActiviteEstDemandee()) {
$gestion_utilisateur = new GestionUtilisateur($this->conteneur);
$utilisateur = $gestion_utilisateur->getUtilisateur();
if ($utilisateur['connecte'] === true) {
$id_utilisateur = $utilisateur['id_utilisateur'];
$requete = $this->sql->getRequeteIdObsMonactiviteTout($id_utilisateur, $this->sql->getLimit()).' -- '.__FILE__.':'.__LINE__;
// Enregistrement de la date de consultation pour ne pas réafficher des événements déjà consultés
$gestion_utilisateur->setDerniereDateConsultationEvenements($id_utilisateur, date('Y-m-d H:i:s'));
} else {
//TODO: que faire si l'on n'est pas connecté ?
}
} else {
$requete = 'SELECT SQL_CALC_FOUND_ROWS id_observation '.
'FROM del_observation AS do '.
$this->sql->getJoin().
'WHERE '.$this->sql->getWhere().
$this->sql->getGroupBy().
$this->sql->getOrderBy().
$this->sql->getLimit().
' -- '.__FILE__.':'.__LINE__;
}
return $requete;
}
private function monActiviteEstDemandee() {
return isset($this->paramsFiltres['masque.type']) && in_array('monactivite',array_keys($this->paramsFiltres['masque.type']));
}
 
/**
* Après avoir récupérer seulement les ids dans une première requête, nous récupérons maintenant les infos.
* Le web service est ainsi 3 fois plus rapide.
*/
private function getInfosObs() {
$idsObsConcat = implode(',', $this->idsObsOrdonnees);
$requete = "SELECT id_observation, nom_sel AS `determination.ns`, nt AS `determination.nt`, ".
'nom_sel_nn AS `determination.nn`, famille AS `determination.famille`, '.
'nom_referentiel AS `determination.referentiel`, ce_zone_geo AS id_zone_geo, pays, '.
'zone_geo, lieudit, station, milieu, date_observation, do.mots_cles_texte, '.
'do.date_transmission, do.commentaire, '.
'do.ce_utilisateur AS `auteur.id`, do.prenom_utilisateur AS `auteur.prenom`, '.
'do.nom_utilisateur AS `auteur.nom`, do.courriel_utilisateur AS `auteur.courriel`, '.
'id_image, date_prise_de_vue AS `date`, hauteur, largeur, nom_original '.
'FROM del_observation AS do '.
' LEFT JOIN del_image AS di ON (do.id_observation = di.ce_observation) '.
"WHERE id_observation IN ($idsObsConcat) ".
' -- '.__FILE__.':'.__LINE__;
if ($this->monActiviteEstDemandee()) {
$this->stockerEvenementsObs($idsObsConcat);
}
//Debug::printr($requete);
return $this->bdd->recupererTous($requete);
}
private function stockerEvenementsObs($idsObsConcat) {
$gestion_utilisateur = new GestionUtilisateur($this->conteneur);
$utilisateur = $gestion_utilisateur->getUtilisateur();
$id_utilisateur = $utilisateur['id_utilisateur'];
$evenements = $this->sql->getEvenementsObs($idsObsConcat, $id_utilisateur);
$this->evenements_obs = array();
foreach($evenements as &$evenement) {
$this->affecterTypeEvenement($evenement, $id_utilisateur, $evenement['id_observation']);
}
}
 
private function affecterTypeEvenement(&$evenement, $id_utilisateur, $id_observation) {
 
$type = "";
$infos = "";
// La date maximale détermine le type d'évènement
switch($evenement['date_max']) {
// Quelqu'un a fait un nouveau commentaire ou proposition
case $evenement['date_com']:
if(!empty($evenement['nom_sel_com'])) {
$type = 'nouvelle_proposition';
$infos = $evenement['proposition_commentaire_nom_sel'];
} else {
$type = 'nouveau_commentaire';
$infos = $evenement['proposition_commentaire_texte'];
}
// J'ai commenté ou fait une proposition
if($evenement['utilisateur_commentaire'] == $id_utilisateur) {
$type .= "_vous_a_obs_autre";
} else {
$type .= "_autre_sur_obs_vous";
}
break;
 
// Quelqu'un a répondu à un de mes commentaires ou une de mes propositions
case $evenement['date_com_reponse']:
if(!empty($evenement['nom_sel_com_parent'])) {
$type = 'nouvelle_reponse_autre_sur_proposition_vous';
} else {
$type = 'nouvelle_reponse_autre_sur_commentaire_vous';
}
$infos = $evenement['proposition_commentaire_texte_commente'];
break;
// Quelqu'un a fait un nouveau vote
case $evenement['date_vote']:
$type = 'nouveau_vote';
// Sur une proposition qui n'est pas à moi sur une observation à moi
if($evenement['utilisateur_commentaire_vote'] != $evenement['utilisateur_observation'] && $evenement['utilisateur_commentaire_vote'] != $id_utilisateur) {
$type .= "_autre_sur_com_autre_obs_vous";
} else {
// Sur une proposition qui est à moi sur une observation (à moi ou non)
$type .= "_autre_sur_com_vous";
}
$infos = $evenement['proposition_commentaire_nom_sel_votee'];
break;
// Quelqu'un a validé une proposition
case $evenement['date_validation']:
$type = "nouvelle_validation_autre_sur_prop_vous";
$infos = $evenement['proposition_validee_nom_sel'];
// $type = "nouvelle_validation_vous_a_prop_autre";
break;
// Cas qui ne devrait jamais arriver
default:
$type = 'inconnu';
$infos = "";
}
$infos_evts = array('type' => $type, 'infos_complementaires' => $infos);
// La requête est un peu trop complexe et certains évènements sortent en doublons
// donc on dédoublonne ici (mais ça n'est pas une solution pérenne)
// TODO: optimiser et simplifier ceci
if(empty($this->evenementsObs[$id_observation])) {
$this->evenementsObs[$id_observation] = array();
}
if(array_search($infos_evts, $this->evenementsObs[$id_observation]) === false) {
$this->evenementsObs[$id_observation][] = $infos_evts;
}
}
 
/**
* Les informations étant extraites d'une vue dont les infos des obs sont dupliquées pour chaque image,
* il nous faut maintenant récupérer qu'une seule fois les données d'observations et y intégrer les données
* des images.
*/
private function formaterObservations() {
$observations = array_map('array_filter', $this->infosObs);
$obsFormatees = array_flip($this->idsObsOrdonnees);// Permet de garder l'ordre de sortie !
foreach ($observations as &$obs) {
$this->nettoyerAuteur($obs);
 
$id = $obs['id_observation'];
// ATTENTION : la requête retourne de nombreuses lignes avec les mêmes données (test de l'existence nécessaire)
if (is_array($obsFormatees[$id]) === false) {
$obsFormatees[$id] = $obs;
}
$obsFormatees[$id]['images'][] = $this->extraireInfosImage($obs);
if(isset($this->evenementsObs[$id])) {
$obsFormatees[$id]['evenements'] = $this->evenementsObs[$id];
}
}
return $obsFormatees;
}
 
private function nettoyerAuteur(&$obs) {
// car auteur.id peut être un email, un hash, ou un annuaire_tela.U_ID
// mais dans les deux premiers cas SELECT courriel AS observateur fait déjà l'affaire
if (!isset($obs['auteur.id']) || !is_numeric($obs['auteur.id'])) {
$obs['auteur.id'] = "0";
}
if (!isset($obs['auteur.nom'])) {
$obs['auteur.nom'] = '[inconnu]';
}
}
 
private function extraireInfosImage(&$obs) {
$champsImageAffichables = array('id_image', 'date', 'hauteur' , 'largeur', 'nom_original');
$image = array_intersect_key($obs, array_flip($champsImageAffichables));
$urlImgTpl = $this->conteneur->getParametre('cel_img_url_tpl');
$image['binaire.href'] = sprintf($urlImgTpl, $image['id_image'], 'XL');
 
unset($obs['id_image'], $obs['date'], $obs['hauteur'], $obs['largeur'], $obs['nom_original']);
return $image;
}
 
/**
* Récupérer toutes les déterminations et le nombre de commentaire au total
* @param array $observations la liste des observations à mettre à jour
*/
private function chargerDeterminations() {
$idObsConcat = implode(',', $this->idsObsOrdonnees);
$requete = 'SELECT * '.
'FROM del_commentaire AS dc '.
'WHERE dc.nom_sel IS NOT NULL '.
"AND ce_observation IN ($idObsConcat) ".
'-- '.__FILE__.':'.__LINE__;
$commentaires = $this->chargerNombreCommentaireObs();
 
$propositions = $this->bdd->recupererTous($requete);
if ($propositions) {
foreach ($propositions as $proposition) {
$idObs = $proposition['ce_observation'];
$idComment = $proposition['id_commentaire'];
$comment = $this->formaterDetermination($idComment, $proposition);
if ($comment) {
$this->infosObsOrdonnees[$idObs]['commentaires'][$idComment] = $comment;
}
$this->infosObsOrdonnees[$idObs]['nb_commentaires'] = isset($commentaires[$idObs]) ? $commentaires[$idObs] : 0;
}
}
}
 
private function formaterDetermination($propositionId, $propositionInfos) {
if (!$propositionInfos) return NULL;
 
$propositionFormatee = array();
foreach ($this->mappings['commentaires'] as $nomChamp => $nomAttributJson) {
if (isset($propositionInfos[$nomChamp])) {
$propositionFormatee[$nomAttributJson] = $propositionInfos[$nomChamp];
}
}
 
// Charger les votes sur les déterminations
$requete = "SELECT * FROM del_commentaire_vote WHERE ce_proposition = $propositionId".
'-- '.__FILE__.':'.__LINE__;
$resultatsVotes = $this->bdd->recupererTous($requete);
foreach ($resultatsVotes as $vote) {
$propositionFormatee['votes'][$vote['id_vote']] = $this->formaterVote($vote);
}
 
$propositionFormatee['nb_commentaires'] = $this->chargerNombreCommentaire($propositionId);
 
return $propositionFormatee;
}
 
/**
* Formater un vote en fonction du fichier de configuration config_votes.ini
* @param $votes array()
*/
private function formaterVote($vote) {
$voteFormate = array();
foreach ($vote as $nomChamp => $valeur) {
$voteFormate[$this->mappings['votes'][$nomChamp]] = $valeur;
}
return $voteFormate;
}
private function chargerNombreCommentaireObs() {
$idObsConcat = implode(',', $this->idsObsOrdonnees);
$requete = 'SELECT ce_observation, COUNT( id_commentaire ) AS nb '.
'FROM del_commentaire '.
"WHERE ce_observation IN ($idObsConcat) ".
'GROUP BY ce_observation '.
'-- '.__FILE__.':'.__LINE__;
$commentaires = $this->bdd->recupererTous($requete);
$commentaires_par_obs = array();
foreach($commentaires as $commentaire) {
$commentaires_par_obs[$commentaire['ce_observation']] = $commentaire['nb'];
}
return $commentaires_par_obs;
}
 
private function chargerNombreCommentaire($propositionId) {
$requete = 'SELECT COUNT( id_commentaire ) AS nb '.
'FROM del_commentaire '.
"WHERE ce_proposition = $propositionId ".
'GROUP BY ce_proposition '.
'-- '.__FILE__.':'.__LINE__;
$commentaires = $this->bdd->recuperer($requete);
return $commentaires ? $commentaires['nb'] : 0;
}
}
Property changes:
Added: svnkit:entry:sha1-checksum
+a907dccbc2c4971fed812325a132c6ba9d675b72
\ No newline at end of property
/tags/v1.10-sodium/services/modules/0.1/observations/ObservationDetails.php
New file
0,0 → 1,211
<?php
// declare(encoding='UTF-8');
/**
* Web service retournant toutes les infos d'une observation donnée :
* images, votes sur image et protocole, commentaires, votes sur commentaires, ...
*
* @category DEL
* @package Services
* @subpackage Observations
* @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 ObservationDetails {
 
private $conteneur;
private $bdd;
private $sql;
private $idObs;
private $protocole;
private $observation;
private $mappings = array();
 
public function __construct(Conteneur $conteneur) {
$this->conteneur = $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->sql = $this->conteneur->getSql();
 
$this->mappings['observations'] = $this->conteneur->getParametreTableau('observations.mapping');
$this->mappings['images'] = $this->conteneur->getParametreTableau('images.mapping');
$this->mappings['votes'] = $this->conteneur->getParametreTableau('votes.mapping');
$this->mappings['commentaires'] = $this->conteneur->getParametreTableau('commentaires.mapping');
// les deux alias suivants sont particuliers afin d'éviter un conflit d'alias lors des jointures avec del_commentaire_vote
$this->mappings['commentaires']['ce_utilisateur'] = '__auteur_com';
$this->mappings['commentaires']['date'] = '__date_com';
}
 
public function consulter($ressources, $parametres) {
$this->idObs = $ressources[0];
$this->protocole = isset($parametres['protocole']) && is_numeric($parametres['protocole']) ? intval($parametres['protocole']) : null;
 
$infos = $this->getInfosObservationEtImages();
if (! $infos) {
$message = "Aucune observation ne possède d'identifiant '{$this->idObs}'.";
throw new Exception($message, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
$this->formaterObservation($infos);
 
// 3) charge les données de votes et protocoles associés aux images
 
if ($this->observation['images']) {
$idsImages = array_keys($this->observation['images']);
$votes = $this->sql->getVotesDesImages($idsImages, $this->protocole);
$this->sql->ajouterInfosVotesProtocoles($votes, $this->observation['images']);
}
 
// 4) charge les commentaires et les votes associés -> modifie/créé $observation['commentaires']
$commentaires = $this->getCommentaires();
$this->ajouterCommentaires($commentaires);
 
// désindexe le tableau (tel qu'apparement attendu par les applis), c'est une exception
// TODO : corriger l'appli cliente pour utiliser les index puis supprimer cette ligne
$this->observation['images'] = array_values($this->observation['images']);
 
// autre élément de post-processing: le ce_utilisateur de l'observation non-numeric...
$this->nettoyerAuteur();
 
// Mettre en forme le résultat et l'envoyer pour affichage
$resultat = new ResultatService();
$resultat->corps = $this->observation;
return $resultat;
}
 
private function getInfosObservationEtImages() {
$obsChamps = $this->sql->getAliasDesChamps($this->mappings['observations'], null, 'do');
$imgChamps = $this->sql->getAliasDesChamps($this->mappings['images'], null, 'di');
 
// champs de l'annuaire (del_utilisateur): id_utilisateur prenom, nom, courriel
$annuaireChamps = implode(', ', array(
"IFNULL(du.prenom, do.prenom_utilisateur) AS `auteur.prenom`",
"IFNULL(du.nom, do.nom_utilisateur) AS `auteur.nom`",
"IFNULL(du.courriel, do.courriel_utilisateur) AS `auteur.courriel`"));
 
$requete = "SELECT $obsChamps, $imgChamps, $annuaireChamps ".
"FROM del_observation AS do ".
" LEFT JOIN del_image AS di ON (do.id_observation = di.ce_observation) ".
" LEFT JOIN del_utilisateur AS du ON (do.ce_utilisateur = du.id_utilisateur) ".
"WHERE do.id_observation = {$this->idObs} ".
'-- '.__FILE__.':'.__LINE__;
//Debug::printr($requete);
return $this->bdd->recupererTous($requete);
}
 
private function formaterObservation($infos) {
$infos = array_filter($infos);
foreach ($infos as $info) {
$image = array_intersect_key($info, array_flip(array('id_image', 'date', 'hauteur' , 'largeur', 'nom_original')));
$urlImgTpl = $this->conteneur->getParametre('cel_img_url_tpl');
$imageFormat = 'XL';
$image['binaire.href'] = sprintf($urlImgTpl, $image['id_image'], $imageFormat);
unset($info['id_image'], $info['date'], $info['hauteur'], $info['largeur'], $info['nom_original']);
 
// ATTENTION : la requête retourne de nombreuses lignes avec les mêmes données (test de l'existence nécessaire)
if (!isset($this->observation)) {
$this->observation = $info;
$this->observation['images'] = array();
}
if (!isset($this->observation['images'][$image['id_image']])) {
$this->observation['images'][$image['id_image']] = $image;
}
}
}
 
private function getCommentaires() {
$selectVotes = array('id_vote', 'ce_proposition', 'ce_utilisateur', 'valeur', 'date');
$selectCommentaires = array('id_commentaire', 'ce_observation', 'ce_proposition', 'ce_commentaire_parent', 'texte',
'ce_utilisateur', 'utilisateur_prenom', 'utilisateur_nom', 'utilisateur_courriel',
'nom_sel', 'nom_sel_nn', 'nom_ret', 'nom_ret_nn', 'nt', 'famille', 'nom_referentiel', 'date',
'proposition_initiale','proposition_retenue');
 
$voteChamps = $this->sql->getAliasDesChamps($this->mappings['votes'], $selectVotes, 'cv');
$commentaireChamps = $this->sql->getAliasDesChamps($this->mappings['commentaires'], $selectCommentaires, 'dc');
 
// LEFT JOIN optionnel, mais explicatif : récupèration des infos de vote que pour les commentaires comportant un nom_sel "valide"
$requete = "SELECT $commentaireChamps, $voteChamps ".
"FROM del_commentaire AS dc ".
" LEFT JOIN del_commentaire_vote AS cv ".
" ON (cv.ce_proposition = dc.id_commentaire AND dc.nom_sel != '' AND dc.nom_sel IS NOT NULL) ".
"WHERE ce_observation = {$this->idObs} ".
'-- '.__FILE__.':'.__LINE__;
 
$commentaires = $this->bdd->recupererTous($requete);
return $commentaires;
 
}
 
private function ajouterCommentaires($commentaires) {
if (!$commentaires) return;
 
$ret = array();
foreach ($commentaires as $comment) {
$commentId = $comment['id_commentaire'];
$voteId = $comment['vote.id'];
 
if (!array_key_exists($commentId, $ret)) {
$comment_extract = array_intersect_key($comment, array_flip($this->mappings['commentaires']));
 
// cas particulier: conflit d'aliases avec del_commentaire_vote
$comment_extract['auteur.id'] = $comment_extract['__auteur_com'];
$comment_extract['date'] = $comment_extract['__date_com'];
unset($comment_extract['__auteur_com'], $comment_extract['__date_com']);
 
// toujours un éléments "votes", quand bien même il n'y en aurait pas
$comment_extract['votes'] = array();
$ret[$commentId] = $comment_extract;
}
 
if (!$comment['nom_sel'] || ! $voteId) continue;
$vote = array_intersect_key($comment, array_flip($this->mappings['votes']));
$ret[$commentId]['votes'][$voteId] = $vote;
}
$this->observation['commentaires'] = $ret;
}
 
private function nettoyerAuteur() {
if (!isset($this->observation['auteur.id']) || !is_numeric($this->observation['auteur.id'])) {
$this->observation['auteur.id'] = '0';
}
if (!isset($this->observation['auteur.nom'])) {
$this->observation['auteur.nom'] = '[inconnu]';
}
}
 
/**
* Modifie une observation directement dans le CEL en faisant un appel à un web service du CEL.
* Utilisé uniquement par les admins.
* Permet de dépublier une observation.
*
* @param array $ressources tableau des informations contenues dans l'url après le nom du service
* @param array $parametres contenu du post
* @return mixed Chaine "OK" (en majuscule) en cas de succès, booléen "false" en cas d'échec
*/
public function modifier($ressources, $parametres) {
$gestionUtilisateurs = $this->conteneur->getUtilisateur();
$gestionUtilisateurs->etreUtilisateurAvecDroitAdmin();
 
$retour = false;
if (isset($parametres['transmission'])) {
$idObs = $ressources[0];
$clientRest = $this->conteneur->getRestClient();
$urlTpl = $this->conteneur->getParametre('urlServiceCelObs');
$url = $urlTpl.$idObs;
$retourCel = $clientRest->modifier($url, $parametres);
$retour = preg_match('/^OK$/i', $retourCel) ? 'OK' : false;
if ($retour === false) {
$message = "Erreur du web service CEL : ".$retourCel;
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
} else {
$message = "Ce web service doit contenir un paramètre 'transmission'.";
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
return $retour;
}
}
Property changes:
Added: svnkit:entry:sha1-checksum
+4089895a5dcb7422fbe6b5f30ea02926993bd44b
\ No newline at end of property
/tags/v1.10-sodium/services/modules/0.1/MotsCles.php
New file
0,0 → 1,148
<?php
// declare(encoding='UTF-8');
/**
* Classe principale de chargement des sous-service "mots-clés" de DEL.
*
* URLs possibles :
* GET
* http://localhost/del/services/0.1/mots-cles?image=#id&auteur.id=#id => les différents mots-clés des images en fonction des paramètres.
* PUT
* http://localhost/del/services/0.1/mots-cles?image=#id&auteur.id=#id&mot_cle=motCle1,motCle2,... => Ajoute différents mots-clés pour une image d'un utilisateur
* DELETE
* http://localhost/del/services/0.1/mots-cles?image=#id&auteur.id=#id => les différents mots-clés des images en fonction des paramètres.
*
* @category DEL
* @package Services
* @subpackage MotsCles
* @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 MotsCles extends RestService {
 
private $parametres = array();
private $ressources = array();
private $methode = null;
private $serviceNom = 'mots_cles';
private $sousServiceNom = null;
private $cheminCourant = null;
 
private $conteneur;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->initialiserRessourcesEtParametres($ressources, $parametres);
return $this->executerService();
}
 
public function ajouter($ressources, $requeteDonnees) {
$this->methode = 'ajouter';
$this->initialiserRessourcesEtParametres($ressources, $requeteDonnees);
return $this->executerService();
}
 
public function supprimer($ressources) {
$this->methode = 'supprimer';
$this->initialiserRessourcesEtParametres($ressources);
return $this->executerService();
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres = array()) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function executerService() {
$resultat = '';
$reponseHttp = new ReponseHttp();
try {
$this->conteneur = new Conteneur($this->parametres);
$resultat = $this->traiterRessources();
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
$reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
}
 
private function traiterRessources() {
$this->analyserRessources();
$retour = $this->initialiserService();
return $retour;
}
 
private function analyserRessources() {
if ($this->methode == 'consulter') {
if (!isset($this->ressources) || empty($this->ressources)) {
$this->sousServiceNom = 'liste-mots-cles';
}
} else if ($this->methode == 'ajouter') {
$this->sousServiceNom = 'ajouter-mot-cle';
} else if ($this->methode == 'supprimer') {
if (isset($this->ressources[0]) && count($this->ressources) == 1 && is_numeric($this->ressources[0])) {
$this->sousServiceNom = 'supprimer-mot-cle';
}
}
 
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function lancerMessageErreurRessource() {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "La ressource demandée '$ressource' ".
"n'est pas disponible pour le service «".$this->serviceNom."» !\n".
"Les URLs disponibles sont : \n".
" - en GET : mots-cles?image=#idImg&auteur.id=#idUtilisateur \n".
" - en PUT : mots-cles?image=#idImg&auteur.id=#idUtilisateur&mots_cles=motCle1,motCle2,...".
" - en DELETE : mots-cles/#idMotCle";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
private function initialiserService() {
$classe = $this->obtenirNomClasseService($this->sousServiceNom);
$chemin = $this->cheminCourant.$this->serviceNom.DS.$classe.'.php';
$retour = '';
$service = null;
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
if ($this->methode == 'consulter') {
$retour = $service->consulter($this->ressources, $this->parametres);
} elseif ($this->methode == 'ajouter') {
$retour = $service->ajouter($this->ressources, $this->parametres);
} elseif ($this->methode == 'supprimer') {
$retour = $service->supprimer($this->ressources);
}
}
 
if (is_null($service)) {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "Le classe '$classe' correspondant à la ressource '$ressource' ".
"n'existe pas dans le service '{$this->serviceNom}' !";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $retour;
}
 
private function obtenirNomClasseService($mot) {
$classeNom = str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
}
/tags/v1.10-sodium/services/modules/0.1/Protocoles.php
New file
0,0 → 1,127
<?php
// declare(encoding='UTF-8');
/**
* Classe principale de chargement des sous-services de Protocoles.
*
* Urls possibles :
* http://localhost/service:del:0.1/protocoles => tous les protocoles
*
* @category DEL
* @package Services
* @subpackage Protocoles
* @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 Protocoles extends RestService {
 
private $parametres = array();
private $ressources = array();
private $methode = null;
private $serviceNom = 'protocoles';
private $sousServiceNom = null;
private $cheminCourant = null;
 
private $conteneur;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->initialiserRessourcesEtParametres($ressources, $parametres);
return $this->executerService();
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres = array()) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function executerService() {
$reponseHttp = new ReponseHttp();
try {
$this->conteneur = new Conteneur($this->parametres);
$resultat = $this->traiterRessources();
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
$reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
}
 
private function traiterRessources() {
$this->analyserRessources();
$retour = $this->initialiserService();
return $retour;
}
 
private function analyserRessources() {
if ($this->methode == 'consulter') {
if (count($this->ressources) == 0) {
$this->sousServiceNom = 'liste-protocoles';
}
}
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function lancerMessageErreurRessource() {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "La ressource demandée '$ressource' ".
"n'est pas disponible pour le service ".$this->serviceNom." !\n".
"Les URLs disponibles sont : \n".
" - en GET : protocoles (paramètres : aucun) \n";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
private function initialiserService() {
$classe = $this->obtenirNomClasseService($this->sousServiceNom);
$chemins = array();
$chemins[] = $this->cheminCourant.$this->serviceNom.DS.$classe.'.php';
$chemins[] = $this->cheminCourant.'commun'.DS.$classe.'.php';
$retour = '';
$service = null;
 
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
if ($this->methode == 'consulter') {
$retour = $service->consulter();
} else {
$message = "Le sous-service '{$this->sousServiceNom}' du service '{$this->serviceNom}' ".
"ne possède pas de méthode '{$this->methode}' !";
$code = RestServeur::HTTP_NON_IMPLEMENTE;
throw new Exception($message, $code);
}
}
}
 
if (is_null($service)) {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "Le classe '$classe' correspondant à la ressource '$ressource' ".
"est introuvable par le service '{$this->serviceNom}' !";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $retour;
}
 
private function obtenirNomClasseService($mot) {
$classeNom = str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
}
/tags/v1.10-sodium/services/modules/0.1/Utilisateurs.php
New file
0,0 → 1,146
<?php
// declare(encoding='UTF-8');
/**
* Classe principale de chargement des sous-services liés aux utilisateurs.
*
* @category DEL
* @package Services
* @subpackage Utilisateurs
* @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 Utilisateurs extends RestService {
 
private $parametres = array();
private $ressources = array();
private $methode = null;
private $serviceNom = 'utilisateurs';
private $sousServiceNom = null;
private $cheminCourant = null;
 
private $conteneur;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourant = dirname(__FILE__).DS;
$this->conteneur = new Conteneur();
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->initialiserRessourcesEtParametres($ressources, $parametres);
return $this->executerService();
}
 
public function modifier($ressources, $requeteDonnees) {
$this->methode = 'modifier';
$this->initialiserRessourcesEtParametres($ressources, $requeteDonnees);
return $this->executerService();
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres = array()) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function executerService() {
$reponseHttp = new ReponseHttp();
try {
$resultat = $this->traiterRessources();
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
$reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
}
 
private function traiterRessources() {
$this->analyserRessources();
$retour = $this->initialiserService();
return $retour;
}
 
private function analyserRessources() {
if ($this->methode == 'consulter') {
//S'il n'y a pas de ressources => envoyer sur identification anonyme
if (!isset($this->ressources) || empty($this->ressources)) {
$this->sousServiceNom = 'identification';
} else {
if(count($this->ressources) == 2 && $this->ressources[1] == 'preferences') {
$this->sousServiceNom = 'preferences';
} else if(count($this->ressources) == 2 && $this->ressources[1] == 'activite') {
$this->sousServiceNom = 'activite';
} else {
$this->sousServiceNom = 'identification';
}
}
} else if ($this->methode == 'modifier') {
if (count($this->ressources) == 2 && $this->ressources[1] == 'preferences') {
$this->sousServiceNom = 'preferences';
}
}
 
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function lancerMessageErreurRessource() {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "La ressource demandée '$ressource' ".
"n'est pas disponible pour le service ".$this->serviceNom." !\n".
"Les URLs disponibles sont : \n".
" * en GET : \n".
" - utilisateurs : identification anonyme à partir des cookies (par défaut quelque soit l'url)\n".
" - utilisateurs/#login/#mot-de-passe : connecte l'utilisateur\n".
" - utilisateurs/deconnecter : déconnecte l'utilisateur actuellement connecté par cookie\n".
" - utilisateurs/#id/preferences : fourni les préférences de l'utilisateur #id\n".
" * en POST : \n".
" - utilisateurs/#id/preferences : permet de modifier \n";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
private function initialiserService() {
$classe = $this->obtenirNomClasseService($this->sousServiceNom);
$chemins = array();
$chemins[] = $this->cheminCourant.$this->serviceNom.DS.$classe.'.php';
$chemins[] = $this->cheminCourant.'commun'.DS.$classe.'.php';
$retour = '';
$service = null;
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
if ($this->methode == 'consulter') {
$retour = $service->consulter($this->ressources, $this->parametres);
} elseif ($this->methode == 'modifier') {
$retour = $service->modifier($this->ressources, $this->parametres);
}
}
}
 
if (is_null($service)) {
$ressource = $this->serviceNom.'/'.implode('/', $this->ressources);
$message = "Le classe '$classe' correspondant à la ressource '$ressource' ".
"n'existe pas dans le service '{$this->serviceNom}' !";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $retour;
}
 
private function obtenirNomClasseService($mot) {
$classeNom = str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
}
/tags/v1.10-sodium/services/modules/0.1/syndication/Tags.php
New file
0,0 → 1,219
<?php
// declare(encoding='UTF-8');
/**
* Service fournissant des informations concernant les tags sur les images de DEL en fonction d'un protocole
* au format RSS1, RSS2 ou ATOM.
*
* @category DEL
* @package Services
* @subpackage Syndication
* @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 Tags {
 
private $categorie = 'Tag';
private $conteneur;
private $bdd;
private $navigation;
private $syndication;
private $mapping = array();
 
public function __construct(Conteneur $conteneur) {
$this->conteneur = $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->navigation = $this->conteneur->getNavigation();
$this->syndication = $this->conteneur->getSyndicationOutils();
$this->mapping = $this->conteneur->getParametreTableau('syndication.mapping');
}
 
public function consulter() {
if ($this->syndication->fluxAdminDemande()) {
$this->syndication->demanderAutorisationAdmin();
}
 
$donnees_brutes = $this->getDerniersVotesImage();
$commentaires_formates = $this->formaterPourRss($donnees_brutes) ;
return $commentaires_formates;
}
 
/**
* Formater les données pour mettre en page le RSS
* */
private function formaterPourRss($elements) {
$derniere_info_en_date = reset($elements);
$donnees = $this->syndication->construireDonneesCommunesAuFlux('tag', $derniere_info_en_date['date']);
foreach ($elements as $element) {
$donnees['items'][] = $this->construireDonneesCommunesAuxItems($element);
}
return $donnees;
}
 
/**
* Générer les données communes & spécifiques à chaque item
* */
private function construireDonneesCommunesAuxItems($info) {
$item = array();
$date_modification_timestamp = strtotime($info['date']);
$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['titre'] = $this->creerTitre($info);
$item['guid'] = $this->creerGuidItem($info);
$item['lien'] = $this->creerLienItem($info);
$item['categorie'] = htmlentities($this->categorie);
$item['description'] = $this->creerDescription($info, $item);
$item['description_encodee'] = htmlspecialchars($this->creerDescription($info, $item));
$item['modifier_par'] = $this->formaterNomTagueur($info);
return $item;
}
 
private function creerGuidItem($element) {
$guid = sprintf($this->conteneur->getParametre('syndication.tag_guid_tpl'), $element['id_tag']);
return $guid;
}
 
private function creerLienItem($element) {
// TODO : ajouter un lien vers la plateforme validation de picto lorsqu'elle sera dispo
$lien = sprintf($this->conteneur->getParametre('img_fiche_tpl'), $element['id_image']);
return $lien;
}
 
private function creerTitre($element) {
$tag = $element['tag'];
$nomSel = htmlspecialchars($element['nom_sel']);
$tagueur = htmlspecialchars($this->formaterNomTagueur($element));
$auteurImg = $this->formaterNomAuteurImg($element);
$titre = "Tag «{$tag}» par $tagueur pour $nomSel de $auteurImg";
return $titre;
}
 
private function creerDescription($donnees, $item) {
$idTag = htmlspecialchars($donnees['id_tag']);
$idObs = htmlspecialchars($donnees['id_observation']);
$idImg = htmlspecialchars($donnees['id_image']);
$urlImg = $this->syndication->getUrlImage($donnees['id_image']);
$miniatureUrl = $this->syndication->getUrlImage($donnees['id_image'], 'CRS');
$nomSelActuel = htmlspecialchars($donnees['nom_sel']);
$dateObs = htmlspecialchars(str_replace(' 00:00:00', '', $donnees['date_observation']));
$lieuObs = htmlspecialchars($donnees['zone_geo']);
$tag = htmlspecialchars($donnees['tag']);
$dateTag = htmlspecialchars(strftime('%A %d %B %Y à %H:%M', strtotime($donnees['date'])));
$auteurImg = htmlspecialchars($this->creerAuteurImg($donnees));
$tagueur = htmlspecialchars($this->creerTagueur($donnees));
 
$description = '<style>.champ{color:grey} .gauche{float:left;padding:0 20px 0 0;} ul{list-style-type:none;padding:0;}</style>'.
'<h2>'."Tag pictoFlora #$idTag pour l'image #$idImg de l'observation #$idObs".'</h2>'.
'<div class="gauche">'.
' <a href="'.$urlImg.'">'.
' <img src="'.$miniatureUrl.'" alt="Img #'.$idImg.'"/>'.
' </a>'.
'</div>'.
'<div class="gauche">'.
" <h3>Image #$idImg de l'observation #$idObs</h3>".
' <ul>'.
' <li><span class="champ">'."Auteur de l'image :</span> $auteurImg</li>".
' <li><span class="champ">'."Nom saisi actuel :</span> <em>$nomSelActuel</em></li>".
' <li><span class="champ">'."Lieu :</span> $lieuObs</li>".
' <li><span class="champ">'."Date :</span> $dateObs</li>".
' </ul>'.
'</div>'.
'<div class="gauche">'.
" <h3>Tag #$idTag</h3>".
' <ul>'.
' <li><span class="champ">'."Tag :</span> <strong>$tag</strong></li>".
' <li><span class="champ">'."Auteur :</span> $tagueur</li>".
' <li><span class="champ">'."Taguée le :</span> $dateTag</li>".
' </ul>'.
'</div>';
return $description;
}
 
private function creerAuteurImg($info) {
$auteur = $this->formaterNomAuteurImg($info).
($this->syndication->fluxAdminDemande() ? ' ('.$info['auteur_courriel'].')' : '');
return $auteur;
}
 
private function formaterNomAuteurImg($info) {
$auteur = 'Anonyme';
if ($info['auteur_prenom'] != '' && $info['auteur_nom'] != '') {
$auteur = $info['auteur_prenom'].' '.$info['auteur_nom'];
}
return $auteur;
}
 
private function creerTagueur($info) {
$tagueur = $this->formaterNomTagueur($info).
($this->syndication->fluxAdminDemande() ? ' ('.$info['tagueur_courriel'].')' : '');
return $tagueur;
}
 
private function formaterNomTagueur($info) {
$tagueur = 'Anonyme';
if ($info['tagueur_prenom'] != '' && $info['tagueur_nom'] != '') {
$tagueur = $info['tagueur_prenom'].' '.$info['tagueur_nom'];
}
return $tagueur;
}
 
/**
* Retrouver les derniers votes image
* */
private function getDerniersVotesImage() {
$elements = array();
$idsTags = $this->getIdsDerniersVotesImage();
if (!empty($idsTags)) {
$idsTagsConcat = implode(', ', $idsTags);
$requete = 'SELECT DISTINCT id_tag, tag, date, '.
' do.id_observation, do.nom_sel, do.zone_geo, do.date_observation, di.id_image, '.
' duo.prenom AS auteur_prenom, duo.nom AS auteur_nom, duo.courriel AS auteur_courriel, '.
' du.prenom AS tagueur_prenom, du.nom AS tagueur_nom, du.courriel AS tagueur_courriel '.
'FROM del_image_tag AS dit '.
' INNER JOIN del_image AS di '.
' ON ce_image = id_image '.
' INNER JOIN del_observation AS do '.
' ON di.ce_observation = do.id_observation '.
' LEFT JOIN del_utilisateur AS duo '.
' ON do.ce_utilisateur = duo.id_utilisateur '.
' LEFT JOIN del_utilisateur AS du '.
' ON if((CHAR_LENGTH(dit.ce_utilisateur) <> 32),CAST(dit.ce_utilisateur AS unsigned),0) '.
' = du.id_utilisateur '.
'WHERE actif = 1 '.
" AND id_tag IN ($idsTagsConcat) ".
'ORDER BY date DESC '.
'LIMIT '.$this->navigation->getDepart().','.$this->navigation->getLimite().' '.
' -- '.__FILE__.' : '.__LINE__;
$elements = $this->bdd->recupererTous($requete);
}
return $elements;
}
 
/**
* Retrouver les ids des derniers votes image
* */
private function getIdsDerniersVotesImage() {
$requete = 'SELECT DISTINCT id_tag '.
'FROM del_image_tag '.
'WHERE actif = 1 '.
// Pas de filtre pour ce service. Utiliser le principe des autres ws de syndication si on devait en rajouter.
'ORDER BY date DESC '.
'LIMIT '.$this->navigation->getDepart().','.$this->navigation->getLimite().' '.
' -- '.__FILE__.' : '.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
 
$idsTags = array();
if ($resultats != false && is_array($resultats)) {
foreach ($resultats as $infos) {
$idsTags[] = $infos['id_tag'];
}
}
return $idsTags;
}
}
Property changes:
Added: svnkit:entry:sha1-checksum
+0aaf0e201a3d29d801b57d08d5878bb16dbdbb41
\ No newline at end of property
/tags/v1.10-sodium/services/modules/0.1/syndication/Votes.php
New file
0,0 → 1,228
<?php
// declare(encoding='UTF-8');
/**
* Service fournissant des informations concernant les votes sur les images de DEL en fonction d'un protocole
* au format RSS1, RSS2 ou ATOM.
*
* @category DEL
* @package Services
* @subpackage Syndication
* @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 Votes {
 
private $categorie = 'Vote protocole';
private $conteneur;
private $bdd;
private $navigation;
private $syndication;
private $mapping = array();
 
public function __construct(Conteneur $conteneur) {
$this->conteneur = $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->navigation = $this->conteneur->getNavigation();
$this->syndication = $this->conteneur->getSyndicationOutils();
$this->mapping = $this->conteneur->getParametreTableau('syndication.mapping');
}
 
public function consulter() {
if ($this->syndication->fluxAdminDemande()) {
$this->syndication->demanderAutorisationAdmin();
}
 
$donnees_brutes = $this->getDerniersVotesImage();
$commentaires_formates = $this->formaterPourRss($donnees_brutes) ;
return $commentaires_formates;
}
 
/**
* Formater les données pour mettre en page le RSS
* */
private function formaterPourRss($elements) {
$derniere_info_en_date = reset($elements);
$donnees = $this->syndication->construireDonneesCommunesAuFlux('vote', $derniere_info_en_date['date_vote']);
foreach ($elements as $element) {
$donnees['items'][] = $this->construireDonneesCommunesAuxItems($element);
}
return $donnees;
}
 
/**
* Générer les données communes & spécifiques à chaque item
* */
private function construireDonneesCommunesAuxItems($info) {
$item = array();
$date_modification_timestamp = strtotime($info['date_vote']);
$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['titre'] = $this->creerTitre($info);
$item['guid'] = $this->creerGuidItem($info);
$item['lien'] = $this->creerLienItem($info);
$item['categorie'] = htmlentities($this->categorie);
$item['description'] = $this->creerDescription($info, $item);
$item['description_encodee'] = htmlspecialchars($this->creerDescription($info, $item));
$item['modifier_par'] = $this->creerVotant($info);
return $item;
}
 
private function creerGuidItem($element) {
$guid = sprintf($this->conteneur->getParametre('syndication.vote_guid_tpl'), $element['id_vote']);
return $guid;
}
 
private function creerLienItem($element) {
$lien = sprintf($this->conteneur->getParametre('img_fiche_tpl'), $element['ce_image']);
return $lien;
}
 
private function creerTitre($element) {
$noteVote = $element['valeur'];
$nomSci = htmlspecialchars($element['nom_sel']);
$votant = htmlspecialchars($this->creerVotant($element));
$observateur = htmlspecialchars($this->creerObservateur($element));
 
$titre = "Vote $noteVote par $votant pour $nomSci de $observateur";
return $titre;
}
 
private function creerDescription($donnees, $item) {
$idVote = htmlspecialchars($donnees['id_vote']);
$idObs = htmlspecialchars($donnees['id_observation']);
$idImg = htmlspecialchars($donnees['ce_image']);
$urlImg = $this->syndication->getUrlImage($donnees['ce_image']);
$miniatureUrl = $this->syndication->getUrlImage($donnees['ce_image'], 'CRS');
$nomSelActuel = htmlspecialchars($donnees['nom_sel']);
$dateObs = htmlspecialchars(str_replace(' 00:00:00', '', $donnees['date_observation']));
$lieuObs = htmlspecialchars($donnees['zone_geo']);
$protocole = htmlspecialchars($donnees['intitule']);
$votant = htmlspecialchars($this->creerVotant($donnees));
$dateVote = htmlspecialchars(strftime('%A %d %B %Y à %H:%M', strtotime($donnees['date_vote'])));
$observateur = htmlspecialchars($this->creerObservateur($donnees));
 
$description = '<style>.champ{color:grey} .gauche{float:left;padding:0 20px 0 0;} ul{list-style-type:none;padding:0;}</style>'.
'<h2>'."Vote pictoFlora #$idVote pour l'image #$idImg de l'observation #$idObs".'</h2>'.
'<div class="gauche">'.
' <a href="'.$urlImg.'">'.
' <img src="'.$miniatureUrl.'" alt="Img #'.$idImg.'"/>'.
' </a>'.
'</div>'.
'<div class="gauche">'.
" <h3>Image #$idImg de l'observation #$idObs</h3>".
' <ul>'.
' <li><span class="champ">'."Auteur de l'image :</span> $observateur</li>".
' <li><span class="champ">'."Nom saisi actuel :</span> <em>$nomSelActuel</em></li>".
' <li><span class="champ">'."Lieu :</span> $lieuObs</li>".
' <li><span class="champ">'."Date :</span> $dateObs</li>".
' </ul>'.
'</div>'.
'<div class="gauche">'.
" <h3>Vote #$idVote</h3>".
' <ul>'.
' <li><span class="champ">'."Protocole :</span> <strong>$protocole</strong></li>".
' <li><span class="champ">'."Valeur :</span> <strong>{$donnees['valeur']}</strong>/5</li>".
' <li><span class="champ">'."Votant :</span> $votant</li>".
' <li><span class="champ">'."À voté le :</span> $dateVote</li>".
' </ul>'.
'</div>';
return $description;
}
 
private function creerVotant($info) {
$votant = 'Anonyme';
if (isset($info['votant_prenom']) && isset($info['votant_nom'])) {
$votant = $info['votant_prenom'].' '.$info['votant_nom'];
}
return $votant;
}
 
private function creerObservateur($info) {
$observateur = 'Anonyme';
if ($info['observateur_prenom'] != '' && $info['observateur_nom'] != '') {
$observateur = $info['observateur_prenom'].' '.$info['observateur_nom'];
}
return $observateur;
}
 
 
 
/**
* Retrouver les derniers votes image
* */
private function getDerniersVotesImage() {
$elements = array();
$idsVotes = $this->getIdsDerniersVotesImage();
if (!empty($idsVotes)) {
$idsVotesConcat = implode(', ', $idsVotes);
$requete = 'SELECT DISTINCT id_vote, ce_image, valeur, divo.date AS date_vote, '.
' duo.prenom AS observateur_prenom, duo.nom AS observateur_nom, '.
' duv.prenom AS votant_prenom, duv.nom AS votant_nom, '.
' do.id_observation, do.nom_sel, do.zone_geo, do.date_observation, dip.intitule '.
'FROM del_image_vote AS divo '.
' INNER JOIN del_image AS di '.
' ON divo.ce_image = di.id_image '.
' INNER JOIN del_observation AS do '.
' ON di.ce_observation = do.id_observation '.
' INNER JOIN del_image_protocole AS dip '.
' ON ce_protocole = id_protocole '.
' LEFT JOIN del_utilisateur AS duo '.
' ON do.ce_utilisateur = duo.id_utilisateur '.
' LEFT JOIN del_utilisateur AS duv '.
' ON if((CHAR_LENGTH(divo.ce_utilisateur) <> 32),CAST(divo.ce_utilisateur AS unsigned),0) '.
' = duv.id_utilisateur '.
"WHERE id_vote IN ($idsVotesConcat) ".
'ORDER BY divo.date DESC '.
'LIMIT '.$this->navigation->getDepart().','.$this->navigation->getLimite().
' -- '.__FILE__.' : '.__LINE__;
$elements = $this->bdd->recupererTous($requete);
}
return $elements;
}
 
/**
* Retrouver les ids des derniers votes image
* */
private function getIdsDerniersVotesImage() {
$clauseWhere = $this->chargerClauseWhere();
$requete = 'SELECT DISTINCT id_vote '.
'FROM del_image_vote '.
($clauseWhere != '' ? "WHERE $clauseWhere " : '').
'ORDER BY date DESC '.
'LIMIT '.$this->navigation->getDepart().','.$this->navigation->getLimite().
' -- '.__FILE__.' : '.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
 
$idsVotes = array();
if ($resultats != false && is_array($resultats)) {
foreach ($resultats as $infos) {
$idsVotes[] = $infos['id_vote'];
}
}
return $idsVotes;
}
 
private function chargerClauseWhere() {
$where = array();
$filtres = $this->navigation->getFiltre();
if (!empty($filtres)) {
$filtrePossibles = $this->conteneur->getParametreTableau('syndication.vote_filtres');
foreach ($filtres as $cleFiltre => $valeur) {
if (in_array($cleFiltre, $filtrePossibles)) {
$champ = $this->mapping[$cleFiltre];
$valeurP = $this->bdd->proteger($valeur);
$where[] = " $champ = $valeurP ";
}
}
}
 
return (!empty($where)) ? implode('AND', $where) : '';
}
}
/tags/v1.10-sodium/services/modules/0.1/syndication/Commentaires.php
New file
0,0 → 1,267
<?php
// declare(encoding='UTF-8');
/**
* Service fournissant des informations concernant les commentaire de DEL au format RSS1, RSS2 ou ATOM.
*
* @category DEL
* @package Services
* @subpackage Syndication
* @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 Commentaires {
 
private $categorie = 'Commentaires';
private $conteneur;
private $contexte;
private $bdd;
private $navigation;
private $mapping = array();
private $syndication;
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->contexte = $this->conteneur->getContexte();
$this->bdd = $this->conteneur->getBdd();
$this->navigation = $this->conteneur->getNavigation();
$this->syndication = $this->conteneur->getSyndicationOutils();
$this->mapping = $this->conteneur->getParametreTableau('syndication.mapping');
}
 
public function consulter() {
if ($this->syndication->fluxAdminDemande()) {
$this->syndication->demanderAutorisationAdmin();
}
 
$donnees_brutes = $this->getDerniersCommentaires();
$commentaires_formates = $this->formaterPourRss($donnees_brutes) ;
return $commentaires_formates;
}
 
private function formaterPourRss($elements) {
$derniere_info_en_date = reset($elements);
$donnees = $this->syndication->construireDonneesCommunesAuFlux('commentaire', $derniere_info_en_date['date']);
foreach ($elements as $element) {
$donnees['items'][] = $this->construireDonneesCommunesAuxItems($element);
}
return $donnees;
}
 
private function construireDonneesCommunesAuxItems($info) {
$item = array();
$date_modification_timestamp = $this->syndication->convertirDateHeureMysqlEnTimestamp($info['date']);
$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['titre'] = $this->creerTitre($info);
$item['guid'] = $this->creerGuidItem($info);
$item['lien'] = $this->creerLienItem($info);
$item['categorie'] = htmlentities($this->categorie);
$item['description'] = $this->creerDescription($info, $item);
$item['description_encodee'] = htmlspecialchars($this->creerDescription($info, $item));
$item['modifier_par'] = $this->creerAuteur($info);
return $item;
}
 
private function creerTitre($element) {
$nomPropose = htmlspecialchars($element['nom_sel']);
$intitule = ($element['nom_sel'] != '') ? "Proposition $nomPropose" : 'Commentaire';
$auteur = htmlspecialchars($this->creerAuteur($element));
$nomSelActuel = htmlspecialchars($element['dob_nom_sel']);
$zoneGeo = htmlspecialchars((($element['dob_zone_geo'] != '') ? $element['dob_zone_geo'] : null));
$dateObs = null;
if (strpos($element['dob_date_observation'], '0000') === false) {
$dateObs = htmlspecialchars(strftime('%d %B %Y', strtotime($element['dob_date_observation'])));
}
 
$titre = "$intitule par $auteur pour $nomSelActuel";
$titre .= ($zoneGeo != null) ? " à $zoneGeo" : "";
$titre .= ($dateObs != null) ? " le $dateObs" : "";
return $titre;
}
 
private function creerAuteur($info) {
$auteur = 'Anonyme';
if ($info['utilisateur_prenom'] != '' && $info['utilisateur_nom'] != '') {
$auteur = $info['utilisateur_prenom'].' '.$info['utilisateur_nom'];
}
return $auteur;
}
 
private function creerGuidItem($element) {
$guid = sprintf($this->conteneur->getParametre('syndication.commentaire_guid_tpl'), $element['id_commentaire']);
return $guid;
}
 
private function creerLienItem($element) {
$lien = sprintf($this->conteneur->getParametre('obs_fiche_tpl'), $element['dob_id_observation']);
return $lien;
}
 
private function creerDescription($donnees, $item) {
$idCommentaire = $donnees['id_commentaire'];
$idObs = $donnees['dob_id_observation'];
$nomPropose = ($donnees['nom_sel'] != '') ? htmlspecialchars($donnees['nom_sel']) : '';
$dateCommentaire = htmlspecialchars(strftime('%A %d %B %Y à %H:%M', $this->syndication->convertirDateHeureMysqlEnTimestamp($donnees['date'])));
$nomSelActuel = htmlspecialchars($donnees['dob_nom_sel']);
$etreProposition = ($nomPropose != '') ? true : false;
$intitule = ($etreProposition) ? 'Proposition' : 'Commentaire';
$txt = ($donnees['texte'] != '') ? htmlspecialchars($donnees['texte']) : '';
$auteur = htmlspecialchars($this->creerAuteur($donnees)).
($this->syndication->fluxAdminDemande() ? ' ('.$donnees['utilisateur_courriel'].')' : '');
$lieuObs = htmlspecialchars((($donnees['dob_zone_geo'] != '') ? $donnees['dob_zone_geo'] : '?'));
$dateObs = htmlspecialchars(str_replace(' 00:00:00', '', $donnees['dob_date_observation']));
$observateur = htmlspecialchars($this->creerObservateur($donnees));
 
$contenuCommentaire = '';
if ($etreProposition) {
$contenuCommentaire =
'<li><span class="champ">'."Nom proposé :</span> <em>$nomPropose</em></li>".
((!empty($txt)) ? '<li><span class="champ">'."Argumentaire :</span> $txt</li>" : '').
'<li><span class="champ">'."Auteur de la proposition :</span> $auteur</li>".
'<li><span class="champ">'."Proposé le :</span> $dateCommentaire</li>";
} else {
$contenuCommentaire =
'<li><span class="champ">'."Commentaire #$idCommentaire :</span> <pre>$txt</pre></li>".
'<li><span class="champ">'."Auteur du commentaire :</span> $auteur</li>".
'<li><span class="champ">'."Commenté le :</span> $dateCommentaire</li>";
}
 
$description = '<style>.champ{color:grey} .gauche{float:left;padding:0 20px 0 0;} ul{list-style-type:none;padding:0;}</style>'.
'<h2>'."$intitule identiPlante #$idCommentaire pour l'observation #$idObs".'</h2>'.
'<div class="gauche">'.
" <h3>Observation #$idObs</h3>".
' <ul>'.
' <li><span class="champ">'."Nom saisi actuel :</span> <em>$nomSelActuel</em></li>".
' <li><span class="champ">'."Lieu :</span> $lieuObs</li>".
' <li><span class="champ">'."Date :</span> $dateObs</li>".
' <li><span class="champ">'."Auteur :</span> $observateur</li>".
' </ul>'.
'</div>'.
'<div class="gauche">'.
" <h3>$intitule #$idCommentaire</h3>".
" <ul>$contenuCommentaire</ul>".
'</div>';
return $description;
}
 
private function creerObservateur($info) {
$observateur = 'Anonyme';
if ($info['observateur_prenom'] != '' && $info['observateur_nom'] != '') {
$observateur = $info['observateur_prenom'].' '.$info['observateur_nom'];
}
return $observateur;
}
 
private function getDerniersCommentaires() {
$commentaires = array();
$idsCommentaires = $this->getIdsDerniersCommentaires();
if (!empty($idsCommentaires)) {
$idsCommentairesconcat = implode(', ', $idsCommentaires);
$requete = 'SELECT DISTINCT dc.*, '.
' dob.id_observation AS dob_id_observation, dob.ce_zone_geo AS dob_ce_zone_geo, '.
' dob.zone_geo AS dob_zone_geo, dob.date_observation AS dob_date_observation, dob.nom_sel AS dob_nom_sel, '.
' duo.prenom AS observateur_prenom, duo.nom AS observateur_nom, duo.courriel AS observateur_courriel '.
'FROM del_commentaire AS dc '.
' INNER JOIN del_observation AS dob '.
' ON dob.id_observation = dc.ce_observation '.
' LEFT JOIN del_utilisateur AS duo '.
' ON dob.ce_utilisateur = duo.id_utilisateur '.
"WHERE id_commentaire IN ($idsCommentairesconcat) ".
'ORDER BY dc.date DESC '.
'LIMIT '.$this->navigation->getDepart().','.$this->navigation->getLimite().' '.
' -- '.__FILE__.' : '.__LINE__;
$commentaires = $this->bdd->recupererTous($requete);
}
return $commentaires;
}
 
private function getIdsDerniersCommentaires() {
$clauseWhere = $this->chargerClauseWhere();
$requete = 'SELECT DISTINCT dc.id_commentaire '.
'FROM del_commentaire AS dc '.
' INNER JOIN del_observation AS dob ON (dc.ce_observation = dob.id_observation) '.
' LEFT JOIN del_utilisateur AS duo ON (dob.ce_utilisateur = duo.id_utilisateur) '.
'WHERE proposition_initiale != 1 '.
($clauseWhere != '' ? "AND $clauseWhere " : '').
'ORDER BY dc.date DESC '.
'LIMIT '.$this->navigation->getDepart().','.$this->navigation->getLimite().' '.
' -- '.__FILE__.' : '.__LINE__;
//echo $requete;
$resultats = $this->bdd->recupererTous($requete);
 
$idsCommentaires = array();
if ($resultats != false && is_array($resultats)) {
foreach ($resultats as $infos) {
$idsCommentaires[] = $infos['id_commentaire'];
}
}
return $idsCommentaires;
}
 
/**
* Charger la clause WHERE en fonction des paramètres de masque
* */
private function chargerClauseWhere() {
$where = array();
$filtres = $this->navigation->getFiltre();
if (!empty($filtres)) {
$filtrePossibles = $this->conteneur->getParametreTableau('syndication.commentaire_filtres');
foreach ($filtres as $cleFiltre => $valeur) {
if (in_array($cleFiltre, $filtrePossibles)) {
if (isset($this->mapping[$cleFiltre])) {
$champ = $this->mapping[$cleFiltre];
}
switch ($cleFiltre) {
case 'espece':
$valeurP = $this->bdd->proteger($valeur.'%');
$where[] = " (dob.$champ LIKE $valeurP OR dc.$champ LIKE $valeurP) ";
break;
case 'auteur':
$where[] = $this->creerFiltreAuteur($valeur);
break;
default:
$valeurP = $this->bdd->proteger($valeur);
$where[] = " $champ = $valeurP ";
}
}
}
}
return (!empty($where)) ? implode(' AND ', $where) : '';
}
 
private function creerFiltreAuteur($auteurId) {
$whereAuteur = '';
if (is_numeric($auteurId)) {
$whereAuteur = " dc.ce_utilisateur = $auteurId ";
} else {
$auteurIdMotif = $this->bdd->proteger($auteurId.'%');
 
if (strpos($auteurId, '@') !== false) {
$whereAuteur = " dc.utilisateur_courriel LIKE $auteurIdMotif ";
} else {
$tableauNomPrenom = explode(' ', $auteurId, 2);
if (count($tableauNomPrenom) == 1) {
$whereAuteur = " (dc.utilisateur_nom LIKE $auteurIdMotif OR dc.utilisateur_prenom LIKE $auteurIdMotif) ";
} else if (count($tableauNomPrenom) == 2) {
// on teste potentiellement un nom prenom ou bien un prénom nom
$nomMotif = $this->bdd->proteger($tableauNomPrenom[0].'%');
$prenomMotif = $this->bdd->proteger($tableauNomPrenom[1].'%');
 
$whereAuteur = ' ('.
"(dc.utilisateur_nom LIKE $nomMotif AND dc.utilisateur_prenom LIKE $prenomMotif) ".
'OR '.
"(dc.utilisateur_nom LIKE $prenomMotif AND dc.utilisateur_prenom LIKE $nomMotif) ".
') ';
}
}
}
return $whereAuteur;
}
}
Property changes:
Added: svnkit:entry:sha1-checksum
+9ac625ab6837ca8768dbe4ffc3ec13c73f2b5009
\ No newline at end of property
/tags/v1.10-sodium/services/modules/0.1/syndication/squelettes/opml.tpl.xml
New file
0,0 → 1,18
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";?>
<opml version="1.0">
<head>
<text/>
</head>
<body>
<outline text="DEL">
<?php foreach ($liste_flux as $flux) : ?>
<outline title="<?=$flux['titre']?>"
description="<?=$flux['description']?>"
htmlUrl="<?=$flux['url_html']?>"
xmlUrl="<?=$flux['url_xml']?>"
type="<?=$flux['type']?>"
text="<?=$flux['texte']?>"/>
<?php endforeach; ?>
</outline>
</body>
</opml>
/tags/v1.10-sodium/services/modules/0.1/syndication/squelettes/rss1.tpl.xml
New file
0,0 → 1,44
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";?>
 
<!DOCTYPE rdf:RDF [
<!ENTITY % HTMLlat1 PUBLIC
"-//W3C//ENTITIES Latin 1 for XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
%HTMLlat1;
]>
 
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns="http://purl.org/rss/1.0/">
 
<channel rdf:about="<?=$guid?>">
<title><?=$titre?></title>
<link><?=$lien_service?></link>
<description><?=$description?></description>
<dc:publisher><?=$editeur?></dc:publisher>
<dc:date><?=$date_maj_W3C?></dc:date>
<?php if (isset($items)) : ?>
<items>
<rdf:Seq>
<?php foreach ($items as $item) : ?>
<rdf:li resource="<?=$item['guid']?>" />
<?php endforeach; ?>
</rdf:Seq>
</items>
<?php endif; ?>
</channel>
 
<?php if (isset($items)) : ?>
<?php foreach ($items as $item) : ?>
<item rdf:about="<?=$item['guid']?>">
<title><?=$item['titre']?></title>
<link><?=(isset($item['lien'])) ? $item['lien'] : 'http://www.tela-botanica.org/'?></link>
<description><?=$item['description_encodee']?></description>
<dc:creator><?=$item['modifier_par']?></dc:creator>
<dc:date><?=$item['date_maj_W3C']?></dc:date>
</item>
<?php endforeach; ?>
<?php endif; ?>
</rdf:RDF>
/tags/v1.10-sodium/services/modules/0.1/syndication/squelettes/rss2.tpl.xml
New file
0,0 → 1,25
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><?=$titre?></title>
<link><?=$lien_service?></link>
<atom:link href="<?=$lien_service?>" rel="self" type="application/rss+xml" />
<description><?=$description?></description>
 
<?php if (isset($items)) : ?>
<?php foreach ($items as $item) : ?>
<item>
<guid><?=$item['guid']?></guid>
<title><?=$item['titre']?></title>
<? if (isset($item['lien'])) : ?>
<link><?=$item['lien']?></link>
<? endif; ?>
<description><?=$item['description_encodee']?></description>
<category><?= $item['categorie'] ?></category>
<author><?=$item['modifier_par']?></author>
<pubDate><?=$item['date_maj_RSS']?></pubDate>
</item>
<?php endforeach; ?>
<?php endif; ?>
</channel>
</rss>
/tags/v1.10-sodium/services/modules/0.1/syndication/squelettes/atom.tpl.xml
New file
0,0 → 1,33
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><?=$titre?></title>
<link href="<?=$lien_service?>" rel="alternate" type="text/html" hreflang="fr" />
<link href="<?=$lien_service?>" rel="self" type="application/atom+xml"/>
<updated><?=$date_maj_ATOM?></updated>
<author>
<name><?=$editeur?></name>
</author>
<id><?=$guid?></id>
<rights>Copyright (c) <?=$annee_courante?>, <?=$editeur?></rights>
<generator uri="<?=$lien_service?>" version="<?=$generateur_version?>"><?=$generateur?></generator>
 
<?php if (isset($items)) : ?>
<?php foreach ($items as $item) : ?>
<entry>
<id><?=$item['guid']?></id>
<title><?=$item['titre']?></title>
<? if (isset($item['lien'])) : ?>
<link href="<?=$item['lien']?>"/>
<? endif; ?>
<updated><?=$item['date_maj_ATOM']?></updated>
<published><?=$item['date_maj_ATOM']?></published>
<author><name><?=$item['modifier_par']?></name></author>
<content type="xhtml" xml:lang="fr">
<div xmlns="http://www.w3.org/1999/xhtml">
<?=$item['description'];?>
</div>
</content>
</entry>
<?php endforeach; ?>
<?php endif; ?>
</feed>
/tags/v1.10-sodium/services/modules/0.1/determinations/ListeImagesDeterminationsProbables.php
New file
0,0 → 1,362
<?php
// declare(encoding='UTF-8');
/**
* Web service récupèrant toutes les données de la table del_obs_images
* pour retourner une liste d'images associées à la détermination la plus probable.
*
* Possibilité de ne renvoyer que les images les mieux notées pour un protocole donné.
*
* @category DEL
* @package Services
* @subpackage Determinations
* @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 ListeImagesDeterminationsProbables {
 
private $indexImagesIds = array();
private $conteneur;
private $navigation;
private $bdd;
 
private $erreurs = array();
private $parametres = array();
private $protocoles = array();
 
private $idsImagesOrdonnees = array();
private $resultats = array();
private $propositions = array();
private $votes = array();
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->navigation = $conteneur->getNavigation();
$this->bdd = $this->conteneur->getBdd();
$this->chargerProtocoles();
}
 
private function chargerProtocoles() {
$requete = 'SELECT id_protocole FROM del_image_protocole -- '.__FILE__.' : '.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
if ($resultats) {
foreach ($resultats as $infos) {
$this->protocoles[] = $infos['id_protocole'];
}
sort($this->protocoles);
}
}
 
public function consulter($parametres) {
$this->parametres = $parametres;
$this->verifierParametres();
 
// Lancement du service
$this->idsImagesOrdonnees = $this->getIdsImages();
$this->modifierEnteteTotal();
$infos = $this->chargerInfos();
if ($infos) {
$this->traiterResultats($infos);
$this->completerResutlats();
}
 
// Mettre en forme le résultat et l'envoyer pour affichage
$resultat = new ResultatService();
$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => $this->resultats);
return $resultat;
}
 
private function verifierParametres() {
$this->verifierParamProtocole();
$this->verifierParamVote();
 
if (!empty($this->erreurs)) {
$msg = "Erreur de configuration :\n".implode("\n\n", $this->erreurs);
throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
}
 
private function verifierParamProtocole() {
if (isset($this->parametres['masque.protocole'])) {
$protocoleExistant = in_array($this->parametres['masque.protocole'], $this->protocoles);
 
if (!is_numeric($this->parametres['masque.protocole']) || $protocoleExistant === false) {
$protocolesListe = implode(', ', $this->protocoles);
$msg = "La valeur pour le protocole doit être un entier compris dans les numéros de protocole ".
"existants : $protocolesListe";
$this->erreurs[] = $msg;
}
}
}
 
private function verifierParamVote() {
if (isset($this->parametres['masque.valeur_min_vote'])) {
$minVote = $this->parametres['masque.valeur_min_vote'];
if (!is_numeric($minVote) || ($minVote < 0 && $minVote > 5)) {
$this->erreurs[] = "La valeur minimum de valeur des votes doit être un entier compris entre 0 et 5.";
}
}
}
 
private function getIdsImages() {
$whereClause = $this->getClauseWhere();
$depart = $this->navigation->getDepart();
$limite = $this->navigation->getLimite();
 
$requete = 'SELECT DISTINCT SQL_CALC_FOUND_ROWS di.id_image '.
'FROM del_image AS di '.
' LEFT JOIN del_image_stat AS ds ON (di.id_image = ds.ce_image) '.
"$whereClause ".
'ORDER BY moyenne DESC, id_image DESC '.
"LIMIT $depart, $limite ".
' -- '.__FILE__.' : '.__LINE__;
//Debug::printr($requete);
$resultats = $this->bdd->recupererTous($requete);
$idImgs = array();
if ($resultats !== false ) {
foreach ($resultats as $resultat) {
$idImgs[] = $resultat['id_image'];
}
}
return $idImgs;
}
 
private function getClauseWhere() {
$where = array();
if (isset($this->parametres['masque.protocole'])) {
$protocoleIdP = $this->bdd->proteger($this->parametres['masque.protocole']);
$where[] = "ds.ce_protocole = $protocoleIdP ";
}
if (isset($this->parametres['masque.valeur_vote_min'])) {
$voteP = $this->bdd->proteger($this->parametres['masque.valeur_vote_min']);
$where[] = "moyenne >= $voteP";
}
return (count($where) > 0) ? 'WHERE '.implode(' AND ', $where).' ' : '';
}
 
private function chargerInfos() {
$idImgsConcat = implode(',', $this->idsImagesOrdonnees);
 
$requete = 'SELECT DISTINCT SQL_CALC_FOUND_ROWS '.
'di.id_image, di.mots_cles_texte AS mots_cles_texte_image, '.
'do.id_observation, nom_referentiel, nom_ret, '.
'nom_ret_nn, nt, famille, ce_zone_geo, zone_geo, date_observation, '.
'do.ce_utilisateur, do.nom_utilisateur, do.prenom_utilisateur, '.
'du.prenom, du.nom '.
'FROM del_image AS di '.
' INNER JOIN del_observation AS do ON (di.ce_observation = do.id_observation) '.
' LEFT JOIN del_utilisateur AS du ON (di.ce_utilisateur = du.id_utilisateur) '.
' LEFT JOIN del_image_stat AS ds ON (di.id_image = ds.ce_image) '.
"WHERE di.id_image IN ($idImgsConcat) ".
'ORDER BY moyenne DESC, id_image DESC '.
' -- '.__FILE__.' : '.__LINE__;
//Debug::printr($requete);
return $this->bdd->recupererTous($requete);
}
 
private function modifierEnteteTotal() {
$requete = 'SELECT FOUND_ROWS() AS nbre -- '.__FILE__.' : '.__LINE__;
$compte = $this->bdd->recuperer($requete);
$total = ($compte !== false) ? (int) $compte['nbre'] : 0;
$this->navigation->setTotal($total);
}
 
/**
* Retourner un tableau d'images formaté en fonction des liaisons trouvées
* @param $infos les infos sur les images et observations
* */
private function traiterResultats($infos) {
//Debug::printr($infos);
foreach ($infos as $info) {
$idImage = $info['id_image'];
$index = $this->formaterIndexResultat($info);
 
$this->obsIds[] = $info['id_observation'];
$this->indexImagesIds[$idImage] = $index;
$this->resultats[$index] = array(
'id_image' => $idImage,
'id_observation' => $info['id_observation'],
'auteur.intitule' => $this->formaterIntituleAuteur($info),
'binaire.href' => $this->formaterBinaireHref($info),
'determination.famille' => $info['famille'],
'determination.referentiel' => $info['nom_referentiel'],
'determination.ns' => $info['nom_ret'],
'determination.nn' => $info['nom_ret_nn'],
'determination.nt' => $info['nt'],
'date_observation' => $info['date_observation'],
'localite' => $this->formaterLieu($info),
'mots_cles_image_cel' => $this->formaterMotsClesCel($info),
'mots_cles_image_del' => ''
);
}
}
 
private function formaterIndexResultat($infos) {
return $infos['id_image'].'-'.$infos['id_observation'];
}
 
private function formaterIntituleAuteur($infos) {
if ($infos['ce_utilisateur'] == 0) {
$infos['prenom'] = $infos['prenom_utilisateur'];
$infos['nom'] = $infos['nom_utilisateur'];
}
$intitule = $infos['prenom'].' '.$infos['nom'];
return $intitule;
}
 
private function formaterBinaireHref($infos) {
return sprintf(
$this->conteneur->getParametre('cel_img_url_tpl'),
$infos['id_image'],
$this->conteneur->getParametre('determinations.format_image')
);
}
 
private function formaterLieu($infos) {
$lieuFormate = '';
if ($infos['ce_zone_geo']) {
$lieu = $infos['zone_geo'];
$id_zone_geo = $infos['ce_zone_geo'];
if (strpos($infos['ce_zone_geo'], 'INSEE-C:') === 0) {
$id_zone_geo = str_replace('INSEE-C:', '', $infos['ce_zone_geo']);
$id_zone_geo = strlen($id_zone_geo) >= 5 ? substr($id_zone_geo, 0, 2) : $id_zone_geo;
}
$lieuFormate = "$lieu ($id_zone_geo)";
}
return $lieuFormate;
}
 
/**
* Formater les mots clés du cel en n'affichant que ceux faisant partie d'une liste définie dans le
* fichier de configuration.
*
* @param $infos le tableau contenant les infos sur une image.
* @return string la chaine filtrée
*/
private function formaterMotsClesCel($infos) {
$motsClesAffiches = $this->conteneur->getParametreTableau('determinations.mots_cles_cel_affiches');
$motsClesCel = explode(',', $infos['mots_cles_texte_image']);
$motsCles = array_intersect($motsClesAffiches, $motsClesCel);
return implode(',', $motsCles);
}
 
private function completerResutlats() {
$this->chargerVotes();
$this->chargerPropositions();
 
$this->completerMotsCles();
 
foreach ($this->resultats as $index => $infos) {
if ($this->doitRemplacerObservationParProposition($index)) {
$id_obs = $infos['id_observation'];
$this->resultats[$index]['determination.famille'] = $this->propositions[$id_obs]['famille'];
$this->resultats[$index]['determination.ns'] = $this->propositions[$id_obs]['nom_sel'];
$this->resultats[$index]['determination.nn'] = $this->propositions[$id_obs]['nom_sel_nn'];
$this->resultats[$index]['determination.nt'] = $this->propositions[$id_obs]['nt'];
$this->resultats[$index]['determination.referentiel'] = $this->propositions[$id_obs]['nom_referentiel'];
}
$this->completerUrlFicheEflore($index);
}
}
 
private function chargerVotes() {
$idsObs = implode(',', $this->obsIds);
$requete = 'SELECT ce_proposition, valeur, ce_utilisateur '.
'FROM del_commentaire_vote '.
'WHERE ce_proposition IN '.
'( SELECT id_commentaire '.
' FROM del_commentaire '.
" WHERE ce_observation IN ($idsObs) AND nom_sel IS NOT NULL ) ".
'ORDER BY ce_proposition '.
' -- '.__FILE__.' : '.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
if ($resultats !== false) {
foreach ($resultats as $vote) {
if (!isset($this->votes[$vote['ce_proposition']])) {
$this->votes[$vote['ce_proposition']] = 0;
}
$valeur = ($vote['valeur'] == 1) ? 1 : -1;
$this->votes[$vote['ce_proposition']] += is_numeric($vote['ce_utilisateur']) ? 3 * $valeur : $valeur;
}
}
}
 
private function chargerPropositions() {
$idsObs = implode(',', $this->obsIds);
$requete = 'SELECT * '.
'FROM del_commentaire '.
"WHERE ce_observation IN ($idsObs) ".
'AND nom_sel IS NOT NULL '.
' -- '.__FILE__.' : '.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
 
foreach($resultats as $proposition) {
$id_proposition = $proposition['id_commentaire'];
$id_obs = $proposition['ce_observation'];
$proposition['valeur'] = (isset($this->votes[$id_proposition])) ? $this->votes[$id_proposition] : -1;
 
if (!isset($this->propositions[$id_obs])) {
$this->propositions[$id_obs] = $proposition;
} else {
$score_actuel = $proposition['valeur'];
$score_precedent = $this->propositions[$id_obs]['valeur'];
if ($score_actuel >= $score_precedent) {
$this->propositions[$id_obs] = $proposition;
}
}
}
}
 
private function completerMotsCles() {
$idsImages = implode(',', array_keys($this->indexImagesIds));
$requete = 'SELECT tag, ce_image '.
'FROM del_image_tag '.
"WHERE ce_image IN ($idsImages) ".
'AND actif = 1 '.
' -- '.__FILE__.' : '.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
 
foreach ($resultats as $info) {
$index = $this->indexImagesIds[$info['ce_image']];
$tag = ($this->resultats[$index]['mots_cles_image_del'] != '') ? ','.$info['tag'] : $info['tag'];
$this->resultats[$index]['mots_cles_image_del'] .= $tag ;
}
}
 
private function doitRemplacerObservationParProposition($index) {
$idObs = $this->resultats[$index]['id_observation'];
return ((isset($this->propositions[$idObs])
&& $this->propositions[$idObs] != null
&& $this->propositions[$idObs]['nom_sel_nn'] != 0)
&& ($this->propositions[$idObs]['valeur'] > 0 || $this->resultats[$index]['determination.nn'] == 0)
);
}
 
private function completerUrlFicheEflore($index) {
if (isset($this->resultats[$index]['determination.nn'])) {
$urlTpl = $this->conteneur->getParametre('determinations.url_fiche_eflore_tpl');
$nn = (int) $this->resultats[$index]['determination.nn'];
$ref = $this->resultats[$index]['determination.referentiel'];
$code_ref = $this->getCodeReferentiel($ref);
if (is_int($nn) && ! isset($code_ref)) {
$code_ref = 'bdtfx';
}
$this->resultats[$index]['url_fiche_eflore'] = sprintf($urlTpl, $code_ref, $nn);
}
}
 
private function getCodeReferentiel($ref) {
$code = $ref;
if ($position = strpos($ref, '_')) {
$code = substr($ref, 0, $position);
} else if ($position = strpos($ref, ':')) {
$code = substr($ref, 0, $position);
}
return $code;
}
}
Property changes:
Added: svnkit:entry:sha1-checksum
+474012b08dfb5d9bd5f4a18e3e5eeb6903cfb084
\ No newline at end of property
/tags/v1.10-sodium/services/modules/0.1/determinations/squelettes/validation_determination.tpl.txt
New file
0,0 → 1,16
IdentiPlante : un telabotaniste vous a aidé
 
Bonjour <?= $auteur_obs_fmt ?>,
Un telabotaniste vous a aidé.
 
<?= $validateur_fmt; ?> (<?= $lien_profil ?>) a validé la détermination proposée par le réseau
sur votre observation <?= $id_obs; ?> (<?= $lien_obs; ?>")
 
Pour savoir pourquoi ce telabotaniste a validé votre observation suivez ce lien : <?= $lien_wiki; ?>.
 
 
Si vous avez besoin d'un renseignement écrivez nous à identiplante_remarque@tela-botanica.org
 
Bonne continuation sur nos outils botaniques !
---------
L'équipe de Tela Botanica
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/tags/v1.10-sodium/services/modules/0.1/determinations/squelettes/validation_determination.tpl.html
New file
0,0 → 1,78
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
<!--
body {
font-family: Arial,Helvetica,Verdana,sans-serif;
font-size: 14px;
}
h1 > a {
color:#fd8c13;
}
.emphase {
color: #777777;
}
h3 {
font-size:14px;
color:#454341 !important;
margin:0px;
}
h3 > a {
color:#454341;
}
h1 a, h3 a, h4 a {
color: inherit;
border-bottom: dotted 1px;
}
h3 a {
border-color:#CCCCCC;
}
a {
cursor: pointer;
color:#598000;
text-decoration:none;
border-bottom:1px dotted #95ae5d;
}
a:hover {
color:#FD8C13;
border-bottom:1px dotted #95ae5d;
}
.lire-suite {
padding-left:10px;
background:url(http://www.tela-botanica.org/sites/commun/generique/images/graphisme/petit_carre.png) no-repeat 0px 4px;
}
.description_message {
color: #333333;
font-size: 1.1em;
font-style: italic;
padding-top: 10px;
}
-->
</style>
</head>
<body>
<div>
<h1><span class="emphase">IdentiPlante</span> : un telabotaniste vous a aid&eacute; </h1>
</div>
<div class="description_message">
Bonjour <?= $auteur_obs_fmt ?>,<br />
Un telabotaniste vous a aidé.
<br />
<br />
<a href="<?= $lien_profil ?>"><?= $validateur_fmt; ?></a> a validé la détermination proposée par le réseau sur votre observation <a href="<?= $lien_obs; ?>"><?= $id_obs; ?></a> .
<br />
Pour savoir pourquoi ce telabotaniste a validé votre observation cliquez ici : <a href="<?= $lien_wiki; ?>"><?= $lien_wiki; ?></a>.
<br />
</div>
<br />
<br />
Si vous avez besoin d'un renseignement écrivez nous à identiplante_remarque@tela-botanica.org
<br />
Bonne continuation sur nos outils botaniques !<br />
<div>---------</div>
L'&eacute;quipe de Tela Botanica<br />
<br/>
</body>
</html>
/tags/v1.10-sodium/services/modules/0.1/determinations/ValiderDetermination.php
New file
0,0 → 1,198
<?php
// declare(encoding='UTF-8');
/**
* Le web service récupére un identifiant de proposition et appelle un service web externe
* (du CEL) afin de modifier le nom de l'observation associée par celui de la proposition.
*
* @category DEL
* @package Services
* @subpackage Determinations
* @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 ValiderDetermination {
 
private $conteneur;
private $bdd;
private $idObs = null;
private $idProposition = null;
private $idAuteurObs = null;
private $idValidateurObs = null;
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->bdd = $this->conteneur->getBdd();
}
 
public function modifier($ressources, $parametres) {
$this->verifierParametres($ressources, $parametres);
$this->idProposition = $ressources[1];
$this->idValidateurObs = $this->validateurEstPresent($parametres) ? $parametres['validateur.id'] : $parametres['auteur.id'] ;
$retourCel = $this->modifierObservationParDetermination();
 
if (preg_match('/^(OK|Not Modified)$/i', $retourCel) == false) {
$msg = "Erreur: le web service du CEL a retourné : $retourCel";
$code = RestServeur::HTTP_CODE_ERREUR;
throw new Exception($msg, $code);
}
return 'OK';
}
 
private function validateurEstPresent($parametres) {
return isset($parametres['validateur.id']) && is_numeric($parametres['validateur.id']) && $parametres['validateur.id'] != 0;
}
 
private function verifierParametres($ressources, $parametres) {
$erreurs = array();
if (!is_numeric($ressources[1])) {
$erreurs[] = "La ressource indiquant l'identifiant de la proposition doit être numérique.";
}
 
// Le paramètre auteur.id (id de l'auteur de la détermination)
// est là pour éviter que le $_POST ne soit vide
if (!isset($parametres['auteur.id'])) {
$erreurs[] = "Le paramètre 'auteur.id' est manquant.";
}
// Le paramètre validateur.id (id de la personne validant la détemrinatiuon)
// est là pour éviter que le $_POST ne soit vide
if (isset($parametres['validateur.id']) && !is_numeric($parametres['validateur.id'])) {
$erreurs[] = "Le paramètre 'validateur.id' doit être un entier.";
}
 
if ($erreurs) {
$msg = "Erreur dans les paramètres d'appel au web service :\n\n" . implode("\n", $erreurs);
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
}
 
/**
* 1) récupère l'observation, autrement échec
* 2) récupère et l'id auteur de l'obs et vérifie qu'il correspond à l'id de l'utilisateur actuel
* 3) prépare les nouvelles valeurs à transférer au service CEL
* 4) effectue la mise à jour
* 5) si tout s'est passé comme convenu, marque la proposition comme "retenue"
*/
private function modifierObservationParDetermination() {
$propositionInfos = $this->getInfosProposition();
$this->idObs = $propositionInfos['ce_observation'];
$this->idAuteurObs = $this->getIdAuteurObs();
$this->verifierDroitUtilisateur();
 
$parametres = array(
'id_observation' => $this->idObs,
'nom_sel_nn' => $propositionInfos['nom_sel_nn'],
'nom_referentiel' => $propositionInfos['nom_referentiel']
);
 
$urlBase = $this->conteneur->getParametre('urlServiceCelObs');
$url = $urlBase.$this->idObs;
$retour = $this->conteneur->getRestClient()->modifier($url, $parametres);
 
// TODO: check sur HTTP code == 200, plutôt que sur texte
if ($retour == 'ok' || $retour == 'OK') {
$this->mettreAJourPropositionRetenue();
if($this->idAuteurObs != $this->idValidateurObs) {
$this->avertirAuteurObservation();
}
}
return $retour;
}
 
private function getInfosProposition() {
$idPropositionP = $this->bdd->proteger($this->idProposition);
$requete = "SELECT id_commentaire, ce_observation, nom_sel_nn, nom_referentiel ".
'FROM del_commentaire '.
"WHERE id_commentaire = $idPropositionP ".
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recuperer($requete);
if (! $resultat) {
throw new Exception("Cette proposition est invalide.", RestServeur::HTTP_CODE_ERREUR);
}
return $resultat;
}
 
private function getIdAuteurObs() {
$obsIdP = $this->bdd->proteger($this->idObs);
$requete = 'SELECT ce_utilisateur '.
'FROM del_observation '.
"WHERE id_observation = $obsIdP ".
' -- '.__FILE__.' : '.__LINE__;
$auteurInfo = $this->bdd->recuperer($requete);
return $auteurInfo['ce_utilisateur'];
}
private function getInfosObs() {
$obsIdP = $this->bdd->proteger($this->idObs);
$requete = 'SELECT * '.
'FROM del_observation '.
"WHERE id_observation = $obsIdP ".
' -- '.__FILE__.' : '.__LINE__;
$obsInfos = $this->bdd->recuperer($requete);
return $obsInfos;
}
 
private function verifierDroitUtilisateur() {
$gestionUtilisateur = $this->conteneur->getUtilisateur();
$utilisateurInfos = $gestionUtilisateur->getUtilisateur();
$utilisateurId = $utilisateurInfos['id_utilisateur'];
 
// si l'utilisateur connecté n'est ni auteur de l'observation, ni au moins administrateur de niveau 1
if (($this->idAuteurObs != $utilisateurId) && $utilisateurInfos['admin'] < 1) {
$msg = "Seul l'utilisateur ayant saisi l'observation, un administrateur ou un validateur peut la valider : veuillez vous identifier.\n";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
}
 
/**
* Remet à 0 le status "proposition_retenue" pour toutes les propositions faites sur cette
* observation à l'exception de celle désormais validée (qui voit son ce_validateur et sa date validation mise à jour)
*/
private function mettreAJourPropositionRetenue() {
$requete = 'UPDATE del_commentaire '.
"SET proposition_retenue = IF(id_commentaire = {$this->idProposition}, 1, 0), ".
"ce_validateur = IF(id_commentaire = {$this->idProposition}, {$this->idValidateurObs} , ce_validateur), ".
"date_validation = IF(id_commentaire = {$this->idProposition}, NOW() , date_validation) ".
"WHERE ce_observation = {$this->idObs} ".
' -- '.__FILE__.' : '.__LINE__;
 
return $this->bdd->requeter($requete);
}
private function avertirAuteurObservation() {
// le validateur est forcément celui qui est actuellement connecté
$gestionUtilisateur = $this->conteneur->getUtilisateur();
$utilisateurInfos = $gestionUtilisateur->getUtilisateur();
$infos_obs = $this->getInfosObs();
$donnees = array(
'auteur_obs_fmt' => $infos_obs['prenom_utilisateur'].' '.$infos_obs['nom_utilisateur'],
'validateur_fmt' => $utilisateurInfos['prenom']." ".$utilisateurInfos['nom'],
'lien_profil' => sprintf($this->conteneur->getParametre('message.lien_profil'), $this->idObs),
'id_obs' => $this->idObs,
'lien_obs' => sprintf($this->conteneur->getParametre('obs_fiche_tpl'), $this->idObs),
'lien_wiki' => $this->conteneur->getParametre('message.lien_wiki_validation')
);
$sujet = $this->conteneur->getParametre('message.titre_message_validation');
$squelettePhp = $this->conteneur->getSquelettePhp();
$squeletteHtml = dirname(__FILE__).DS.'squelettes'.DS.'validation_determination.tpl.html';
$corpsHtml = $squelettePhp->analyser($squeletteHtml, $donnees);
$squeletteTxt = dirname(__FILE__).DS.'squelettes'.DS.'validation_determination.tpl.txt';
$corpsTxt = $squelettePhp->analyser($squeletteTxt, $donnees);
$messagerie = $this->conteneur->getMessagerie();
$messagerie->envoyerHtml($infos_obs['courriel_utilisateur'],
$sujet,
$corpsHtml,
$corpsTxt);
}
}
/tags/v1.10-sodium/services/modules/0.1/Ontologie.php
New file
0,0 → 1,89
<?php
// declare(encoding='UTF-8');
/**
* Classe de récupération d'ontologies diverses
*
* @category DEL
* @package Services
* @subpackage Ontologies
* @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 Ontologie extends RestService {
 
private $parametres = array();
private $ressources = array();
private $methode = null;
private $serviceNom = 'ontologie';
 
private $conteneur;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->conteneur = new Conteneur($parametres);
if(!isset($ressources[0])) {
$message = "Le nom de l'ontologie doit être renseigné ".
"Les ontologies disponibles sont : \n".
" - en GET : pays \n";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
} else {
$fonction = 'get'.ucwords($ressources[0]);
if(method_exists($this, $fonction)) {
$resultat = $this->$fonction();
$reponseHttp = new ReponseHttp();
$reponseHttp->setResultatService($resultat);
$reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
} else {
$message = "L'ontologie demandée n'existe pas ".
"Les ontologies disponibles sont : \n".
" - en GET : pays \n";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
}
}
public function getPays() {
$url = $this->conteneur->getParametre('url_service_base_eflore')."iso-3166-1/zone-geo?masque.statut=officiellement%20attribu%C3%A9&navigation.limite=1000";
$restClient = $this->conteneur->getRestClient();
$resultatJson = $restClient->consulter($url);
$liste_pays = json_decode($resultatJson, true);
 
$pays_fmt = array();
foreach($liste_pays['resultat'] as $pays) {
// Les pays renvoyé par le web service sont tous en majuscule
$nom = mb_convert_case($pays['nom'], MB_CASE_TITLE, 'UTF-8');
$pays_fmt[] = array('code_iso_3166_1' => $pays['code'], 'nom_fr' => $nom);
}
// Tri par nom plutot que par code
usort($pays_fmt, array($this, "trierPays"));
$resultat = new ResultatService();
$resultat->corps = $pays_fmt;
return $resultat;
}
protected function trierPays($a, $b) {
return strcmp($a['nom_fr'], $b['nom_fr']);
}
}
?>
/tags/v1.10-sodium/services/modules/0.1/plantnet/Changements.php
New file
0,0 → 1,307
<?php
/**
* Le web service plantnet récupère toutes les infos de la vue del_plantnet.
* Ordonées par date de modification.
* Les images sont regroupées en observations.
* Les tags, les votes et les propositions de determinations sont intégrés à l'observation.
*
* @category DEL
* @package Services
* @subpackage Plantnet
* @version 0.1
* @author Mathias CHOUET <mathias@tela-botanica.org>
* @author Samuel DUFOUR-KOWALSKI <samuel.dufour@cirad.fr>
* @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 Changements {
 
private $conteneur;
private $navigation;
private $bdd;
 
private $parametres = array();
private $ressources = array();
private $date_defaut = '1900-01-01';
private $idsObsImg = array();
private $infosObsImg = array();
 
 
public function __construct(Conteneur $conteneur = null) {
/* restore_exception_handler(); */
/* restore_error_handler(); */
/* ini_set("display_errors", "1"); */
 
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->navigation = $conteneur->getNavigation();
$this->bdd = $this->conteneur->getBdd();
}
 
/**
* Méthode principale de la classe.
* Lance la récupération des images dans la base et les place dans un objet ResultatService
* pour l'afficher.
* @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
* @param array $parametres les paramètres situés après le ? dans l'url
* */
public function consulter($ressources, $parametres) {
// initialiserRessourcesEtParametres()
$this->ressources = $ressources;
$this->parametres = $parametres;
 
if (!isset($parametres['date'])) {
$this->parametres['date'] = $this->date_defaut;
}
 
// Lancement du service
$this->idsObsImg = $this->getIdsObsImg();
$infos = array();
$total = 0;
if ($this->idsObsImg) {
$total = $this->getTotal();
 
$this->infosObsImg = $this->recupererInfos();
$infos = $this->formaterInfos();
$infos = $this->chargerPropositionPlusProbable($infos);
$infos = $this->orderArray($infos);
}
$this->navigation->setTotal($total);
 
// Mettre en forme le résultat et l'envoyer pour affichage
$resultat = new ResultatService();
$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => $infos);
return $resultat;
}
 
/*-------------------------------------------------------------------------------
CHARGEMENT DES IMAGES
--------------------------------------------------------------------------------*/
 
private function getIdsObsImg() {
$date_debut = "'{$this->parametres['date']}'";
$limite = @min(intval($this->parametres['navigation.limite']), 1000);
$limite = $limite ? $limite : 10; // 0 => 10
$depart = intval(@$this->parametres['navigation.depart']);
 
$requete =
'SELECT SQL_CALC_FOUND_ROWS p.id_observation, p.id_image, '.
'GROUP_CONCAT(iv.valeur) AS votes, '.
'GROUP_CONCAT(DISTINCT tag) AS tags, '.
'GREATEST('.
' IFNULL(p.date_creation, \''.$this->date_defaut.'\'), '.
' IFNULL(p.date_modification, \''.$this->date_defaut.'\'), '.
' IFNULL(MAX(it.date), \''.$this->date_defaut.'\'), '.
' IFNULL(MAX(it.date_modification), \''.$this->date_defaut.'\'), '.
' IFNULL(MAX(iv.date), \''.$this->date_defaut.'\'), '.
' IFNULL(MAX(c.date), \''.$this->date_defaut.'\'), '.
' IFNULL(MAX(cv.date), \''.$this->date_defaut.'\')) AS modif_date '.
 
'FROM del_plantnet AS p '.
' LEFT JOIN del_image_vote AS iv '.
' ON (id_image = iv.ce_image AND iv.ce_protocole = 3) '.
' LEFT JOIN del_image_tag AS it '.
' ON (id_image = it.ce_image AND it.actif = 1) '.
' LEFT JOIN del_commentaire AS c '.
' ON (id_observation = c.ce_observation) '.
' LEFT JOIN del_commentaire_vote AS cv '.
' ON (c.id_commentaire = cv.ce_proposition) '.
'GROUP BY id_image, id_observation '.
'HAVING MAX(p.date_creation) >= '.$date_debut.' '.
' OR MAX(p.date_modification) >= '.$date_debut.' '.
' OR MAX(it.date) >= '.$date_debut.' '.
' OR MAX(it.date_modification) >= '.$date_debut.' '.
' OR MAX(iv.date) >= '.$date_debut.' '.
' OR MAX(c.date) >= '.$date_debut.' '.
' OR MAX(cv.date) >= '.$date_debut.' '.
'ORDER BY modif_date DESC '.
'LIMIT '.$depart.', '.$limite.
' -- '.__FILE__.':'.__LINE__;
//echo $requete; exit;
// GROUP BY (très couteux) car multiples observations associées à une image
// charlie est ici :-)
// eg: 16150,16185,16245,16246,118995,129989
return $this->bdd->recupererTous($requete);
}
 
private function getTotal() {
$compte = $this->bdd->recuperer('SELECT FOUND_ROWS() AS nbre');
$total = (int) $compte['nbre'];
return $total;
}
 
// recupere les donnée associées (fait en 2 requetes pour optimiser)
private function recupererInfos() {
// recuperer les ids
$idsImg = array();
foreach ($this->idsObsImg as $ids) {
$id = $ids['id_image'];
$idsImg[] = $id;
}
$idsImgConcat = implode(',', $idsImg);
 
$requete = 'SELECT '.
'id_observation, id_image, '.
'nom_sel, '.
'nom_referentiel, nom_ret, nom_ret_nn, nt, famille, '.
'zone_geo, latitude, longitude, '.
'date_observation, date_creation, date_transmission, '.
'mots_cles_texte, '.
'ce_utilisateur, prenom_utilisateur, nom_utilisateur, courriel_utilisateur, '.
'i_mots_cles_texte AS mots_cles_texte_image, nom_original AS nom_image '.
'FROM del_plantnet AS p '.
"WHERE id_image IN ($idsImgConcat) ".
' -- '.__FILE__.':'.__LINE__;
// recuperer les donnees
$resultats = $this->bdd->recupererTous($requete);
 
// regroupe les données par id_image
$img_data = array();
foreach ($resultats as $infos) {
$idImg = $infos['id_image'];
$img_data[$idImg] = $infos;
}
return $img_data;
}
 
/**
* Retourner un tableau d'images formaté en fonction des liaisons trouvées
* @param $liaisons les liaisons de la table del_obs_images
*/
private function formaterInfos() {
// regroupe les observations
$obs = array();
$imgCelTpl = $this->conteneur->getParametre('cel_img_url_tpl');
foreach ($this->idsObsImg as $ids) {
$idobs = $ids['id_observation'];
$idimg = $ids['id_image'];
 
$imgdata = $this->infosObsImg[$idimg];
 
if (!isset($obs[$idobs])) {
$obs[$idobs] = array();
}
 
$obs[$idobs]['id_observation'] = $idobs;
$obs[$idobs]['auteur_id'] = $imgdata['ce_utilisateur'];
$obs[$idobs]['auteur_prenom'] = $imgdata['prenom_utilisateur'];
$obs[$idobs]['auteur_nom'] = $imgdata['nom_utilisateur'];
$obs[$idobs]['auteur_courriel'] = $imgdata['courriel_utilisateur'];
 
$obs[$idobs]['mots_cles_obs_cel'] = $this->formaterMotsClesCel($imgdata['mots_cles_texte']);
 
$obs[$idobs]['date_observation'] = $imgdata['date_observation'];
$obs[$idobs]['date_publication'] = $imgdata['date_transmission'];
$obs[$idobs]['date_creation'] = $imgdata['date_creation'];
$obs[$idobs]['date_changement'] = $ids['modif_date'];
 
$obs[$idobs]['nom_sel'] = $imgdata['nom_sel'];
$obs[$idobs]['nom_referentiel'] = $imgdata['nom_referentiel'];
$obs[$idobs]['nom_ret'] = $imgdata['nom_ret'];
$obs[$idobs]['nn'] = $imgdata['nom_ret_nn'];
$obs[$idobs]['nt'] = $imgdata['nt'];
$obs[$idobs]['famille'] = $imgdata['famille'];
 
$obs[$idobs]['zone_geo'] = $imgdata['zone_geo'];
$obs[$idobs]['latitude'] = floatval($imgdata['latitude']);
$obs[$idobs]['longitude'] = floatval($imgdata['longitude']);
 
if (!isset($obs[$idobs]['images'])) {
$obs[$idobs]['images'] = array();
}
 
$img_obj = array(
'id_image' => $idimg,
'nom_image' => $imgdata['nom_image'],
'url' => sprintf($imgCelTpl, $idimg, 'O'),
'votes' => array_map('intval', explode(',', $ids['votes'])),
'tags' => explode(',', $ids['tags']),
'mots_cles_img_cel' => $this->formaterMotsClesCel($imgdata['mots_cles_texte_image'])
);
// push
$obs[$idobs]['images'][] = $img_obj;
}
return $obs;
}
 
/**
* Charger les votes pour chaque image
*/
private function chargerPropositionPlusProbable(&$obs) {
$obsIds = array_keys($obs);
$idsObsConcat = implode(',', $obsIds);
 
$requete = 'SELECT ce_observation, id_commentaire, valeur, nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, cv.ce_utilisateur '.
'FROM del_commentaire_vote AS cv, del_commentaire AS c '.
"WHERE ce_observation IN ($idsObsConcat) ".
'AND nom_sel IS NOT NULL '.
'AND c.id_commentaire = cv.ce_proposition '.
' -- '.__FILE__.':'.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
 
// calcul des votes
// un vote identifié a un facteur de 3
// additionne tous les vote par ce_proposition
$votes = array(); // map ce_proposition -> score
foreach ($resultats as $vote) {
if (!isset($votes[$vote['id_commentaire']])) {
$votes[$vote['id_commentaire']] = 0;
}
$valeur = ($vote['valeur'] == 1) ? 1 : -1;
$votes[$vote['id_commentaire']] += is_numeric($vote['ce_utilisateur']) ? 3 * $valeur : $valeur;
}
 
foreach ($resultats as $vote) {
$idobs = $vote['ce_observation'];
 
if (!isset($obs[$idobs]['determinations'])) {
$obs[$idobs]['determinations'] = array();
}
 
$obs[$idobs]['determinations'][$vote['id_commentaire']] =
array('nom_sel' => $vote['nom_sel'],
'nom_ret' => $vote['nom_ret'],
'score' => $votes[$vote['id_commentaire']],
'nn' => $vote['nom_sel_nn']);
}
return $obs;
}
 
private function orderArray(&$obs) {
$ret = array();
foreach ($obs as $o) {
$ret[] = $o;
}
 
function cmp($a, $b) {
return ($a['date_changement'] < $b['date_changement']) ? 1 : -1;
}
 
usort($ret, 'cmp');
return $ret;
}
 
/**
* Formater les mots clés du cel en n'affichant que ceux faisant partie
* d'une liste définie dans le fichier de configuration
* @param $chaineMotCleCel la chaine de mots clés du cel
* @return string la chaine filtrée
*/
private function formaterMotsClesCel($chaineMotCleCel) {
$mots_cles_cel_affiches = "fleur,fleurs,feuille,feuilles,ecorce,fruit,fruits,port,plantnet,plantscan_new,plantnet-mobile";
 
$result = array_intersect(
explode(',', $mots_cles_cel_affiches), // $tabMotsClesAffiches
explode(',', $chaineMotCleCel)); // $tabMotsClesCel
 
if (count($result) === 0) {
return array();
}
$ret = explode(',', implode(',', $result));
return $ret;
}
 
}
Property changes:
Added: svnkit:entry:sha1-checksum
+688f54846ca97b444ba8c783a83a3fc869a30bf3
\ No newline at end of property
/tags/v1.10-sodium/services/modules/0.1/communes/ListeCommunes.php
New file
0,0 → 1,50
<?php
// declare(encoding='UTF-8');
/**
* Web service fournissant une liste de noms de communes correspondants au terme recherché.
*
* @category DEL
* @package Services
* @subpackage Communes
* @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 ListeCommunes {
 
private $conteneur;
private $navigation;
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->navigation = $conteneur->getNavigation();
}
 
public function consulter() {
$communes = $this->chargerCommunes();
$total = $this->compterCommunes($communes);
$this->navigation->setTotal($total);
$this->navigation->setSansLimite();
 
$resultat = new ResultatService();
$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => $communes);
return $resultat;
}
 
private function chargerCommunes() {
$urlCelTpl = $this->conteneur->getParametre('urlServiceCelCommune');
$url = $urlCelTpl.$this->navigation->getFiltre('masque.nom');
$restClient = $this->conteneur->getRestClient();
$resultatJson = $restClient->consulter($url);
$resultat = json_decode($resultatJson);
return $resultat;
}
 
private function compterCommunes($communes) {
return count($communes);
}
}
/tags/v1.10-sodium/services/modules/0.1/commentaires/ListeCommentaires.php
New file
0,0 → 1,108
<?php
// declare(encoding='UTF-8');
/**
* Retourne la liste commentaires correspondant aux filtres passés dans l'url :
* http://localhost/del/services/0.1/commentaires => liste tous les commentaires
* Filtres : voir le fichier de config : commentaires.masques_possibles
*
* @category DEL
* @package Services
* @subpackage Commentaires
* @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 ListeCommentaires {
 
private $conteneur;
private $navigation;
private $bdd;
 
private $mapping = array();
private $mappingInverse = array();
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = ($conteneur == null) ? new Conteneur() : $conteneur;
$this->navigation = $this->conteneur->getNavigation();
$this->bdd = $this->conteneur->getBdd();
 
$this->mapping = $this->conteneur->getParametreTableau('commentaires.mapping');
$this->mappingInverse = array_flip($this->mapping);
}
 
/**
* Méthode principale de la classe.
* Lance la récupération des images dans la base et les place dans un objet ResultatService
* pour l'afficher.
* @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
* @param array $parametres les paramètres situés après le ? dans l'url
* */
public function consulter($ressources) {
// Lancement du service
$commentaires = $this->chargerCommentaires();
$total = $this->compterCommentairesTotal();
 
$commentaires = $this->formaterCommentaires($commentaires);
$this->navigation->setTotal($total);
 
$resultat = new ResultatService();
$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => $commentaires);
return $resultat;
}
 
/**
* Chargement depuis la bdd de tous les commentaires
* */
private function chargerCommentaires() {
$requete = 'SELECT DISTINCT SQL_CALC_FOUND_ROWS * '.
'FROM del_commentaire '.
'WHERE '.$this->creerClauseWhere().' '.
'LIMIT '.$this->navigation->getDepart().','.$this->navigation->getLimite().' '.
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recupererTous($requete);
return is_array($resultat) ? $resultat : array();
}
 
private function creerClauseWhere() {
$where = array();
$filtres = $this->navigation->getFiltre();
if (!empty($filtres)) {
foreach ($filtres as $cle => $valeur) {
$where[] = $this->mappingInverse[$cle].' = '.$this->bdd->proteger($valeur);
}
}
$clauseWhere = (!empty($where)) ? ' '.implode(' AND ', $where).' ' : ' 1 ';
return $clauseWhere;
}
 
/**
* Compter le nombre total de commentaires dans la base vis à vis des filtres de l'url.
* Utilisation du mécanisme SQL_CALC_FOUND_ROW de Mysql pour éviter une deuxième requete avec un COUNT.
*/
private function compterCommentairesTotal() {
$requete = 'SELECT FOUND_ROWS() AS nbre ';
$resultats = $this->bdd->recuperer($requete);
return (int) $resultats['nbre'];
}
 
/**
* Formater les commentaires
* @param $commentaires les commentaires à mettre à jour
* @return $commentaires les commentaires mis à jour
* */
private function formaterCommentaires($commentaires) {
$retour = array();
foreach ($commentaires as $idCommentaire => $infos) {
$idCommentaire = $infos['id_commentaire'];
foreach ($this->mapping as $nomChampBdd => $nomAttributSortie) {
$retour[$idCommentaire][$nomAttributSortie] = $infos[$nomChampBdd];
}
}
return $retour;
}
}
/tags/v1.10-sodium/services/modules/0.1/commentaires/CommentaireDetails.php
New file
0,0 → 1,68
<?php
// declare(encoding='UTF-8');
/**
* Retourne le contenu d'un commentaire pour un identifiant donné.
* http://localhost/service:del:0.1/commentaires/#id => retourne le contenu d'un commentaire d'id #id
*
* @category DEL
* @package Services
* @subpackage Commentaires
* @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 CommentaireDetails {
 
private $conteneur;
private $bdd;
private $idCommentaire;
 
private $mapping = array();
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->bdd = $this->conteneur->getBdd();
 
$this->mapping = $this->conteneur->getParametreTableau('commentaires.mapping');
}
 
public function consulter($ressources) {
$this->idCommentaire = $ressources[0];
 
// Lancement du service
$commentaire = $this->chargerCommentaire();
$commentaire = $this->formaterCommentaires($commentaire);
 
// Mettre en forme le résultat et l'envoyer pour affichage*/
$resultat = new ResultatService();
$resultat->corps = $commentaire;
 
return $resultat;
}
 
private function chargerCommentaire() {
$requete = 'SELECT * '.
'FROM del_commentaire '.
'WHERE id_commentaire = '.$this->idCommentaire.' '.
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recuperer($requete);
if ($resultat === false) {
$message = "Aucune information ne correspond au commentaire # «{$this->idCommentaire}».";
throw new Exception($message, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
return is_array($resultat) ? $resultat : array();
}
 
private function formaterCommentaires($infos) {
$retour = array();
foreach ($this->mapping as $nomChampBdd => $nomAttributSortie) {
$retour[$nomAttributSortie] = $infos[$nomChampBdd];
}
return $retour;
}
}
/tags/v1.10-sodium/services/modules/0.1/commentaires/SupprimerCommentaire.php
New file
0,0 → 1,134
<?php
// declare(encoding='UTF-8');
/**
* Permet de supprimer un commentaire.
*
* @category DEL
* @package Services
* @subpackage Commentaires
* @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 SupprimerCommentaire {
 
private $conteneur;
private $navigation;
private $bdd;
private $utilisateur;
 
private $commentaireId;
private $utilisateurId;
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->navigation = $conteneur->getNavigation();
$this->bdd = $this->conteneur->getBdd();
$this->utilisateur = $this->conteneur->getUtilisateur();
}
 
public function supprimer($ressources) {
$this->commentaireId = $ressources[0];
 
$utilisateur = $this->utilisateur->getUtilisateurIdentifie();
$this->verifierIdentificationUtilisateur($utilisateur);
$this->utilisateurId = $utilisateur['id_utilisateur'];
 
// la suppression est autorisée pour le propriétaire et l'admin sur un commentaire ou une proposition
// qui n'a jamais été commentée en retour
if ($this->etreCommentaireSansEnfant() && $this->etreUtilisateurAutorise() &&
$this->nePasEtreDeterminationInitiale()) {
$this->supprimerCommentaire();
$this->supprimerVotesAssocies();
}
 
$resultat = new ResultatService();
return $resultat;
}
 
private function verifierIdentificationUtilisateur($utilisateur) {
if ($utilisateur == null) {
$msg = "Ce service nécessite d'être identifié.";
throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
}
private function nePasEtreDeterminationInitiale() {
$idCommentaireP = $this->bdd->proteger($this->commentaireId);
$requete = 'SELECT * '.
'FROM del_commentaire '.
"WHERE id_commentaire = $idCommentaireP ".
"AND (proposition_initiale = 1 OR proposition_retenue = 1) ".
' -- '.__FILE__.' : '.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
if (!empty($resultats)) {
$msg = "Impossible de supprimer la proposition initiale ou la proposition retenue.";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
return true;
}
 
private function etreCommentaireSansEnfant() {
$idCommentaireP = $this->bdd->proteger($this->commentaireId);
$requete = 'SELECT * '.
'FROM del_commentaire '.
"WHERE (ce_proposition = $idCommentaireP ".
"OR ce_commentaire_parent = $idCommentaireP) ".
' -- '.__FILE__.' : '.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
if (!empty($resultats)) {
$msg = "Impossible de supprimer le commentaire car il a des réponses.";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
return true;
}
 
private function etreUtilisateurAutorise() {
if (! $this->etreProprietaire() && ! $this->utilisateur->etreAdmin()) {
$msg = "Impossible de supprimer le commentaire car l'utilisateur n'a pas les droits requis.";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
return true;
}
 
private function etreProprietaire() {
$requete = 'SELECT * '.
'FROM del_commentaire '.
"WHERE id_commentaire = {$this->commentaireId} ".
"AND ce_utilisateur = {$this->utilisateurId} ".
' -- '.__FILE__.' : '.__LINE__;
$resultats = $this->bdd->recupererTous($requete);
return !empty($resultats);
}
 
private function supprimerCommentaire() {
$commentaireIdP = $this->bdd->proteger($this->commentaireId);
$utilisateurIdP = $this->bdd->proteger($this->utilisateurId);
$requete = 'DELETE FROM del_commentaire '.
"WHERE id_commentaire = $commentaireIdP ".
"AND ce_utilisateur = $utilisateurIdP ".
' -- '.__FILE__.' : '.__LINE__;
$retour = $this->bdd->requeter($requete);
if (!$retour) {
$msg = 'Erreur lors de la suppression.';
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
}
 
private function supprimerVotesAssocies() {
$commentaireId = $this->bdd->proteger($this->commentaireId);
$requete = 'DELETE FROM del_commentaire_vote '.
"WHERE ce_proposition = $commentaireId ".
' -- '.__FILE__.' : '.__LINE__;
$retour = $this->bdd->requeter($requete);
if (!$retour) {
$msg = 'Erreur lors de la suppression des votes associés.';
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
}
}
/tags/v1.10-sodium/services/modules/0.1/commentaires/AjouterCommentaire.php
New file
0,0 → 1,243
<?php
// declare(encoding='UTF-8');
/**
* Permet d'ajouter un commentaire.
*
* @category DEL
* @package Services
* @subpackage Commentaires
* @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 AjouterCommentaire {
 
private $conteneur;
private $navigation;
private $bdd;
private $parametres = array();
 
private $mapping = array();
private $erreurs = array();
 
public function __construct(Conteneur $conteneur) {
$this->conteneur = $conteneur;
$this->navigation = $this->conteneur->getNavigation();
$this->bdd = $this->conteneur->getBdd();
 
$this->mapping = $this->conteneur->getParametreTableau('commentaires.mapping');
}
 
public function ajouter($parametres) {
$this->parametres = $parametres;
$this->verifierParametres();
 
$this->completerParametresUtilisateur();
$this->gererPropositionInitiale();
// Dernière chance de rattachement au référentiel d'un nom
// sans nn (cas du copier-coller ou bien de l'appli tierce
// qui envoie des infos incomplètes)
$this->tenterEnrichissementTaxonomique();
$idCommentaireAjoute = $this->insererCommentaire();
 
// Mettre en forme le résultat et l'envoyer pour affichage
$resultat = new ResultatService();
$resultat->corps = array('id_commentaire' => $idCommentaireAjoute);
 
return $resultat;
}
 
private function verifierParametres() {
if (!isset($this->parametres['observation'])) {
$this->erreurs[] = "Impossible d'ajouter un commentaire sans identifiant d'observation (paramètre 'observation').";
}
 
if (!isset($this->parametres['auteur.id'])) {
$this->verifierParamsAuteurAnonyme();
}
 
$this->verifierParamsNonVide();
 
if (isset($this->parametres['nom_sel_nn']) && !isset($this->parametres['nom_referentiel'])) {
$this->erreurs[] = "Si le paramètre «nom_sel_nn» est présent, le paramètre «nom_referentiel» doit l'être aussi.";
}
 
if (!empty($this->erreurs)) {
$msg = "Erreur de configuration :\n".implode("\n\n", $this->erreurs);
throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
}
 
private function verifierParamsAuteurAnonyme() {
$paramsAuteur = array('auteur.nom', 'auteur.prenom', 'auteur.courriel');
$paramsAuteurManquant = array();
foreach ($paramsAuteur as $param) {
if (!isset($this->parametres[$param])) {
$paramsAuteurManquant[] = $param;
}
}
 
if (!empty($paramsAuteurManquant)) {
$msgAuteurTpl = "Si le parametre 'auteur.id' n'est pas utilisé, il est nécessaire d'indiquer les ".
"nom (paramètre 'auteur.nom'), prénom (paramètre 'auteur.prenom') et courriel ".
"(paramètre 'auteur.courriel') de l'auteur.\nLes paramètres suivant sont abscents : %s\n";
$this->erreurs[] = sprintf($msgAuteurTpl, implode(', ', $paramsAuteurManquant));
}
}
 
private function verifierParamsNonVide() {
$paramsNonVide = array('nom_sel', 'nom_referentiel', 'nom_sel_nn');
foreach ($paramsNonVide as $param) {
if (isset($this->parametres[$param]) && trim($this->parametres[$param]) == '' ) {
$this->erreurs[] = "S'il est présent le paramètre «$param» ne peut pas être vide.";
}
}
}
 
private function completerParametresUtilisateur() {
$utilisateur = (isset($this->parametres['auteur.id'])) ? $this->obtenirUtilisateurAvecId() : $this->obtenirUtilisateurSansId();
if ($utilisateur !== false) {
foreach ($utilisateur as $param => $valeur) {
$this->parametres[$param] = $valeur;
}
}
}
 
private function obtenirUtilisateurAvecId() {
$auteurIdP = $this->bdd->proteger($this->parametres['auteur.id']);
$requete = "SELECT id_utilisateur AS 'auteur.id', nom AS 'auteur.nom', prenom AS 'auteur.prenom', courriel AS 'auteur.courriel' ".
'FROM del_utilisateur '.
"WHERE id_utilisateur = $auteurIdP ".
' -- '.__FILE__.' : '.__LINE__;
$utilisateur = $this->bdd->recuperer($requete);
return $utilisateur;
}
 
private function obtenirUtilisateurSansId() {
$nomP = $this->bdd->proteger($this->parametres['auteur.nom']);
$prenomP = $this->bdd->proteger($this->parametres['auteur.prenom']);
$courrielP = $this->bdd->proteger($this->parametres['auteur.courriel']);
 
$requete = "SELECT id_utilisateur AS 'auteur.id', nom AS 'auteur.nom', prenom AS 'auteur.prenom', ".
"courriel AS 'auteur.courriel' ".
'FROM del_utilisateur '.
"WHERE courriel = $courrielP AND nom = $nomP AND prenom = $prenomP ".
' -- '.__FILE__.' : '.__LINE__;
$utilisateur = $this->bdd->recuperer($requete);
return $utilisateur;
}
 
private function gererPropositionInitiale() {
if ($this->verifierExistencePropositionInitiale() === false) {
$this->creerPropositionInitiale();
// TODO : en cas d'échec de la création de la proposition ajouter un log...
}
}
 
private function verifierExistencePropositionInitiale() {
$idObsP = $this->bdd->proteger($this->parametres['observation']);
$requete = 'SELECT COUNT(*) >= 1 AS existe '.
'FROM del_commentaire '.
"WHERE ce_observation = $idObsP ".
' AND proposition_initiale = 1 '.
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recuperer($requete);
return $resultat['existe'] == 1;
}
 
private function creerPropositionInitiale() {
$idObsP = $this->bdd->proteger($this->parametres['observation']);
$requete = 'INSERT IGNORE INTO del_commentaire '.
'(ce_observation, ce_utilisateur, utilisateur_prenom, utilisateur_nom, utilisateur_courriel, '.
'nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, nt, famille, nom_referentiel, date, proposition_initiale) '.
'SELECT id_observation, ce_utilisateur, prenom, nom, courriel, nom_sel, '.
"IF(nom_sel_nn = 0, NULL, nom_sel_nn), IF(nom_ret = '', NULL, nom_ret), IF(nom_ret_nn = 0, NULL, nom_ret_nn), ".
"IF(nt = 0, NULL, nt), IF(famille = '', NULL, famille), IF(nom_sel_nn = 0, NULL, nom_referentiel), NOW(), '1' ".
'FROM del_observation AS do '.
' LEFT JOIN del_utilisateur AS du '.
' ON do.ce_utilisateur = du.id_utilisateur '.
"WHERE id_observation = $idObsP ".
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->executer($requete);
return $resultat;
}
 
private function insererCommentaire() {
$champs = $this->creerEnteteChamps();
$values = $this->creerClauseValues();
$requete = "INSERT INTO del_commentaire (date, $champs) VALUES (NOW(), $values) ".
' -- '.__FILE__.' : '.__LINE__;
 
$retour = $this->bdd->executer($requete);
if ($retour == null) {
$msgTpl = "Erreur inopinée lors de l'insertion du commentaire lié à l'observation «%s».";
$msg = sprintf($msgTpl, $this->parametres['observation']);
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
 
$idCommentaire = $this->bdd->recupererIdDernierAjout();
return $idCommentaire;
}
 
private function creerEnteteChamps() {
return $this->creerSuiteChampsOuValeurs('champs');
}
 
private function creerClauseValues() {
return $this->creerSuiteChampsOuValeurs('valeurs');
}
 
private function creerSuiteChampsOuValeurs($mode) {
$suite = array();
foreach ($this->mapping as $nomChampBdd => $nomAttributSortie) {
if (isset($this->parametres[$nomAttributSortie]) && $this->parametres[$nomAttributSortie] != null) {
if ($mode == 'valeurs') {
$suite[] = $this->bdd->proteger($this->parametres[$nomAttributSortie]);
} else if ($mode == 'champs') {
$suite[] = $nomChampBdd;
} else {
$msg = "Erreur interne : mauvais paramètre passé à la méthode 'creerSuiteChampsOuValeurs'";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
}
}
return implode(', ', $suite);
}
private function tenterEnrichissementTaxonomique() {
if($this->commentaireEstPropositionSansNn()) {
// TODO: utiliser le référentiel de l'obs si celui-ci
// n'est pas fourni dans le commentaire et prendre le résultat
// si celui-ci est unique
$referentiel = $this->parametres['nom_referentiel'];
$requete = urlencode($this->parametres['nom_sel']);
$url = sprintf($this->conteneur->getParametre('nomstaxons.url_autocompletion_tpl'), $referentiel, $requete);
$restClient = $this->conteneur->getRestClient();
// Un retour vide est possible (un cas normal où il n'y a pas de résultat)
// mais il fait planter le retour du service si on active l'affichage des erreurs
// donc on passe sciemment les erreurs sous silence (car cette erreur n'en est pas une)
$resultatJson = @$restClient->consulter($url);
$resultats = json_decode($resultatJson, true);
 
// On ne fait l'affectation que si l'on est sur (donc si un seul résultat)
if (isset($resultats['resultat']) && count($resultats['resultat']) == 1) {
$info = array_pop($resultats['resultat']);
$this->parametres['nom_sel_nn'] = $info['num_nom'];
}
}
}
private function commentaireEstPropositionSansNn() {
// Pas besoin de tester si c'est vide, normalement verifierParametres
// l'a déjà fait au-dessus
return isset($this->parametres['nom_sel'])
&& isset($this->parametres['nom_referentiel'])
&& !isset($this->parametres['nom_sel_nn']);
}
}
/tags/v1.10-sodium/services/modules/0.1/Statistiques.php
New file
0,0 → 1,135
<?php
// declare(encoding='UTF-8');
/**
* Accès aux sous-services de statistiques pour Identiplante / Pictoflora
*
* @see Documentation : <http://www.tela-botanica.org/wikini/DevInformatiques/wakka.php?wiki=AppliDelStats>
*
* @category DEL
* @package Services
* @subpackage Statistiques
* @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 Statistiques extends RestService {
 
private $parametres = array();
private $ressources = array();
private $methode = null;
private $serviceNom = 'statistiques';
private $sousServiceNom = null;
private $cheminCourant = null;
 
private $conteneur;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->initialiserRessourcesEtParametres($ressources, $parametres);
return $this->executerService();
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres = array()) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function executerService() {
$reponseHttp = new ReponseHttp();
try {
$this->conteneur = new Conteneur($this->parametres);
$resultat = $this->traiterRessources();
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
$reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
}
 
private function traiterRessources() {
$this->analyserRessources();
$retour = $this->initialiserService();
return $retour;
}
 
private function analyserRessources() {
if ($this->methode == 'consulter') {
$this->sousServiceNom = 'statistiques-par-annee';
}
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function lancerMessageErreurRessource() {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "La ressource demandée '$ressource' ".
"n'est pas disponible pour le service {$this->serviceNom} !\n".
self::getDoc();
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
public static function getDoc() {
return "Les URLs disponibles pour ce service sont :\n".
" * en GET :\n".
" - statistiques/tout\n".
" - statistiques/moyenneObsSansNomParMois\n".
" - statistiques/moyenneObsIdentifieesParMois\n".
" - statistiques/pourcentageObsIdentifieesEnFinDAnnee\n".
" - statistiques/pourcentageObsIdentifieesEnFinDAnneePlusPlus\n".
" - statistiques/moyenneActionsParJour\n".
" - statistiques/personnesEnvoyantUnePropositionParMois\n";
}
 
private function initialiserService() {
$classe = $this->obtenirNomClasseService($this->sousServiceNom);
$chemins = array();
$chemins[] = $this->cheminCourant.$this->serviceNom.DS.$classe.'.php';
$chemins[] = $this->cheminCourant.'commun'.DS.$classe.'.php';
$retour = '';
$service = null;
 
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
if ($this->methode == 'consulter') {
$retour = $service->consulter();
} else {
$message = "Le sous-service '{$this->sousServiceNom}' du service '{$this->serviceNom}' ".
"ne possède pas de méthode '{$this->methode}' !";
$code = RestServeur::HTTP_NON_IMPLEMENTE;
throw new Exception($message, $code);
}
}
}
 
if (is_null($service)) {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "Le classe '$classe' correspondant à la ressource '$ressource' ".
"est introuvable par le service '{$this->serviceNom}' !";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $retour;
}
 
private function obtenirNomClasseService($mot) {
$classeNom = str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
}
/tags/v1.10-sodium/services/modules/0.1/mots_cles/AjouterMotCle.php
New file
0,0 → 1,120
<?php
// declare(encoding='UTF-8');
/**
* Ajoute un ou plusieurs mots-clés en les associant à un identifiant d'image
*
* @category DEL
* @package Services
* @subpackage MotsCles
* @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 AjouterMotCle {
 
private $conteneur;
private $bdd;
private $parametres = array();
private $idDernierAjout = null;
private $nbreMotsClesAjoutes = null;
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->bdd = $this->conteneur->getBdd();
}
 
/**
* Ajoute un mot-clé si les objets fournis en paramètres sont valides
* pour l'afficher.
* @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
* @param array $parametres les paramètres situés après le ? dans l'url
* */
public function ajouter($ressources, $parametres) {
$this->parametres = $parametres;
 
// Gestion des configuration du script
$this->verifierParametres();
$this->insererMotCle();
TelaBotanica\Del\Commun\MotsClesImage::updateStats($this->bdd, $this->parametres['image']);
 
// Mettre en forme le résultat et l'envoyer pour affichage
$resultat = new ResultatService();
$resultat->corps = array('nbre' => $this->nbreMotsClesAjoutes, 'id' => $this->idDernierAjout);
 
return $resultat;
}
 
public function verifierParametres() {
$erreurs = array();
 
if (!isset($this->parametres['image'])) {
$erreurs[] = " - impossible d'ajouter un mot clé sans l'indication de l'identifiant de l'image associée";
} else if(!is_numeric($this->parametres['image'])) {
$erreurs[] = " - l'identifiant d'image doit être un entier";
}
 
if (!isset($this->parametres['mot_cle'])) {
$erreurs[] = " - impossible d'ajouter un mot clé sans le mot clé";
}
 
if (!isset($this->parametres['auteur.id'])) {
$erreurs[] = " - impossible d'ajouter un mot clé sans l'identifiant de l'auteur associé";
}
 
if (!empty($erreurs)) {
$msg = "Erreur de configuration :\n".implode("\n", $erreurs);
throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
}
 
/**
* Insère un mot clé dans la table
* */
private function insererMotCle() {
$clauseValues = $this->creerClauseValues();
$requete = 'INSERT INTO del_image_tag '.
'(ce_image, ce_utilisateur, tag, tag_normalise, date, actif, date_modification) '.
"VALUES $clauseValues ".
' -- '.__FILE__.' : '.__LINE__;
$nbreInsertion = $this->bdd->executer($requete);
$idDernierAjout = $this->bdd->recupererIdDernierAjout();
if ($nbreInsertion == null) {
$msgTpl = "Erreur lors de l'insertion d'un des tags «%s» pour l'image «%s» de l'auteur «%s»";
$msg = sprintf($msgTpl, $this->parametres['mot_cle'], $this->parametres['image'], $this->parametres['auteur.id']);
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
$this->nbreMotsClesAjoutes = $nbreInsertion;
$this->listerIdAjoutes($idDernierAjout, $nbreInsertion);
}
 
private function listerIdAjoutes($dernierId, $nbreInsertion) {
$this->idDernierAjout[] = $dernierId;
for ($i = 1 ; $i <= ($nbreInsertion - 1); $i++ ) {
$this->idDernierAjout[] = ++$dernierId;
}
}
 
private function creerClauseValues() {
$id_image = intval($this->parametres['image']);
$idImageP = $this->bdd->proteger($id_image);
$id_auteur = $this->parametres['auteur.id'];
$idAuteurP = $this->bdd->proteger($id_auteur);
$mots_cles = explode(',', $this->parametres['mot_cle']);
 
$values = array();
foreach ($mots_cles as $mot_cle) {
$motCleP = $this->bdd->proteger(trim($mot_cle));
$mot_cle_normalise = TelaBotanica\Del\Commun\MotsClesImage::normaliserMotCle($mot_cle);
$motCleNormaliseP = $this->bdd->proteger($mot_cle_normalise);
 
$values[] = "($idImageP, $idAuteurP, $motCleP, $motCleNormaliseP, NOW(), 1, NOW())";
}
$clauseValues = implode(',', $values);
return $clauseValues;
}
}
/tags/v1.10-sodium/services/modules/0.1/mots_cles/ListeMotsCles.php
New file
0,0 → 1,106
<?php
// declare(encoding='UTF-8');
/**
* Récupère des listes de mots clés associés aux images
*
* @category DEL
* @package Services
* @subpackage MotsCles
* @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 ListeMotsCles {
 
private $conteneur;
private $navigation;
private $bdd;
 
private $mapping = array();
private $mappingInverse = array();
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->navigation = $conteneur->getNavigation();
$this->bdd = $this->conteneur->getBdd();
 
$this->mapping = $this->conteneur->getParametreTableau('mots-cles.mapping');
$this->mappingInverse = array_flip($this->mapping);
}
 
/**
* Méthode principale de la classe.
* Lance la récupération des images dans la base et les place dans un objet ResultatService
* pour l'afficher.
* @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
* @param array $parametres les paramètres situés après le ? dans l'url
* */
public function consulter($ressources, $parametres) {
// Lancement du service
$motsCles = $this->chargerMotsCles();
$total = $this->compterMotsClesTotal();
 
$motsClesSortie = $this->formaterMotsCles($motsCles);
$this->navigation->setTotal($total);
 
$resultat = new ResultatService();
$resultat->corps = array('entete' => $this->navigation->getEntete(), 'resultats' => $motsClesSortie);
return $resultat;
}
 
private function chargerMotsCles() {
$requete = 'SELECT DISTINCT SQL_CALC_FOUND_ROWS * '.
'FROM del_image_tag '.
'WHERE actif = 1 '.$this->creerClauseWhere().
'LIMIT '.$this->navigation->getDepart().','.$this->navigation->getLimite().' '.
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recupererTous($requete);
return is_array($resultat) ? $resultat : array();
}
 
private function creerClauseWhere() {
$where = array();
$filtres = $this->navigation->getFiltre();
if (!empty($filtres)) {
foreach ($filtres as $cle => $valeur) {
$where[] = $this->mappingInverse[$cle].' = '.$this->bdd->proteger($valeur);
}
}
$clauseWhere = (!empty($where)) ? ' AND '.implode(' AND ', $where).' ' : '';
return $clauseWhere;
}
 
/**
* Compter le nombre total de commentaires dans la base vis à vis des filtres de l'url.
* Utilisation du mécanisme SQL_CALC_FOUND_ROW de Mysql pour éviter une deuxième requete avec un COUNT.
*/
private function compterMotsClesTotal() {
$requete = 'SELECT FOUND_ROWS() AS nbre ';
$resultats = $this->bdd->recuperer($requete);
return (int) $resultats['nbre'];
}
 
/**
* Formater les mots clés pour la sortie.
*
* @param $mots_cles les mots clés à formater
* @return $mots_cles les mots clés mis à jour au format de la sortie du web service
*/
private function formaterMotsCles($mots_cles) {
$retour = array();
foreach ($mots_cles as $mot_cle) {
// Boucle sur le mapping pour respecter l'ordre des champs de sortie
foreach ($this->mapping as $nomChampBdd => $nomAttributSortie) {
if (isset($mot_cle[$nomChampBdd])) {
$retour[$mot_cle['id_tag']][$nomAttributSortie] = $mot_cle[$nomChampBdd];
}
}
}
return $retour;
}
}
/tags/v1.10-sodium/services/modules/0.1/mots_cles/SupprimerMotCle.php
New file
0,0 → 1,76
<?php
// declare(encoding='UTF-8');
/**
* Supprime un mot clé par son identifiant
*
* @category DEL
* @package Services
* @subpackage MotsCles
* @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 SupprimerMotCle {
 
private $conteneur;
private $bdd;
private $ressources = array();
private $motCleId;
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->bdd = $this->conteneur->getBdd();
}
 
/**
* Supprime un mot-clé si les données fournis en paramètres sont valides.
*
* @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
*/
public function supprimer($ressources) {
$this->ressources = $ressources;
$this->verifierRessources();
 
$this->motCleId = $this->ressources[0];
$this->supprimerMotCle();
TelaBotanica\Del\Commun\MotsClesImage::updateStats($this->bdd, $this->motCleId);
 
// Mettre en forme le résultat et l'envoyer pour affichage
$resultat = new ResultatService();
return $resultat;
}
 
private function verifierRessources() {
$erreurs = array();
 
if (!isset($this->ressources[0])) {
$erreurs[] = " - impossible de supprimer un mot clé sans l'identifiant associé ;";
} else if(!is_numeric($this->ressources[0])) {
$erreurs[] = " - l'identifiant de mot clé doit être un entier ;";
}
 
if (!empty($erreurs)) {
$msg = "Erreur de configuration :\n".implode("\n", $erreurs);
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
}
 
private function supprimerMotCle() {
$idMotCleP = $this->bdd->proteger($this->motCleId);
$requete = 'UPDATE del_image_tag '.
'SET actif = 0, date_modification = NOW() '.
"WHERE id_tag = $idMotCleP ".
' -- '.__FILE__.' : '.__LINE__;
$retour = $this->bdd->executer($requete);
if ($retour == null) {
$msg = "Erreur lors de la suppression du mot-clé d'id $idMotCleP";
throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
}
return $retour;
}
}
/tags/v1.10-sodium/services/modules/0.1/protocoles/ListeProtocoles.php
New file
0,0 → 1,66
<?php
// declare(encoding='UTF-8');
/**
* Récupère tous les protocoles avec id, nom et descriptif
*
* @category DEL
* @package Services
* @subpackage Protocoles
* @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 ListeProtocoles {
 
private $conteneur;
private $navigation;
private $bdd;
 
private $mapping = array();
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->navigation = $conteneur->getNavigation();
$this->bdd = $this->conteneur->getBdd();
}
 
public function consulter() {
// Gestion des configuration du script
$this->mapping = $this->conteneur->getParametreTableau('protocoles.mapping');
 
$protocoles = $this->chargerProtocoles();
$protocoles = $this->formaterProtocoles($protocoles);
$this->navigation->setTotal(count($protocoles));
 
$resultat = new ResultatService();
$resultat->corps = array(
'entete' => $this->navigation->getEntete(),
'resultats' => $protocoles);
return $resultat;
}
 
private function chargerProtocoles() {
$requete = 'SELECT * FROM del_image_protocole -- '.__FILE__.' : '.__LINE__;
return $this->bdd->recupererTous($requete);
}
 
private function formaterProtocoles($protocoles) {
$protocolesRetour = array();
foreach ($protocoles as $protocole) {
$protocoleFormate = array();
$idProtocole = $protocole['id_protocole'];
foreach($protocole as $champProtocole => $valeur) {
if (isset($this->mapping[$champProtocole])) {
$protocoleFormate[$this->mapping[$champProtocole]] = $valeur;
}
}
$protocolesRetour[$idProtocole] = $protocoleFormate;
}
return $protocolesRetour;
}
}
/tags/v1.10-sodium/services/modules/0.1/Images.php
New file
0,0 → 1,227
<?php
// declare(encoding='UTF-8');
/**
* Classe principale de chargement des sous-services "images" de DEL.
*
* Cette classe se charge toujours de :
* - vérifier l'existance des ressources (services) demandés
* - vérifier la cohérence et le format des paramêtres passées dans l'url
* En fonction, de la compléxité du service, elle peut :
* - dans un premier temps, exécuter directement les actions : consulter, ajouter, modifier, supprimer.
* - dans un second temps, charger dynamiquement d'éventuelles sous-classes du service en fonction des ressources présentes dans l'URL.
*
* URLs possibles :
* GET :
* http://localhost/del/services/0.1/images/ => toutes les images : classe ListeImages
* http://localhost/del/services/0.1/images/#idImg/votes => tous les votes d'une image (#idImg) classés par protocole : classe VotesImage
*
* Non Implémenté : http://localhost/del/services/0.1/images/#id => une image donnée => en test pour remplacer les appels à eflore/cel
* Non Implémenté : http://localhost/del/services/0.1/images/#id/votes?protocole=#id => tous les votes d'une image et d'un protocole donné
*
* PUT :
* http://localhost/del/services/0.1/images/#idImg => ajouter un vote sur une image donnée (#idImg)
*
* POST :
* http://localhost/del/services/0.1/images/#idImg => modifier un vote sur une image donnée (#idImg)
*
* DELETE :
* http://localhost/del/services/0.1/images/#idImg => supprimer une image donnée (#idImg)
* http://localhost/del/services/0.1/images/#idImg/votes/#idVote => supprimer un vote (#idVote) d'une image donnée (#idImg)
*
* @category DEL
* @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>
*/
restore_error_handler();
restore_exception_handler();
error_reporting(E_ALL);
 
class Images extends RestService {
 
private $conteneur;
private $cheminCourant;
private $parametres = array();
private $ressources = array();
private $methode;
private $serviceNom = 'images';
private $sousServiceNom;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->conteneur = new Conteneur();
$this->cheminCourant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->initialiserRessourcesEtParametres($ressources, $parametres);
return $this->executerService();
}
 
public function ajouter($ressources, $requeteDonnees) {
$this->methode = 'ajouter';
$this->initialiserRessourcesEtParametres($ressources, $requeteDonnees);
return $this->executerService();
}
 
public function modifier($ressources, $requeteDonnees) {
$this->methode = 'modifier';
$this->initialiserRessourcesEtParametres($ressources, $requeteDonnees);
return $this->executerService();
}
 
public function supprimer($ressources) {
$this->methode = 'supprimer';
$this->initialiserRessourcesEtParametres($ressources);
return $this->executerService();
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres = array()) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function executerService() {
$resultat = $this->traiterRessources();
if ($resultat === true || $resultat === false) {
return $resultat;
}
 
$reponseHttp = new ReponseHttp();
$reponseHttp->setResultatService($resultat);
$reponseHttp->emettreLesEntetes();
return $reponseHttp->getCorps();
}
 
private function traiterRessources() {
$this->analyserRessources();
$retour = $this->initialiserService();
return $retour;
}
 
private function analyserRessources() {
if ($this->methode == 'consulter') {
$this->analyserRessoucesConsultation();
} else if ($this->methode == 'modifier' || $this->methode == 'ajouter') {
$this->analyserRessoucesModification();
} else if ($this->methode == 'supprimer') {
$this->analyserRessoucesSuppression();
}
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function analyserRessoucesConsultation() {
if (count($this->ressources) == 0) {
$this->sousServiceNom = 'liste-images';
} else if (count($this->ressources) == 2) {
if ($this->etreRessourceIdentifiant(0) && $this->verifierRessourceValeur(1, 'votes')) {
$this->sousServiceNom = 'votes-image';
}
}
}
 
private function analyserRessoucesModification() {
if (count($this->ressources) == 2) {
if ($this->etreRessourceIdentifiant(0) && $this->verifierRessourceValeur(1, 'votes')) {
$this->sousServiceNom = 'votes-image';
}
}
}
 
private function analyserRessoucesSuppression() {
if (count($this->ressources) == 1 && $this->etreRessourceIdentifiant(0)) {
$this->sousServiceNom = 'liste-images';
} else if (count($this->ressources) == 3) {
if ($this->etreRessourceIdentifiant(0) && $this->verifierRessourceValeur(1, 'votes') && $this->etreRessourceIdentifiant(2) ) {
$this->sousServiceNom = 'votes-image';
}
}
}
 
private function etreRessourceIdentifiant($num) {
$presenceId = false;
if (isset($this->ressources[$num]) && is_numeric($this->ressources[$num])) {
$presenceId = true;
}
return $presenceId;
}
 
private function verifierRessourceValeur($num, $valeur) {
$ok = false;
if (isset($this->ressources[$num]) && $this->ressources[$num] == $valeur) {
$ok = true;
}
return $ok;
}
 
private function lancerMessageErreurRessource() {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "La ressource demandée '$ressource' ".
"n'est pas disponible pour le service ".$this->serviceNom." !\n".
$this->getDoc();
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
public function getDoc() {
return "Les URLs disponibles sont : \n".
" * en GET : \n".
" - images => toutes les images\n".
" - images/#idImg/votes => tous les votes d'une image (#idImg) classés par protocole\n".
" * en PUT : \n".
" - /images/#idImg/votes => ajouter un vote sur une image donnée (#idImg)\n".
" * en POST : \n".
" - /images/#idImg/votes => modifier un vote sur une image donnée (#idImg)\n".
" * en DELETE : \n".
" - /images/#idImg => supprimer une image donnée (#idImg)\n".
" - /images/#idImg/votes/#idVote => supprimer un vote (#idVote) d'une image donnée (#idImg)";
}
 
private function initialiserService() {
$classe = $this->obtenirNomClasseService($this->sousServiceNom);
$chemins = array();
$chemins[] = $this->cheminCourant.$this->serviceNom.DS.$classe.'.php';
$chemins[] = $this->cheminCourant.'commun'.DS.$classe.'.php';
$retour = '';
$service = null;
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
if ($this->methode == 'consulter') {
$retour = $service->consulter($this->ressources, $this->parametres);
} elseif ($this->methode == 'ajouter') {
$retour = $service->ajouter($this->ressources, $this->parametres);
} elseif ($this->methode == 'modifier') {
$retour = $service->modifier($this->ressources, $this->parametres);
} elseif ($this->methode == 'supprimer') {
$retour = $service->supprimer($this->ressources);
}
}
}
 
if (is_null($service)) {
$ressource = implode('/', $this->ressources);
$msg = "Le classe '$classe' correspondant à la ressource '$ressource' ".
"n'existe pas dans le service '{$this->serviceNom}' !\n".$this->getDoc();
throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
return $retour;
}
 
private function obtenirNomClasseService($mot) {
$classeNom = str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
}
/tags/v1.10-sodium/services/modules/0.1/utilisateurs/Preferences.php
New file
0,0 → 1,57
<?php
// declare(encoding='UTF-8');
/**
* Permet la gestion des préférences utilisateur
*
* @category DEL
* @package Services
* @subpackage Utilisateurs
* @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 Preferences extends GestionUtilisateur {
 
/**
* Renvoie les préférences d'un utilisateur
* @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
* @param array $parametres les paramètres situés après le ? dans l'url
* */
public function consulter($ressources, $parametres) {
$id_utilisateur = $ressources[0];
$this->controleUtilisateurIdentifie($id_utilisateur);
// Mettre en forme le résultat et l'envoyer pour affichage
$resultat = new ResultatService();
$resultat->corps = $this->obtenirPreferencesUtilisateur($id_utilisateur);
return $resultat;
}
 
/**
* Modifie les préférences de l'utilisateur
* @param array $ressources les ressources situées après l'url de base (ex : http://url/ressource1/ressource2)
* @param array $parametres les paramètres situés d ans le post
* */
public function modifier($ressources, $parametres) {
$id_utilisateur = $ressources[0];
$this->controleUtilisateurIdentifie($id_utilisateur);
$prefs = $this->modifierPreferencesUtilisateur($id_utilisateur, $parametres);
// Mettre en forme le résultat et l'envoyer pour affichage
$resultat = new ResultatService();
$resultat->corps = $prefs;
return $resultat;
}
 
private function modifierPreferencesUtilisateur($id_utilisateur, $prefs) {
$requete = 'UPDATE del_utilisateur_infos '.
'SET preferences = '.$this->bdd->proteger(json_encode($prefs)).' '.
'WHERE id_utilisateur = '.$this->bdd->proteger($id_utilisateur).' '.
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->executer($requete);
return $resultat;
}
}
Property changes:
Added: svnkit:entry:sha1-checksum
+f73e59fae7ac415df9c26a992af76cb1c409a1ec
\ No newline at end of property
/tags/v1.10-sodium/services/modules/0.1/utilisateurs/Activite.php
New file
0,0 → 1,35
<?php
// declare(encoding='UTF-8');
/**
* Permet de consulter l'activité d'un utilisateur de Del
*
* @category DEL
* @package Services
* @subpackage Utilisateurs
* @version 0.1
* @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 Activite extends GestionUtilisateur {
 
/**
* Retourne l'activité de l'utilisateur en cours, ou false si aucun utilisateur connu
* n'est identifié (mode anonyme) @TODO retrouner un truc mieux
* */
public function consulter($ressources, $parametres) {
 
if ($this->utilisateur['connecte'] === true) {
$id_utilisateur = $this->utilisateur['id_utilisateur'];
$activite = $this->getEvenements($id_utilisateur);
 
// Mettre en forme le résultat et l'envoyer pour affichage
$resultat = new ResultatService();
$resultat->corps = $activite;
 
return $resultat;
}
return false;
}
}
/tags/v1.10-sodium/services/modules/0.1/utilisateurs/Identification.php
New file
0,0 → 1,30
<?php
// declare(encoding='UTF-8');
/**
* Gestion de l'identification des utilisateurs
*
* @category DEL
* @package Services
* @subpackage Utilisateurs
* @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 Identification extends GestionUtilisateur {
 
public function consulter($ressources, $parametres) {
$utilisateur = $this->utilisateur;
if ($utilisateur['connecte'] === true) {
$this->ajouterEvenements($utilisateur);
}
 
$resultat = new ResultatService();
$resultat->corps = $utilisateur;
 
return $resultat;
}
}
/tags/v1.10-sodium/services/modules/0.1/Nomstaxons.php
New file
0,0 → 1,135
<?php
// declare(encoding='UTF-8');
/**
* Classe principale de chargement des sous-services Noms et Taxons utilisés par DEL.
*
* @category DEL
* @package Services
* @subpackage NomsTaxons
* @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 Nomstaxons extends RestService {
 
private $parametres = array();
private $ressources = array();
private $methode = null;
private $serviceNom = 'nomstaxons';
private $sousServiceNom = null;
private $cheminCourant = null;
 
private $conteneur;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->initialiserRessourcesEtParametres($ressources, $parametres);
return $this->executerService();
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres = array()) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function executerService() {
$reponseHttp = new ReponseHttp();
try {
$this->conteneur = new Conteneur($this->parametres);
$resultat = $this->traiterRessources();
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
$reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
}
 
private function traiterRessources() {
$this->analyserRessources();
$retour = $this->initialiserService();
return $retour;
}
 
private function analyserRessources() {
if ($this->methode == 'consulter') {
if (count($this->ressources) == 0
&& $this->verifierPresenceParametre('masque.nom')
&& $this->verifierPresenceParametre('masque.referentiel')) {
$this->sousServiceNom = 'liste-taxons';
}
}
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function verifierPresenceParametre($cle) {
if (isset($this->parametres[$cle]) && trim($this->parametres[$cle]) == '') {
$message = "Le service demandé '{$this->serviceNom}' ".
"nécessite l'utilisation de paramètres (non vide) : masque.nom & masque.referentiel\n";
throw new Exception($message, RestServeur::HTTP_CODE_ECHEC_CONDITION);
}
return true;
}
 
private function lancerMessageErreurRessource() {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "La ressource demandée '$ressource' ".
"n'est pas disponible pour le service ".$this->serviceNom." !\n".
"Les URLs disponibles sont : \n".
" - en GET : nomstaxons (paramètres : masque.nom & masque.referentiel) \n";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
private function initialiserService() {
$classe = $this->obtenirNomClasseService($this->sousServiceNom);
$chemins = array();
$chemins[] = $this->cheminCourant.$this->serviceNom.DS.$classe.'.php';
$chemins[] = $this->cheminCourant.'commun'.DS.$classe.'.php';
$retour = '';
$service = null;
 
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
if ($this->methode == 'consulter') {
$retour = $service->consulter();
} else {
$message = "Le sous-service '{$this->sousServiceNom}' du service '{$this->serviceNom}' ".
"ne possède pas de méthode '{$this->methode}' !";
$code = RestServeur::HTTP_NON_IMPLEMENTE;
throw new Exception($message, $code);
}
}
}
 
if (is_null($service)) {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "Le classe '$classe' correspondant à la ressource '$ressource' ".
"est introuvable par le service '{$this->serviceNom}' !";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $retour;
}
 
private function obtenirNomClasseService($mot) {
$classeNom = str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
}
/tags/v1.10-sodium/services/modules/0.1/statistiques/StatistiquesParAnnee.php
New file
0,0 → 1,1077
<?php
/**
* Statistiques par année sur l'utilisation de Identiplante / Pictoflora
*
* @see Documentation : <http://www.tela-botanica.org/wikini/DevInformatiques/wakka.php?wiki=AppliDelStats>
*
* @category DEL
* @package Services
* @subpackage Statistiques
* @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 StatistiquesParAnnee {
 
private $conteneur;
private $contexte;
private $navigation;
private $bdd;
 
private $annee = null;
private $type = 'tout';
private $methode = '';
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->contexte = $conteneur->getContexte();
$this->navigation = $conteneur->getNavigation();
$this->bdd = $this->conteneur->getBdd();
}
 
public function consulter() {
$this->intitialiserParametresEtRessources();
$this->verifierPreRequis();
 
$resultat = new ResultatService();
$resultat->corps = call_user_func(array($this, $this->methode));
return $resultat;
}
 
private function intitialiserParametresEtRessources() {
$this->type = $this->contexte->getRessource(2) != null ? $this->contexte->getRessource(2) : $this->type;
$this->methode = $this->obtenirNomMethode($this->type);
$this->annee =(int) $this->contexte->getQS('annee') != null ? intval($this->contexte->getQS('annee')) : null;
}
 
private function verifierPreRequis() {
$erreurs = array();
 
if ($this->annee != null && !is_int($this->annee)) {
$erreurs[] = "Le paramètre 'annee' doit être un entier.";
}
if (method_exists($this, $this->obtenirNomMethode($this->type)) === false) {
$erreurs[] = "Les stats de type '{$this->type}' n'existent pas.";
}
if (!empty($erreurs)) {
$msg = "Erreur de configuration :\n".implode("\n", $erreurs)."\n\n".Statistiques::getDoc();
throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
}
}
 
/**
* Ouh la jolie méthode magique !!
* @param unknown $mot
* @return string
*/
private function obtenirNomMethode($mot) {
$classeNom = 'get'.str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
 
/**
* Statistiques sur les observations
* "MPM" = moyenne par mois
* "TC" = tag à déterminer ou certitude incertaine
* - Nombre d'observations au total
* - Nombre d'obs sans identification (ou tag ou certitude)
* - Nombre d'obs sans identification
* - Nombre d'obs avec tag à déterminer ou certitude incertaine
* - Nombre d'obs avec tag à déterminer ou certitude incertaine et retenue
* - Nombre d'obs avec tag à déterminer ou certitude incertaine et avec consensus
* - Nombre d'obs avec tag à déterminer ou certitude incertaine et avec consensus mais non validées
* - Nombre d'observations ayant une proposition retenue (parmi les observations de l'année)
* - Nombre d'observations ayant une proposition retenue ou en consensus (parmi les observations de l'année)
*/
private function getObservations() {
$nbObsTotal = $this->getNbObsTotal();
$nbObsSansIdentOuTC = $this->getNbObsSansIdentOuTC();
$nbObsSansIdent = $this->getNbObsSansIdent();
$nbObsTC = $this->getNbObsTC();
$nbObsTCRetenue = $this->getNbObsTCRetenue();
$nbObsTCConsensus = $this->getNbObsTCConsensus();
$nbObsTCConsensusNonValide = $this->getNbObsTCConsensusNonValide();
$nbPropositionsRetenuesObsAnnee = $this->getNbPropositionsRetenuesObsAnnee();
$nbPropositionsConsensusObsAnnee = $this->getNbPropositionsConsensusObsAnnee();
return array(
'nbObsTotal' => $nbObsTotal,
'nbObsTotalMPM' => $this->getNbObsTotal(true),
'nbObsSansIdentOuTC' => $nbObsSansIdentOuTC,
'nbObsSansIdentOuTCMPM' => $this->getNbObsSansIdentOuTC(true),
'nbObsSansIdentOuTCPC' => $nbObsTotal == 0 ? 0 : round(($nbObsSansIdentOuTC / $nbObsTotal) * 100, 2),
'nbObsSansIdent' => $nbObsSansIdent,
'nbObsSansIdentMPM' => $this->getNbObsSansIdent(true),
'nbObsSansIdentPC' => $nbObsTotal == 0 ? 0 : round(($nbObsSansIdent / $nbObsTotal) * 100, 2),
'nbObsTC' => $nbObsTC,
'nbObsTCMPM' => $this->getNbObsTC(true),
'nbObsTCPC' => $nbObsTotal == 0 ? 0 : round(($nbObsTC / $nbObsTotal) * 100, 2),
'nbObsTCRetenue' => $nbObsTCRetenue,
'nbObsTCRetenueMPM' => $this->getNbObsTCRetenue(true),
'nbObsTCRetenuePC' => $nbObsTotal == 0 ? 0 : round(($nbObsTCRetenue / $nbObsTotal) * 100, 2),
'nbObsTCConsensus' => $nbObsTCConsensus,
'nbObsTCConsensusMPM' => $this->getNbObsTCConsensus(true),
'nbObsTCConsensusPC' => $nbObsTotal == 0 ? 0 : round(($nbObsTCConsensus / $nbObsTotal) * 100, 2),
'nbObsTCConsensusNonValide' => $nbObsTCConsensusNonValide,
'nbObsTCConsensusNonValideMPM' => $this->getNbObsTCConsensusNonValide(true),
'nbObsTCConsensusNonValidePC' => $nbObsTotal == 0 ? 0 : round(($nbObsTCConsensusNonValide / $nbObsTotal) * 100, 2),
'nbPropositionsRetenuesObsAnnee' => $nbPropositionsRetenuesObsAnnee,
'nbPropositionsRetenuesObsAnneeMPM' => $this->getNbPropositionsRetenuesObsAnnee(true),
'nbPropositionsRetenuesObsAnneePC' => $nbObsTotal == 0 ? 0 : round(($nbPropositionsRetenuesObsAnnee / $nbObsTotal) * 100, 2),
'nbPropositionsConsensusObsAnnee' => $nbPropositionsConsensusObsAnnee,
'nbPropositionsConsensusObsAnneeMPM' => $this->getNbPropositionsConsensusObsAnnee(true),
'nbPropositionsConsensusObsAnneePC' => $nbObsTotal == 0 ? 0 : round(($nbPropositionsConsensusObsAnnee / $nbObsTotal) * 100, 2),
);
}
 
/**
* Nombre d'observations au total
*/
private function getNbObsTotal($mpm=false) {
$requete = "SELECT COUNT(id_observation) AS nb_total FROM del_observation";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date_transmission) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete, 'date_transmission');
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'obs sans identification (ou tag ou certitude)
*/
private function getNbObsSansIdentOuTC($mpm=false) {
$requete = "SELECT COUNT(id_observation) AS nb_total FROM del_observation WHERE";
if ($this->annee != null) {
$requete .= ' YEAR(date_transmission) = ' . $this->annee . " AND";
}
$requete .= " (mots_cles_texte LIKE '%determiner%' OR nom_sel_nn = '' OR nom_sel_nn IS NULL OR certitude IN ('aDeterminer','douteux'))";
if ($mpm) {
$requete = $this->encapsulerMPM($requete, 'date_transmission');
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'obs sans identification
*/
private function getNbObsSansIdent($mpm=false) {
$requete = "SELECT COUNT(id_observation) AS nb_total FROM del_observation WHERE";
if ($this->annee != null) {
$requete .= ' YEAR(date_transmission) = ' . $this->annee . " AND";
}
$requete .= " (nom_sel_nn = '' OR nom_sel_nn IS NULL)";
if ($mpm) {
$requete = $this->encapsulerMPM($requete, 'date_transmission');
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'obs avec tag à déterminer ou certitude incertaine
*/
private function getNbObsTC($mpm=false) {
$requete = "SELECT COUNT(id_observation) AS nb_total FROM del_observation WHERE";
if ($this->annee != null) {
$requete .= ' YEAR(date_transmission) = ' . $this->annee . " AND";
}
$requete .= " (mots_cles_texte LIKE '%determiner%' OR certitude IN ('aDeterminer','douteux'))";
if ($mpm) {
$requete = $this->encapsulerMPM($requete, 'date_transmission');
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'obs avec tag à déterminer ou certitude incertaine et retenue
*/
private function getNbObsTCRetenue($mpm=false) {
$requete = "SELECT COUNT(*) AS nb_total FROM del_commentaire WHERE proposition_retenue = 1 AND ce_observation IN (SELECT id_observation FROM del_observation WHERE";
if ($this->annee != null) {
$requete .= ' YEAR(date_transmission) = ' . $this->annee . " AND";
}
$requete .= " (certitude IN ('aDeterminer','douteux')))";
if ($mpm) {
// @TODO vérifier que grouper sur "date" est pertinent
// date_transmission n'est pas dispo pour grouper ici :-/
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'obs avec tag à déterminer ou certitude incertaine et avec consensus
*/
private function getNbObsTCConsensus($mpm=false) {
$requete = "SELECT COUNT(id_observation) AS nb_total FROM del_observation WHERE";
if ($this->annee != null) {
$requete .= ' YEAR(date_transmission) = ' . $this->annee . " AND";
}
$requete .= " (mots_cles_texte LIKE '%determiner%' OR certitude IN ('aDeterminer','douteux')) AND id_observation IN"
. " (SELECT ce_observation FROM del_commentaire WHERE proposition_initiale = 1"
. " AND nom_sel_nn != 0"
. " AND nom_sel_nn IS NOT NULL"
. " AND id_commentaire IN (SELECT ce_proposition FROM del_commentaire_vote dcv";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) <= ' . $this->annee;
}
$requete .= " GROUP BY ce_proposition HAVING SUM(CASE"
. " WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' != 0 THEN 3"
. " WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' != 0 THEN -3"
. " WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' = 0 THEN 1"
. " WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' = 0 THEN -1"
. " END) >= 4))";
if ($mpm) {
$requete = $this->encapsulerMPM($requete, 'date_transmission');
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'obs avec tag à déterminer ou certitude incertaine et avec consensus mais non validées
*/
private function getNbObsTCConsensusNonValide($mpm=false) {
$requete = "SELECT COUNT(id_observation) AS nb_total FROM del_observation WHERE";
if ($this->annee != null) {
$requete .= ' YEAR(date_transmission) = ' . $this->annee . " AND";
}
$requete .= " (mots_cles_texte LIKE '%determiner%' OR certitude IN ('aDeterminer','douteux')) AND id_observation IN"
. " (SELECT ce_observation FROM del_commentaire WHERE proposition_initiale = 1 AND proposition_retenue = 0"
. " AND nom_sel_nn != 0"
. " AND nom_sel_nn IS NOT NULL"
. " AND id_commentaire IN (SELECT ce_proposition FROM del_commentaire_vote dcv";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) <= ' . $this->annee;
}
$requete .= " GROUP BY ce_proposition HAVING SUM(CASE"
. " WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' != 0 THEN 3"
. " WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' != 0 THEN -3"
. " WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' = 0 THEN 1"
. " WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' = 0 THEN -1"
. " END) >= 4))";
if ($mpm) {
$requete = $this->encapsulerMPM($requete, 'date_transmission');
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Statistiques sur les propositions, les commentaires et les votes
* "MPM" = moyenne par mois
* - Nombre de votes
* - Nombre de commentaires
* - Nombre d'actions par jour
* - Nombres de propositions sur toutes les obs
* - Nombre d'observations ayant une proposition retenue (parmi toutes les observations)
* - Nombre d'observations ayant une proposition retenue ou en consensus (parmi toutes les observations)
* - Nombre de propositions sur les obs d'une année
*/
private function getPropositions() {
return array(
'nbVotes' => $this->getNbVotes(),
'nbVotesMPM' => $this->getNbVotes(true),
'nbMoyenActionsParJour' => $this->getNbMoyenActionsParJour(),
'nbCommentaires' => $this->getNbCommentaires(),
'nbCommentairesMPM' => $this->getNbCommentaires(true),
'nbPropositionsToutesObs' => $this->getNbPropositionsToutesObs(),
'nbPropositionsToutesObsMPM' => $this->getNbPropositionsToutesObs(true),
'nbPropositionsRetenuesToutesObs' => $this->getNbPropositionsRetenuesToutesObs(),
'nbPropositionsRetenuesToutesObsMPM' => $this->getNbPropositionsRetenuesToutesObs(true),
'nbPropositionsConsensusToutesObs' => $this->getNbPropositionsConsensusToutesObs(),
'nbPropositionsConsensusToutesObsMPM' => $this->getNbPropositionsConsensusToutesObs(true),
'nbPropositionsObsAnnee' => $this->getNbPropositionsObsAnnee(),
'nbPropositionsObsAnneeMPM' => $this->getNbPropositionsObsAnnee(true),
);
}
 
/**
* Nombre moyen d'actions par jour (commentaire, proposition, vote)
*/
private function getNbMoyenActionsParJour() {
$requete = "SELECT (SELECT (SELECT count(*) FROM del_commentaire";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
$requete .= ") + (SELECT count(*) FROM del_commentaire_vote";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
$requete .= ") + (SELECT count(*) FROM del_commentaire";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date_validation) = ' . $this->annee;
}
$requete .= ")) / (";
if ($this->annee != null) {
$requete .= "SELECT IF( YEAR(CURDATE()) = " . $this->annee . ", DAYOFYEAR(CURDATE()), 365) ";
} else {
$requete .= "365";
}
$requete .= ")";
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre de propositions faites sur toutes les observations (hors initiales)
*/
private function getNbPropositionsToutesObs($mpm=false) {
$requete = "SELECT COUNT(DISTINCT id_commentaire) AS nb_total FROM del_commentaire WHERE";
if ($this->annee != null) {
$requete .= ' YEAR(date) = ' . $this->annee . " AND";
}
$requete .= " (nom_sel_nn IS NOT NULL OR nom_sel_nn != '') AND proposition_initiale = 0";
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'observations ayant une proposition retenue (parmi toutes les observations)
*/
private function getNbPropositionsRetenuesToutesObs($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_observation) AS nb_total FROM del_commentaire WHERE";
if ($this->annee != null) {
$requete .= ' YEAR(date) = ' . $this->annee . " AND";
}
$requete .= " proposition_retenue = 1";
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'observations ayant une proposition retenue ou en consensus (parmi toutes les observations)
*/
private function getNbPropositionsConsensusToutesObs($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_observation) AS nb_total FROM del_commentaire dc WHERE"
. " dc.proposition_retenue = 1"
. " OR (dc.proposition_initiale = 1"
. " AND dc.nom_sel_nn != 0"
. " AND dc.nom_sel_nn IS NOT NULL"
. " AND dc.id_commentaire IN"
. " (SELECT ce_proposition FROM del_commentaire_vote dcv WHERE";
if ($this->annee != null) {
$requete .= " year(date) < " . $this->annee . " AND";
}
$requete .= " ce_proposition NOT IN (SELECT ce_proposition FROM del_commentaire_vote dcv";
if ($this->annee != null) {
$requete .= " WHERE year(date) < " . ($this->annee - 1);
}
$requete .= " GROUP BY ce_proposition"
. " HAVING SUM(CASE"
. " WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' != 0 THEN 3"
. " WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' != 0 THEN -3"
. " WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' = 0 THEN 1"
. " WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' = 0 THEN -1"
. " END) >= 4)"
. " GROUP BY ce_proposition"
. " HAVING SUM(CASE"
. " WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' != 0 THEN 3"
. " WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' != 0 THEN -3"
. " WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' = 0 THEN 1"
. " WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' = 0 THEN -1"
. " END) >= 4"
. " )"
. " )";
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'observations ayant une proposition retenue (parmi les observations de l'année)
*/
private function getNbPropositionsObsAnnee($mpm=false) {
if ($this->annee == null) {
return null;
}
$requete = "SELECT COUNT(DISTINCT ce_observation) AS nb_total FROM del_commentaire WHERE YEAR(date) = " . $this->annee . " AND "
. "(nom_sel_nn IS NOT NULL OR nom_sel_nn != '') AND proposition_initiale = 0 AND ce_observation in"
. " (SELECT id_observation FROM del_observation WHERE year(date_transmission) = " . $this->annee . ")";
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'observations ayant une proposition retenue ou en consensus (parmi les observations de l'année)
*/
private function getNbPropositionsRetenuesObsAnnee($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_observation) AS nb_total FROM del_commentaire WHERE ";
if ($this->annee != null) {
$requete .= "YEAR(date) = " . $this->annee . " AND ";
}
$requete .= "proposition_retenue = 1 AND ce_observation in (SELECT id_observation FROM del_observation ";
if ($this->annee != null) {
$requete .= "WHERE year(date_transmission) = " . $this->annee;
}
$requete .= ")";
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre de proposition en consensus faites sur les observations d'une année
*/
private function getNbPropositionsConsensusObsAnnee($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_observation) AS nb_total FROM del_commentaire dc WHERE ce_observation in ("
. " SELECT id_observation FROM del_observation ";
if ($this->annee != null) {
$requete .= "WHERE year(date_transmission) = " . $this->annee ;
}
$requete .= ") AND ("
. " dc.proposition_retenue = 1 OR (dc.proposition_initiale = 1"
. " AND dc.nom_sel_nn != 0 AND dc.nom_sel_nn IS NOT NULL AND dc.id_commentaire IN"
. " (SELECT ce_proposition FROM del_commentaire_vote dcv";
if ($this->annee != null) {
$requete .= " WHERE year(date) <= " . $this->annee;
}
$requete .= " GROUP BY ce_proposition"
. " HAVING SUM(CASE"
. " WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' != 0 THEN 3"
. " WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' != 0 THEN -3"
. " WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' = 0 THEN 1"
. " WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP '^-?[0-9]+$' = 0 THEN -1"
. " END) >= 4)"
. "))";
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre de votes
*/
private function getNbVotes($mpm=false) {
$requete = "SELECT COUNT(DISTINCT id_vote) AS nb_total FROM del_commentaire_vote";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre de commentaires
*/
private function getNbCommentaires($mpm=false) {
$requete = "SELECT COUNT(DISTINCT id_commentaire) AS nb_total FROM del_commentaire WHERE ce_proposition != '' AND (nom_sel IS NULL OR nom_sel = '')";
if ($this->annee != null) {
$requete .= ' AND YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Statistiques sur les utilisateurs d'Identiplante
* "AF" = ayant fait un(e)
* "MPM" = moyenne par mois
* - Nombre total d'utilisateurs
* - Nombre d'utilisateurs ayant fait une proposition
* - Nombre d'utilisateurs identifiés ayant fait un vote
* - Nombre d'utilisateurs anonymes ayant fait un vote
* - Nombre d'utilisateurs ayant fait un commentaire
* - Nombre d'utilisateurs ayant fait une action
*/
private function getUtilisateursIp() {
return array(
'nbUtilisateursTotal' => $this->getNbUtilisateursIpTotal(),
'nbUtilisateursAFProposition' => $this->getNbUtilisateursAFProposition(),
'nbUtilisateursAFCommentaire' => $this->getNbUtilisateursAFCommentaire(),
'nbUtilisateursAFVote' => $this->getNbUtilisateursAFVote(),
'nbUtilisateursAnonymesAFVote' => $this->getNbUtilisateursAnonymesAFVote(),
'nbUtilisateursAFAction' => $this->getNbUtilisateursAFAction(),
'nbUtilisateursAFPropositionMPM' => $this->getNbUtilisateursAFProposition(true),
'nbUtilisateursAFCommentaireMPM' => $this->getNbUtilisateursAFCommentaire(true),
'nbUtilisateursAFVoteMPM' => $this->getNbUtilisateursAFVote(true),
'nbUtilisateursAnonymesAFVoteMPM' => $this->getNbUtilisateursAnonymesAFVote(true),
'nbUtilisateursAFActionMPM' => $this->getNbUtilisateursAFActionMPM()
);
}
 
/**
* Nombre total d'utilisateurs d'Identiplante
*/
private function getNbUtilisateursIpTotal() {
$requete = "SELECT COUNT(DISTINCT ce_utilisateur) AS nb_total FROM del_commentaire";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'utilisateurs d'Identiplante ayant fait au moins une proposition
*/
private function getNbUtilisateursAFProposition($mpm=false) {
$requete = "SELECT COUNT(DISTINCT utilisateur_courriel) AS nb_total FROM del_commentaire WHERE ce_proposition = '' AND nom_sel IS NOT NULL AND nom_sel != ''";
if ($this->annee != null) {
$requete .= ' AND YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'utilisateurs d'Identiplante ayant fait au moins un commentaire
*/
private function getNbUtilisateursAFCommentaire($mpm=false) {
$requete = "SELECT COUNT(DISTINCT utilisateur_courriel) AS nb_total FROM del_commentaire WHERE ce_proposition != '' AND (nom_sel IS NULL OR nom_sel = '')";
if ($this->annee != null) {
$requete .= ' AND YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'utilisateurs d'Identiplante identifiés prenant part aux votes
*/
private function getNbUtilisateursAFVote($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_utilisateur) AS nb_total FROM del_commentaire_vote WHERE ce_utilisateur REGEXP '^-?[0-9]+$'";
if ($this->annee != null) {
$requete .= ' AND YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'utilisateurs d'Identiplante anonymes prenant part aux votes
*/
private function getNbUtilisateursAnonymesAFVote($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_utilisateur) AS nb_total FROM del_commentaire_vote WHERE ce_utilisateur NOT REGEXP '^-?[0-9]+$'";
if ($this->annee != null) {
$requete .= ' AND YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'utilisateurs d'Identiplante ayant fait une action (commentaire, vote, proposition)
*/
private function getNbUtilisateursAFAction() {
$requete = "SELECT COUNT(*) AS nb_total FROM (SELECT ce_utilisateur FROM del_commentaire_vote";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
$requete .= " UNION SELECT ce_utilisateur FROM del_commentaire";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
$requete .= " ) AS action";
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Moyenne par mois du nombre d'utilisateurs d'Identiplante ayant fait une action
* (commentaire, vote, proposition) -> n'est pas encapsulable par encapsulerMPM()
*/
private function getNbUtilisateursAFActionMPM() {
$requete = "SELECT avg(nb_total) FROM (SELECT count(*) as nb_total FROM"
. " (SELECT * FROM (SELECT ce_utilisateur, date FROM del_commentaire_vote";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
$requete .= " UNION SELECT ce_utilisateur, date FROM del_commentaire";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
$requete .= " ) AS action GROUP BY ce_utilisateur) AS utildate GROUP BY CONCAT(year(date),month(date))) as truc";
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Liste des utilisateurs dont les propositions ont été votées positivement
*/
private function getListeMeilleursProposeurs() {
$liste = array();
$requete = "SELECT * FROM (SELECT utilisateur_courriel, ce_utilisateur, count(prop) as nb_prop"
. " FROM (SELECT ce_proposition as prop, COUNT(DISTINCT id_vote) AS nb_vote FROM del_commentaire_vote where";
if ($this->annee != null) {
$requete .= " year(date) = " . $this->annee . " AND";
}
$requete .= " valeur = 1 GROUP BY ce_proposition) AS vote, del_commentaire WHERE nb_vote > 3 AND prop = id_commentaire AND ce_utilisateur != 0 GROUP BY ce_utilisateur)"
. " AS utlisateurs WHERE nb_prop > 10 ORDER BY nb_prop DESC LIMIT 20";
$resultat = $this->bdd->recupererTous($requete);
 
// Formatage de la liste avec les intitulés des utilisateurs
$ids = array_column($resultat, 'ce_utilisateur');
$ids = array_filter($ids, 'is_numeric'); // on oublie les ids de session et autres facéties
$infosUtilisateurs = $this->recupererIntitulesUtilisateursParIds($ids, true);
foreach ($resultat as &$util) {
$ce = $util['ce_utilisateur'];
$util['intitule'] = isset($infosUtilisateurs[$ce]['intitule']) ? $infosUtilisateurs[$ce]['intitule'] : null;
}
 
return array(
'liste' => $resultat
);
}
 
/**
* Liste des utilisateurs ayant fait le plus de votes positifs
* @TODO et le plus de votes sur des propositions retenues (ou ayant atteint un consensus)
*/
private function getListeMeilleursVoteurs() {
$liste = array();
$requete = "SELECT * FROM (SELECT courriel, ce_utilisateur, COUNT(DISTINCT id_vote) AS nombre FROM del_commentaire_vote, del_utilisateur where";
if ($this->annee != null) {
$requete .= " year(date) = " . $this->annee . " AND";
}
$requete .= " ce_utilisateur = id_utilisateur AND valeur = 1 GROUP BY ce_utilisateur) AS utilisateurs WHERE nombre > 100 ORDER BY nombre DESC LIMIT 20";
$resultat = $this->bdd->recupererTous($requete);
 
// Formatage de la liste avec les intitulés des utilisateurs
$ids = array_column($resultat, 'ce_utilisateur');
$ids = array_filter($ids, 'is_numeric'); // on oublie les ids de session et autres facéties
$infosUtilisateurs = $this->recupererIntitulesUtilisateursParIds($ids, true);
foreach ($resultat as &$util) {
$ce = $util['ce_utilisateur'];
$util['intitule'] = isset($infosUtilisateurs[$ce]['intitule']) ? $infosUtilisateurs[$ce]['intitule'] : null;
}
 
return array(
'liste' => $resultat
);
}
 
/**
* Liste des utilisateurs ayant fait au moins une proposition par mois toute l'année
*/
private function getListeProposeursReguliers() {
$liste = array();
$requete = "SELECT cal.nbmois, SUM(somme) / cal.nbmois as moyenne, ce_utilisateur, utilisateur_courriel FROM (SELECT count(*) as somme,"
. " CONCAT(YEAR(date),'-',MONTH(date)) as anneemois, ce_utilisateur, utilisateur_courriel, id_commentaire FROM del_commentaire"
. " WHERE ce_proposition = '' AND nom_sel_nn != '' AND nom_sel_nn IS NOT NULL";
if ($this->annee != null) {
$requete .= " AND year(date) = " . $this->annee;
}
$requete .= " GROUP BY anneemois, ce_utilisateur, utilisateur_courriel) as ppm, (SELECT count(distinct CONCAT(YEAR(date),'-',MONTH(date))) as nbmois FROM del_commentaire WHERE";
if ($this->annee != null) {
$requete .= " year(date) = " . $this->annee . " AND";
}
$requete .= " ce_proposition = '' AND nom_sel_nn != '' AND nom_sel_nn IS NOT NULL) as cal GROUP BY ce_utilisateur, utilisateur_courriel HAVING SUM(somme) / cal.nbmois >= 1"
. " ORDER BY moyenne DESC"; // @ TODO limite ?
$resultat = $this->bdd->recupererTous($requete);
 
// Formatage de la liste avec les intitulés des utilisateurs
$ids = array_column($resultat, 'ce_utilisateur');
$ids = array_filter($ids, 'is_numeric'); // on oublie les ids de session et autres facéties
$infosUtilisateurs = $this->recupererIntitulesUtilisateursParIds($ids, true);
foreach ($resultat as &$util) {
$ce = $util['ce_utilisateur'];
$util['intitule'] = isset($infosUtilisateurs[$ce]['intitule']) ? $infosUtilisateurs[$ce]['intitule'] : null;
}
 
return array(
'liste' => $resultat
);
}
 
/**
* Statistiques sur Sauvages de ma Rue (Sdmr)
* "MPM" = moyenne par mois
* - Nombre total d'observations sdmr
* - Nombre d'observations Sauvages de PACA
*/
private function getSdmr() {
return array(
'nbObsSdmrTotal' => $this->getNbObsSdmrTotal(),
'nbObsSdmrTotalMPM' => $this->getNbObsSdmrTotal(true),
'nbObsSdmrPACA' => $this->getNbObsSdmrPACA(),
'nbObsSdmrPACAMPM' => $this->getNbObsSdmrPACA(true)
);
}
 
/**
* Nombre total d'observations Sauvages de ma Rue
*/
private function getNbObsSdmrTotal($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_observation) as nb_total FROM del_commentaire WHERE";
if ($this->annee != null) {
$requete .= ' YEAR(date) <= ' . $this->annee . ' AND';
}
$requete .= " ce_observation in (SELECT id_observation FROM del_observation WHERE mots_cles_texte like '%sauvages%')";
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre total d'observations Sauvages de ma Rue en PACA
*/
private function getNbObsSdmrPACA($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_observation) as nb_total FROM del_commentaire WHERE";
if ($this->annee != null) {
$requete .= ' YEAR(date) <= ' . $this->annee . ' AND';
}
$requete .= " ce_observation in (SELECT id_observation FROM del_observation"
. " WHERE SUBSTR(ce_zone_geo, 9 , 2) IN (13,04,05,06,83,84) AND mots_cles_texte like '%sauvages%')";
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Statistiques sur les images de Pictoflora
* "MPM" = Moyenne par mois
* - Nombre total d'images
* - Nombre d'images ayant au moins un mot-clé
* - Nombre d'images ayant au moins un vote
* - Nombre d'images de l'année ayant au moins un mot-clé
* - Nombre d'images de l'année ayant au moins un vote
*/
private function getImages() {
return array(
'nbImagesTotal' => $this->getNbImagesTotal(),
'nbImagesTotalMPM' => $this->getNbImagesTotal(true),
'nbImagesAyantTag' => $this->getNbImagesAyantTag(),
'nbImagesAyantTagMPM' => $this->getNbImagesAyantTag(true),
'nbImagesAyantVote' => $this->getNbImagesAyantVote(),
'nbImagesAyantVoteMPM' => $this->getNbImagesAyantVote(true),
'nbImagesAnneeAyantTag' => $this->getNbImagesAnneeAyantTag(),
'nbImagesAnneeAyantTagMPM' => $this->getNbImagesAnneeAyantTag(true),
'nbImagesAnneeAyantVote' => $this->getNbImagesAnneeAyantVote(),
'nbImagesAnneeAyantVoteMPM' => $this->getNbImagesAnneeAyantVote(true),
);
}
 
/**
* Nombre total d'images Pictoflora
*/
private function getNbImagesTotal($mpm=false) {
$requete = "SELECT COUNT(*) AS nb_total FROM del_image";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date_transmission) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete, 'date_transmission');
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre total d'images Pictoflora ayant au moins un mot-clé
*/
private function getNbImagesAyantTag($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_image) AS nb_total FROM del_image_tag";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre total d'images Pictoflora ayant au moins un vote
*/
private function getNbImagesAyantVote($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_image) AS nb_total FROM del_image_vote";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre total d'images Pictoflora de l'année ayant au moins un mot-clé
*/
private function getNbImagesAnneeAyantTag($mpm=false) {
if ($this->annee == null) {
return null;
}
$requete = "SELECT COUNT(DISTINCT ce_image) AS nb_total FROM del_image_tag WHERE YEAR(date) = " . $this->annee
. " AND ce_image IN (SELECT id_image FROM del_image WHERE year(date_transmission) = " . $this->annee . ")";
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre total d'images Pictoflora de l'année ayant au moins un vote
*/
private function getNbImagesAnneeAyantVote($mpm=false) {
if ($this->annee == null) {
return null;
}
$requete = "SELECT COUNT(DISTINCT ce_image) AS nb_total FROM del_image_vote WHERE YEAR(date) = " . $this->annee
. " AND ce_image IN (SELECT id_image FROM del_image WHERE year(date_transmission) = " . $this->annee . ")";
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Statistiques sur les votes et mots-clés (tags) de Pictoflora
* "MPM" = moyenne par mois
* - Nombre total de votes
* - Nombre total de mots clés
* - Nombre d'images ayant le mot-clé "defiPhoto"
*/
private function getTagsVotes() {
return array(
'nbTagsTotal' => $this->getNbTagsTotal(),
'nbTagsTotalMPM' => $this->getNbTagsTotal(true),
'nbVotesTotal' => $this->getNbVotesTotal(),
'nbVotesTotalMPM' => $this->getNbVotesTotal(true),
// devra être paramétré par une liste de mots-clés
//'nbImagesTagDP' => $this->getNbImagesTagDP(),
//'nbImagesTagDPMPM' => $this->getNbImagesTagDP(true)
);
}
 
/**
* Nombre total de mots clés Pictoflora
*/
private function getNbTagsTotal($mpm=false) {
$requete = "SELECT COUNT(*) AS nb_total FROM del_image_tag";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre total de votes Pictoflora
*/
private function getNbVotesTotal($mpm=false) {
$requete = "SELECT COUNT(*) AS nb_total FROM del_image_vote";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Statistiques sur les utilisateurs de Pictoflora
* "MPM" = Moyenne par mois
* "AF" = Ayant fait
* - Nombre d'utilisateurs ayant ajouté un mot-clé
* - Nombre d'utilisateurs ayant voté
* - Nombre d'utilisateurs ayant fait une action
*/
private function getUtilisateursPf() {
return array(
'nbUtilisateursAFTag' => $this->getNbUtilisateursPfAFTag(),
'nbUtilisateursAFTagMPM' => $this->getNbUtilisateursPfAFTag(true),
'nbUtilisateursAFVote' => $this->getNbUtilisateursPfAFVote(),
'nbUtilisateursAFVoteMPM' => $this->getNbUtilisateursPfAFVote(true),
'nbUtilisateursAFAction' => $this->getNbUtilisateursPfAFAction(),
'nbUtilisateursAFActionMPM' => $this->getNbUtilisateursPfAFActionMPM()
);
}
 
/**
* Nombre d'utilisateurs ayant ajouté un mot-clé
*/
private function getNbUtilisateursPfAFTag($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_utilisateur) AS nb_total FROM del_image_tag";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'utilisateurs ayant fait un vote
*/
private function getNbUtilisateursPfAFVote($mpm=false) {
$requete = "SELECT COUNT(DISTINCT ce_utilisateur) AS nb_total FROM del_image_vote";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
if ($mpm) {
$requete = $this->encapsulerMPM($requete);
}
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Nombre d'utilisateurs ayant fait une action
*/
private function getNbUtilisateursPfAFAction() {
$requete = "SELECT COUNT(*) AS nb_total FROM (SELECT ce_utilisateur FROM del_image_tag";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
$requete .= " UNION SELECT ce_utilisateur FROM del_image_vote";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
$requete .= ") AS action";
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Moyenne par mois du nombre d'utilisateurs ayant fait une action
* -> n'est pas encapsulable par encapsulerMPM()
*/
private function getNbUtilisateursPfAFActionMPM() {
$requete = "SELECT avg(nb_total) FROM (SELECT COUNT(*) AS nb_total FROM (SELECT * FROM (SELECT ce_utilisateur, date FROM del_image_tag";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
$requete .= " UNION SELECT ce_utilisateur, date FROM del_image_vote";
if ($this->annee != null) {
$requete .= ' WHERE YEAR(date) = ' . $this->annee;
}
$requete .= ") AS action GROUP BY ce_utilisateur) AS utildate GROUP BY CONCAT(year(date),month(date))) as truc";
$resultat = $this->bdd->recupererTous($requete);
return intval(array_pop($resultat[0]));
}
 
/**
* Liste des mots-clés les plus fréquents
*/
private function getListeMeilleursTags() {
$liste = array();
$requete = "SELECT count(*) as occurrences, tag FROM del_image_tag";
if ($this->annee != null) {
$requete .= " WHERE YEAR(date) = " . $this->annee;
}
$requete .= " GROUP BY tag ORDER BY occurrences DESC LIMIT 20";
$resultat = $this->bdd->recupererTous($requete);
return array(
'liste' => $resultat
);
}
 
/**
* Liste des utilisateurs ayant ajouté le plus de mots-clés
*/
private function getListeMeilleursTagueurs() {
$resultat = array();
$requete = "SELECT count(*) as nombre, IF (ce_utilisateur REGEXP '^-?[0-9]+$' OR ce_utilisateur REGEXP '^.+@.+$', ce_utilisateur, null) as ce_util FROM del_image_tag";
if ($this->annee != null) {
$requete .= " WHERE year(date) = " . $this->annee;
}
$requete .= " GROUP BY ce_util ORDER BY nombre DESC LIMIT 20";
$resultat = $this->bdd->recupererTous($requete);
 
// Formatage de la liste avec les intitulés des utilisateurs
$ids = array_column($resultat, 'ce_util');
$ids = array_filter($ids, 'is_numeric'); // on oublie les ids de session et autres facéties
$infosUtilisateurs = $this->recupererIntitulesUtilisateursParIds($ids, true);
foreach ($resultat as &$util) {
$ce = $util['ce_util'];
if (isset($infosUtilisateurs[$ce]['intitule'])) {
$util['intitule'] = $infosUtilisateurs[$ce]['intitule'];
} else {
$posa = strpos($ce, '@');
if ($posa !== false) {
$util['intitule'] = substr($ce, 0, $posa+1) . '...';
} else {
$util['intitule'] = null;
}
}
}
 
return array(
'liste' => $resultat
);
}
 
/**
* Encapsule une reqûete de comptage dans un autre morceau de requête
* afin de calculer la moyenne par mois
* @param string $requete count() qui doit renvoyer une colonne 'nb_total'
*/
protected function encapsulerMPM($requete, $colonne="date") {
$requeteEncapsulee = "SELECT AVG(nb_total) as moyenne FROM ("
. $requete
. " GROUP BY CONCAT(year($colonne),month($colonne)) ) AS nombre";
return $requeteEncapsulee;
}
 
/**
* Prend en paramêtre un tableau d'identifiants utilisateurs et retourne après avoir interrogé un
* webservice de l'annuaire un tableau avec en clé l'id et en valeur l'intitulé
* @param array $ids un tableau d'ids
*/
protected function recupererIntitulesUtilisateursParIds(array $ids) {
$service = "utilisateur/infos-par-id/" . implode(',', $ids);
$url = $this->conteneur->getParametre('urlServiceBaseAnnuaire') . $service;
//echo "URL: $url\n\n";
$json = $this->conteneur->getRestClient()->consulter($url);
$resultat = json_decode($json, true);
return $resultat;
}
}
/tags/v1.10-sodium/services/modules/0.1/Observations.php
New file
0,0 → 1,227
<?php
// declare(encoding='UTF-8');
/**
* Classe principale de chargement des services Observations.
*
* URLs possibles :
* GET :
* http://localhost/service:del:0.1/observations
* toutes les observations (infos obs, infos images, infos propositions, infos nb commentaires)
*
* http://localhost/service:del:0.1/observations?retour.format=widget
* toutes les infos des observations pour le Widget DEL
*
* http://localhost/service:del:0.1/observations/#idObs
* une observation donnée et ses images, SANS LES propositions & nombre de commentaire*
*
* http://localhost/service:del:0.1/observations/#idObs/#idVote/vote
* toutes les infos sur les votes d'une proposition
*
* PUT :
* http://localhost/service:del:0.1/observations/#idObs/#idCommentaire/vote
* ajoute un vote (+ ou -) pour une obs et une proposition donnée
*
* POST :
* http://localhost/service:del:0.1/observations/#idObs
* utilisé seulement par les admins pour modifier une obs depuis DEL (dépublication des obs)
*
* http://localhost/service:del:0.1/observations/#idObs/#idCommentaire/vote
* modifie un vote (+ ou -) pour une obs et une proposition donnée
*
* @category DEL
* @package Services
* @subpackage Observations
* @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 Observations extends RestService {
 
private $parametres = array();
private $ressources = array();
private $methode = null;
private $serviceNom = 'observations';
private $sousServiceNom = null;
private $cheminCourant = null;
 
private $conteneur;
 
/** Indique si oui (true) ou non (false), on veut utiliser les paramètres bruts. */
protected $utilisationParametresBruts = true;
 
public function __construct() {
$this->cheminCourant = dirname(__FILE__).DS;
}
 
public function consulter($ressources, $parametres) {
$this->methode = 'consulter';
$this->initialiserRessourcesEtParametres($ressources, $parametres);
return $this->executerService();
}
 
public function ajouter($ressources, $requeteDonnees) {
$this->methode = 'ajouter';
$this->initialiserRessourcesEtParametres($ressources, $requeteDonnees);
return $this->executerService();
}
 
public function modifier($ressources, $requeteDonnees) {
$this->methode = 'modifier';
$this->initialiserRessourcesEtParametres($ressources, $requeteDonnees);
return $this->executerService();
}
 
private function executerService() {
$reponseHttp = new ReponseHttp();
try {
$this->conteneur = new Conteneur($this->parametres);
$resultat = $this->traiterRessources();
$reponseHttp->setResultatService($resultat);
} catch (Exception $e) {
$reponseHttp->ajouterErreur($e);
}
$reponseHttp->emettreLesEntetes();
$corps = $reponseHttp->getCorps();
return $corps;
}
 
private function initialiserRessourcesEtParametres($ressources, $parametres = array()) {
$this->ressources = $ressources;
$this->parametres = $parametres;
}
 
private function traiterRessources() {
$this->analyserRessources();
$retour = $this->initialiserService();
return $retour;
}
 
private function analyserRessources() {
if ($this->methode == 'consulter') {
$this->analyserRessoucesConsultation();
} else if ($this->methode == 'modifier' || $this->methode == 'ajouter') {
$this->analyserRessoucesModification();
}
}
 
private function analyserRessoucesConsultation() {
if (count($this->ressources) == 0) {
// http://localhost/service:del:0.1/observations
$this->sousServiceNom = 'liste-observations';
} else if (count($this->ressources) == 1) {
if ($this->etreRessourceIdentifiant(0)) {
// http://localhost/service:del:0.1/observations/#idObs
$this->sousServiceNom = 'observation-details';
}
} else if (count($this->ressources) == 3) {
if ($this->etreRessourceIdentifiant(0) && $this->etreRessourceIdentifiant(1) && $this->verifierRessourceValeur(2, 'vote')) {
// http://localhost/service:del:0.1/observations/#idObs/#idProposition/vote/
$this->sousServiceNom = 'vote-observation';
}
}
 
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function analyserRessoucesModification() {
if (count($this->ressources) == 1) {
if ($this->methode == 'modifier' && $this->etreRessourceIdentifiant(0)) {
// http://localhost/service:del:0.1/observations/#idObs
$this->sousServiceNom = 'observation-details';
}
} else if (count($this->ressources) == 3) {
if ($this->etreRessourceIdentifiant(0) && $this->etreRessourceIdentifiant(1) && $this->verifierRessourceValeur(2, 'vote')) {
// http://localhost/service:del:0.1/observations/#idObs/#idProposition/vote/
$this->sousServiceNom = 'vote-observation';
}
}
 
if ($this->sousServiceNom == null) {
$this->lancerMessageErreurRessource();
}
}
 
private function etreRessourceIdentifiant($num) {
$presenceId = false;
if (isset($this->ressources[$num]) && is_numeric($this->ressources[$num])) {
$presenceId = true;
}
return $presenceId;
}
 
private function verifierRessourceValeur($num, $valeur) {
$ok = false;
if (isset($this->ressources[$num]) && $this->ressources[$num] == $valeur) {
$ok = true;
}
return $ok;
}
 
private function verifierParametreValeur($cle, $valeur) {
$ok = false;
if (isset($this->parametres[$cle]) && $this->ressources[$cle] == $valeur) {
$ok = true;
}
return $ok;
}
 
private function lancerMessageErreurRessource() {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "La ressource demandée '$ressource' ".
"n'est pas disponible pour le service ".$this->serviceNom." !\n".
"Les URLs disponibles sont : \n".
" - en GET : observations, observations/#idObs/#idProposition/vote \n".
" - en POST : observations/#id, observations/#idObs/#idProposition/vote \n".
" - en PUT : observations/#idObs/#idProposition/vote \n";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
 
private function initialiserService() {
$classe = $this->obtenirNomClasseService($this->sousServiceNom);
$chemins = array();
$chemins[] = $this->cheminCourant.$this->serviceNom.DS.$classe.'.php';
$chemins[] = $this->cheminCourant.'commun'.DS.$classe.'.php';
$retour = '';
$service = null;
foreach ($chemins as $chemin) {
if (file_exists($chemin)) {
require_once $chemin;
$service = new $classe($this->conteneur);
if ($this->methode == 'consulter') {
$retour = $service->consulter($this->ressources, $this->parametres);
} elseif ($this->methode == 'ajouter') {
$retour = $service->ajouter($this->ressources, $this->parametres);
} elseif ($this->methode == 'modifier') {
$retour = $service->modifier($this->ressources, $this->parametres);
} else {
$message = "Le sous-service '{$this->sousServiceNom}' du service '{$this->serviceNom}' ".
"ne possède pas de méthode '{$this->methode}' !";
$code = RestServeur::HTTP_NON_IMPLEMENTE;
throw new Exception($message, $code);
}
}
}
 
if (is_null($service)) {
$ressource = $this->sousServiceNom.'/'.implode('/', $this->ressources);
$message = "Le classe '$classe' correspondant à la ressource '$ressource' ".
"n'existe pas dans le service '{$this->serviceNom}' !";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $retour;
}
 
private function obtenirNomClasseService($mot) {
$classeNom = str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot))));
return $classeNom;
}
}