Subversion Repositories eFlore/Projets.eflore-projets

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6 jpm 1
<?php
2
/**
3
* Description :
4
* Classe Langues.php fournit des informations sur ensemble structuré des termes et concepts représentant les éléments
5
* d'un domaine de connaissances .
6
* Le but étant de fournir un ensemble minimal d'information comprenant :
7
* un identifiant (numérique ou alphanumérique sous forme de ChatMot si possible), un nom, une region et
8
* éventuellement une relation hiérarchique avec un autre terme (=classe).
9
* Si l'url finit par /langues on retourne une liste de termes (seulement les 100 premières par défaut).
10
* L'url peut contenir des paramètres optionnels passés après le ? : /observations?param1=val1&param2=val2&...
11
*
12
* Les paramètres de requête disponibles sont : masque, masque.code, masque.nom, masque.region , recherche,
13
* distinct, retour.format, navigation.depart et navigation.limite.
14
*
15
* Encodage en entrée : utf8
16
* Encodage en sortie : utf8
17
* @package framework-v3
18
* @author Delphine Cauquil <delphine@tela-botanica.org>
19
* @author Jennifer Dhé <jennifer.dhe@tela-botanica.org>
20
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
21
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
22
* @version 1.0
23
* @copyright 1999-${year} Tela Botanica (accueil@tela-botanica.org)
24
*/
25
 
26
class Langues extends Commun {
27
 
28
	protected $service = 'langues';
29
 
30
	/**
31
	 * Permet de stocker la requete formulée : /langues | /langues/#id | /langues/#id/champ | /langues/#id/relations
32
	 * Est remplit au cours de l'analyse des ressources (traiterRessources()), par défaut, a la valeur du service.
33
	 * Est utilisée principalement pr déterminer le format du tableau à retourner.	 */
34
	protected $format_reponse = 'langues';
35
 
36
	/** Variables constituant les parametres de la requete SQL (champ, condition, group by, limit) remplie
37
	 * selon ressources et paramètres	 */
38
	protected $requete_champ = ' * ';
39
	protected $requete_condition = '';
40
	protected $limite_requete 	 = array(
41
		'depart' => 0,
42
		'limite' => 100
43
	);
44
 
45
	/** Stockage des ressources et paramétres */
46
	protected $table_ressources = array();
47
	protected $table_param = array();
48
	/**
49
	 * Precise la contenance plus ou moins précise du tableau à retourner :
50
	 *  - min = les données présentes dans la table
51
	 *  - max = les données de la table + les informations complémentaires (pour les identifiants et les codes)
52
	 *  - oss = la liste des nom_sci (uniquement pour noms et taxons)
53
	 */
54
	protected $retour_format = 'max';
55
	protected $retour_langue = 'fr';
56
	/** Valeur du paramètre de requete recherche :
57
	 *  - stricte : le masque est passé tel quel à l'opérateur LIKE.
58
	 *  - etendue : ajout automatique du signe % à la place des espaces et en fin de masque avec utilisation de LIKE.
59
	 *  - floue : recherche tolérante vis-à-vis d'approximations ou d'erreurs (fautes d'orthographe par exemple) */
60
	protected $recherche;
61
 
62
	/** Permet de stocker le tableau de résultat (non encodé en json) */
63
	protected $table_retour = array();
64
	/** Stocke le nombre total de résultats de la requete principale. Est calculée lors de l'assemblage de la requete */
65
	protected $total_resultat;
66
 
67
// +-------------------------------------------------------------------------------------------------------------------+
13 jpm 68
	public function traiterParametres() {
69
		if (isset($this->parametres) && !empty($this->parametres)) {
70
			$this->table_param = $$this->parametres;
6 jpm 71
 
72
		//   masque : filtre la liste en fonction d'un masque de recherche portant sur le code, le nom ou la region.
73
        //   masque.code : filtre uniquement sur le code. masque.nom : filtre uniquement sur le nom.
74
        //   masque.region : filtre uniquement sur la region.
75
			if (isset($parametres['recherche']) && $parametres['recherche'] != '') {
76
				$this->recherche = $parametres['recherche'];
77
			}
78
 
79
			foreach ($parametres as $param => $valeur) {
80
				switch ($param) {
13 jpm 81
					case 'masque' :
82
						$this->ajouterLeFiltreMasque('masque', $valeur);
83
						break;
84
					case 'masque.code' :
85
						$this->ajouterLeFiltreMasque('id', $valeur);
86
						break;
87
					case 'masque.nom' :
88
						$this->ajouterLeFiltreMasque('nom', $valeur);
89
						break;
90
					case 'retour.langue' :
91
						$this->retour_langue = $valeur;break;
92
					case 'retour.format' :
93
						$this->retour_format = $valeur;
94
						break;
95
					case 'navigation.depart' :
96
						$this->limite_requete['depart'] = $valeur;
97
						break;
98
			        case 'navigation.limite' :
99
			        	$this->limite_requete['limite'] = $valeur;
100
			        	break;
101
			        case 'recherche' :
102
			        	break;
103
					default :
104
						$p = 'Erreur dans les paramètres de recherche de votre requête : '.
105
						'</br> Le paramètre " '.$param.' " n\'existe pas.';
106
						$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $p);
6 jpm 107
				}
108
			}
109
		}
110
	}
