Subversion Repositories eFlore/Projets.eflore-projets

Rev

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

Rev Author Line No. Line
6 jpm 1
<?php
2
/**
3
* Description :
4
* Classe NomsVernaculaires.php fournit une liste de noms vernaculaires et leur liaison à la bdtfx
109 jpm 5
* Le but étant de fournir un ensemble minimal d'information comprenant :
6
* un identifiant (numérique ou alphanumérique sous forme de ChatMot si possible), un nom, une langue et
6 jpm 7
* une relation avec un taxon de la bdtfx.
8
* Si l'url finit par /noms-vernaculaires on retourne une liste de noms (seulement les 100 premières par défaut).
9
* L'url peut contenir des paramètres optionnels passés après le ? : /observations?param1=val1&param2=val2&...
109 jpm 10
*
11
* Les paramètres de requête disponibles sont : masque, masque.code, masque.nom, masque.region , recherche,
6 jpm 12
* distinct, retour.format, navigation.depart et navigation.limite.
109 jpm 13
*
6 jpm 14
* Encodage en entrée : utf8
15
* Encodage en sortie : utf8
16
* @package framework-v3
109 jpm 17
* @author Delphine Cauquil <delphine@tela-botanica.org>
6 jpm 18
* @author Jennifer Dhé <jennifer.dhe@tela-botanica.org>
19
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
20
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
21
* @version 1.0
22
* @copyright 1999-${year} Tela Botanica (accueil@tela-botanica.org)
23
*/
24
class NomsVernaculaires extends Commun {
25
	protected $champ_infos = array(
729 raphael 26
		'taxon' => array('service' => 'taxons', 'ressource' => 'nt:', 'projet' => 'bdtfx', 'nom' => 'nom_sci',
27
						 // utilisés par ajouterChampsOntologieLigneResultat()
28
						 'intitule' => 'taxon.code', // intitulé du champ tel qu'il sera renvoyé en JSON
29
						 'bdd_champ' => 'num_taxon'), // intitulé du champ tel qu'il est présent dans l'enregistrement MySQL
30
		'conseil_emploi' => array('service' => 'ontologies', 'ressource' => 'numStatut:', 'projet' => 'nvjfl', 'nom' => 'nom',
31
								  'intitule' => 'conseil_emploi', 'bdd_champ' => 'num_statut'),
32
		'genre' => array('service' => 'ontologies', 'ressource' => 'genreNombre:', 'projet' => 'nvjfl', 'nom' => 'nom',
33
						 'intitule' => 'genre', 'bdd_champ' => 'num_genre'));
109 jpm 34
 
6 jpm 35
	protected $service = 'noms-vernaculaires';
109 jpm 36
 
6 jpm 37
	/**
38
	 * Permet de stocker la requete formulée : /noms-vernaculaires | /noms-vernaculaires/#id |
39
	 *  /noms-vernaculaires/#id/champ | /noms-vernaculaires/#id/relations
109 jpm 40
	 * Est remplit au cours de l'analyse des ressources (traiterRessources()), par défaut, a la valeur du service.
6 jpm 41
	 * Est utilisée principalement pr déterminer le format du tableau à retourner.	 */
109 jpm 42
	protected $format_reponse = 'noms-vernaculaires';
43
 
44
	/** Variables constituant les parametres de la requete SQL (champ, condition, limit) remplie
6 jpm 45
	 * selon ressources et paramètres */
46
	protected $requete_champ = array(' * ');
47
	protected $requete_condition = '';
48
	protected $limite_requete = array(
109 jpm 49
		'depart' => 0,
6 jpm 50
		'limite' => 100
51
	);
284 jpm 52
 
53
	protected $champ_tri = 'code_langue';
54
	protected $direction_tri = 'asc';
286 aurelien 55
 
56
	/**
57
	 * Indique les champs supplémentaires à retourner
58
	 *  - conseil_emploi = conseil d'emploi du nom vernaculaire
59
	 *  - genre = genre et nombre du nom
60
	 *  - taxon = nom retenu associé à ce nom
61
	 */
62
	protected $champs_supp = array();
109 jpm 63
 
6 jpm 64
	/**
109 jpm 65
	 * Precise la contenance plus ou moins précise du tableau à retourner :
66
	 *  - min = les données présentes dans la table
6 jpm 67
	 *  - max = les données de la table + les informations complémentaires (pour les identifiants et les codes)
68
	 *  - oss = la liste des nom_sci (uniquement pour noms et taxons) */
69
	protected $retour_format = 'max';
109 jpm 70
	/** Valeur du paramètre de requete recherche :
71
	 *  - stricte : le masque est passé tel quel à l'opérateur LIKE.
72
	 *  - etendue : ajout automatique du signe % à la place des espaces et en fin de masque avec utilisation de LIKE.
6 jpm 73
	 *  - floue : recherche tolérante vis-à-vis d'approximations ou d'erreurs (fautes d'orthographe par exemple) */
74
	protected $recherche;
284 jpm 75
 
6 jpm 76
	/** Permet de stocker le tableau de résultat (non encodé en json) */
77
	protected $table_retour = array();
78
	/** Stocke le nombre total de résultats de la requete principale. Est calculée lors de l'assemblage de la requete */
79
	protected $total_resultat;
536 gduche 80
 
81
	private $config;
82
 
563 aurelien 83
	public function __construct($config) {
536 gduche 84
		$this->config = is_null($config) ? Config::get('NomsVernaculaires') : $config;
85
	}
109 jpm 86
 
87
	//+------------------------------------------------------------------------------------------------------+
6 jpm 88
	// créer une condition en fonction du paramétre
109 jpm 89
	public function traiterParametres() {
90
		if (isset($this->parametres) && !empty($this->parametres)) {
91
 
92
			if (isset($this->parametres['recherche']) && $this->parametres['recherche'] != '') {
93
				$this->recherche = $this->parametres['recherche'];
6 jpm 94
			}
109 jpm 95
			foreach ($this->parametres as $param => $valeur) {
6 jpm 96
				switch ($param) {
109 jpm 97
					case 'masque' :
284 jpm 98
						$this->ajouterFiltreMasque('nom_vernaculaire', $valeur);
109 jpm 99
						break;
100
					case 'masque.nt' :
284 jpm 101
						$this->ajouterFiltreMasque('num_taxon', $valeur);
109 jpm 102
						break;
103
					case 'masque.nv' :
284 jpm 104
						$this->ajouterFiltreMasque('nom_vernaculaire', $valeur);
109 jpm 105
						break;
106
					case 'masque.lg' :
284 jpm 107
						$this->ajouterFiltreMasque('code_langue', $valeur);
109 jpm 108
						break;
109
					case 'masque.cce' :
284 jpm 110
						$this->ajouterFiltreMasque('num_statut', $valeur);
109 jpm 111
						break;
112
					case 'retour.format' :
113
						$this->retour_format = $valeur;
114
						break;
115
					case 'navigation.depart' :
116
						$this->limite_requete['depart'] = $valeur;
117
						break;
118
					case 'navigation.limite' :
119
						$this->limite_requete['limite'] = $valeur;
120
						break;
286 aurelien 121
					case 'retour.champs' :
122
						$this->champs_supp = explode(',',$valeur);
123
					break;
109 jpm 124
					case 'recherche' :
125
						break;
152 delphine 126
					case 'version.projet' :
127
						break;
109 jpm 128
					default :
129
						$p = 'Erreur dans les paramètres de recherche de votre requête : '.
130
							'</br> Le paramètre " '.$param.' " n\'existe pas.';
131
							$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $p);
6 jpm 132
				}
133
			}
134
		}
135
	}
