Subversion Repositories eFlore/Applications.cel

Rev

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

Rev Author Line No. Line
3120 delphine 1
<?php
2
// declare(encoding='UTF-8');
3
/**
4
 * Service affichant les dernières photo publiques du CEL ouvrable sous forme de diaporama.
5
 * Encodage en entrée : utf8
6
 * Encodage en sortie : utf8
7
 *
8
 * Cas d'utilisation et documentation :
9
 * @link http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=AideCELWidgetPhoto
10
 *
11
 * Paramètres :
12
 * ===> extra = booléen (1 ou 0)  [par défaut : 1]
13
 * Affiche / Cache la vignette en taille plus importante au bas du widget.
14
 * ===> vignette = [0-9]+,[0-9]+  [par défaut : 4,3]
15
 * Indique le nombre de vignette par ligne et le nombre de ligne.
16
 *
17
 * @author		Jean-Pascal MILCENT <jpm@tela-botanica.org>
18
 * @license	GPL v3 <http://www.gnu.org/licenses/gpl.txt>
19
 * @license	CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
20
 * @version	$Id$
21
 * @copyright	Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
22
 */
23
class Saisie2 extends WidgetCommun {
24
 
25
	const DS = DIRECTORY_SEPARATOR;
26
	const SERVICE_DEFAUT = 'saisie';
27
	const LANGUE_DEFAUT = 'fr';
28
	const PROJET_DEFAUT = 'base';
29
	const WS_NOM = 'noms';
30
	const EFLORE_API_VERSION = '0.1';
31
	private $cel_url_tpl = null;
32
	/** Si spécifié, on ajoute une barre de navigation inter-applications */
33
	private $bar;
34
	//private $parametres_autorises = array('projet', 'type', 'langue', 'order');
35
	private $parametres_autorises = array(
36
			'projet' => 'projet',
37
			'type' => 'type',
38
			'langue' => 'langue',
39
			'order' => 'order'
40
	);
41
	/**
42
	 * Méthode appelée par défaut pour charger ce widget.
43
	 */
44
	public function executer() {
45
		$retour = null;
46
		// Pour la création de l'id du cache nous ne tenons pas compte du paramètre de l'url callback
47
		unset($this->parametres['callback']);
48
		extract($this->parametres);
49
		$this->bar = (isset($bar)) ? $bar : false;
50
		/* Le fichier Framework.php du Framework de Tela Botanica doit être appelé avant tout autre chose dans l'application.
51
		 Sinon, rien ne sera chargé.
52
		 L'emplacement du Framework peut varier en fonction de l'environnement (test, prod...). Afin de faciliter la configuration
53
		 de l'emplacement du Framework, un fichier framework.defaut.php doit être renommé en framework.php et configuré pour chaque installation de
54
		 l'application.
55
		 Chemin du fichier chargeant le framework requis */
56
		$framework = dirname(__FILE__).'/framework.php';
57
		if (!file_exists($framework)) {
58
			$e = "Veuillez paramêtrer l'emplacement et la version du Framework dans le fichier $framework";
59
			trigger_error($e, E_USER_ERROR);
60
		} else {
61
			// Inclusion du Framework
62
			require_once $framework;
63
			// Ajout d'information concernant cette application
64
			Framework::setCheminAppli(__FILE__);// Obligatoire
65
			Framework::setInfoAppli(Config::get('info'));// Optionnel
66
 
67
		}
68
		$langue = (isset($langue)) ? $langue : self::LANGUE_DEFAUT;
69
		$this->langue = I18n::setLangue($langue);
70
		$this->parametres['langue'] = $langue;
71
 
72
		if (!isset($mode)) {
73
			$mode = self::SERVICE_DEFAUT;
74
		}
75
		if (!isset($projet)) {
76
			$this->parametres['projet'] = self::PROJET_DEFAUT;
77
		}
78
 
79
		$methode = $this->traiterNomMethodeExecuter($mode);
80
		if (method_exists($this, $methode)) {
81
			$retour = $this->$methode();
82
		} else {
83
			$this->messages[] = "Ce type de service '$methode' n'est pas disponible.";
84
		}
85
 
86
		$contenu = '';
87
		if (is_null($retour)) {
88
			$this->messages[] = 'La ressource demandée a retourné une valeur nulle.';
89
		} else {
90
			if (isset($retour['donnees'])) {
91
				$retour['donnees']['prod'] = ($this->config['parametres']['modeServeur'] == "prod");
92
				$retour['donnees']['bar'] = $this->bar;
93
				$retour['donnees']['url_base'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], '');
94
				$retour['donnees']['url_ws_annuaire'] = sprintf($this->config['chemins']['baseURLServicesAnnuaireTpl'], 'utilisateur/identite-par-courriel/');
3204 delphine 95
				$retour['donnees']['authTpl'] = $this->config['manager']['authTpl'].'?projet='.$this->parametres['projet'].'&langue='.$this->parametres['langue'];
3120 delphine 96
				$retour['donnees']['mode'] = $mode;
97
				$squelette = dirname(__FILE__).self::DS.'squelettes'.self::DS.$retour['squelette'].'.tpl.html';
98
				$contenu = $this->traiterSquelettePhp($squelette, $retour['donnees']);
99
			} else {
100
				$this->messages[] = 'Les données à transmettre au squelette sont nulles.';
101
			}
102
		}
103
		$this->envoyer($contenu);
104
	}
