Subversion Repositories eFlore/Projets.eflore-projets

Rev

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