111
 
112
	public function ajouterLeFiltreMasque($nom_champ, $valeur) {
113
		if ($nom_champ == 'id') {
114
			$this->requete_condition[] = $nom_champ.' = '.$this->getBdd()->proteger($valeur);
115
		} else {
116
			if ($this->recherche == 'floue') {
117
				if ($nom_champ == 'masque') {
118
					$this->requete_condition[] = '( id = '.$this->getBdd()->proteger($valeur)
119
						.' OR ( SOUNDEX(nom) = SOUNDEX(\''.$valeur.'\')'
120
						.' OR SOUNDEX(REVERSE(nom)) = SOUNDEX(REVERSE(\''.$valeur.'\')) '
121
						.')) ';
122
				} else {
123
					$this->requete_condition[] = '(SOUNDEX('.$nom_champ.') = SOUNDEX(\''.$valeur.'\')'
124
						.' OR SOUNDEX(REVERSE('.$nom_champ.')) = SOUNDEX(REVERSE(\''.$valeur.'\'))) ';
125
				}
126
			} else {
127
				if ($this->recherche == 'etendue') {
128
					$valeur = str_replace(' ','%', $valeur);
129
					$valeur .= '%';
130
				}
131
 
132
				if ($nom_champ == 'masque') {
133
					$this->requete_condition[] = '(dep = '.$this->getBdd()->proteger($valeur)
134
						.' OR nccenr LIKE '.$this->getBdd()->proteger($valeur)
135
						.' OR region = '.$this->getBdd()->proteger($valeur).')';
136
				} else {
137
					$this->requete_condition[] = $nom_champ.' LIKE '.$this->getBdd()->proteger($valeur);
138
				}
139
			}
140
		}
141
	}
142
 
143
// +-------------------------------------------------------------------------------------------------------------------+
13 jpm 144
	public function traiterRessources() {
145
		if (isset($this->ressources) && !empty($this->ressources)) {
146
			$this->table_ressources = $this->ressources;
6 jpm 147
			if (isset($this->table_ressources[0]) && !empty($this->table_ressources[0])) {
148
				//requete = /langues/#id
149
				$this->traiterRessourceId();
150
				if (isset($this->table_ressources[1]) && !empty($this->table_ressources[1])) {
151
					//requete = /langues/#id/#champ ou /langues/#id/relations
152
					$this->traiterRessourceChampOuRelations();
153
				}
154
			}
155
		}
156
	}
157
 
158
	public function traiterRessourceId() {
159
		//requete : /langues/#id (ex : /langues/7)
160
		if (preg_match('/^[a-z]{2}$/', $this->table_ressources[0])) {
161
			$this->requete_condition[] = ' id = '.$this->getBdd()->proteger($this->table_ressources[0]);
162
			$this->format_reponse .= '/id';
163
		} else {
164
			$r = 'Erreur dans les ressources de votre requête : </br> La ressource " '.$this->table_ressources[0].
165
				' " n\'existe pas.';
166
			$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $r);
167
		}
168
	}
169
 
170
 
171
	public function traiterRessourceChampOuRelations() {
172
		//requete = /langues/#id/relations :
173
		if ($this->table_ressources[1] == 'relations') {
174
			$r = 'Erreur dans les ressources de votre requête : </br> La ressource " '.$this->table_ressources[1].
175
				' " n\'existe pas.';
176
			$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $r);
177
		//requete = /langues/#id/#champ :
178
		} else {
179
			$this->format_reponse .= '/champ';
180
		}
181
	}
182
 
