Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 809 | Rev 832 | 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) {
831 raphael 470
			$valeur_recherche = $resultat[$bdd_champ]; // NvjflOntologieIndex uniquement pour "conseil_emploi", donc $bdd_champ = 'num_statut'
731 raphael 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);
831 raphael 495
 
496
		// TODO, le webservice d'ontologies devrait être modifié pour retourner un tableau
497
		// indexé par critère requesté à *CHAQUE* fois, y compris lorsque 1 seul critère est
498
		// demandé.
499
		if(array_key_exists('id', $val) && count($criteres_requete) == 1) {
500
			$k = key($criteres_requete);
501
			$criteres_requete[$k] = $val;
502
			return;
503
		}
504
 
505
		// subtilité, cette affectation modifie par conséquent $resultats[X]['_result_ontologies' . RES_VAL_SEP . 'nvjfl']
731 raphael 506
		// dont la référence pointe toujours sur $v
507
		foreach($val as $k => $v) $criteres_requete[$k] = $val->$k;
508
	}
509
 
510
	/* Fonction finale du tryptique: réordonne les valeurs obtenues auprès du web-service
511
	   NVJFL en adéquation avec les champs attendus en sortie. Pour ce faire, $champs_infos
512
	   est nécessaire. D'autre part, l'index spécifique '_result_ontologies' . RES_VAL_SEP . 'nvjfl'
513
	   est supprimé après avoir été correctement copié. */
514
	static function NvjflOntologieCombine(&$resultats, $champs_infos) {
515
		extract($champs_infos);
516
		foreach($resultats as &$resultat) {
831 raphael 517
			if(!array_key_exists('_result_ontologies' . RES_VAL_SEP . 'nvjfl', $resultat)) continue;
731 raphael 518
			// equivalent de chercher signification
519
			$resultat[$intitule] = $resultat['_result_ontologies' . RES_VAL_SEP . 'nvjfl']->$nom;
520
			unset($resultat['_result_ontologies' . RES_VAL_SEP . 'nvjfl']);
521
		}
522
	}
523
 
730 raphael 524
	/**
525
	 * Ajoute les champs d'ontologie supplémentaires si necéssaire
526
	 * en faisant appels aux web services associés
286 aurelien 527
	 * @param array $ligne_resultat
528
	 *
529
	 * @return array la ligne modifiée
530
	 */
284 jpm 531
	public function ajouterChampsOntologieLigneResultat($ligne_resultat) {
532
		foreach($this->champ_infos as $cle => $champs_supplementaires) {
729 raphael 533
			if(!in_array($cle, $this->champs_supp)) continue;
534
			// extrait, depuis un élément de $champ_infos:
535
			// $service, $ressource, $projet, $nom, $intitule, $bdd_champ
536
			extract($champs_supplementaires);
537
			$valeur_recherche = $ligne_resultat[$bdd_champ];
538
			if(!trim($valeur_recherche)) continue;
539
			$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur_recherche, $projet);
540
			$ligne_resultat[$intitule] = $this->chercherSignificationCode($url, $nom);
277 aurelien 541
		}
284 jpm 542
		return $ligne_resultat;
277 aurelien 543
	}
544
 
284 jpm 545
	/**
546
	 * Fonction qui ajoute les attributions à une ligne de résultats
547
	 *
548
	 * @param array $ligne_tableau_resultat
549
	 * @param array $nom_sci
550
	 */
551
	public function ajouterTaxonsAttributionsLigneResultat(&$ligne_tableau_resultat, &$noms_sci) {
285 aurelien 552
		if (isset($noms_sci[$ligne_tableau_resultat['num_taxon']])) {
553
			$ligne_tableau_resultat['nom_retenu.code'] = $noms_sci[$ligne_tableau_resultat['num_taxon']]['id'];
554
			$ligne_tableau_resultat['taxon'] = $noms_sci[$ligne_tableau_resultat['num_taxon']]['nom_sci'];
627 aurelien 555
		} else {
556
			$ligne_tableau_resultat = null;
284 jpm 557
		}
558
		return $ligne_tableau_resultat;
559
	}
560
 