105
 
106
 
107
	private function executerSaisie() {
3200 delphine 108
		$retour = array();
3120 delphine 109
		$retour['squelette'] = 'saisie';
110
		$retour['donnees']['general'] = I18n::get('General');
111
		$retour['donnees']['aide'] = I18n::get('Aide');
112
		$retour['donnees']['observateur'] = I18n::get('Observateur');
113
		$retour['donnees']['observation'] = I18n::get('Observation');
114
		$retour['donnees']['widget'] = $this->rechercherProjet();
115
		return $retour;
116
	}
117
 
118
	/* Recherche si le projet existe sinon va chercher les infos de base */
119
	private function rechercherProjet() {
120
		// projet avec un squelette défini (et non juste un mot-clé d'observation)
3200 delphine 121
		$estProjetDefini = true; $tab = array();
3120 delphine 122
		$url = $this->config['manager']['celUrlTpl'].'?projet='.$this->parametres['projet'].'&langue='.$this->parametres['langue'];
123
		$json = $this->getDao()->consulter($url);
124
		if ($json == false) {
125
			$url = $this->config['manager']['celUrlTpl'].'?projet=base&langue='.$this->parametres['langue'];
126
			$json = $this->getDao()->consulter($url);
127
			$estProjetDefini = false;
128
		} else {
129
			$tab = $this->rechercherChampsSupp();
130
		}
131
		$tableau = json_decode($json, true);
132
		$tableau = $this->traiterParametres($estProjetDefini, $tableau[0]);
133
		$tableau['especes'] = $this->rechercherInfosEspeces($tableau);
134
		if ($tableau['milieux'] != "") {
135
			$tableau['milieux']= explode(";", $tableau['milieux']);
136
		} else {
137
			$tableau['milieux'] = array();
138
		}
139
		$tableau['chpSupp'] = $tab;
140
		return $tableau;
141
	}
142
 
143
	/* Recherche si un projet a des champs de saisie supplémentaire */
144
	private function rechercherChampsSupp() {
3200 delphine 145
		$retour = array();
3204 delphine 146
		$url = $this->config['manager']['celChpSupTpl'].'?projet='.$this->parametres['projet'].'&langue='.$this->parametres['langue'];
147
		$json = $this->getDao()->consulter($url);
148
		$retour = (array) json_decode($json, true);
3120 delphine 149
		return $retour;
150
	}
151
 
152
	// remplace certains parametres définis en bd par les parametres définis dans l'url
153
	private function traiterParametres($estProjetDefini, $tableau) {
154
		$criteres = array('tag', 'motcle', 'projet', 'titre', 'logo');
155
		$criteresProjetNonDefini = array('commune', 'num_nom', 'referentiel');
156
		foreach($this->parametres as $nom_critere => $valeur_critere) {
157
			if (($estProjetDefini == false || $tableau['projet'] == "base") && in_array($nom_critere, $criteresProjetNonDefini)) {
158
				$tableau[$nom_critere] = $valeur_critere;
159
			} else if (in_array($nom_critere, $criteres)) {
160
				$tableau[$nom_critere] = $valeur_critere;
161
			}
162
		}
163
		return $tableau;
164
	}
165
 
166
 
