Subversion Repositories eFlore/Applications.cel

Rev

Rev 1631 | Rev 2152 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1582 jpm 1
<?php
2
// declare(encoding='UTF-8');
3
/**
4
 * Service permettant de récupérer toutes les informations d'une observation publique.
5
 * Encodage en entrée : utf8
6
 * Encodage en sortie : utf8
7
 *
8
 * Cas d'utilisation :
9
 * GET /CelObs/[id] : oû id est l'identifiant d'une observation publique
10
 *
11
 * @author Jean-Pascal MILCENT <jpm@clapas.org>
12
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
13
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
14
 * @version $Id$
15
 * @copyright © 2013, Jean-Pascal MILCENT
16
 */
17
class CelObs extends Cel {
18
	private $rechercheObs = null;
19
	private $chpsEtendus = null;
2143 jpm 20
	private $donnees = null;
1582 jpm 21
 
22
	public function __construct($config) {
23
		parent::__construct($config);
24
		$this->rechercheObs = new RechercheObservation($config);
25
		$this->chpsEtendus = new GestionChampsEtendus($config, 'obs');
26
	}
27
 
28
	function getElement($ressources){
29
		$retour = false;
30
		$idObs = $ressources[0];
31
		if (isset($idObs) && preg_match('/^[0-9]+$/', $idObs)) {
32
 
33
			$criteres = array('id_observation' => $idObs, 'transmission' => 1);
1631 raphael 34
			$obsTrouvee = $this->rechercheObs->rechercherObservations(null, $criteres, 0, 1)->get();
1582 jpm 35
 
36
			$observation = array();
37
			if (is_array($obsTrouvee) && count($obsTrouvee) > 0) {
38
				$observation = $obsTrouvee[0];
39
			}
40
			$observation = $this->preparerChamps($observation);
41
			$observation = $this->selectionnerChamps($observation);
42
			$observation = $this->formaterClePourJs($observation);
43
 
44
			$champsEtendus = $this->chpsEtendus->consulter($idObs);
45
			if (is_array($champsEtendus) && count($champsEtendus) > 0) {
46
				$champsEtendus = $this->preparerChampsEtendus($champsEtendus);
47
				$observation['extension'] = $champsEtendus;
48
			}
49
 
50
			$this->envoyerJson($observation);
51
			$retour = true;
52
		}
53
		return $retour;
54
	}
55
 
56
	private function preparerChamps($champs) {
57
		if (isset($champs['date_observation'])) {
58
			$date = explode(' ', $champs['date_observation']);
59
			$champs['date_observation'] = $date[0];
60
		}
61
		return $champs;
62
	}
63
 
64
	private function selectionnerChamps($observation) {
65
		$champs = array('id_observation', 'nom_sel', 'nom_ret', 'nom_ret_nn', 'nt', 'famille',
66
			'nom_referentiel', 'ce_zone_geo', 'zone_geo', 'lieudit', 'station', 'milieu', 'latitude', 'longitude',
67
			'geodatum', 'date_observation', 'mots_cles_texte', 'commentaire', 'date_creation', 'date_modification',
68
			'date_transmission', 'code_insee_calcule', 'abondance', 'certitude', 'phenologie', 'altitude');
69
		$selection = array();
70
		foreach ($champs as $chp) {
71
			if (isset($observation[$chp])) {
72
				$selection[$chp] = $observation[$chp];
73
			}
74
		}
75
		return $selection;
76
	}
77
 
78
	private function formaterClePourJs(Array $tableau) {
79
		$tableauJs = array();
80
		foreach ($tableau as $cle => $valeur) {
81
			if ($cle == 'ce_zone_geo') {
82
				$cle = 'codeZoneGeo';
83
			} else {
84
				$cle = str_replace(' ', '', ucwords(str_replace('_', ' ', $cle)));
85
				$cle{0} = strtolower($cle{0});
86
			}
87
			$tableauJs[$cle] = $valeur;
88
		}
89
		return $tableauJs;
90
	}
91
 
92
	private function preparerChampsEtendus($champs) {
93
		$retour = array();
94
		foreach ($champs as $chp) {
95
			$retour[$chp['cle']] = array('valeur' => $chp['valeur'], 'label' => $chp['label']);
96
		}
97
		return $retour;
98
	}
2143 jpm 99
 
100
	/**
101
	 * Méthode appelée avec une requête de type POST et un identifiant d'observation.
102
	 * Modifie une observation en fonction des informations envoyées en POST.
103
	 * Utilisé par:
104
	 * - service:del:0.1/determinations/ : ValiderDetermination.php::modifierObservationParDetermination()
105
	 * - service:del:0.1/observations/#idObs [POST] : pour dépublier une observation
106
	 *
107
	 * @param $uid array	$uid[0] (int) : identifiant observation
108
	 * @param pairs array	tableau contenant les champs à modifier sous la forme : nom_du_champ=nouvelle_valeur
109
	 */
110
	public function updateElement($ressources, $donnees) {
111
		$this->donnees = $donnees;
112
		if ($this->controlerAccessibiliteWs()) {
113
			if ($this->controleAppelIpAutorisee()) {
114
				$idObs = isset($ressources[0]) ? $ressources[0] : '';
115
				$this->verifierIdentifiantObs($idObs);
116
 
117
				$idObs = explode(',', $idObs);
118
				// Seulement la dépublication
119
				if (isset($this->donnees['transmission']) && count($this->donnees) == 1) {
120
					$gestionnaireObs = new GestionObservation($this->config);
121
					$detransmissionObs = $gestionnaireObs->modifierTransmissionObservation($idObs, false);
122
					if ($detransmissionObs === false) {
123
						$msg = "Un problème est survenu (voir log). Les observations n'ont pas pu être dépubliées.";
124
						$this->envoyerMessageErreur(304, $msg);
125
					}
126
				} if (count($this->donnees) == 3) {
127
					$donneesObligatoires = array('id_observation', 'ce_utilisateur', 'nom_sel');
128
					if ($this->verifierDonneesObligatoires($donneesObligatoires)) {
129
						$this->modifierObservationDepuisDEL($idObs);
130
					}
131
				} else {
132
					$msg = "La modification complète d'une observation n'est pas implémentée. \n".
133
						"Uniquement la dépublication pour l'instant fonctionne";
134
					$this->envoyerMessageErreur(501, $msg);
135
				}
136
 
137
				$this->envoyer('OK');
138
			} else {
139
				$msg = "Accès interdit. \n"."Vous n'êtes pas autorisé à accéder à ce service depuis '{$_SERVER['REMOTE_ADDR']}' !\n";
140
				$this->envoyerMessageErreur(401, $msg);
141
			}
142
		}
143
	}
144
 
145
	private function modifierObservationDepuisDEL($idObs) {
146
		$gestion_observation = new GestionObservation($this->config);
147
		$pairs = array_map('trim', $this->donnees);
148
		$utilisateur = $pairs['ce_utilisateur'];
149
		unset($pairs['ce_utilisateur'], $pairs['id_observation']);
150
 
151
		// mise à jour des mots-clefs suite à une validation:
152
		// typiquement, DEL modifierObservationParDetermination()
153
		// nous enverra obsKeywordDelete=aDeterminer en plus de certitude=Certaine
154
		$obsKeywordDelete = @trim($pairs['obsKeywordDelete']);
155
		// $imgKeywordDelete = @trim($pairs['imgKeywordDelete']);
156
		unset($pairs['obsKeywordDelete']); // , $pairs['imgKeywordDelete']);
157
 
158
		// complete les données de la proposition validée car:
159
		// 1) la table tb_del.del_commentaire ne contient pas toutes les informations nécessaires
160
		// 2) la table tb_del.del_commentaire ne *devrait* pas contenir beaucoup plus que nom_sel et nom_sel_nn
161
		// 3) la génération de ces données ici, au moment de l'UPDATE, est le meilleur garant de leur fiabilité
162
		$more_data = $this->NN2(@$pairs['nom_sel_nn'], @$pairs['nom_referentiel']);
163
		if($more_data) $pairs = array_merge($pairs, $more_data);
164
 
165
		$modification = $gestion_observation->modifierObservationPublique($utilisateur, $idObs, $pairs);
166
		if($modification) {
167
			$gestion_mots_cles = new GestionMotsClesChemin($this->config, 'obs');
168
			// supression des éventuelles liaison de l'obs avec le mot clé contenu dans obsKeywordDelete
169
			$supp_liaison_mot_cle = $gestion_mots_cles->supprimerLiaisonPourMotCleEtIdElementLie($obsKeywordDelete, $idObs, $utilisateur);
170
			// TODO : quel impact de la valeur de retour ?
171
			header("Content-Type: text/plain; charset=utf-8");
172
			die("OK"); // attention, compatibilité avec ValiderDetermination.php de DEL !
173
		}
174
		// cf TODO: n'arrivera pas tant que l'UPDATE ajoutera systématiquement date_modification = now()
175
		elseif($modification === 0) {
176
            header("HTTP/1.0 304 Not Modified"); // XXX: PHP 5.4 // http_response_code(304); // Not Modified
177
			header("Content-Type: text/plain; charset=utf-8");
178
			die("Not Modified");
179
		}
180
		else {
181
			header("HTTP/1.0 500 Internal Server Error"); // XXX: PHP: 5.4 // http_response_code(500); // Internal Server Error
182
			header("Content-Type: text/plain; charset=utf-8");
183
			die("Impossible de modifier l'observation associée à cet identifiant " . mysql_error());
184
		}
185
	}
186
 
187
	private function verifierIdentifiantObs($chaine) {
188
		$ok = preg_match('/^(?:[0-9]+,)*[0-9]+$/', $chaine);
189
		if ($ok == false) {
190
			$msg = "Indiquer un ou plusieurs identifiants d'obs séparés par des virgules.";
191
			$this->envoyerMessageErreur(412, $msg);
192
		}
193
		return $ok;
194
	}
195
 
196
	private function verifierDonneesObligatoires($champsObligatoires) {
197
		foreach ($champsObligatoires as $param) {
198
			if (! isset($this->donnees[$param])) {
199
				$msg = sprintf("Paramètre %s manquant (parmi %s)", $param, implode(', ', $champsObligatoires));
200
				$this->envoyerMessageErreur(412, $msg);
201
			}
202
		}
203
	}
204
 
205
	private function NN2($id, $ref) {
206
		if(!$db || !$id || !$ref) return FALSE;
207
		switch($ref) {
208
			case "bdtfx":
209
				return $this->bdd->query(sprintf(, self::db, self::bdtfx,  self::db, self::bdtfx, intval($id), __FILE__, __LINE__))->fetch(PDO::FETCH_ASSOC);
210
		case "bdtxa":
211
		  return $this->bdd->query(sprintf("SELECT o.num_nom_retenu AS nom_ret_nn, o.num_tax AS nt, CONCAT(o.nom_sci, ' ', o.auteur) AS nom_sel". // subtilité: "num_tax"
212
									" , o.famille, CONCAT(ret.nom_sci, ' ', ret.auteur) AS nom_ret".
213
									" FROM %s.%s o".
214
									" LEFT JOIN %s.%s ret ON o.num_nom_retenu != 0 AND o.num_nom_retenu = ret.num_nom".
215
									" WHERE o.num_nom = %d -- %s:%d", self::db, self::bdtxa,  self::db, self::bdtxa, intval($id), __FILE__, __LINE__))->fetch(PDO::FETCH_ASSOC);
216
		case "isfan":
217
		  return $this->bdd->query(sprintf("SELECT o.num_nom_retenu AS nom_ret_nn, o.num_taxonomique AS nt, CONCAT(o.nom_sci, ' ', o.auteur) AS nom_sel".
218
									" , o.famille, CONCAT(ret.nom_sci, ' ', ret.auteur) AS nom_ret".
219
									" FROM %s.%s o".
220
									" LEFT JOIN %s.%s ret ON o.num_nom_retenu != 0 AND o.num_nom_retenu = ret.num_nom".
221
									" WHERE o.num_nom = %d -- %s:%d", self::db, self::isfan,  self::db, self::isfan, intval($id), __FILE__, __LINE__))->fetch(PDO::FETCH_ASSOC);
222
		case "bdtao":
223
		  return $this->bdd->query(sprintf("SELECT o.num_nom_retenu AS nom_ret_nn, o.num_taxonomique AS nt, CONCAT(o.nom_sci, ' ', o.auteur) AS nom_sel".
224
									" , o.famille, CONCAT(ret.nom_sci, ' ', ret.auteur) AS nom_ret".
225
									" FROM %s.%s o".
226
									" LEFT JOIN %s.%s ret ON o.num_nom_retenu != 0 AND o.num_nom_retenu = ret.num_nom".
227
									" WHERE o.num_nom = %d -- %s:%d", self::db, self::bdtao,  self::db, self::bdtao, intval($id), __FILE__, __LINE__))->fetch(PDO::FETCH_ASSOC);
228
		}
229
		return FALSE;
230
	}
231
 
232
	const db = 'tb_eflore';
233
	const bdtfx = 'bdtfx_v2_00';
234
	const bdtxa = 'bdtxa_v1_01';
235
	const isfan = 'isfan_v2013';
236
	const bdtao = 'bdtao_v1_00';
237
 
238
	private function getInfosBdtfx($id_nom) {
239
		$idNomP = $this->bdd->proteger($id_nom);
240
		$requete = "SELECT o.num_nom_retenu AS nom_ret_nn, o.num_taxonomique AS nt, o.famille, ".
241
			"	CONCAT(o.nom_sci, ' ', o.auteur) AS nom_sel, ".
242
			"	CONCAT(ret.nom_sci, ' ', ret.auteur) AS nom_ret ".
243
			"FROM bdtfx_v2_00 AS o ".
244
			"	LEFT JOIN bdtfx_v2_00 AS ret ON (o.num_nom_retenu != 0 AND o.num_nom_retenu = ret.num_nom) ".
245
			"WHERE o.num_nom = $idNomP ".
246
			' -- '.__FILE__.' : '.__LINE__;
247
		$resultat = Cel::db()->executerRequete($requete, Cel::db::SQL_RETOUR_LIGNE);
248
		return $resultat;
249
	}
1582 jpm 250
}