109 jpm 136
 
284 jpm 137
	public function ajouterFiltreMasque($nom_champ, $valeur) {
6 jpm 138
		if ($nom_champ == 'num_taxon') { // si il s'agit d'un chiffre
139
			$this->requete_condition[] = $nom_champ.' = '.$this->getBdd()->proteger($valeur);
140
		} else {
141
			if ($this->recherche == 'floue') {
142
				$this->requete_condition[] = '(SOUNDEX('.$nom_champ.') = SOUNDEX(\''.$valeur.'\')'
143
					.' OR SOUNDEX(REVERSE('.$nom_champ.')) = SOUNDEX(REVERSE(\''.$valeur.'\'))) ';
144
			} else {
145
				if ($this->recherche == 'etendue') {
180 delphine 146
					$valeur = '%'.str_replace(' ','% ', $valeur);
6 jpm 147
					$valeur .= '%';
148
				}
149
				$this->requete_condition[] = $nom_champ.' LIKE '.$this->getBdd()->proteger($valeur);
150
			}
151
		}
152
	}
153
 
109 jpm 154
	//+------------------------------------------------------------------------------------------------------+
6 jpm 155
	// en fonction de la présence des ressources modifie requete_champ et requete_condition
109 jpm 156
	public function traiterRessources() {
157
		if (isset($this->ressources) && !empty($this->ressources)) {
158
			if (isset($this->ressources[0]) && !empty($this->ressources[0])) {
6 jpm 159
				$this->traiterRessourceId(); // ajoute condition id=#valeur
109 jpm 160
				if (isset($this->ressources[1]) && !empty($this->ressources[1])) {
160 delphine 161
					$this->traiterRessourceChamp(); //modifie requete_champ ou requete_condition
6 jpm 162
				}
163
			}
164
		} else { //rajoute distinct pour ne pas avoir plusieurs fois le même nom
165
			$this->requete_champ = array('distinct(id)', 'nom_vernaculaire ');
166
		}
167
	}
109 jpm 168
 
6 jpm 169
	//requete : /noms-vernaculaires/#id (ex : /noms-vernaculaires/7)
170
	public function traiterRessourceId() {
109 jpm 171
		if (is_numeric($this->ressources[0])) {
172
			$this->requete_condition[] = ' id = '.$this->getBdd()->proteger($this->ressources[0]);
6 jpm 173
			$this->format_reponse .= '/id';
160 delphine 174
		} elseif ($this->ressources[0] == 'attributions') {
175
			$this->format_reponse .= '/attributions';
6 jpm 176
		} else {
109 jpm 177
			$r = 'Erreur dans les ressources de votre requête : </br> La ressource " '.$this->ressources[0].
6 jpm 178
				' " n\'existe pas.';
109 jpm 179
			$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $r);
6 jpm 180
		}
181
	}
109 jpm 182
 
183
 
160 delphine 184
	public function traiterRessourceChamp() {
185
		$this->format_reponse .= '/champ';
186
		$this->analyserChamp();
6 jpm 187
	}
109 jpm 188
 