183
// +-------------------------------------------------------------------------------------------------------------------+
184
	public function assemblerLaRequete() {
185
      	$requete = 	' SELECT '.$this->requete_champ.
13 jpm 186
      				' FROM '.$this->table
187
      				.$this->formerRequeteCondition()
188
      				.$this->formerRequeteLimite();
6 jpm 189
      	return $requete;
190
	}
191
 
192
	public  function formerRequeteCondition() {
193
		$condition = '';
194
		if ($this->requete_condition != null) {
195
			$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
196
		}
197
		return $condition;
198
	}
199
 
200
 
201
	//ajout d'une limite seulement pour les listes (pas plus de 100 resultats retournés pr les requetes
202
	// suivantes : /langues et /langues/#id/relations)
203
	public function formerRequeteLimite() {
204
		if (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
205
			//cas ou la requete presente un navigation.depart supérieur au nb total de resultats.
206
			$this->limite_requete['depart'] =
207
				(($nb - $this->limite_requete['limite']) < 0) ? 0 : ($nb - $this->limite_requete['limite']);
208
			$this->requete_limite = ' LIMIT '.$this->limite_requete['depart'].', '.$this->limite_requete['limite'];
209
		} else {
210
			$this->requete_limite = ' LIMIT '.$this->limite_requete['depart'].', '.$this->limite_requete['limite'];
211
		}
212
		return $this->requete_limite;
213
	}
214
 
215
	public function recupererTotalResultat() {
216
		//on récupère le nombre total de résultats de la requete (ex : le nombre d'id contenu dans la liste /langues)
13 jpm 217
		$requete = 'SELECT count(*) as nombre FROM '.
218
			$this->table.
219
			$this->formerRequeteCondition();
6 jpm 220
		$res = $this->getBdd()->recuperer($requete);
221
 
222
		if ($res) {
223
			$total = $res['nombre'];
224
		} else {
225
			$t = 'Fonction recupererTotalResultat() : <br/>Données introuvables dans la base';
226
			$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $t);
227
		}
228
		return $total;
229
	}
230
 
231
// +-------------------------------------------------------------------------------------------------------------------+
232
	// determine en fct du service appelé (/langues | /langues/#id | /langues/#id/champ |
233
	// /langues/#id/relations) le format du tableau à retourner. Encode en json
234
	public function retournerResultatFormate($resultat) {
235
		$this->recupererTableConfig('correspondance_champs');
236
		switch ($this->format_reponse) {
13 jpm 237
			case 'langues' :
238
				$reponse = $this->formaterLangues($resultat);
239
				break;
240
			case 'langues/id' :
241
				$reponse = $this->formaterLanguesId($resultat[0]);
242
				break;
243
			case 'langues/id/champ' :
244
				$reponse = $this->formaterLanguesIdChamp($resultat[0]);
245
				break;
6 jpm 246
		}
247
		return $reponse;
248
	}
249
 
250
	public function formaterLangues($resultat) {
251
		//on remplit la table $table_retour_json['entete']
252
		$this->table_retour['depart'] = $this->limite_requete['depart'];
253
		$this->table_retour['limite'] = $this->limite_requete['limite'];
254
		$this->table_retour['total']  = $this->total_resultat;
255
		//formuler les urls precedentes et suivantes affichées dans l'entete du resultat
256
		$url = $this->formulerUrl($this->total_resultat, '/langues');
13 jpm 257
		if (isset($url['precedent']) && $url['precedent'] != '') {
258
			$this->table_retour['href.precedent'] = $url['precedent'];
259
		}
260
		if (isset($url['suivant']) && $url['suivant'] != '') {
261
			$this->table_retour['href.suivant']   = $url['suivant'];
262
		}
6 jpm 263
 
264
		$table_retour_json['entete'] = $this->table_retour;
265
		$this->table_retour = array();
266
		if ($this->retour_langue == 'fr') {$nom = 'nom'; } else {$nom = 'nom_'.$this->retour_langue;}
267
		if (isset($this->table_param['masque_nom'])) $resultat = $this->trierRechercheFloue($this->table_param['masque_nom'], $resultat, $nom);
268
		//on remplit la table $table_retour_json['resultat']
269
		foreach ($resultat as $tab) {
270
			foreach ($tab as $key => $valeur) {
271
				if ($valeur != '') {
13 jpm 272
					//TODO : vérifier d'où venez $id
273
					if ($key == 'id') {// ATTENTION : au départ valait $id!
274
						$num = $valeur;
275
						$this->table_retour['code'] = $valeur;
276
						break;
6 jpm 277
					} elseif ($key == 'nom_'.$this->retour_langue || ($this->retour_langue == 'fr' && $key == 'nom')) {
13 jpm 278
						$this->table_retour['nom'] = $valeur;
279
						break;
6 jpm 280
					} else {
281
						switch ($key) {
13 jpm 282
							case 'id' :
283
								$num = $valeur; $this->table_retour['code'] = $valeur;
284
								break;
285
							case 'nom' :
286
								$this->table_retour['nom'] = $valeur;
287
								break;
6 jpm 288
						}
289
					}
290
				}
291
			}
292
			if ($this->retour_format == 'max') {
293
				$this->table_retour['href'] = $this->ajouterHref('langues', $num);
294
			}
295
			$resultat_json[$num] = $this->table_retour;
296
			$this->table_retour = array();
297
		}
298
		$table_retour_json['resultat'] = $resultat_json;
299
		return $table_retour_json;
300
	}