167
	private function rechercherInfosEspeces($infos_projets) { //print_r($infos_projets);exit;
168
		$retour = ""; $referentiel = $infos_projets['referentiel'];
169
		$urlWsNsTpl = $this->config['chemins']['baseURLServicesEfloreTpl'];
170
		$urlWsNs = sprintf($urlWsNsTpl, self::EFLORE_API_VERSION, $referentiel, self::WS_NOM);
171
		$urlWsNsSansRef = sprintf($urlWsNsTpl, self::EFLORE_API_VERSION, '{referentiel}', self::WS_NOM);
172
		$retour['url_ws_autocompletion_ns'] = $urlWsNs;
173
		$retour['url_ws_autocompletion_ns_tpl'] = $urlWsNsSansRef;
174
		$retour['ns_referentiel'] = $referentiel;
175
 
176
		if (isset($infos_projets['type_especes'])) {
177
			switch ($infos_projets['type_especes']) {
178
				case "referentiel" : $referentiel = $infos_projets['referentiel']; break;
179
				case "liste" : $referentiel = $infos_projets['referentiel']; break;
180
				case "fixe" :
181
					$retour['especes'] = $this->chargerInfosTaxon($infos_projets['referentiel'], $infos_projets['especes']);
182
					break;
183
			}
184
		} else if (isset($infos_projets['referentiel'])) {
185
			$referentiel = $infos_projets['referentiel'];
186
			if (isset($infos_projets['num_nom'])) {
187
				$retour['especes'] = $this->chargerInfosTaxon($infos_projets['referentiel'], $infos_projets['num_nom']);
188
			}
189
		}
190
 
191
		$projetsAListeDeNoms = $this->transformerEnTableau($this->config['projets']['liste_noms']);
192
		if (in_array($this->projet, $projetsAListeDeNoms) && !$this->especeEstImposee()) {
193
			$projetsAListeDeNomsSciEtVerna = $this->transformerEnTableau($this->config['projets']['liste_noms_sci_et_verna']);
194
			if (in_array($this->projet, $projetsAListeDeNomsSciEtVerna)) {
195
				$retour['taxons'] = $this->recupererListeNoms();
196
			} else {
197
				$retour['taxons'] = $this->recupererListeNomsSci();
198
			}
199
		}
200
		return $retour;
201
	}
202
 
203
	/**
204
	 * Consulte un webservice pour obtenir des informations sur le taxon dont le
205
	 * numéro nomenclatural est $num_nom (ce sont donc plutôt des infos sur le nom
206
	 * et non le taxon?)
207
	 * @param string|int $num_nom
208
	 * @return array
209
	 */
210
	protected function chargerInfosTaxon($referentiel, $num_nom) {
211
		$url_service_infos = sprintf($this->config['chemins']['infosTaxonUrl'], $referentiel, $num_nom);
212
		$infos = json_decode(file_get_contents($url_service_infos));
213
		// trop de champs injectés dans les infos espèces peuvent
214
		// faire planter javascript
215
		$champs_a_garder = array('id', 'nom_sci','nom_sci_complet', 'nom_complet',
216
				'famille','nom_retenu.id', 'nom_retenu_complet', 'num_taxonomique');
217
		$resultat = array();
218
		$retour = array();
219
		if (isset($infos) && !empty($infos)) {
220
			$infos = (array)$infos;
221
			if (isset($infos['nom_sci']) && $infos['nom_sci'] != '') {
222
				$resultat = array_intersect_key($infos, array_flip($champs_a_garder));
223
				$resultat['retenu'] = ($infos['id'] == $infos['nom_retenu.id']) ? "true" : "false";
224
				$retour['espece_imposee'] = true;
225
				$retour['nn_espece_defaut'] = $nnEspeceImposee;
226
				$retour['nom_sci_espece_defaut'] = $resultat['nom_complet'];
227
				$retour['infos_espece'] = $this->array2js($resultat, true);
228
			}
229
		}
230
		return $retour;
231
	}
232
 
233
	protected function getReferentielImpose() {
234
		$referentiel_impose = true;
235
		if (!empty($_GET['referentiel']) && $_GET['referentiel'] != "autre") {
236
			$this->ns_referentiel = $_GET['referentiel'];
237
		} else if (isset($this->configProjet['referentiel'])) {
238
			$this->ns_referentiel = $this->configProjet['referentiel'];
239
		} else if (isset($this->configMission['referentiel'])) {
240
			$this->ns_referentiel = $this->configMission['referentiel'];
241
		} else {
242
			$referentiel_impose = false;
243
		}
244
		return $referentiel_impose;
245
	}
246
 
247
	/**
248
	 * Trie par nom français les taxons lus dans le fichier tsv
249
	 */
250
	protected function recupererListeNomsSci() {
251
		$taxons = $this->recupererListeTaxon();
252
		if (is_array($taxons)) {
253
			$taxons = self::trierTableauMd($taxons, array('nom_fr' => SORT_ASC));
254
		}
255
		return $taxons;
256
	}
257
 
258
	/**
259
	 * @TODO documenter
260
	 * @return array
261
	 */