6 jpm 189
	public function analyserChamp() {
190
		$this->requete_champ = array();
191
		$this->recupererTableConfig('champs_possibles');// s'il y a plusieurs champs correspondant au champ demandé ils sont séparé par des |
109 jpm 192
		$champs = explode(' ', $this->ressources[1]);
6 jpm 193
		foreach ($champs as $champ) {
194
			preg_match('/^([^.]+)(\.([^.]+))?$/', $champ, $match);
195
			if (isset($this->champs_possibles[$match[1]])) {
196
				$this->requete_champ[] = str_replace('|', ', ', $this->champs_possibles[$match[1]]);
197
			} elseif (isset($this->champs_possibles[$match[0]])) {
198
				$this->requete_champ[] = str_replace('|', ', ', $this->champs_possibles[$match[0]]);
199
			} else {
200
				$champs_possibles = implode('</li><li>', array_keys($this->champs_possibles));
201
				$c = 'Erreur dans votre requête : </br> Le champ "'.$champ_possibles.'" n\'existe pas. '.
202
					'Les champs disponibles sont : <li>'.$champs_possibles.'</li> et leurs déclinaisons (ex. ".code").';
203
				$this->renvoyerErreur(RestServeur::HTTP_CODE_MAUVAISE_REQUETE, $c);
204
			}
205
		}
206
	}
109 jpm 207
 
208
	//+------------------------------------------------------------------------------------------------------+
6 jpm 209
	public function assemblerLaRequete() {
210
		$requete = ' SELECT '.$this->formerRequeteChamp().
659 delphine 211
					', CASE num_statut WHEN "" THEN 1 ELSE 0 END AS is_null '.
6 jpm 212
					' FROM '.$this->table
659 delphine 213
					.$this->formerRequeteCondition().
214
					' ORDER BY is_null ASC, num_statut ASC '
6 jpm 215
					.$this->formerRequeteLimite();
216
		return $requete;
217
	}
109 jpm 218
 
6 jpm 219
	public  function formerRequeteChamp() {
220
		if (in_array('*', $this->requete_champ)) {
221
			$champ = ' * ';
222
		} else {
223
			$champ = implode(', ', $this->requete_champ);
224
		}
225
		return $champ;
226
	}
109 jpm 227
 
6 jpm 228
	public  function formerRequeteCondition() {
229
		$condition = '';
109 jpm 230
		if ($this->requete_condition != null) {
6 jpm 231
			$condition = ' WHERE '.implode(' AND ', $this->requete_condition);
109 jpm 232
		}
6 jpm 233
		return $condition;
234
	}
109 jpm 235
 
236
	//ajout d'une limite seulement pour les listes (pas plus de 100 resultats retournés pr les requetes
6 jpm 237
	// suivantes : /noms-vernaculaires et /noms-vernaculaires/#id/relations)
238
	public function formerRequeteLimite() {
239
		if (in_array($this->format_reponse , array($this->service.'/id', $this->service.'/id/champs'))) {
109 jpm 240
			$this->requete_limite = '';
6 jpm 241
		} elseif (($depart = $this->limite_requete['depart']) > ($this->total_resultat = $this->recupererTotalResultat())) {
109 jpm 242
			$this->limite_requete['depart'] =
6 jpm 243
				(($this->total_resultat - $this->limite_requete['limite']) < 0) ? 0 : ($this->total_resultat - $this->limite_requete['limite']);
109 jpm 244
			$this->requete_limite = ' LIMIT '.$this->limite_requete['depart'].', '.$this->limite_requete['limite'];
6 jpm 245
		} else {
109 jpm 246
			$this->requete_limite = ' LIMIT '.$this->limite_requete['depart'].', '.$this->limite_requete['limite'];
6 jpm 247
		}
248
		return $this->requete_limite;
249
	}
109 jpm 250
 
6 jpm 251
	//on récupère le nombre total de résultats de la requete (ex : le nombre d'id contenu dans la liste /noms-vernaculaires)
252
	public function recupererTotalResultat() {
160 delphine 253
		$distinct = ($this->format_reponse == 'noms-vernaculaires/attributions') ? 'id' : 'distinct(id)';
254
		$requete = 'SELECT count('.$distinct.') as nombre FROM '
6 jpm 255
			.$this->table
256
			.$this->formerRequeteCondition();
257
		$res = $this->getBdd()->recuperer($requete);
109 jpm 258
 
6 jpm 259
		if ($res) {
260
			$total = $res['nombre'];
261
		} else {
160 delphine 262
			$t = 'Fonction recupererTotalResultat() : <br/>Données introuvables dans la base '.$requete;
6 jpm 263
			$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $t);
264
		}
265
		return $total;
266
	}
109 jpm 267
 
268
	//+------------------------------------------------------------------------------------------------------+
269
	// determine en fct du service appelé (/noms-vernaculaires | /noms-vernaculaires/#id | /noms-vernaculaires/#id/champ |
6 jpm 270
	// /noms-vernaculaires/#id/relations) le format du tableau à retourner.
271
	public function retournerResultatFormate($resultat) {
272
		$this->recupererTableConfig('correspondance_champs');
273
		switch ($this->format_reponse) {
132 aurelien 274
			case 'noms-vernaculaires'				:
275
				$reponse = ($this->retour_format == 'oss') ? $this->formaterEnOss($resultat) : $this->formaterNomsVernaculaires($resultat);			break;
160 delphine 276
			case 'noms-vernaculaires/attributions'	: $reponse = $this->formaterNomsVernaculairesAttributions($resultat);	break;
6 jpm 277
			case 'noms-vernaculaires/id'			: $reponse = $this->formaterNomsVernaculairesId($resultat);			break;
278
			case 'noms-vernaculaires/id/champ'		: $reponse = $this->formaterNomsVernaculairesIdChamp($resultat);	break;
279
			default									:																	break;
280
		}
281
		return $reponse;
282
	}