301
 
302
	public function formaterLanguesId($resultat) {
303
		foreach ($resultat as $key => $valeur) {
304
			if ($valeur != '') {
305
				$this->afficherDonnees($key, $valeur);
306
			}
307
		}
308
		unset($this->table_retour['href']);
309
		return $this->table_retour;
310
	}
311
 
312
 
313
	public function formaterLanguesIdChamp($resultat) {
314
		//on recupère tous les resultats possibles
315
		$reponse = $this->formaterLanguesId($resultat);
316
		$this->table_retour = array();
317
		//on recupère les résultats demandés à partir du tableau de résultat complet
318
		$this->table_retour['id'] = $reponse['code'];
319
		$champs = explode(' ', $this->table_ressources[1]);
320
 
321
		foreach ($champs as $champ) {
322
			if ($champ == 'nom') $champ = 'nom.fr';
323
			if ($this->verifierValiditeChamp($champ)) {
324
				if (strrpos($champ, '.*') !== false) {
325
					$this->afficherPointEtoile($champ, $reponse);
326
 
327
				} else {
328
					if (isset($reponse[$champ])) {
329
						$this->table_retour[$champ] = $reponse[$champ];
330
					} else {
331
						$this->table_retour[$champ] = null;
332
					}
333
				}
334
			}
335
		}
336
		return $this->table_retour;
337
	}
338
 
339
	public function verifierValiditeChamp($champ) {
340
		preg_match('/^([^.]+)(:?\.([^.]+))?$/', $champ, $match);
341
		$champs_possibles = $this->correspondance_champs;
342
		$champs_possibles[] = 'nom';
343
		$champs_possibles[] = 'iso-639-2';
344
		$champs_possibles[] = 'iso-639-3';
345
 
346
		if (in_array($match[1], $champs_possibles)) {
347
			$validite = true;
348
		} elseif (in_array($match[0], $champs_possibles)) {
349
			$validite = true;
350
		} else {
351
			$champs_possibles = implode('</li><li>', $champs_possibles);
352
			$c = 'Erreur dans votre requête : </br> Le champ "'.$champ_possibles.'" n\'existe pas. '.
353
				'Les champs disponibles sont : <li>'.$champs_possibles.'</li>';
354
			$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $c);
355
		}
356
		return $validite;
357
	}
358
 
359
	public function afficherPointEtoile($champ, $reponse) {
360
		preg_match('/^([^.]+\.)\*$/', $champ, $match);
361
		foreach ($reponse as $chp => $valeur) {
362
			if (strrpos($chp, $match[1]) !== false) {
363
				if ($valeur != '') {
364
					$this->table_retour[$chp] = $valeur;
365
				} else {
366
					$this->table_retour[$chp] = null;
367
				}
368
			}
369
		}
370
	}
371
 
372
	public function afficherDonnees($champ, $valeur) {
373
		if ($this->retour_format == 'max') {
374
			if (strpos($champ, 'iso_639_') !== false) {
375
				$projet = substr(str_replace('_', '-', $champ),5);
376
				$this->table_retour[$projet.'.code'] = $valeur;
377
				$this->table_retour[$projet.'.href'] = $this->ajouterHrefAutreProjet('langues', '', $valeur, $projet);
378
			} else {
379
				$this->table_retour[$this->correspondance_champs[$champ]] = $valeur;
380
			}
381
		} else {
382
			$this->table_retour[$this->correspondance_champs[$champ]] = $valeur;
383
		}
384
	}
385
 
386
}
387
 
388
?>