262
	protected function recupererListeNoms() {
263
		$taxons = $this->recupererListeTaxon();
264
		$nomsAAfficher = array();
265
		$nomsSpeciaux = array();
266
		if (is_array($taxons)) {
267
			foreach ($taxons as $taxon) {
268
				$nomSciTitle = $taxon['nom_ret'].
269
				($taxon['nom_fr'] != '' ? ' - '.$taxon['nom_fr'] : '' ).
270
				($taxon['nom_fr_autre'] != '' ? ' - '.$taxon['nom_fr_autre'] : '' );
271
				$nomFrTitle = $taxon['nom_sel'].
272
				($taxon['nom_ret'] != $taxon['nom_sel']? ' - '.$taxon['nom_ret'] : '' ).
273
				($taxon['nom_fr_autre'] != '' ? ' - '.$taxon['nom_fr_autre'] : '' );
274
 
275
				if ($taxon['groupe'] == 'special') {
276
					$nomsSpeciaux[] = array(
277
							'num_nom' => $taxon['num_nom_sel'],
278
							'nom_a_afficher' => $taxon['nom_fr'],
279
							'nom_a_sauver' => $taxon['nom_sel'],
280
							'nom_title' => $nomSciTitle,
281
							'nom_type' => 'nom-special');
282
				} else {
283
					$nomsAAfficher[] = array(
284
							'num_nom' => $taxon['num_nom_sel'],
285
							'nom_a_afficher' => $taxon['nom_sel'],
286
							'nom_a_sauver' => $taxon['nom_sel'],
287
							'nom_title' => $nomSciTitle,
288
							'nom_type' => 'nom-sci');
289
					$nomsAAfficher[] = array(
290
							'num_nom' => $taxon['num_nom_sel'],
291
							'nom_a_afficher' => $taxon['nom_fr'],
292
							'nom_a_sauver' => $taxon['nom_fr'],
293
							'nom_title' => $nomFrTitle,
294
							'nom_type' => 'nom-fr');
295
				}
296
			}
297
			$nomsAAfficher = self::trierTableauMd($nomsAAfficher, array('nom_a_afficher' => SORT_ASC));
298
			$nomsSpeciaux = self::trierTableauMd($nomsSpeciaux, array('nom_a_afficher' => SORT_ASC));
299
		}
300
		return array('speciaux' => $nomsSpeciaux, 'sci-et-fr' => $nomsAAfficher);
301
	}
302
 
303
	/**
304
	 * Lit une liste de taxons depuis un fichier tsv fourni
305
	 */
306
	protected function recupererListeTaxon() {
307
		$taxons = array();
308
		if ($this->projet == 'missions-flore') {
309
			$fichier_tsv = dirname(__FILE__).self::DS.'configurations'.self::DS.$this->projet.'_'.$this->mission.'_taxons.tsv';
310
		} else {
311
			$fichier_tsv = dirname(__FILE__).self::DS.'configurations'.self::DS.$this->projet.'_taxons.tsv';
312
		}
313
		if (file_exists($fichier_tsv) && is_readable($fichier_tsv)) {
314
			$taxons = $this->decomposerFichierTsv($fichier_tsv);
315
		} else {
316
			$this->debug[] = "Impossible d'ouvrir le fichier '$fichier_tsv'.";
317
		}
318
		return $taxons;
319
	}
320
 
321
	/**
322
	 * Découpe un fihcier tsv
323
	 */
324
	protected function decomposerFichierTsv($fichier, $delimiter = "\t"){
325
		$header = null;
326
		$data = array();
327
		if (($handle = fopen($fichier, 'r')) !== FALSE) {
328
			while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
329
				if (!$header) {
330
					$header = $row;
331
				} else {
332
					$data[] = array_combine($header, $row);
333
				}
334
			}
335
			fclose($handle);
336
		}
337
		return $data;
338
	}
339
 
340
	/**
341
	 * Convertit un tableau PHP en Javascript - @WTF pourquoi ne pas faire un json_encode ?
342
	 * @param array $array
343
	 * @param boolean $show_keys
344
	 * @return une portion de JSON représentant le tableau
345
	 */
346
	protected function array2js($array,$show_keys) {
347
		$tableauJs = '{}';
348
		if (!empty($array)) {
349
			$total = count($array) - 1;
350
			$i = 0;
351
			$dimensions = array();
352
			foreach ($array as $key => $value) {
353
				if (is_array($value)) {
354
					$dimensions[$i] = array2js($value,$show_keys);
355
					if ($show_keys) {
356
						$dimensions[$i] = '"'.$key.'":'.$dimensions[$i];
357
					}
358
				} else {
359
					$dimensions[$i] = '"'.addslashes($value).'"';
360
					if ($show_keys) {
361
						$dimensions[$i] = '"'.$key.'":'.$dimensions[$i];
362
					}
363
				}
364
				if ($i == 0) {
365
					$dimensions[$i] = '{'.$dimensions[$i];
366
				}
367
				if ($i == $total) {
368
					$dimensions[$i].= '}';
369
				}
370
				$i++;
371
			}
372
			$tableauJs = implode(',', $dimensions);
373
		}
374
		return $tableauJs;
375
	}
376
 
377
 
378
}
379
?>