Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 13 | 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
// +-------------------------------------------------------------------------------------------------------------------+
68
	public function traiterParametres($parametres) {
69
		if (isset($parametres) && !empty($parametres)) {
70
			$this->table_param = $parametres;
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) {
81
					case 'masque' 			  :  $this->ajouterLeFiltreMasque('masque', $valeur); 				break;
82
					case 'masque_code' 		  :  $this->ajouterLeFiltreMasque('id', $valeur); 				break;
83
					case 'masque_nom' 		  :  $this->ajouterLeFiltreMasque('nom', $valeur); 					break;
84
					case 'retour_langue' 	:  $this->retour_langue = $valeur; 			break;
85
					case 'retour_format' 	  :  $this->retour_format = $valeur;								break;
86
					case 'navigation_depart'  :  $this->limite_requete['depart'] = $valeur;	  					break;
87
			        case 'navigation_limite'  :  $this->limite_requete['limite'] = $valeur;	  					break;
88
			        case 'recherche'		: 																			break;
89
					default					:  $p = 'Erreur dans les paramètres de recherche de votre requête : '.
90
												'</br> Le paramètre " '.$param.' " n\'existe pas.';
91
											$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $p);						break;
92
				}
93
			}
94
		}
95
	}
96
 
97
	public function ajouterLeFiltreMasque($nom_champ, $valeur) {
98
		if ($nom_champ == 'id') {
99
			$this->requete_condition[] = $nom_champ.' = '.$this->getBdd()->proteger($valeur);
100
		} else {
101
			if ($this->recherche == 'floue') {
102
				if ($nom_champ == 'masque') {
103
					$this->requete_condition[] = '( id = '.$this->getBdd()->proteger($valeur)
104
						.' OR ( SOUNDEX(nom) = SOUNDEX(\''.$valeur.'\')'
105
						.' OR SOUNDEX(REVERSE(nom)) = SOUNDEX(REVERSE(\''.$valeur.'\')) '
106
						.')) ';
107
				} else {
108
					$this->requete_condition[] = '(SOUNDEX('.$nom_champ.') = SOUNDEX(\''.$valeur.'\')'
109
						.' OR SOUNDEX(REVERSE('.$nom_champ.')) = SOUNDEX(REVERSE(\''.$valeur.'\'))) ';
110
				}
111
			} else {
112
				if ($this->recherche == 'etendue') {
113
					$valeur = str_replace(' ','%', $valeur);
114
					$valeur .= '%';
115
				}
116
 
117
				if ($nom_champ == 'masque') {
118
					$this->requete_condition[] = '(dep = '.$this->getBdd()->proteger($valeur)
119
						.' OR nccenr LIKE '.$this->getBdd()->proteger($valeur)
120
						.' OR region = '.$this->getBdd()->proteger($valeur).')';
121
				} else {
122
					$this->requete_condition[] = $nom_champ.' LIKE '.$this->getBdd()->proteger($valeur);
123
				}
124
			}
125
		}
126
	}
127
 
128
// +-------------------------------------------------------------------------------------------------------------------+
129
	public function traiterRessources(&$ressources) {
130
		if (isset($ressources) && !empty($ressources)) {
131
			$this->table_ressources = $ressources;
132
			if (isset($this->table_ressources[0]) && !empty($this->table_ressources[0])) {
133
				//requete = /langues/#id
134
				$this->traiterRessourceId();
135
				if (isset($this->table_ressources[1]) && !empty($this->table_ressources[1])) {
136
					//requete = /langues/#id/#champ ou /langues/#id/relations
137
					$this->traiterRessourceChampOuRelations();
138
				}
139
			}
140
		}
141
	}
142
 
143
	public function traiterRessourceId() {
144
		//requete : /langues/#id (ex : /langues/7)
145
		if (preg_match('/^[a-z]{2}$/', $this->table_ressources[0])) {
146
			$this->requete_condition[] = ' id = '.$this->getBdd()->proteger($this->table_ressources[0]);
147
			$this->format_reponse .= '/id';
148
		} else {
149
			$r = 'Erreur dans les ressources de votre requête : </br> La ressource " '.$this->table_ressources[0].
150
				' " n\'existe pas.';
151
			$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $r);
152
		}
153
	}
154
 
155
 