608 mathilde 283
 
284
	public function ajouterJsonEnTeteNV() {
285
		$table_retour_json['masque'] = $this->recupererMasque();
286
		$table_retour_json['depart'] = $this->limite_requete['depart'];
287
		$table_retour_json['limite'] = $this->limite_requete['limite'];
288
		$table_retour_json['total']  = $this->total_resultat;
6 jpm 289
		$url = $this->formulerUrl($this->total_resultat, '/noms-vernaculaires');
608 mathilde 290
		if (isset($url['precedent']) && $url['precedent'] != '') {
291
			$table_retour_json['href.precedent'] = $url['precedent'];
6 jpm 292
		}
608 mathilde 293
		if (isset($url['suivant']) && $url['suivant']   != '') {
294
			$table_retour_json['href.suivant']   = $url['suivant'];
152 delphine 295
		}
608 mathilde 296
		return $table_retour_json;
297
	}
298
 
299
	public function ajouterJsonResultatNV($resultat) {
6 jpm 300
		foreach ($resultat as $tab) {
301
			foreach ($tab as $key => $valeur) {
302
				if ($valeur != '') {
303
					switch ($key) {
304
						case 'id'				: $num = $valeur;								break;
305
						case 'nom_vernaculaire'	: $this->table_retour['nom'] = $valeur;			break;
306
						default					:												break;
307
					}
308
				}
309
			}
608 mathilde 310
		    if ($this->retour_format == 'max') $this->table_retour['href'] = $this->ajouterHref('noms-vernaculaires', $num);
6 jpm 311
			$resultat_json[$num] = $this->table_retour;
312
			$this->table_retour = array();
313
		}
608 mathilde 314
		return  $resultat_json;
315
	}
109 jpm 316
 
608 mathilde 317
 
318
	public function formaterNomsVernaculaires($resultat) {
319
		$table_retour_json['entete'] = $this->ajouterJsonEnTeteNV();
320
		$resultat = $this->hierarchiserResultat($resultat);
321
		$table_retour_json['resultat'] = $this->ajouterJsonResultatNV($resultat);
6 jpm 322
		return $table_retour_json;
323
	}
132 aurelien 324
 
608 mathilde 325
	public function hierarchiserResultat($resultat) {
326
		//tri recherche floue
327
		if (isset($this->parametres['masque.nv'])) {
328
			$resultat = $this->trierRechercheFloue($this->parametres['masque.nv'], $resultat, 'nom_vernaculaire');
329
		}
330
		if (isset($this->parametres['masque'])) {
331
			$resultat = $this->trierRechercheFloue($this->parametres['masque'], $resultat, 'nom_vernaculaire');
332
		}
333
		return $resultat;
334
	}
335
 
160 delphine 336
	public function recupererMasque() {
337
		$tab_masque = array();
338
		foreach ($this->parametres as $param=>$valeur) {
339
			if (strstr($param, 'masque') != false) {
340
				$tab_masque[] = $param.'='.$valeur;
341
			}
342
		}
343
		$masque = implode('&', $tab_masque);
344
		return $masque;
345
	}
346
 
132 aurelien 347
	public function formaterEnOss($resultat) {
348
		$table_nom = array();
349
		$oss = '';
350
		foreach ($resultat as $tab) {
351
			if (isset($tab['nom_vernaculaire']) ) {
352
				if (!in_array($tab['nom_vernaculaire'], $table_nom)) {
353
					$table_nom[] = $tab['nom_vernaculaire'];
354
					$oss [] = $tab['nom_vernaculaire'];
355
				}
356
			}
357
		}
358
		if (isset($this->masque)) $masque = implode('&', $this->masque);
359
		else $masque = 'Pas de masque';
360
		$table_retour_oss = array($masque, $oss);
361
		return $table_retour_oss;
362
	}
160 delphine 363
 