561
	private function trierLigneTableau($a, $b) {
562
		$retour = 0;
563
 
564
		if ($a[$this->champ_tri] == $b[$this->champ_tri]) {
565
			$retour = 0;
566
		}
567
 
568
		if($this->champ_tri == 'code_langue') {
569
			if ($a[$this->champ_tri] == 'fra' && $b[$this->champ_tri] != 'fra') {
570
				$retour = ($this->direction_tri == 'asc') ? -1 : 1;
571
			} else if ($a[$this->champ_tri] != 'fra' && $b[$this->champ_tri] == 'fra') {
572
				$retour = ($this->direction_tri == 'asc') ? 1 : -1;
573
			} else {
574
				$retour = $this->comparerChaineSelonDirectionTri($a[$this->champ_tri], $b[$this->champ_tri]);
575
			}
576
		} else {
577
			$retour = $this->comparerChaineSelonDirectionTri($a[$this->champ_tri], $b[$this->champ_tri]);
578
		}
579
		return $retour;
580
	}
581
 
582
	private function comparerChaineSelonDirectionTri($a, $b) {
583
		if($this->direction_tri == 'asc') {
584
			return ($a < $b) ? -1 : 1;
585
		} else {
586
			return ($a > $b) ? -1 : 1;
587
		}
588
	}
589
 
6 jpm 590
	// formatage de la reponse /id ss la forme
591
	// id, nom_vernaculaire, attributions
592
	// langue
593
	// num_nom (correspond à un taxon bdtfx)
594
	public function formaterNomsVernaculairesId($resultat) {
595
		foreach ($resultat as $taxon) { // pour chaque attribution à un taxon bdtfx
596
			// on crée les variables qui serviront de clés et on les enléves du tableau
597
			$num_nom = $taxon['num_nom_vernaculaire']; // unique pour un trinôme id, langue, taxon
598
			unset($taxon['num_nom_vernaculaire']);
599
			$langue = $taxon['code_langue'];
600
			unset($taxon['code_langue']);
109 jpm 601
 
6 jpm 602
			foreach ($this->correspondance_champs as $key => $correspondance) { // ordonne les infos pour affichage
603
				if (isset($taxon[$key]) && $taxon[$key] != "") {
604
					$this->afficherDonnees($correspondance, $taxon[$key], $langue, $num_nom);
605
				}
606
			}
607
			foreach ($taxon as $key => $valeur) { // rajoute les champs non prévus dans l'api
608
				if (!isset($this->correspondance_champs[$key]) && $valeur != "") {
609
					$this->afficherDonnees($key, $valeur, $langue, $num_nom);
610
				}
611
			}
612
			if ($this->retour_format == 'max') $this->chargerBiblio($num_nom, $langue);
613
		}
614
		if ($this->retour_format == 'max') $this->afficherTaxons(); // va chercher les noms de tous les taxons
615
		unset($this->table_retour['href']);
616
		return $this->table_retour;
617
	}
109 jpm 618
 
6 jpm 619
	public function afficherDonnees($champ, $valeur, $langue = '', $num_nom = '') {
620
		if ($champ == 'id' || $champ == 'nom_vernaculaire') {
621
			$this->table_retour[$champ] = $valeur;
622
		} elseif (preg_match('/^(.*)\.code$/', $champ, $match)) {
623
				switch ($match[1]) {
624
					case 'taxon'	: if ($this->retour_format == 'max') {$this->taxons[$num_nom] = $valeur;}
625
						$this->afficherPointCode($match[1], $langue, $num_nom, $valeur);	break;
109 jpm 626
					case 'langue'	: //$this->afficherPointCode($match[1], 'iso-639-3', 'langues', $valeur);
6 jpm 627
						break;
628
					case 'genre'	: $this->afficherPointCode($match[1], $langue, $num_nom, $valeur);	break;
629
					case 'conseil_emploi'	: $this->afficherPointCode($match[1], $langue, $num_nom, $valeur);	break;
630
					default : break;
631
				}
109 jpm 632
 
6 jpm 633
		} elseif ($langue != '') {
634
			$this->table_retour['attributions'][$langue][$num_nom][$champ] = $valeur;
635
		} else {
636
			$this->table_retour[$champ] = $valeur;
637
		}
638
	}