156
	public function traiterRessourceChampOuRelations() {
157
		//requete = /langues/#id/relations :
158
		if ($this->table_ressources[1] == 'relations') {
159
			$r = 'Erreur dans les ressources de votre requête : </br> La ressource " '.$this->table_ressources[1].
160
				' " n\'existe pas.';
161
			$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $r);
162
		//requete = /langues/#id/#champ :
163
		} else {
164
			$this->format_reponse .= '/champ';
165
		}
166
	}
167
 
168
// +-------------------------------------------------------------------------------------------------------------------+
169
	public function assemblerLaRequete() {
170
      	$requete = 	' SELECT '.$this->requete_champ.
171
      					' FROM '.$this->table
172
      						.$this->formerRequeteCondition()
173
      						.$this->formerRequeteLimite();
174
      	return $requete;
175
	}
176
 
177
	public  function formerRequeteCondition() {
178
		$condition = '';
179
		if ($this->requete_condition != null) {
180
			$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
181
		}
182
		return $condition;
183
	}
184
 
185
 
186
	//ajout d'une limite seulement pour les listes (pas plus de 100 resultats retournés pr les requetes
187
	// suivantes : /langues et /langues/#id/relations)
188
	public function formerRequeteLimite() {
189
		if (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
190
			//cas ou la requete presente un navigation.depart supérieur au nb total de resultats.
191
			$this->limite_requete['depart'] =
192
				(($nb - $this->limite_requete['limite']) < 0) ? 0 : ($nb - $this->limite_requete['limite']);
193
			$this->requete_limite = ' LIMIT '.$this->limite_requete['depart'].', '.$this->limite_requete['limite'];
194
		} else {
195
			$this->requete_limite = ' LIMIT '.$this->limite_requete['depart'].', '.$this->limite_requete['limite'];
196
		}
197
		return $this->requete_limite;
198
	}
199
 
200
	public function recupererTotalResultat() {
201
		//on récupère le nombre total de résultats de la requete (ex : le nombre d'id contenu dans la liste /langues)
202
		$requete = 'SELECT count(*) as nombre FROM '
203
			.$this->table
204
			.$this->formerRequeteCondition();
205
		$res = $this->getBdd()->recuperer($requete);
206
 
207
		if ($res) {
208
			$total = $res['nombre'];
209
		} else {
210
			$t = 'Fonction recupererTotalResultat() : <br/>Données introuvables dans la base';
211
			$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $t);
212
		}
213
		return $total;
214
	}
215
 
216
// +-------------------------------------------------------------------------------------------------------------------+
217
	// determine en fct du service appelé (/langues | /langues/#id | /langues/#id/champ |
218
	// /langues/#id/relations) le format du tableau à retourner. Encode en json
219
	public function retournerResultatFormate($resultat) {
220
		$this->recupererTableConfig('correspondance_champs');
221
		switch ($this->format_reponse) {
222
			case 'langues' 				: $reponse = $this->formaterLangues($resultat); 			 break;
223
			case 'langues/id' 			: $reponse = $this->formaterLanguesId($resultat[0]); 	 break;
224
			case 'langues/id/champ' 		: $reponse = $this->formaterLanguesIdChamp($resultat[0]); break;
225
			default : break;
226
		}
227
		return $reponse;
228
	}
229
 
230
	public function formaterLangues($resultat) {
231
		//on remplit la table $table_retour_json['entete']
232
		$this->table_retour['depart'] = $this->limite_requete['depart'];
233
		$this->table_retour['limite'] = $this->limite_requete['limite'];
234
		$this->table_retour['total']  = $this->total_resultat;
235
		//formuler les urls precedentes et suivantes affichées dans l'entete du resultat
236
		$url = $this->formulerUrl($this->total_resultat, '/langues');
237
		if ($url['precedent'] != '') { $this->table_retour['href.precedent'] = $url['precedent']; }
238
		if ($url['suivant']   != '') { $this->table_retour['href.suivant']   = $url['suivant']; }
239
 
240
		$table_retour_json['entete'] = $this->table_retour;
241
		$this->table_retour = array();
242
		if ($this->retour_langue == 'fr') {$nom = 'nom'; } else {$nom = 'nom_'.$this->retour_langue;}
243
		if (isset($this->table_param['masque_nom'])) $resultat = $this->trierRechercheFloue($this->table_param['masque_nom'], $resultat, $nom);
244
		//on remplit la table $table_retour_json['resultat']
245
		foreach ($resultat as $tab) {
246
			foreach ($tab as $key => $valeur) {
247
				if ($valeur != '') {
248
					if ($key == $id) {
249
						$num = $valeur; $this->table_retour['code'] = $valeur; break;
250
					} elseif ($key == 'nom_'.$this->retour_langue || ($this->retour_langue == 'fr' && $key == 'nom')) {
251
						$this->table_retour['nom'] = $valeur; break;
252
					} else {
253
						switch ($key) {
254
							case 'id'  : $num = $valeur; $this->table_retour['code'] = $valeur;	break;
255
							case 'nom' : $this->table_retour['nom'] = $valeur;					break;
256
							default    : 						 									break;
257
						}
258
					}
259
				}
260
			}
261
			if ($this->retour_format == 'max') {
262
				$this->table_retour['href'] = $this->ajouterHref('langues', $num);
263
			}
264
			$resultat_json[$num] = $this->table_retour;
265
			$this->table_retour = array();
266
		}
267
		$table_retour_json['resultat'] = $resultat_json;
268
		return $table_retour_json;
269
	}
