Rev 1949 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?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-dessusreturn isset($this->parametres['nom_sel'])&& isset($this->parametres['nom_referentiel'])&& !isset($this->parametres['nom_sel_nn']);}}