109 jpm 639
 
6 jpm 640
	public function afficherPointCode($nomChamp, $langue, $num_nom, $valeur) {
641
		if (isset($this->champ_infos[$nomChamp])) {
642
			extract($this->champ_infos[$nomChamp]);
643
		}
109 jpm 644
 
6 jpm 645
		if ($this->retour_format == 'max') {
646
			$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur, $projet);
647
			if ($service == 'taxons') {
648
				$code_valeur = '';
164 delphine 649
				$this->table_retour['attributions'][$langue][$num_nom]['nom_retenu.code'] = $code_valeur;
109 jpm 650
			} else {
6 jpm 651
				$code_valeur = $this->chercherSignificationCode($url, $nom);
652
			}
653
			if ($projet != '') $projet .= '.';
654
			$this->table_retour['attributions'][$langue][$num_nom][$nomChamp] = $code_valeur;
655
			$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.code'] = $projet.$ressource.$valeur;
656
			$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.href'] = $url;
657
		} else {
658
			if ($projet != '') $projet .= '.';
659
			$this->table_retour['attributions'][$langue][$num_nom][$nomChamp.'.code'] = $projet.$ressource.$valeur;
660
		}
661
	}
109 jpm 662
 
6 jpm 663
	public function chercherSignificationCode($url, $nom) {
664
		if (isset($this->signification_code[$url])) {
665
			$valeur = $this->signification_code[$url];
666
		} else {
667
			$res = $this->consulterHref($url);
668
			$valeur = $res->$nom;
669
			$this->signification_code[$url] = $valeur;
670
		}
671
		return $valeur;
672
	}
109 jpm 673
 
6 jpm 674
	public function afficherTaxons() {
160 delphine 675
		$resultat = $this->recupererNomTaxons();
6 jpm 676
		foreach ($this->table_retour['attributions'] as $code_langue=>$langue) {
677
			foreach ($langue as $num_nom=>$taxon) {
678
				$num_tax = ltrim($taxon['taxon.code'], 'bdtfx.nt:');
679
				if (isset($resultat[$num_tax])) {
164 delphine 680
					$this->table_retour['attributions'][$code_langue][$num_nom]['nom_retenu.code'] = $resultat[$num_tax]['id'];
681
					$this->table_retour['attributions'][$code_langue][$num_nom]['taxon'] = $resultat[$num_tax]['nom_sci'];
6 jpm 682
				}
683
			}
684
		}
685
	}
160 delphine 686
 
687
	public function recupererNomTaxons() {
627 aurelien 688
		$taxons = array_unique($this->taxons);
689
		$url = Config::get('url_service_base').'bdtfx/taxons?navigation.limite=500&ns.structure=au&masque.nt='.implode(',', $taxons);
160 delphine 690
		$res = $this->consulterHref($url);
691
		foreach ($res->resultat as $id=>$taxon) {
164 delphine 692
			$resultat[$taxon->num_taxonomique]['id'] = 'bdtfx.nn:'.$id;
627 aurelien 693
			$resultat[$taxon->num_taxonomique]['nom_sci'] = $taxon->nom_sci_complet;
160 delphine 694
		}
695
		return $resultat;
696
	}
6 jpm 697
 
698
	public function formaterNomsVernaculairesIdChamp($resultat) {
109 jpm 699
		$this->table_retour['id'] = $this->ressources[0];
700
		$champs = explode(' ', $this->ressources[1]);
6 jpm 701
		if (in_array('attributions', $champs) != false) {
702
			$this->formaterNomsVernaculairesId($resultat);
703
			unset($this->table_retour['nom_vernaculaire']);
160 delphine 704
		} else {
6 jpm 705
			$champ_attributions = array('num_taxon', 'zone_usage', 'num_statut', 'num_genre', 'notes');
706
			foreach ($resultat as $taxon) {
707
				foreach ($taxon as $key=>$valeur) {
708
					if ($key == 'code_langue' && in_array('langue', $champs) != false) {
709
						$this->table_retour['attributions']['langue'][] = $valeur;
710
					} elseif (in_array($key, $champ_attributions) != false) {
711
						$this->afficherPoint($this->correspondance_champs[$key] , $valeur, $taxon['code_langue'], $taxon['num_nom_vernaculaire']);
712
					} elseif (in_array($key, $champs) != false) {
713
						$this->table_retour[$key] = $valeur;
714
					}
715
				}
716
				if (in_array('biblio', $champs) != false) $this->chargerBiblio($taxon['num_nom_vernaculaire'], $taxon['code_langue']);
717
			}
718
			if (in_array('biblio', $champs) != false && array_search('biblio.num_ref', $this->table_retour) != false) $this->table_retour['biblio'] = null;
719
		}
720
		return $this->table_retour;
721
	}