364
	public function formaterNomsVernaculairesAttributions($resultat) {
365
		//on remplie la table $table_retour_json['entete']
366
		$table_retour_json['entete']['masque'] = $this->recupererMasque();
367
		$table_retour_json['entete']['depart'] = $this->limite_requete['depart'];
368
		$table_retour_json['entete']['limite'] = $this->limite_requete['limite'];
369
		$table_retour_json['entete']['total']  = $this->total_resultat;
370
		$url = $this->formulerUrl($this->total_resultat, '/noms-vernaculaires/attributions');
729 raphael 371
		if (!empty($url['precedent'])) {
160 delphine 372
			$table_retour_json['entete']['href.precedent'] = $url['precedent'];
373
		}
729 raphael 374
		if (!empty($url['suivant'])) {
160 delphine 375
			$table_retour_json['entete']['href.suivant']   = $url['suivant'];
376
		}
284 jpm 377
		foreach ($resultat as &$tab) {
730 raphael 378
			$nnv = $tab['num_nom_vernaculaire'];
379
			$resultat_json[$nnv]['id'] = $tab['id'];
380
			$resultat_json[$nnv]['nom_vernaculaire'] = $tab['nom_vernaculaire'];
381
			$resultat_json[$nnv]['code_langue'] = $tab['code_langue'];
382
			$resultat_json[$nnv]['taxon.code'] = 'bdtfx.nt:'.$tab['num_taxon'];
160 delphine 383
			if ($this->retour_format == 'max') {
284 jpm 384
				$this->taxons[] = $tab['num_taxon']; // utilisé pour chercher les noms latins plus bas
729 raphael 385
				if($this->champs_supp) {
730 raphael 386
					//$resultat_json[$nnv] = $this->ajouterChampsOntologieLigneResultat($tab);
387
					// simple initialisation par copie de la référence de l'original
388
					$resultat_json[$nnv] = &$tab;
286 aurelien 389
				}
729 raphael 390
				else {
730 raphael 391
					$resultat_json[$nnv]['num_taxon'] = $tab['num_taxon'];
392
					$resultat_json[$nnv]['nom_retenu.code'] = $tab['num_taxon'];
393
					$resultat_json[$nnv]['taxon'] = $tab['num_taxon'];
394
					$resultat_json[$nnv]['href'] = $this->ajouterHref('noms-vernaculaires', $tab['id']);
729 raphael 395
				}
160 delphine 396
			}
280 aurelien 397
		}
730 raphael 398
 
399
		// dans ce cas (particulier?) nous n'avons pour l'heure initialisé qu'une référence
400
		// vers le tableau de valeurs original
401
		if ($this->retour_format == 'max' && $this->champs_supp) {
402
			// récupérons désormais les ontologies
403
			$this->ajouterChampsOntologieLigneTousResultats($resultat_json);
404
		}
405
 
280 aurelien 406
		if ($this->retour_format == 'max') {
284 jpm 407
			// On est obligé de faire un deuxième boucle pour demander tous les taxons présents en une
408
			// fois et les attribuer aux noms car c'est beaucoup plus rapide
409
			$noms_sci = $this->recupererNomTaxons();
286 aurelien 410
			foreach ($resultat_json as $num_nom => &$tab) {
411
				$tab = $this->ajouterTaxonsAttributionsLigneResultat($tab, $noms_sci);
627 aurelien 412
				if($tab == null) {
413
					unset($resultat_json[$num_nom]);
414
				}
284 jpm 415
			}
160 delphine 416
		}
280 aurelien 417
 
160 delphine 418
		$table_retour_json['resultat'] = $resultat_json;
419
		return $table_retour_json;
420
	}
421
 
286 aurelien 422
	/**
423
	 * Ajoute les champs d'ontologie supplémentaires si necéssaire
424
	 * en faisant appels aux web services associés
730 raphael 425
	 * @param array in/out $resultats: tous les résultats
426
	 */
427
	public function ajouterChampsOntologieLigneTousResultats(&$resultats) {
428
		foreach($this->champ_infos as $cle => $champs_supplementaires) {
429
			if(!in_array($cle, $this->champs_supp)) continue;
430
 
731 raphael 431
			// TODO: n'activer QUE lorsque le webservice ontologie Nvjfl supportera le multi-critère
432
			// cf: services/modules/0.1/commun/Ontologies.php
433
			if(FALSE && $cle == 'conseil_emploi') {
730 raphael 434
				// la factorisation des toutes les valeurs recherchées (pour tous les
435
				// résultats, peut [potentiellement] être effectuée ci-dessous)
731 raphael 436
				$ontologieParamPending = static::NvjflOntologieIndex($resultats, $champs_supplementaires);
437
				$this->NvjflOntologieExpand($ontologieParamPending);
438
				self::NvjflOntologieCombine($resultats, $champs_supplementaires);
439
				continue;
730 raphael 440
			}
441
 
442
			// extrait, depuis un élément de $champ_infos:
443
			// $service, $ressource, $projet, $nom, $intitule, $bdd_champ
444
			extract($champs_supplementaires);
445
 
446
			foreach ($resultats as &$tab) {
447
				$valeur_recherche = $tab[$bdd_champ];
448
				if(!trim($valeur_recherche)) continue;
449
 
450
				$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur_recherche, $projet);
451
				$tab[$intitule] = $this->chercherSignificationCode($url, $nom);
452
			}
453
		}
454
	}
455
 
731 raphael 456
	/* Récupère les valeurs recherchées pour une liste de résultats, (plus ou moins)
457
	   spécifiquement au service d'Ontologies de NVJFL.
458
	   Aggrège les valeurs dans le tableau retourné.
459
	   Une référence vers l'index du tableau (NULL pour l'instant) est laissée dans
460
	   un élément du résultat. */
461
	static function NvjflOntologieIndex(&$resultats, $champs_infos) {
462
		$ontologieParamPending = Array();
463
		extract($champs_infos);
464
		foreach($resultats as &$resultat) {
465
			$valeur_recherche = $resultat[$bdd_champ];
466
			if(!trim($valeur_recherche)) continue;
467
			$ontologieParamPending[$ressource . $valeur_recherche] = NULL;
468
			// placeholder pour le résultat
469
			$resultat['_result_ontologies' . RES_VAL_SEP . 'nvjfl'] =
470
				&$ontologieParamPending[$ressource . $valeur_recherche];
471
		}
472
		return $ontologieParamPending;
473
	}
474
 
475
	// TODO: switch to static si il peut en être de même pour ajouterHrefAutreProjet()
476
	/* À partir d'un aggrégat des critère de requêtes d'ontologies, spécifiques à NVJFL,
477
	   créé une URL multi-critère.
478
	   Celle-ci, dans ce cas précis, n'est que la concaténation, par des virgules,
479
	   des couples <ressource - valeur recherchée>.
480
	   L'URL est appelée et la valeur correspondante, dans $criteres_requete, remplacée.
481
 
482
	   Note: dans le cadre du tryptique index/expand/combine pour lequel cette fonction existe,
483
	   la valeur est référencée par une élément d'une ou plusieurs lignes de $resultat correspondantes.
484
	   Celle(s)-ci sera[ont] donc changée(s) dans la foulée. */