270
 
271
	public function formaterLanguesId($resultat) {
272
		foreach ($resultat as $key => $valeur) {
273
			if ($valeur != '') {
274
				$this->afficherDonnees($key, $valeur);
275
			}
276
		}
277
		unset($this->table_retour['href']);
278
		return $this->table_retour;
279
	}
280
 
281
 
282
	public function formaterLanguesIdChamp($resultat) {
283
		//on recupère tous les resultats possibles
284
		$reponse = $this->formaterLanguesId($resultat);
285
		$this->table_retour = array();
286
		//on recupère les résultats demandés à partir du tableau de résultat complet
287
		$this->table_retour['id'] = $reponse['code'];
288
		$champs = explode(' ', $this->table_ressources[1]);
289
 
290
		foreach ($champs as $champ) {
291
			if ($champ == 'nom') $champ = 'nom.fr';
292
			if ($this->verifierValiditeChamp($champ)) {
293
				if (strrpos($champ, '.*') !== false) {
294
					$this->afficherPointEtoile($champ, $reponse);
295
 
296
				} else {
297
					if (isset($reponse[$champ])) {
298
						$this->table_retour[$champ] = $reponse[$champ];
299
					} else {
300
						$this->table_retour[$champ] = null;
301
					}
302
				}
303
			}
304
		}
305
		return $this->table_retour;
306
	}
307
 
308
	public function verifierValiditeChamp($champ) {
309
		preg_match('/^([^.]+)(:?\.([^.]+))?$/', $champ, $match);
310
		$champs_possibles = $this->correspondance_champs;
311
		$champs_possibles[] = 'nom';
312
		$champs_possibles[] = 'iso-639-2';
313
		$champs_possibles[] = 'iso-639-3';
314
 
315
		if (in_array($match[1], $champs_possibles)) {
316
			$validite = true;
317
		} elseif (in_array($match[0], $champs_possibles)) {
318
			$validite = true;
319
		} else {
320
			$champs_possibles = implode('</li><li>', $champs_possibles);
321
			$c = 'Erreur dans votre requête : </br> Le champ "'.$champ_possibles.'" n\'existe pas. '.
322
				'Les champs disponibles sont : <li>'.$champs_possibles.'</li>';
323
			$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $c);
324
		}
325
		return $validite;
326
	}
327
 
328
	public function afficherPointEtoile($champ, $reponse) {
329
		preg_match('/^([^.]+\.)\*$/', $champ, $match);
330
		foreach ($reponse as $chp => $valeur) {
331
			if (strrpos($chp, $match[1]) !== false) {
332
				if ($valeur != '') {
333
					$this->table_retour[$chp] = $valeur;
334
				} else {
335
					$this->table_retour[$chp] = null;
336
				}
337
			}
338
		}
339
	}
340
 
341
	public function afficherDonnees($champ, $valeur) {
342
		if ($this->retour_format == 'max') {
343
			if (strpos($champ, 'iso_639_') !== false) {
344
				$projet = substr(str_replace('_', '-', $champ),5);
345
				$this->table_retour[$projet.'.code'] = $valeur;
346
				$this->table_retour[$projet.'.href'] = $this->ajouterHrefAutreProjet('langues', '', $valeur, $projet);
347
			} else {
348
				$this->table_retour[$this->correspondance_champs[$champ]] = $valeur;
349
			}
350
		} else {
351
			$this->table_retour[$this->correspondance_champs[$champ]] = $valeur;
352
		}
353
	}
354
 
355
}
356
 
357
?>