109 jpm 722
 
6 jpm 723
	public function afficherPoint($champ, $valeur, $langue, $num_nom) {
724
		preg_match('/^(.*)\.code$/', $champ, $match);
725
		$champ = $match[1];
726
		if (isset($this->champ_infos[$champ])) {
727
			extract($this->champ_infos[$champ]);
728
			$url = $this->ajouterHrefAutreProjet($service, $ressource, $valeur, $projet);
729
			$projet .= '.';
730
		}
109 jpm 731
 
732
		$champs = explode(' ', $this->ressources[1]);
6 jpm 733
		if (in_array($champ.'.*', $champs) !== false && isset($projet)) {
734
			$this->table_retour['attributions'][$langue][$num_nom][$champ.'.code'] = $projet.$ressource.$valeur;
735
			$this->table_retour['attributions'][$langue][$num_nom][$champ.'.href'] = $url;
109 jpm 736
		}
6 jpm 737
		if (in_array($champ.'.code', $champs) !== false && isset($projet)) {
738
			$this->table_retour['attributions'][$langue][$num_nom][$champ.'.code'] = $projet.$ressource.$valeur;
109 jpm 739
		}
6 jpm 740
		if (in_array($champ.'.href', $champs) !== false && isset($projet)) {
741
			$this->table_retour['attributions'][$langue][$num_nom][$champ.'.href'] = $url;
109 jpm 742
		}
6 jpm 743
		if (in_array($champ, $champs) !== false) {
744
			if (isset($url)) {
745
				$this->table_retour['attributions'][$langue][$num_nom][$champ] = $this->chercherSignificationCode($url, $nom);
746
			} else {
747
				$this->table_retour['attributions'][$langue][$champ] = $valeur;
748
			}
109 jpm 749
		}
6 jpm 750
	}
751
 
752
	public function afficherLangue($nomChamp, $projet, $service, $valeur, $ressource = '', $nom = 'nom') {
753
		if ($this->retour_format == 'max') {
754
				$this->table_retour['attributions'][$nomChamp] = $nom;
755
				$this->table_retour['attributions'][$nomChamp.'.code'] = $projet.$ressource.$valeur;
756
				$this->table_retour['attributions'][$nomChamp.'.href'] = $url;
757
		} else {
758
			$this->table_retour['attributions'][$nomChamp.'.code'] = $projet.$ressource.$valeur;
759
		}
760
	}
109 jpm 761
 
6 jpm 762
	public function chargerBiblio($num_nom, $langue) {
763
		list($table, $version) = explode('_v',$this->table);
764
		$requete = "SELECT b.*, lb.notes FROM nvjfl_lien_biblio_v$version lb, nvjfl_biblio_v$version b ".
765
					"WHERE b.num_ref = lb.num_ref AND lb.num_nom = '$num_nom' ;";
284 jpm 766
		$resultat = $this->getBdd()->recupererTous($requete);
109 jpm 767
 
6 jpm 768
		 if ($resultat == '') { //cas ou la requete comporte des erreurs
769
		 	$r = 'La requête SQL formée comporte une erreur !!';
770
			$this->renvoyerErreur(RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE, $r);
771
			Debug::printr($requete);
772
		 } elseif ($resultat) {
773
			foreach ($resultat as $res) {
774
			   	foreach ($res as $cle => $valeur) {
775
			   		if ($valeur !== "") {
776
			   			$this->table_retour['attributions'][$langue][$num_nom]['biblio.'.$cle] = $valeur;
777
			   		}
778
			    }
779
			}
780
		}
781
	}
109 jpm 782
 
6 jpm 783
}
784
?>