485
	public function NvjflOntologieExpand(&$criteres_requete) {
486
		// équivalent spécifique de ajouterHrefAutreProjet()
487
		$valeurs_requises = implode(',', array_keys($criteres_requete));
488
		$url = Config::get('url_service_base').'nvjfl/ontologies/'.$valeurs_requises;
489
		$val = $this->consulterHref($url);
490
		// modifie par conséquent $resultats[X]['_result_ontologies' . RES_VAL_SEP . 'nvjfl']
491
		// dont la référence pointe toujours sur $v
492
		foreach($val as $k => $v) $criteres_requete[$k] = $val->$k;
493
	}
494
 
495
	/* Fonction finale du tryptique: réordonne les valeurs obtenues auprès du web-service
496
	   NVJFL en adéquation avec les champs attendus en sortie. Pour ce faire, $champs_infos
497
	   est nécessaire. D'autre part, l'index spécifique '_result_ontologies' . RES_VAL_SEP . 'nvjfl'
498
	   est supprimé après avoir été correctement copié. */
499
	static function NvjflOntologieCombine(&$resultats, $champs_infos) {
500
		extract($champs_infos);
501
		foreach($resultats as &$resultat) {
502
			if(!isset($resultat['_result_ontologies' . RES_VAL_SEP . 'nvjfl'])) continue;
503
			// equivalent de chercher signification
504
			$resultat[$intitule] = $resultat['_result_ontologies' . RES_VAL_SEP . 'nvjfl']->$nom;
505
			unset($resultat['_result_ontologies' . RES_VAL_SEP . 'nvjfl']);
506
		}
507
	}
508
 
730 raphael 509
	/**
510
	 * Ajoute les champs d'ontologie supplémentaires si necéssaire
511
	 * en faisant appels aux web services associés
286 aurelien 512
	 * @param array $ligne_resultat
513
	 *
514
	 * @return array la ligne modifiée
515
	 */
284 jpm 516
	public function ajouterChampsOntologieLigneResultat($ligne_resultat) {
517
		foreach($this->champ_infos as $cle => $champs_supplementaires) {
729 raphael 518
			if(!in_array($cle, $this->champs_supp)) continue;
519
			// extrait, depuis un élément de $champ_infos:
520
			// $service, $ressource, $projet, $nom, $intitule, $bdd_champ
521
			extract($champs_supplementaires);
522
			$valeur_recherche = $ligne_resultat[$bdd_champ];
523
			if(!trim($valeur_recherche)) continue;
524
			$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur_recherche, $projet);
525
			$ligne_resultat[$intitule] = $this->chercherSignificationCode($url, $nom);
277 aurelien 526
		}
284 jpm 527
		return $ligne_resultat;
277 aurelien 528
	}
529
 
284 jpm 530
	/**
531
	 * Fonction qui ajoute les attributions à une ligne de résultats
532
	 *
533
	 * @param array $ligne_tableau_resultat
534
	 * @param array $nom_sci
535
	 */
536
	public function ajouterTaxonsAttributionsLigneResultat(&$ligne_tableau_resultat, &$noms_sci) {
285 aurelien 537
		if (isset($noms_sci[$ligne_tableau_resultat['num_taxon']])) {
538
			$ligne_tableau_resultat['nom_retenu.code'] = $noms_sci[$ligne_tableau_resultat['num_taxon']]['id'];
539
			$ligne_tableau_resultat['taxon'] = $noms_sci[$ligne_tableau_resultat['num_taxon']]['nom_sci'];
627 aurelien 540
		} else {
541
			$ligne_tableau_resultat = null;
284 jpm 542
		}
543
		return $ligne_tableau_resultat;
544
	}
545
 
546
	private function trierLigneTableau($a, $b) {
547
		$retour = 0;
548
 
549
		if ($a[$this->champ_tri] == $b[$this->champ_tri]) {
550
			$retour = 0;
551
		}
552
 
553
		if($this->champ_tri == 'code_langue') {
554
			if ($a[$this->champ_tri] == 'fra' && $b[$this->champ_tri] != 'fra') {
555
				$retour = ($this->direction_tri == 'asc') ? -1 : 1;
556
			} else if ($a[$this->champ_tri] != 'fra' && $b[$this->champ_tri] == 'fra') {
557
				$retour = ($this->direction_tri == 'asc') ? 1 : -1;
558
			} else {
559
				$retour = $this->comparerChaineSelonDirectionTri($a[$this->champ_tri], $b[$this->champ_tri]);
560
			}
561
		} else {
562
			$retour = $this->comparerChaineSelonDirectionTri($a[$this->champ_tri], $b[$this->champ_tri]);
563
		}
564
		return $retour;
565
	}
566
 
567
	private function comparerChaineSelonDirectionTri($a, $b) {
568
		if($this->direction_tri == 'asc') {
569
			return ($a < $b) ? -1 : 1;
570
		} else {
571
			return ($a > $b) ? -1 : 1;
572
		}
573
	}
574
 
6 jpm 575
	// formatage de la reponse /id ss la forme
576
	// id, nom_vernaculaire, attributions
577
	// langue
578
	// num_nom (correspond à un taxon bdtfx)
