Subversion Repositories eFlore/Applications.del

Rev

Rev 1977 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
858 gduche 1
<?php
2
// declare(encoding='UTF-8');
3
/**
1793 jpm 4
 * Permet d'ajouter un commentaire.
858 gduche 5
 *
1795 jpm 6
 * @category   DEL
7
 * @package    Services
1793 jpm 8
 * @subpackage Commentaires
1795 jpm 9
 * @version    0.1
10
 * @author     Mathias CHOUET <mathias@tela-botanica.org>
11
 * @author     Jean-Pascal MILCENT <jpm@tela-botanica.org>
12
 * @author     Aurelien PERONNET <aurelien@tela-botanica.org>
13
 * @license    GPL v3 <http://www.gnu.org/licenses/gpl.txt>
14
 * @license    CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
15
 * @copyright  1999-2014 Tela Botanica <accueil@tela-botanica.org>
858 gduche 16
 */
17
 
18
class AjouterCommentaire {
1299 jpm 19
 
858 gduche 20
	private $conteneur;
21
	private $navigation;
22
	private $bdd;
23
	private $parametres = array();
1299 jpm 24
 
1795 jpm 25
	private $mapping = array();
1805 jpm 26
	private $erreurs = array();
858 gduche 27
 
1793 jpm 28
	public function __construct(Conteneur $conteneur) {
29
		$this->conteneur = $conteneur;
1795 jpm 30
		$this->navigation =  $this->conteneur->getNavigation();
1793 jpm 31
		$this->bdd = $this->conteneur->getBdd();
1795 jpm 32
 
33
		$this->mapping = $this->conteneur->getParametreTableau('commentaires.mapping');
858 gduche 34
	}
1299 jpm 35
 
1795 jpm 36
	public function ajouter($parametres) {
37
		$this->parametres = $parametres;
38
		$this->verifierParametres();
1299 jpm 39
 
1795 jpm 40
		$this->completerParametresUtilisateur();
41
		$this->gererPropositionInitiale();
1949 aurelien 42
		// Dernière chance de rattachement au référentiel d'un nom
43
		// sans nn (cas du copier-coller ou bien de l'appli tierce
44
		// qui envoie des infos incomplètes)
45
		$this->tenterEnrichissementTaxonomique();
1795 jpm 46
		$idCommentaireAjoute = $this->insererCommentaire();
1299 jpm 47
 
883 aurelien 48
		// Mettre en forme le résultat et l'envoyer pour affichage
858 gduche 49
		$resultat = new ResultatService();
1795 jpm 50
		$resultat->corps = array('id_commentaire' => $idCommentaireAjoute);
1299 jpm 51
 
858 gduche 52
		return $resultat;
53
	}
1299 jpm 54
 
1795 jpm 55
	private function verifierParametres() {
858 gduche 56
		if (!isset($this->parametres['observation'])) {
1805 jpm 57
			$this->erreurs[] = "Impossible d'ajouter un commentaire sans identifiant d'observation (paramètre 'observation').";
1299 jpm 58
		}
59
 
874 gduche 60
		if (!isset($this->parametres['auteur.id'])) {
1805 jpm 61
			$this->verifierParamsAuteurAnonyme();
1299 jpm 62
		}
63
 
1805 jpm 64
		$this->verifierParamsNonVide();
65
 
66
		if (isset($this->parametres['nom_sel_nn']) && !isset($this->parametres['nom_referentiel'])) {
67
			$this->erreurs[] = "Si le paramètre «nom_sel_nn» est présent, le paramètre «nom_referentiel» doit l'être aussi.";
883 aurelien 68
		}
1299 jpm 69
 
1805 jpm 70
		if (!empty($this->erreurs)) {
71
			$msg = "Erreur de configuration :\n".implode("\n\n", $this->erreurs);
1795 jpm 72
			throw new Exception($msg, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
858 gduche 73
		}
74
	}
1299 jpm 75
 
1805 jpm 76
	private function verifierParamsAuteurAnonyme() {
77
		$paramsAuteur = array('auteur.nom', 'auteur.prenom', 'auteur.courriel');
78
		$paramsAuteurManquant = array();
79
		foreach ($paramsAuteur as $param) {
80
			if (!isset($this->parametres[$param])) {
81
				$paramsAuteurManquant[] = $param;
82
			}
83
		}
84
 
85
		if (!empty($paramsAuteurManquant)) {
86
			$msgAuteurTpl = "Si le parametre 'auteur.id' n'est pas utilisé, il est nécessaire d'indiquer les ".
87
			"nom (paramètre 'auteur.nom'), prénom (paramètre 'auteur.prenom') et courriel ".
88
			"(paramètre 'auteur.courriel') de l'auteur.\nLes paramètres suivant sont abscents : %s\n";
89
			$this->erreurs[] = sprintf($msgAuteurTpl, implode(', ', $paramsAuteurManquant));
90
		}
91
	}
92
 
93
	private function verifierParamsNonVide() {
94
		$paramsNonVide = array('nom_sel', 'nom_referentiel', 'nom_sel_nn');
95
		foreach ($paramsNonVide as $param) {
96
			if (isset($this->parametres[$param]) && trim($this->parametres[$param]) == '' ) {
97
				$this->erreurs[] = "S'il est présent le paramètre «$param» ne peut pas être vide.";
98
			}
99
		}
100
	}
101
 
1795 jpm 102
	private function completerParametresUtilisateur() {
103
		$utilisateur =  (isset($this->parametres['auteur.id'])) ? $this->obtenirUtilisateurAvecId() : $this->obtenirUtilisateurSansId();
104
		if ($utilisateur !== false) {
105
			foreach ($utilisateur as $param => $valeur) {
106
				$this->parametres[$param] = $valeur;
1299 jpm 107
			}
858 gduche 108
		}
1795 jpm 109
	}
1299 jpm 110
 
1795 jpm 111
	private function obtenirUtilisateurAvecId() {
112
		$auteurIdP = $this->bdd->proteger($this->parametres['auteur.id']);
113
		$requete = "SELECT id_utilisateur AS 'auteur.id', nom AS 'auteur.nom', prenom AS 'auteur.prenom', courriel AS 'auteur.courriel' ".
114
			'FROM del_utilisateur '.
115
			"WHERE id_utilisateur = $auteurIdP ".
116
			' -- '.__FILE__.' : '.__LINE__;
117
		$utilisateur = $this->bdd->recuperer($requete);
858 gduche 118
		return $utilisateur;
119
	}
1299 jpm 120
 
1795 jpm 121
	private function obtenirUtilisateurSansId() {
122
		$nomP = $this->bdd->proteger($this->parametres['auteur.nom']);
123
		$prenomP = $this->bdd->proteger($this->parametres['auteur.prenom']);
124
		$courrielP = $this->bdd->proteger($this->parametres['auteur.courriel']);
1299 jpm 125
 
126
		$requete = "SELECT id_utilisateur AS 'auteur.id', nom AS 'auteur.nom', prenom AS 'auteur.prenom', ".
1795 jpm 127
			"courriel AS 'auteur.courriel' ".
1299 jpm 128
			'FROM del_utilisateur '.
1795 jpm 129
			"WHERE courriel = $courrielP AND nom = $nomP AND prenom = $prenomP ".
130
			' -- '.__FILE__.' : '.__LINE__;
131
		$utilisateur = $this->bdd->recuperer($requete);
132
		return $utilisateur;
858 gduche 133
	}
1299 jpm 134
 
1795 jpm 135
	private function gererPropositionInitiale() {
1803 jpm 136
		if ($this->verifierExistencePropositionInitiale() === false) {
1795 jpm 137
			$this->creerPropositionInitiale();
138
			// TODO : en cas d'échec de la création de la proposition ajouter un log...
858 gduche 139
		}
140
	}
1299 jpm 141
 
1795 jpm 142
	private function verifierExistencePropositionInitiale() {
143
		$idObsP =  $this->bdd->proteger($this->parametres['observation']);
1299 jpm 144
		$requete = 'SELECT COUNT(*) >= 1 AS existe '.
145
			'FROM del_commentaire '.
1795 jpm 146
			"WHERE ce_observation = $idObsP ".
147
			'	AND proposition_initiale = 1 '.
148
			' -- '.__FILE__.' : '.__LINE__;
1251 aurelien 149
		$resultat = $this->bdd->recuperer($requete);
150
		return $resultat['existe'] == 1;
151
	}
1299 jpm 152
 
1795 jpm 153
	private function creerPropositionInitiale() {
154
		$idObsP =  $this->bdd->proteger($this->parametres['observation']);
155
		$requete = 'INSERT IGNORE INTO del_commentaire '.
1299 jpm 156
			'(ce_observation, ce_utilisateur, utilisateur_prenom, utilisateur_nom, utilisateur_courriel, '.
1301 jpm 157
			'nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, nt, famille, nom_referentiel, date, proposition_initiale) '.
1802 jpm 158
			'SELECT id_observation, ce_utilisateur, prenom, nom, courriel, nom_sel, '.
159
			"IF(nom_sel_nn = 0, NULL, nom_sel_nn), IF(nom_ret = '', NULL, nom_ret), IF(nom_ret_nn = 0, NULL, nom_ret_nn), ".
160
			"IF(nt = 0, NULL, nt), IF(famille = '', NULL, famille), IF(nom_sel_nn = 0, NULL, nom_referentiel), NOW(), '1' ".
1299 jpm 161
			'FROM del_observation AS do '.
162
			'	LEFT JOIN del_utilisateur AS du '.
163
			'		ON do.ce_utilisateur = du.id_utilisateur '.
1795 jpm 164
			"WHERE id_observation = $idObsP ".
165
			' -- '.__FILE__.' : '.__LINE__;
166
		$resultat = $this->bdd->executer($requete);
1251 aurelien 167
		return $resultat;
168
	}
1299 jpm 169
 
1795 jpm 170
	private function insererCommentaire() {
171
		$champs = $this->creerEnteteChamps();
172
		$values = $this->creerClauseValues();
173
		$requete = "INSERT INTO del_commentaire (date, $champs) VALUES (NOW(), $values) ".
174
			' -- '.__FILE__.' : '.__LINE__;
1299 jpm 175
 
1795 jpm 176
		$retour = $this->bdd->executer($requete);
177
		if ($retour == null) {
178
			$msgTpl = "Erreur inopinée lors de l'insertion du commentaire lié à l'observation «%s».";
179
			$msg = sprintf($msgTpl, $this->parametres['observation']);
180
			throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
858 gduche 181
		}
1299 jpm 182
 
1795 jpm 183
		$idCommentaire = $this->bdd->recupererIdDernierAjout();
184
		return $idCommentaire;
858 gduche 185
	}
1299 jpm 186
 
1795 jpm 187
	private function creerEnteteChamps() {
188
		return $this->creerSuiteChampsOuValeurs('champs');
189
	}
190
 
191
	private function creerClauseValues() {
192
		return $this->creerSuiteChampsOuValeurs('valeurs');
193
	}
194
 
195
	private function creerSuiteChampsOuValeurs($mode) {
196
		$suite = array();
197
		foreach ($this->mapping as $nomChampBdd => $nomAttributSortie) {
198
			if (isset($this->parametres[$nomAttributSortie]) && $this->parametres[$nomAttributSortie] != null) {
199
				if ($mode == 'valeurs') {
200
					$suite[] = $this->bdd->proteger($this->parametres[$nomAttributSortie]);
201
				} else if ($mode == 'champs') {
202
					$suite[] = $nomChampBdd;
203
				} else {
204
					$msg = "Erreur interne : mauvais paramètre passé à la méthode 'creerSuiteChampsOuValeurs'";
205
					throw new Exception($msg, RestServeur::HTTP_CODE_ERREUR);
206
				}
858 gduche 207
			}
208
		}
1795 jpm 209
		return implode(', ', $suite);
858 gduche 210
	}
1949 aurelien 211
 
212
	private function tenterEnrichissementTaxonomique() {
213
		if($this->commentaireEstPropositionSansNn()) {
1977 aurelien 214
			// TODO: utiliser le référentiel de l'obs si celui-ci
215
			// n'est pas fourni dans le commentaire et prendre le résultat
216
			// si celui-ci est unique
1949 aurelien 217
			$referentiel = $this->parametres['nom_referentiel'];
218
			$requete = urlencode($this->parametres['nom_sel']);
219
 
220
			$url = sprintf($this->conteneur->getParametre('nomstaxons.url_autocompletion_tpl'), $referentiel, $requete);
221
			$restClient = $this->conteneur->getRestClient();
222
			// Un retour vide est possible (un cas normal où il n'y a pas de résultat)
223
			// mais il fait planter le retour du service si on active l'affichage des erreurs
224
			// donc on passe sciemment les erreurs sous silence (car cette erreur n'en est pas une)
225
			$resultatJson = @$restClient->consulter($url);
226
			$resultats = json_decode($resultatJson, true);
227
 
228
			// On ne fait l'affectation que si l'on est sur (donc si un seul résultat)
229
			if (isset($resultats['resultat']) && count($resultats['resultat']) == 1) {
230
				$info = array_pop($resultats['resultat']);
231
				$this->parametres['nom_sel_nn'] = $info['num_nom'];
232
			}
233
		}
234
	}
235
 
236
	private function commentaireEstPropositionSansNn() {
237
		// Pas besoin de tester si c'est vide, normalement verifierParametres
238
		// l'a déjà fait au-dessus
239
		return isset($this->parametres['nom_sel'])
240
				&& isset($this->parametres['nom_referentiel'])
241
						&& !isset($this->parametres['nom_sel_nn']);
242
	}
1793 jpm 243
}