579
	public function formaterNomsVernaculairesId($resultat) {
580
		foreach ($resultat as $taxon) { // pour chaque attribution à un taxon bdtfx
581
			// on crée les variables qui serviront de clés et on les enléves du tableau
582
			$num_nom = $taxon['num_nom_vernaculaire']; // unique pour un trinôme id, langue, taxon
583
			unset($taxon['num_nom_vernaculaire']);
584
			$langue = $taxon['code_langue'];
585
			unset($taxon['code_langue']);
109 jpm 586
 
6 jpm 587
			foreach ($this->correspondance_champs as $key => $correspondance) { // ordonne les infos pour affichage
588
				if (isset($taxon[$key]) && $taxon[$key] != "") {
589
					$this->afficherDonnees($correspondance, $taxon[$key], $langue, $num_nom);
590
				}
591
			}
592
			foreach ($taxon as $key => $valeur) { // rajoute les champs non prévus dans l'api
593
				if (!isset($this->correspondance_champs[$key]) && $valeur != "") {
594
					$this->afficherDonnees($key, $valeur, $langue, $num_nom);
595
				}
596
			}
597
			if ($this->retour_format == 'max') $this->chargerBiblio($num_nom, $langue);
598
		}
599
		if ($this->retour_format == 'max') $this->afficherTaxons(); // va chercher les noms de tous les taxons
600
		unset($this->table_retour['href']);
601
		return $this->table_retour;
602
	}
109 jpm 603
 
6 jpm 604
	public function afficherDonnees($champ, $valeur, $langue = '', $num_nom = '') {
605
		if ($champ == 'id' || $champ == 'nom_vernaculaire') {
606
			$this->table_retour[$champ] = $valeur;
607
		} elseif (preg_match('/^(.*)\.code$/', $champ, $match)) {
608
				switch ($match[1]) {
609
					case 'taxon'	: if ($this->retour_format == 'max') {$this->taxons[$num_nom] = $valeur;}
610
						$this->afficherPointCode($match[1], $langue, $num_nom, $valeur);	break;
109 jpm 611
					case 'langue'	: //$this->afficherPointCode($match[1], 'iso-639-3', 'langues', $valeur);
6 jpm 612
						break;
613
					case 'genre'	: $this->afficherPointCode($match[1], $langue, $num_nom, $valeur);	break;
614
					case 'conseil_emploi'	: $this->afficherPointCode($match[1], $langue, $num_nom, $valeur);	break;
615
					default : break;
616
				}
109 jpm 617
 
6 jpm 618
		} elseif ($langue != '') {
619
			$this->table_retour['attributions'][$langue][$num_nom][$champ] = $valeur;
620
		} else {
621
			$this->table_retour[$champ] = $valeur;
622
		}
623
	}
109 jpm 624
 
6 jpm 625
	public function afficherPointCode($nomChamp, $langue, $num_nom, $valeur) {
626
		if (isset($this->champ_infos[$nomChamp])) {
627
			extract($this->champ_infos[$nomChamp]);
628
		}
109 jpm 629
 
6 jpm 630
		if ($this->retour_format == 'max') {
631
			$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur, $projet);
632
			if ($service == 'taxons') {
633
				$code_valeur = '';
164 delphine 634
				$this->table_retour['attributions'][$langue][$num_nom]['nom_retenu.code'] = $code_valeur;
109 jpm 635
			} else {
6 jpm 636
				$code_valeur = $this->chercherSignificationCode($url, $nom);
637
			}
638
			if ($projet != '') $projet .= '.';
639
			$this->table_retour['attributions'][$langue][$num_nom][$nomChamp] = $code_valeur;
640
			$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.code'] = $projet.$ressource.$valeur;
641
			$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.href'] = $url;
642
		} else {
643
			if ($projet != '') $projet .= '.';
644
			$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.code'] = $projet.$ressource.$valeur;
645
		}
646
	}
109 jpm 647
 
6 jpm 648
	public function chercherSignificationCode($url, $nom) {
649
		if (isset($this->signification_code[$url])) {
650
			$valeur = $this->signification_code[$url];
651
		} else {
652
			$res = $this->consulterHref($url);
653
			$valeur = $res->$nom;
654
			$this->signification_code[$url] = $valeur;
655
		}
656
		return $valeur;
657
	}
109 jpm 658
 
6 jpm 659
	public function afficherTaxons() {
160 delphine 660
		$resultat = $this->recupererNomTaxons();
6 jpm 661
		foreach ($this->table_retour['attributions'] as $code_langue=>$langue) {
662
			foreach ($langue as $num_nom=>$taxon) {
663
				$num_tax = ltrim($taxon['taxon.code'], 'bdtfx.nt:');
664
				if (isset($resultat[$num_tax])) {
164 delphine 665
					$this->table_retour['attributions'][$code_langue][$num_nom]['nom_retenu.code'] = $resultat[$num_tax]['id'];
666
					$this->table_retour['attributions'][$code_langue][$num_nom]['taxon'] = $resultat[$num_tax]['nom_sci'];
6 jpm 667
				}
668
			}
669
		}
670
	}
160 delphine 671
 
672
	public function recupererNomTaxons() {
627 aurelien 673
		$taxons = array_unique($this->taxons);
674
		$url = Config::get('url_service_base').'bdtfx/taxons?navigation.limite=500&ns.structure=au&masque.nt='.implode(',', $taxons);
160 delphine 675
		$res = $this->consulterHref($url);
676
		foreach ($res->resultat as $id=>$taxon) {
164 delphine 677
			$resultat[$taxon->num_taxonomique]['id'] = 'bdtfx.nn:'.$id;
627 aurelien 678
			$resultat[$taxon->num_taxonomique]['nom_sci'] = $taxon->nom_sci_complet;
160 delphine 679
		}
680
		return $resultat;
681
	}
6 jpm 682
 
683
	public function formaterNomsVernaculairesIdChamp($resultat) {
109 jpm 684
		$this->table_retour['id'] = $this->ressources[0];
685
		$champs = explode(' ', $this->ressources[1]);
6 jpm 686
		if (in_array('attributions', $champs) != false) {
687
			$this->formaterNomsVernaculairesId($resultat);
688
			unset($this->table_retour['nom_vernaculaire']);
160 delphine 689
		} else {
6 jpm 690
			$champ_attributions = array('num_taxon', 'zone_usage', 'num_statut', 'num_genre', 'notes');
691
			foreach ($resultat as $taxon) {
692
				foreach ($taxon as $key=>$valeur) {
693
					if ($key == 'code_langue' && in_array('langue', $champs) != false) {
694
						$this->table_retour['attributions']['langue'][] = $valeur;
695
					} elseif (in_array($key, $champ_attributions) != false) {
696
						$this->afficherPoint($this->correspondance_champs[$key] , $valeur, $taxon['code_langue'], $taxon['num_nom_vernaculaire']);
697
					} elseif (in_array($key, $champs) != false) {
698
						$this->table_retour[$key] = $valeur;
699
					}
700
				}
701
				if (in_array('biblio', $champs) != false) $this->chargerBiblio($taxon['num_nom_vernaculaire'], $taxon['code_langue']);
702
			}
703
			if (in_array('biblio', $champs) != false && array_search('biblio.num_ref', $this->table_retour) != false) $this->table_retour['biblio'] = null;
704
		}
705
		return $this->table_retour;
706
	}
109 jpm 707
 
6 jpm 708
	public function afficherPoint($champ, $valeur, $langue, $num_nom) {
709
		preg_match('/^(.*)\.code$/', $champ, $match);
710
		$champ = $match[1];
711
		if (isset($this->champ_infos[$champ])) {
712
			extract($this->champ_infos[$champ]);
713
			$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur, $projet);
714
			$projet .= '.';
715
		}
109 jpm 716
 
717
		$champs = explode(' ', $this->ressources[1]);
6 jpm 718
		if (in_array($champ.'.*', $champs) !== false && isset($projet)) {
719
			$this->table_retour['attributions'][$langue][$num_nom][$champ.'.code'] = $projet.$ressource.$valeur;
720
			$this->table_retour['attributions'][$langue][$num_nom][$champ.'.href'] = $url;
109 jpm 721
		}
6 jpm 722
		if (in_array($champ.'.code', $champs) !== false && isset($projet)) {
723
			$this->table_retour['attributions'][$langue][$num_nom][$champ.'.code'] = $projet.$ressource.$valeur;
109 jpm 724
		}
6 jpm 725
		if (in_array($champ.'.href', $champs) !== false && isset($projet)) {
726
			$this->table_retour['attributions'][$langue][$num_nom][$champ.'.href'] = $url;
109 jpm 727
		}
6 jpm 728
		if (in_array($champ, $champs) !== false) {
729
			if (isset($url)) {
730
				$this->table_retour['attributions'][$langue][$num_nom][$champ] = $this->chercherSignificationCode($url, $nom);
731
			} else {
732
				$this->table_retour['attributions'][$langue][$champ] = $valeur;
733
			}
109 jpm 734
		}
6 jpm 735
	}
736
 
737
	public function afficherLangue($nomChamp, $projet, $service, $valeur, $ressource = '', $nom = 'nom') {
738
		if ($this->retour_format == 'max') {
739
				$this->table_retour['attributions'][$nomChamp] = $nom;
740
				$this->table_retour['attributions'][$nomChamp.'.code'] = $projet.$ressource.$valeur;
741
				$this->table_retour['attributions'][$nomChamp.'.href'] = $url;
742
		} else {
743
			$this->table_retour['attributions'][$nomChamp.'.code'] = $projet.$ressource.$valeur;
744
		}
745
	}
109 jpm 746
 
6 jpm 747
	public function chargerBiblio($num_nom, $langue) {
748
		list($table, $version) = explode('_v',$this->table);
749
		$requete = "SELECT b.*, lb.notes FROM nvjfl_lien_biblio_v$version lb, nvjfl_biblio_v$version b ".
750
					"WHERE b.num_ref = lb.num_ref AND lb.num_nom = '$num_nom' ;";
284 jpm 751
		$resultat = $this->getBdd()->recupererTous($requete);
109 jpm 752
 
6 jpm 753
		 if ($resultat == '') { //cas ou la requete comporte des erreurs
754
		 	$r = 'La requête SQL formée comporte une erreur !!';
755
			$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $r);
756
			Debug::printr($requete);
757
		 } elseif ($resultat) {
758
			foreach ($resultat as $res) {
759
			   	foreach ($res as $cle => $valeur) {
760
			   		if ($valeur !== "") {
761
			   			$this->table_retour['attributions'][$langue][$num_nom]['biblio.'.$cle] = $valeur;
762
			   		}
763
			    }
764
			}
765
		}
766
	}
109 jpm 767
 
6 jpm 768
}
769
?>