Subversion Repositories eFlore/Applications.cel

Rev

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

Rev Author Line No. Line
1654 aurelien 1
<?php
2461 jpm 2
// declare(encoding='UTF-8');
1656 raphael 3
/**
2461 jpm 4
 * Classe métier de mise en forme des groupes de colonnes pour les exports.
5
 *
6
 * @internal   Mininum PHP version : 5.2
7
 * @category   CEL
8
 * @package    Services
9
 * @subpackage Bibliothèques
10
 * @version    0.1
11
 * @author     Mathias CHOUET <mathias@tela-botanica.org>
12
 * @author     Raphaël Droz <raphael@tela-botania.org>
13
 * @author     Jean-Pascal MILCENT <jpm@tela-botanica.org>
14
 * @author     Aurelien PERONNET <aurelien@tela-botanica.org>
15
 * @license    GPL v3 <http://www.gnu.org/licenses/gpl.txt>
16
 * @license    CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
17
 * @copyright  1999-2014 Tela Botanica <accueil@tela-botanica.org>
18
 */
19
define('SEPARATEUR_IMAGES', ' / ');
20
define('PREFIX_CHAMPS_ETENDUS', 'ext:');
1835 raphael 21
// utilisé par formaterUrlUser() [ nécessaire pour le widget d'export)
22
define('USER_BASEURL', 'http://www.tela-botanica.org/profil:%d');
1656 raphael 23
 
2461 jpm 24
class FormateurGroupeColonne {
1656 raphael 25
 
1702 raphael 26
	// cache pour les données des fonctions
1656 raphael 27
	static $cache = Array();
28
 
1702 raphael 29
	// test sur la table cel_references, mis à TRUE si la table existe
30
	static $is_table = false;
31
 
1714 raphael 32
	// les groupes de champs utilisables
33
	static $fieldGroups = array(
34
		'standard',
3498 delphine 35
	    'standardexport',
36
	    'auteur',
1714 raphael 37
		'avance',
38
		'etendu',
3498 delphine 39
		'baseflor'
1714 raphael 40
	);
41
 
1702 raphael 42
	// les données baseflor à récupérer: colonnes présentes dans cel_references
43
	// et intitulés associés
44
	static $baseflor_col = array(
2461 jpm 45
		've_lumiere' => 'Lumière',
46
		've_temperature' => 'Température',
47
		've_continentalite' => 'Continentalité',
48
		've_humidite_atmos' => 'Humidité Atmosphérique',
49
		've_humidite_edaph' => 'Humidité',
50
		've_reaction_sol' => 'Réaction (pH)',
51
		've_nutriments_sol' => 'Nutriments',
52
		've_salinite' => 'Salinité',
53
		've_texture_sol' => 'Texture' ,
54
		've_mat_org_sol' => 'Matière Organique',
55
		'catminat_code' => 'Code Catminat',
56
		'syntaxon' => 'Syntaxon',
1702 raphael 57
	);
58
 
1741 raphael 59
	// TODO: dirty, ordre des champs étendus... souhaité pour florilèges:
60
	static $ordre_champ_etendus_Florileges = array(
2461 jpm 61
		'personneStructure',
62
		'personneService',
63
		'personneFonction',
64
		'adresse',
65
		'latitudeDebutRue',
66
		'longitudeDebutRue',
67
		'latitudeFinRue',
68
		'longitudeFinRue',
69
		'typoUrbaine',
70
		'revetementSol',
71
		'presenceZoneVegetalise',
72
		'hauteurBatimentAvoisinant',
73
		'intensiteGestion',
74
		'periodiciteTraitementPhyto',
75
		'dateArretTraitementPhyto',
76
		'itineraireGestion',
77
		'dateDerniereIntervention',
78
		'hauteurPlante',
79
		'resistanceTraitementPhyto',
80
		'vitesseCroissance',
81
		'perceptionTechnicien',
82
		'perceptionRiverainMauvaise',
1741 raphael 83
	);
84
 
3134 delphine 85
	static function colGroupsValidation($groupe_de_champs = 'standard,avance', $programme = "") {
2461 jpm 86
		if (! $groupe_de_champs) return FALSE;
87
		if (is_string($groupe_de_champs)) {
1714 raphael 88
			$groupe_de_champs = array_flip(explode(',', $groupe_de_champs));
2461 jpm 89
		} elseif(is_array($groupe_de_champs)) {
1714 raphael 90
			$groupe_de_champs = array_flip($groupe_de_champs);
2461 jpm 91
		} else {
92
			return null;
1714 raphael 93
		}
2461 jpm 94
		$groupe_de_champs = array_intersect_key(array_flip(self::$fieldGroups), $groupe_de_champs);
95
		if (!$groupe_de_champs) {
96
			return false;
1714 raphael 97
		}
3134 delphine 98
		if ($programme != "") {
99
			$groupe_de_champs['avance'] = true;
100
			$groupe_de_champs['etendu'] = true;
101
		}
1714 raphael 102
		// toujours ajouter standard
2461 jpm 103
		$groupe_de_champs['standard'] = true;
1714 raphael 104
		return implode(',', array_keys($groupe_de_champs));
105
	}
106
 
1654 aurelien 107
	/*
108
	* @param $fieldSets: un liste de noms de colonnes ou de sets de colonnes
109
	*		séparés par des virgules
110
	* 		eg: "espece" ou "champs-etendus", ...
111
	*
112
	* @return: un tableau associatif déjà ordonné
113
	* 		clé: abbrev [machine-name] de la colonne (eg: "espece" ou "mot-clef")
114
	* 		valeur: des données relative à cette colonne, cf GenColInfo
115
	*
1757 raphael 116
	* Si la colonne n'utilise pas de fonction de récupération particulière
117
	* (ie: si le champ exportés [ou importé] correspond exactement au champ dans la base de donnée)
118
	* Alors 'abbrev' doit avoir la même valeur que le nom de la colonne dans la table mysql `cel_obs`.
1654 aurelien 119
	*/
120
	static function nomEnsembleVersListeColonnes($groupe_de_champs = 'standard') {
2461 jpm 121
		if (! $groupe_de_champs) {
122
			$groupe_de_champs = 'standard';
123
		}
124
		if (is_string($groupe_de_champs)) {
1711 raphael 125
			$groupe_de_champs = array_flip(explode(',', $groupe_de_champs));
2461 jpm 126
		} elseif(is_array($groupe_de_champs)) {
1711 raphael 127
			$groupe_de_champs = array_flip($groupe_de_champs);
2461 jpm 128
		} else {
129
			return null;
1711 raphael 130
		}
2461 jpm 131
		$groupe_de_champs = array_intersect_key(array_flip(self::$fieldGroups), $groupe_de_champs);
132
		if (!$groupe_de_champs) {
133
			return null;
1711 raphael 134
		}
135
 
2461 jpm 136
		$colonnes = array();
3134 delphine 137
		if (isset($groupe_de_champs['standardexport'])) {
1654 aurelien 138
			$colonnes += Array(
3134 delphine 139
				'guid'			=> self::GenColInfo(Array('abbrev' => 'guid',
140
																'nom' => 'Identifiant unique')),
3467 delphine 141
			    'id_observation'	=> self::GenColInfo(Array('abbrev' => 'id_observation',
142
                                            			        'nom' => 'Identifiant',
143
                                            			        'extra' => 1,
144
                                            			        'importable' => FALSE)),
1757 raphael 145
				'nom_sel'			=> self::GenColInfo(Array('abbrev' => 'nom_sel',
146
															  'nom' => 'Espèce')),
147
				'nom_sel_nn'		=> self::GenColInfo(Array('abbrev' => 'nom_sel_nn',
148
															  'nom' => 'Numéro nomenclatural',
149
															  'importable' => FALSE)),
150
				'nom_ret'			=> self::GenColInfo(Array('abbrev' => 'nom_ret',
151
															  'nom' => 'Nom retenu',
152
															  'importable' => FALSE)),
153
				'nom_ret_nn'		=> self::GenColInfo(Array('abbrev' => 'nom_ret_nn',
154
															  'nom' => 'Numéro nomenclatural nom retenu',
155
															  'importable' => FALSE)),
156
				'famille'			=> self::GenColInfo(Array('abbrev' => 'famille',
157
															  'nom' => 'Famille',
158
															  'importable' => FALSE)),
159
				'nom_referentiel'	=> self::GenColInfo(Array('abbrev' => 'nom_referentiel',
3480 delphine 160
															  'nom' => 'Référentiel taxonomique')),
3467 delphine 161
			    'certitude'			=> self::GenColInfo(Array('abbrev' => 'certitude',
162
			                                                 'nom' => 'Certitude')),
163
			    'type_donnees'		=> self::GenColInfo(Array('abbrev' => 'type_donnees',
164
			                                                 'nom' => 'Type d\'observation')),
165
			    'source'			=> self::GenColInfo(Array('abbrev' => 'source',
166
			                                                 'nom' => 'Source de la saisie')),
167
			    'spontaneite'			=> self::GenColInfo(Array('abbrev' => 'spontaneite',
168
			                                                 'nom' => 'Spontanéité')),
169
			    'latitude'			=> self::GenColInfo(Array('abbrev' => 'latitude',
170
			        'nom' => 'Latitude',
171
			        'extra' => 1)),
172
			    'longitude'			=> self::GenColInfo(Array('abbrev' => 'longitude',
173
			        'nom' => 'Longitude',
174
			        'extra' => 1)),
175
 
176
			    'geodatum'			=> self::GenColInfo(Array('abbrev' => 'geodatum',
177
			        'nom' => 'Référentiel Géographique',
178
			        'extra' => 1,
179
			        'importable' => FALSE)),
180
 
181
			    'pays'				=> self::GenColInfo(Array('abbrev' => 'pays',
2538 aurelien 182
															  'nom' => 'Pays')),
1757 raphael 183
				'zone_geo'			=> self::GenColInfo(Array('abbrev' => 'zone_geo',
184
															  'nom' => 'Commune')),
185
				'ce_zone_geo'		=> self::GenColInfo(Array('abbrev' => 'ce_zone_geo',
3467 delphine 186
															  'nom' => 'Identifiant Commune')),
187
			    'localisation_floutage'	=> self::GenColInfo(Array('abbrev' => 'localisation_floutage',
188
			                                                 'nom' => 'Floutage (niveau de localisation diffusé)')),
189
			    'altitude'			=> self::GenColInfo(Array('abbrev' => 'altitude',
190
                                        			        'nom' => 'Altitude',
191
                                        			        'extra' => 1)), // pas de trim0 car INT(5) en DB
192
			    'lieudit'			=> self::GenColInfo(Array('abbrev' => 'lieudit',
1757 raphael 193
															  'nom' => 'Lieu-dit')),
194
				'milieu'			=> self::GenColInfo(Array('abbrev' => 'milieu',
195
															  'nom' => 'Milieu')),
3467 delphine 196
			    'date_observation'	=> self::GenColInfo(Array('abbrev' => 'date_observation',
197
			                                                 'nom' => 'Date',
198
			                                                 'fonction' => 'formaterDate')),
199
			    'commentaire'		=> self::GenColInfo(Array('abbrev' => 'commentaire',
1757 raphael 200
															  'nom' => 'Notes')),
3134 delphine 201
				'programme'			=> self::GenColInfo(Array('abbrev' => 'programme',
3142 delphine 202
																'nom' => 'Programme de sciences participatives ou observatoire citoyen',
203
																'importable' => FALSE)),
204
				'mots_cles_texte'	=> self::GenColInfo(Array('abbrev' => 'mots_cles_texte',
205
																'nom' => 'Mots Clés',
206
																'importable' => FALSE)),
207
				'url_identiplante'			=> self::GenColInfo(Array('abbrev' => 'url_identiplante',
208
															'nom' => "Lien vers l'observation sur IdentiPlante",
209
															'importable' => FALSE)),
3482 delphine 210
			    'images'			=> self::GenColInfo(Array('abbrev' => 'images',
3467 delphine 211
			        'nom' => 'Image(s)',
212
			        'extra' => 1)),
213
 
214
			    );
3134 delphine 215
		} elseif (isset($groupe_de_champs['standard'])) {
216
			$colonnes += Array(
3467 delphine 217
			    'guid'			=> self::GenColInfo(Array('abbrev' => 'guid',
218
			        'nom' => 'Identifiant unique')),
219
			    'id_observation'	=> self::GenColInfo(Array('abbrev' => 'id_observation',
220
			        'nom' => 'Identifiant',
221
			        'extra' => 1,
222
			        'importable' => FALSE)),
223
			    'nom_sel'			=> self::GenColInfo(Array('abbrev' => 'nom_sel',
224
			        'nom' => 'Espèce')),
225
			    'nom_sel_nn'		=> self::GenColInfo(Array('abbrev' => 'nom_sel_nn',
226
			        'nom' => 'Numéro nomenclatural',
227
			        'importable' => FALSE)),
228
			    'nom_ret'			=> self::GenColInfo(Array('abbrev' => 'nom_ret',
229
			        'nom' => 'Nom retenu',
230
			        'importable' => FALSE)),
231
			    'nom_ret_nn'		=> self::GenColInfo(Array('abbrev' => 'nom_ret_nn',
232
			        'nom' => 'Numéro nomenclatural nom retenu',
233
			        'importable' => FALSE)),
234
			    'famille'			=> self::GenColInfo(Array('abbrev' => 'famille',
235
			        'nom' => 'Famille',
236
			        'importable' => FALSE)),
237
			    'nom_referentiel'	=> self::GenColInfo(Array('abbrev' => 'nom_referentiel',
3481 delphine 238
			        'nom' => 'Référentiel taxonomique')),
3467 delphine 239
			    'certitude'			=> self::GenColInfo(Array('abbrev' => 'certitude',
240
			        'nom' => 'Certitude')),
241
			    'type_donnees'		=> self::GenColInfo(Array('abbrev' => 'type_donnees',
242
			        'nom' => 'Type d\'observation')),
243
			    'source'			=> self::GenColInfo(Array('abbrev' => 'source',
244
			        'nom' => 'Source de la saisie')),
245
			    'spontaneite'			=> self::GenColInfo(Array('abbrev' => 'spontaneite',
246
			        'nom' => 'Spontanéité')),
247
			    'latitude'			=> self::GenColInfo(Array('abbrev' => 'latitude',
248
			        'nom' => 'Latitude',
249
			        'extra' => 1)),
250
			    'longitude'			=> self::GenColInfo(Array('abbrev' => 'longitude',
251
			        'nom' => 'Longitude',
252
			        'extra' => 1)),
253
 
254
			    'geodatum'			=> self::GenColInfo(Array('abbrev' => 'geodatum',
255
			        'nom' => 'Référentiel Géographique',
256
			        'extra' => 1,
257
			        'importable' => FALSE)),
258
 
259
			    'pays'				=> self::GenColInfo(Array('abbrev' => 'pays',
260
			        'nom' => 'Pays')),
261
			    'zone_geo'			=> self::GenColInfo(Array('abbrev' => 'zone_geo',
262
			        'nom' => 'Commune')),
263
			    'ce_zone_geo'		=> self::GenColInfo(Array('abbrev' => 'ce_zone_geo',
264
			        'nom' => 'Identifiant Commune')),
265
			    'localisation_floutage'	=> self::GenColInfo(Array('abbrev' => 'localisation_floutage',
266
			        'nom' => 'Floutage (niveau de localisation diffusé)')),
267
			    'altitude'			=> self::GenColInfo(Array('abbrev' => 'altitude',
268
			        'nom' => 'Altitude',
269
			        'extra' => 1)), // pas de trim0 car INT(5) en DB
270
			    'lieudit'			=> self::GenColInfo(Array('abbrev' => 'lieudit',
271
			        'nom' => 'Lieu-dit')),
272
			    'milieu'			=> self::GenColInfo(Array('abbrev' => 'milieu',
273
			        'nom' => 'Milieu')),
274
			    'date_observation'	=> self::GenColInfo(Array('abbrev' => 'date_observation',
275
			        'nom' => 'Date',
276
			        'fonction' => 'formaterDate')),
277
			    'commentaire'		=> self::GenColInfo(Array('abbrev' => 'commentaire',
278
			        'nom' => 'Notes')),
279
			    'programme'			=> self::GenColInfo(Array('abbrev' => 'programme',
280
			        'nom' => 'Programme de sciences participatives ou observatoire citoyen',
281
			        'importable' => FALSE)),
282
			    'mots_cles_texte'	=> self::GenColInfo(Array('abbrev' => 'mots_cles_texte',
283
			        'nom' => 'Mots Clés',
284
			        'importable' => FALSE)),
285
 
3482 delphine 286
			    'images'			=> self::GenColInfo(Array('abbrev' => 'images',
3467 delphine 287
			        'nom' => 'Image(s)',
288
			        'extra' => 1)),
289
			    'url_identiplante'			=> self::GenColInfo(Array('abbrev' => 'url_identiplante',
290
			        'nom' => "Lien vers l'observation sur IdentiPlante",
291
			        'importable' => FALSE)),
292
 
3134 delphine 293
					);
1654 aurelien 294
		}
2143 jpm 295
 
3498 delphine 296
		if (isset($groupe_de_champs['auteur'])) {
297
		    $colonnes += array(
298
		        'auteur' => self::GenColInfo(array(
299
		            'abbrev' => 'pseudo_utilisateur',
300
		            'nom' => 'Auteur',
301
		            'extra' => 1,
302
		            'fonction_data' => 'formaterUrlUser',
303
		            'importable' => false)),
304
		    );
305
		}
306
 
1654 aurelien 307
		if(isset($groupe_de_champs['avance'])) {
1656 raphael 308
			$colonnes += array(
3467 delphine 309
			    'localisation_coherence' => self::GenColInfo(Array('abbrev' => 'localisation_coherence',
310
			        'nom' => 'Cohérence entre la localité et les coordonnées GPS')),
311
			    'localisation_precision' => self::GenColInfo(Array('abbrev' => 'localisation_precision',
312
			        'nom' => 'Précision de la localisation')),
313
			    'station'			=> self::GenColInfo(Array('abbrev' => 'station',
314
			        'nom' => 'Station')),
315
			    'validation_identiplante'			=> self::GenColInfo(Array('abbrev' => 'validation_identiplante',
316
			        'nom' => 'Détermination validée sur IdentiPlante',
317
			        'importable' => FALSE)),
318
			    'score_identiplante'			=> self::GenColInfo(Array('abbrev' => 'score_identiplante',
3497 delphine 319
			        'nom' => 'Score IdentiPlante',
3467 delphine 320
			        'importable' => FALSE)),
321
			    'abondance'			=> self::GenColInfo(Array('abbrev' => 'abondance',
322
			        'nom' => 'Abondance',
323
			        'extra' => 1)),
324
			    'phenologie'		=> self::GenColInfo(Array('abbrev' => 'phenologie',
325
			        'nom' => 'Phénologie',
326
			        'extra' => 1)),
327
			    'herbier'			=> self::GenColInfo(Array('abbrev' => 'herbier',
328
			        'nom' => 'Présence d\'un échantillon d\'herbier',
329
			        'extra' => 1)),
330
 
1757 raphael 331
				// TODO: importable = FALSE car pas de merge de données importées
332
				'date_creation'		=> self::GenColInfo(Array('abbrev' => 'date_creation',
333
															  'nom' => 'Date Création',
334
															  'extra' => 1,
335
															  'importable' => FALSE)),
336
				'date_modification'	=> self::GenColInfo(Array('abbrev' => 'date_modification',
337
															  'nom' => 'Date Modification',
338
															  'extra' => 1,
339
															  'importable' => FALSE)),
1656 raphael 340
 
1757 raphael 341
				// rappel transmission = 1, signifie simplement "public"
342
				// des données importées peuvent être d'emblée "publiques"
343
				// "importable" = TRUE
344
				'transmission'		=> self::GenColInfo(Array('abbrev' => 'transmission',
345
															  'nom' => 'Transmis',
346
															  'extra' => 1,
347
															  'fonction' => 'boolOuiNon')),
348
				'date_transmission'	=> self::GenColInfo(Array('abbrev' => 'date_transmission',
349
															  'nom' => 'Date Transmission',
350
															  'extra' => 1,
351
															  'importable' => FALSE)),
3497 delphine 352
			    'observateur'		=> self::GenColInfo(Array('abbrev' => 'observateur',
353
                                            			        'nom' => 'Observateur',
354
                                            			        'extra' => 1)),
355
			    'observateur_structure'	=> self::GenColInfo(Array('abbrev' => 'observateur_structure',
356
                                            			        'nom' => 'Structure de l\'observateur',
357
                                            			        'extra' => 1)),
358
			    'determinateur'		=> self::GenColInfo(Array('abbrev' => 'determinateur',
359
                                            			        'nom' => 'Déterminateur',
360
                                            			        'extra' => 1)),
361
			    'biblio'	=> self::GenColInfo(Array('abbrev' => 'biblio',
362
                                            			        'nom' => 'Source bibliographique',
363
                                            			        'extra' => 1)),
2143 jpm 364
 
1656 raphael 365
 
1757 raphael 366
				/* 'nom_commun'			=> self::GenColInfo(Array('abbrev' => 'nom_commun',
367
				   'nom' => 'Nom Commun',
368
				   'extra' => 1,
369
				   'fonction_data' => 'getNomCommun',
370
				   'importable' => FALSE),
1685 raphael 371
 
1757 raphael 372
				   'nom-commun'			=> self::GenColInfo(Array('abbrev' => 'nom-commun',
373
				   'nom' => 'Nom Commun',
374
				   'extra' => 1,
375
				   'fonction_data' => 'getNomCommun_v2'),
376
 
377
				   'nom-commun'			=> self::GenColInfo(Array('abbrev' => 'nom-commun',
378
				   'nom' => 'Nom Commun',
379
				   'extra' => 1,
380
				   'fonction_data' => 'getNomCommun_v3'),
3467 delphine 381
				   'importable' => FALSE), */ /* cas particu 'getNomCommun_v4' */
382
				/*'nom-commun' => self::GenColInfo(array(
2461 jpm 383
					'abbrev' => 'nom-commun',
384
					'nom' => 'Nom Commun',
385
					'extra' => 1,
3467 delphine 386
					'fonction_data' => null ,
387
					'preload' => array(__CLASS__, 'getNomCommun_preload')))*/
1702 raphael 388
			);
389
		}
1685 raphael 390
 
3498 delphine 391
		if (isset($groupe_de_champs['etendu'])) {
392
		    $colonnes += array(
393
		        // champ dynamique
394
		        'etendu' => self::GenColInfo(array(
395
		            'abbrev' => 'etendu',
396
		            'nom' => '',
397
		            'extra' => 1,
398
		            'importable' => false,
399
		            'preload' => array(__CLASS__, 'champsEtendus_preload'),
400
		            'dyna' => array(__CLASS__, 'champsEtendus_ligne'))),
401
		    );
402
		}
403
 
1702 raphael 404
		if(isset($groupe_de_champs['baseflor'])) {
405
			$colonnes += array(
406
				// champ dynamique
2461 jpm 407
				'baseflor' => self::GenColInfo(array(
408
					'abbrev' => 'baseflor',
409
					'nom' => '',
410
					'extra' => 1,
411
					'importable' => false,
412
					'preload' => array(__CLASS__, 'baseflor_preload'),
413
					'dyna' => array(__CLASS__, 'baseflor_ligne'))),
1654 aurelien 414
			);
1702 raphael 415
		}
1656 raphael 416
 
3498 delphine 417
 
1835 raphael 418
 
3498 delphine 419
 
1654 aurelien 420
		return $colonnes;
421
	}
1694 raphael 422
 
423
	static function preload($colonnes, $cel, $ids) {
424
		$result = array();
2461 jpm 425
		foreach ($colonnes as $abbrev => $colonne) {
426
			if (!$colonne['preload']) {
427
				continue;
428
			}
1702 raphael 429
			$result[$abbrev] = call_user_func($colonne['preload'], $cel, $ids);
1694 raphael 430
		}
431
		return $result;
432
	}
2143 jpm 433
 
1656 raphael 434
	public static function getIntitulesColonnes($colonnes) {
1702 raphael 435
		// array_filter pour supprimer les colonnes "dynamique" n'ayant pas défini $nom (cf GenColInfo())
436
		return array_filter(array_map(array('FormateurGroupeColonne', 'retournerNomItem'), $colonnes));
1654 aurelien 437
	}
2143 jpm 438
 
1671 aurelien 439
	public static function retournerNomItem(&$item) {
440
		return $item['nom'];
441
	}
1694 raphael 442
 
1656 raphael 443
	public static function getLigneObservation(&$obs, &$colonnes, $cel = false) {
1654 aurelien 444
		$ligne_formatee = array();
445
		foreach($colonnes as $abbrev => $colonne) {
446
			$valeur = null;
2461 jpm 447
			if ($colonne['extra'] == 2 || ! is_null($colonne['dyna'])) {
448
				continue;
449
			}
2143 jpm 450
 
1835 raphael 451
			// valeur directe depuis cel_obs ?
2461 jpm 452
			if (isset($obs[$abbrev])) {
453
				$valeur = $obs[$abbrev];
454
			}
2143 jpm 455
 
1835 raphael 456
			// pré-processeur des champs
2461 jpm 457
			if (function_exists($colonne['fonction'])) {
1654 aurelien 458
				$valeur = $colonne['fonction']($valeur);
2461 jpm 459
			} else if(method_exists(__CLASS__, $colonne['fonction'])) {
1654 aurelien 460
				$valeur = call_user_func(array(__CLASS__, $colonne['fonction']), $valeur);
2461 jpm 461
			} else if($colonne['fonction']) {
1654 aurelien 462
				die("méthode {$colonne['fonction']} introuvable");
2461 jpm 463
			} else if(function_exists($colonne['fonction_data'])) {// fonction pour obtenir des champs (étendus)
1654 aurelien 464
				$valeur = $colonne['fonction_data']($obs);
2461 jpm 465
			} else if(method_exists(__CLASS__, $colonne['fonction_data'])) {
1654 aurelien 466
				$valeur = call_user_func(array(__CLASS__, $colonne['fonction_data']), $obs);
467
			}
2143 jpm 468
 
3467 delphine 469
 
1765 raphael 470
			// ici à cause du passage de $cel ($this->utilisateur)
3467 delphine 471
 
2461 jpm 472
			if ($abbrev == 'nom-commun') {
1765 raphael 473
				$valeur = FormateurGroupeColonne::getNomCommun_v4($obs);
1685 raphael 474
			}
2143 jpm 475
 
2461 jpm 476
			if ($valeur == null) {
477
				$valeur = '';
1654 aurelien 478
			}
2143 jpm 479
 
2461 jpm 480
			// fin de section "cas particuliers"
1654 aurelien 481
			$ligne_formatee[] = $valeur;
482
		}
1694 raphael 483
 
1835 raphael 484
		// uniquement les champs dynamiques
1702 raphael 485
		foreach($colonnes as $abbrev => $colonne) {
486
			$valeur = null;
2461 jpm 487
			if (is_null($colonne['dyna'])) {
488
				continue;
489
			}
490
			call_user_func_array($colonne['dyna'], array($obs, &$ligne_formatee));
1702 raphael 491
		}
1654 aurelien 492
		return $ligne_formatee;
493
	}
2143 jpm 494
 
1654 aurelien 495
	/*
496
	* Wrapper générant un tableau associatif:
1694 raphael 497
	* Ne pas changer les valeurs par défaut du prototype sans réflexion sur l'implication pour nomEnsembleVersListeColonnes()
2143 jpm 498
 
1654 aurelien 499
	* @param $abbrev (obligatoire): nom court de colonne, largement utilisé lors de l'import.
500
	*		  En effet chaque ligne importée est accessible à l'aide du `define` de $abbrev en majuscule, préfixé de "C_"
501
	*		  Exemple: $ligne[C_LONGITUDE] pour "longitude".
502
	*		  cf: ImportXLS::detectionEntete()
2143 jpm 503
 
1654 aurelien 504
	* @param $nom (obligatoire): nom complet de colonne (utilisé pour la ligne d'en-tête)
1702 raphael 505
	*		  Les définition de champs dynamique (correspondant à de multiples colonnes) doivent laisser cette valeur
506
	*		  vide afin de ne pas créer une colonne supplémentaire erronée.
2143 jpm 507
 
1654 aurelien 508
	* @param $is_extra:
509
	* Si 0, la colonne est une colonne standard
510
	* Si 1, la colonne est extra [le plus souvent générée automatiquement]
511
	*		 (auquel cas une bordure bleue entoure son nom dans la ligne d'entête)
512
	* Si 2, la colonne n'est pas traité à l'export, mais une définition peut lui être donnée
513
	*		 qui pourra être utilisée à l'import, exemple: "image"
2143 jpm 514
 
1654 aurelien 515
	* @param $fonction (optionnel): un nom d'un fonction de préprocessing
516
	* 		  $fonction doit prendre comme seul argument la valeur d'origine et retourner la valeur transformée
2143 jpm 517
 
1654 aurelien 518
	* @param $fonction_data (optionnel): une *méthode* d'obtention de donnée
519
	* 		  $fonction_data doit prendre comme premier argument le tableau des champs de l'enregistrement existant
520
	*		  $fonction_data doit retourner une valeur
2143 jpm 521
 
1654 aurelien 522
	* @param $importable (optionnel): défini si la colonne est traitée (ou absolument ignorée par PHPExcel) lors de
523
	*		  l'import.
1694 raphael 524
 
525
	* @param $preload (optionnel): défini une fonction de préchargement massif de donnée potentiellement utilisable par $fonction_data.
526
	*		  Utile, notamment, dans le cadre de l'export
1702 raphael 527
 
528
	* @param $fonction_dynamique (optionnel): défini une fonction ajoutant un nombre arbitraire de colonnes à une ligne donnée
529
	*		  Utile, notamment, dans le cadre de l'export des champs étendus ou des données baseflor
530
	*		  La fonction doit TOUJOURS alterer la ligne en lui ajoutant une nombre CONSTANT d'éléments (NULL ou non)
1765 raphael 531
	*		  La fonction doit prendre comme arguments ($obs, &$ligne_formatee)
1654 aurelien 532
	*/
1757 raphael 533
	static function GenColInfo($args) {
2461 jpm 534
		$default = array(
535
			'abbrev' => null,
536
			'nom' => null,
537
			'extra' => 0,
538
			'fonction' => null,
539
			'fonction_data' => null,
540
			'importable' => true,
541
			'preload' => null,
542
			'dyna' => null);
1757 raphael 543
		$ret = array_intersect_key($args, $default);
544
		return array_merge($default, $ret);
1654 aurelien 545
	}
2143 jpm 546
 
1656 raphael 547
	static function formaterDate($date_heure_mysql) {
1671 aurelien 548
		//return "";
2461 jpm 549
		if (!$date_heure_mysql || $date_heure_mysql == "0000-00-00 00:00:00") {
550
			return null;
551
		}
1671 aurelien 552
		// malheureusement pas disponible en php < 5.3
553
		//$date_format = DateTime::createFromFormat("Y-m-d H:i:s", $date_heure_mysql);
554
		$val = explode(' ', $date_heure_mysql);
555
		$date = explode('-', $val[0]);
556
		$heure = explode(':', $val[1]);
557
		$timestamp = mktime((int) $heure[0], (int) $heure[1], (int) $heure[2], (int) $date[1], (int) $date[2], (int) $date[0]);
2461 jpm 558
		if (!$timestamp) {
559
			return null;
560
		}
1656 raphael 561
		// TODO: les widgets ne font malheureusement pas usage de l'heure dans le CEL
562
		// TODO: si modification, ne pas oublier de modifier le format d'import correspondant
1698 raphael 563
		//	dans ImportXLS, traiterDateObs() (actuellement: "Y/m/d" car utilisation de strtotime() qui ne lit pas tout)
564
		// $date_formatee = strftime('%d/%m/%Y', $timestamp);
565
		$date_formatee = strftime('%Y/%m/%d', $timestamp);
2461 jpm 566
		if (!$date_formatee) {
567
			return '00/00/0000';
568
		}
1654 aurelien 569
		return $date_formatee;
570
	}
1757 raphael 571
 
1835 raphael 572
 
1759 raphael 573
 
574
 
2143 jpm 575
 
2730 mathias 576
	/**
577
	 * Enlève les zéros excédentaires (devenus nomades) au début et à la fin d'une
578
	 * latitude ou longitude, en prenant garde à ne pas foirer les nombres 0.xyz
579
	 */
1757 raphael 580
	public static function trim0($lonlat) {
2730 mathias 581
		$retour = trim($lonlat, "0");
582
		// si on a trop enlevé de zéros à gauche, on en remet un (mode synthobois)
583
		if (substr($retour, 0, 1) == ".") {
584
			$retour = "0" . $retour;
585
		}
586
		return $retour;
1757 raphael 587
	}
588
 
589
	public static function boolOuiNon($transmission) {
590
		return $transmission ? 'oui' : '';
591
	}
2143 jpm 592
 
3497 delphine 593
	static function formaterUrlUser($obs) {
594
	    $is_id = is_numeric($obs['ce_utilisateur']);
595
	    return sprintf("%s %s",
596
	        $obs['pseudo_utilisateur'],
597
	        $is_id ? sprintf(' (' . USER_BASEURL . ')', $obs['ce_utilisateur']) : '');
598
	}
2143 jpm 599
 
1654 aurelien 600
	// TODO: référentiel ne devrait pas être généré au moment d'un Config::get,
601
	// comme dans Config::get('nomsVernaRechercheLimiteeTpl')
602
	// Par exemple, la variable pour "nva" ?
603
	function getNomCommun($obs) {
604
		$langue = 'fra';
605
		list($referentiel) = explode(':', strtolower($obs['nom_referentiel']));
606
		if($referentiel == 'bdtfx') $referentiel = 'nvjfl';
607
		else return '';
2143 jpm 608
 
1654 aurelien 609
		$cache_id = $referentiel . '-' . $obs['nt'] . '-' . $langue;
1657 raphael 610
		if(isset(self::$cache['getNomCommun'][$cache_id])) {
1656 raphael 611
			//debug: error_log("require url_service_nom_attribution: OK ! (pour \"{$obs['nom_ret']}\")");
1657 raphael 612
			return self::$cache['getNomCommun'][$cache_id];
1654 aurelien 613
		}
614
		// pas de cache:
615
		//debug: error_log("require url_service_nom_attribution pour \"{$obs['nom_ret']}\"");
2143 jpm 616
 
1654 aurelien 617
		// pour bdtfx:
618
		// /service:eflore:0.1/nvjfl/noms-vernaculaires/attributions?masque.nt=X&masque.lg=fra&retour.champs=num_statut
619
		// /projet/services/modules/0.1/nvjfl/NomsVernaculaires.php
620
		$url = str_replace(Array('{referentiel}', '{valeur}', '{langue}'),
1656 raphael 621
						   Array($referentiel, $obs['nt'], $langue),
1657 raphael 622
						   self::$config['eflore']['url_service_nom_attribution']) . // TODO !
1656 raphael 623
			"&retour.champs=num_statut";
1654 aurelien 624
		$noms = @json_decode(file_get_contents($url));
625
		if(! $noms) return '';
1673 raphael 626
		$noms = array_filter((array)($noms->resultat), array($this, retournerNumStatutUn)); // XXX: php 5.3
1654 aurelien 627
		$nom = array_pop($noms)->nom_vernaculaire;
2143 jpm 628
 
1654 aurelien 629
		// cache
1657 raphael 630
		self::$cache['getNomCommun'][$cache_id] = $nom;
1654 aurelien 631
		return $nom;
632
	}
2143 jpm 633
 
1671 aurelien 634
	private function retournerNumStatutUn(&$item) {
635
		return ($item->num_statut == 1);
636
	}
1673 raphael 637
 
638
	private function retournerNumStatutUnArr(&$item) {
639
		return ($item['num_statut'] == 1);
640
	}
2143 jpm 641
 
1656 raphael 642
	// si getNomCommun_v2 ou getNomCommun_v3 sont utilisés
643
	/* require_once('/home/raphael/eflore/framework/framework/Framework.php');
644
	Framework::setCheminAppli("/home/raphael/eflore/projets/services/index.php");
645
	Framework::setInfoAppli(Config::get('info'));
646
	require_once('/home/raphael/eflore/projets/services/modules/0.1/Projets.php');*/
2143 jpm 647
 
1654 aurelien 648
	/* Tente de bootstraper le framework au plus court et d'initialiser une instance de
1656 raphael 649
	   NomsVernaculaires pour obtenir le nom commun */
1654 aurelien 650
	function getNomCommun_v2($obs) {
651
		static $service;
1656 raphael 652
		$service = new Projets();
2143 jpm 653
 
1654 aurelien 654
		$langue = 'fra';
655
		list($referentiel) = explode(':', strtolower($obs['nom_referentiel']));
656
		if($referentiel == 'bdtfx') $referentiel = 'nvjfl';
657
		else return '';
2143 jpm 658
 
1654 aurelien 659
		$cache_id = $referentiel . '-' . $obs['nt'] . '-' . $langue;
1657 raphael 660
		if(isset(self::$cache['getNomCommun'][$cache_id])) {
1656 raphael 661
			error_log("require NomsVernaculaires.php: OK ! (pour \"{$obs['nom_ret']}\")");
1657 raphael 662
			return self::$cache['getNomCommun'][$cache_id];
1654 aurelien 663
		}
664
		// pas de cache:
665
		error_log("require NomsVernaculaires.php pour \"{$obs['nom_ret']}\"");
2143 jpm 666
 
1656 raphael 667
		$donnees = Array('masque.nt' => $obs['nt'],
668
						 'masque.lg' => $langue,
669
						 'retour.champs' => 'num_statut');
1654 aurelien 670
		$noms = $service->consulter(Array('nvjfl', 'noms-vernaculaires'), $donnees);
2143 jpm 671
 
1654 aurelien 672
		if(! $noms) return '';
1673 raphael 673
		$noms = array_filter((array)($noms->resultat), array($this, retournerNumStatutUn)); // XXX: php 5.3
1654 aurelien 674
		$nom = array_pop($noms)->nom_vernaculaire;
2143 jpm 675
 
1656 raphael 676
		// cache
1657 raphael 677
		self::$cache['getNomCommun'][$cache_id] = $nom;
1654 aurelien 678
		return $nom;
679
	}
2143 jpm 680
 
681
 
1654 aurelien 682
	/* Effectue un bootstraping plus sage que ci-dessus, mais le gain d'efficacité
1656 raphael 683
	   n'est pas aussi retentissant qu'espéré */
1654 aurelien 684
	static $service;
685
	function getNomCommun_v3($obs) {
686
		if(! $this->service) $this->service = new Projets();
2143 jpm 687
 
1654 aurelien 688
		$langue = 'fra';
689
		list($referentiel) = explode(':', strtolower($obs['nom_referentiel']));
690
		if($referentiel == 'bdtfx') $referentiel = 'nvjfl';
691
		else return '';
2143 jpm 692
 
1654 aurelien 693
		$cache_id = $referentiel . '-' . $obs['nt'] . '-' . $langue;
1657 raphael 694
		if(isset(self::$cache['getNomCommun'][$cache_id])) {
1656 raphael 695
			error_log("require NomsVernaculaires.php: OK ! (pour \"{$obs['nom_ret']}\")");
1657 raphael 696
			return self::$cache['getNomCommun'][$cache_id];
1654 aurelien 697
		}
698
		// pas de cache:
1656 raphael 699
		error_log("require NomsVernaculaires.php pour \"{$obs['nom_ret']}\"");
2143 jpm 700
 
1654 aurelien 701
		$donnees = Array('masque.nt' => $obs['nt'],
1656 raphael 702
						 'masque.lg' => $langue,
703
						 'retour.champs' => 'conseil_emploi');
704
		$this->service->initialiserRessourcesEtParametres(Array('nvjfl', 'noms-vernaculaires', 'attributions'), $donnees);
1654 aurelien 705
		try {
1656 raphael 706
			$noms = $this->service->traiterRessources();
2143 jpm 707
		} catch(Exception $e) {
1656 raphael 708
			return '';
1654 aurelien 709
		}
1656 raphael 710
		if(! $noms) return '';
1673 raphael 711
		$noms = array_filter($noms['resultat'], array($this, retournerNumStatutUnArr)); // XXX: php 5.3
1656 raphael 712
		$premier_nom = array_pop($noms);
1654 aurelien 713
		$nom = $premier_nom['nom_vernaculaire'];
2143 jpm 714
 
1654 aurelien 715
		// cache
1657 raphael 716
		self::$cache['getNomCommun'][$cache_id] = $nom;
1654 aurelien 717
		return $nom;
718
	}
1685 raphael 719
 
1694 raphael 720
 
1702 raphael 721
 
2143 jpm 722
 
3467 delphine 723
 
1765 raphael 724
	static function getNomCommun_v4($obs) {
2446 jpm 725
		// Attention la fonction suppose que l'on ait fait appel à getNomCommun_preload avant
2281 aurelien 726
		// d'être appelée
1685 raphael 727
		if(! $obs['nt']) return NULL;
1765 raphael 728
		if(! self::referenceTableExiste()) return NULL;
1689 raphael 729
 
1685 raphael 730
		$langue = 'fra';
731
		list($referentiel) = explode(':', strtolower($obs['nom_referentiel']));
732
		$cache_id = $referentiel . '-' . $obs['nt'] . '-' . $langue;
733
 
2281 aurelien 734
		$nom = null;
1757 raphael 735
		// cache:
2281 aurelien 736
		if(isset(self::$cache['getNomCommun'])) {
1757 raphael 737
			if(isset(self::$cache['getNomCommun'][$cache_id])) return self::$cache['getNomCommun'][$cache_id];
738
			// XXX: problème de valeurs NULL ?
2281 aurelien 739
			if(array_key_exists($cache_id, self::$cache['getNomCommun'])) {
740
				$nom = self::$cache['getNomCommun'][$cache_id];
741
			}
1757 raphael 742
		}
1685 raphael 743
 
744
		return $nom;
745
	}
1702 raphael 746
 
747
 
748
	/* Cette fonction initialise le cache des données baseflor en 1 fois, sur la liste des observations à exporter.
749
	   Ainsi, les appels successifs à baseflor_ligne() ne sont pas couteux (pas de requête SQL) */
750
	static function baseflor_preload($cel, $obsids) {
751
		if(!$obsids) return;
1765 raphael 752
		if(!self::referenceTableExiste()) return NULL;
1702 raphael 753
 
2254 aurelien 754
		// Attention (en attendant de faire une meilleure table et une meilleure requete) le distinct est très important
755
		$req = sprintf("SELECT DISTINCT referentiel, num_nom_retenu, %s FROM cel_references r" .
2297 mathias 756
						" INNER JOIN cel_obs c ON (r.num_nom_retenu = c.nom_ret_nn)" .
757
						" AND r.referentiel = IF(LOCATE(':', c.nom_referentiel) = 0, c.nom_referentiel, SUBSTR(c.nom_referentiel FROM 1 FOR LOCATE(':', c.nom_referentiel) - 1))" .
758
						" WHERE c.id_observation IN (%s)",
759
						//" AND catminat_code IS NOT NULL", // TODO: suppression des NULL ici signifie que le cache sera partiel...
760
						implode(',', array_keys(self::$baseflor_col)),
761
						implode(',', $obsids));
1765 raphael 762
		$res = Cel::db()->requeter($req);
1706 raphael 763
		if(!$res) return NULL;
1702 raphael 764
 
765
		foreach($res as $v) {
766
			$data = $v;
767
			unset($data['referentiel']); // non nécessaire
768
			unset($data['num_nom_retenu']); // non nécessaire
2446 jpm 769
 
2244 aurelien 770
			// Des fois les synonymes ont des valeurs pour baseflor et pas le nom retenu et vice versa
2446 jpm 771
			// on les fusionne pour avoir le maximum d'infos, en attendant de repenser la table référence
2244 aurelien 772
			if(isset(self::$cache['getBaseflor'][$v['referentiel'] . '-' . $v['num_nom_retenu']])) {
2446 jpm 773
				$orig  = array_filter(self::$cache['getBaseflor'][$v['referentiel'] . '-' . $v['num_nom_retenu']], 'strlen');
774
				$data  = array_filter($data , 'strlen');
2244 aurelien 775
				$data = array_merge($orig, $data);
776
			}
2446 jpm 777
 
1702 raphael 778
			self::$cache['getBaseflor'][$v['referentiel'] . '-' . $v['num_nom_retenu']] = $data;
779
		}
780
 
781
		return NULL;
782
	}
1685 raphael 783
 
2446 jpm 784
	/**
2312 mathias 785
	 * Attention la fonction suppose que l'on ait fait appel à baseflor_preload avant
786
	 * d'être appelée
787
	 * @CASSECOUILLES elle pourrait le détecter et le faire elle-même
788
	 */
1765 raphael 789
	static function baseflor_ligne($obs, &$ligne) {
2312 mathias 790
		$clefsBF = array_keys(self::$baseflor_col);
791
		// par défaut des colonnes vides pour ne pas décaler le bousin
792
		$donneesBF = array_fill_keys($clefsBF, "");
1702 raphael 793
 
2312 mathias 794
		// s'il y a des données baseflor
795
		if ($obs['nom_ret_nn'] && self::referenceTableExiste() && count(self::$cache['getBaseflor']) > 0) {
796
			// l'astuce à un franc vingt
797
			list($referentiel) = explode(':', strtolower($obs['nom_referentiel']));
798
			$cache_id = $referentiel . '-' . $obs['nom_ret_nn'];
1702 raphael 799
 
2312 mathias 800
			// si les données baseflor existent dans le cache pour ce nom_ret_nn
801
			if (array_key_exists($cache_id, self::$cache['getBaseflor'])) {
802
				$donneesBFATrous = self::$cache['getBaseflor'][$cache_id];
803
				foreach($clefsBF as $colbf) { // remplit les trous tout en préservant l'ordre
804
					if(array_key_exists($colbf, $donneesBFATrous)) {
805
						$donneesBF[$colbf] = $donneesBFATrous[$colbf];
806
					} else {
807
						$donneesBF[$colbf] = "";
808
					}
809
				}
810
			}
1702 raphael 811
		}
2312 mathias 812
 
813
		// Quand les données sont prêtes, on les fusionne
814
		$ligne = array_merge($ligne, $donneesBF);
1702 raphael 815
	}
2446 jpm 816
 
1715 raphael 817
	static function champsEtendus_preload($cel, $obsids) {
3478 delphine 818
		// obs étendues
819
	    $gestion_obs_etendus = new GestionChampsEtendus($cel->config);
820
	    // champs étendus
3479 delphine 821
	    $gestion_champs_etendus = new GestionChampsEtendus2($cel->config);
3478 delphine 822
		$colonnes_champs_supp_par_obs = $gestion_obs_etendus->consulterClesParLots($obsids);
2446 jpm 823
 
824
		// Supprime les champs étendus considérés comme privés dans le cas de l'export public en chargeant
2403 aurelien 825
		// le catalogue et en excluant ceux qui sont explicitement privés
826
		if(!$cel->export_prive) {
827
			$indices_a_supprimer = array();
828
			$catalogue_champs_etendus = $gestion_champs_etendus->consulterCatalogueChampsEtendusPredefinis();
829
			foreach($catalogue_champs_etendus as $champ_catalogue) {
830
				if($champ_catalogue['options']['prive'] == 1) {
2446 jpm 831
					// Les champs étendus peuvent avoir des variantes lorsqu'ils apparaissent de multiples fois.
2407 aurelien 832
					// Vont donc matcher monChamp mais aussi monChamp:1, monChamp:2 ou bien monChamp1, monChamp: etc...
833
					// pour plus de sécurité (ce filtra n'est affectué qu'une fois au début de l'export donc on ne s'en prive pas)
834
					$entrees = preg_grep("/".$champ_catalogue['cle']."(?::?\d*)?$/", $colonnes_champs_supp_par_obs);
2403 aurelien 835
					$indices_a_supprimer = array_merge($indices_a_supprimer, array_keys($entrees));
836
				}
837
			}
838
			// les champs étendus sont renvoyés dans l'export suivant les colonnes présentes dans ce tableau
839
			// les éliminer de la liste des colonnes suffit à les faire ignorer par l'export
2446 jpm 840
			foreach($indices_a_supprimer as $indice_supp) {
841
				unset($colonnes_champs_supp_par_obs[$indice_supp]);
2403 aurelien 842
			}
843
		}
2446 jpm 844
 
1741 raphael 845
		// ces deux lignes réordonnent l'ordre des colonnes des champs étendus en fonction de l'ordre (très spécifique)
846
		// de self::$ordre_champ_etendus_Florileges, les champs non-mentionnés sont ajoutés à la fin.
847
		$colonnes_champs_supp_par_obs = self::sortArrayByArray(array_flip($colonnes_champs_supp_par_obs),
848
															   self::$ordre_champ_etendus_Florileges);
849
		$colonnes_champs_supp_par_obs = array_keys($colonnes_champs_supp_par_obs);
850
 
1718 raphael 851
		// si le SELECT des clefs ne retourne rien, une autre requêtes est inutile
852
		// TODO: optimize, 1 seule requête
853
		if(!$colonnes_champs_supp_par_obs) return Array('header' => array(), 'data' => array());
854
 
3478 delphine 855
		$champs_supp_par_obs = $gestion_obs_etendus->consulterParLots($obsids);
1741 raphael 856
 
1791 raphael 857
		self::$cache['champsEtendus']['header'] = self::champsEtendus_prefixHeader($colonnes_champs_supp_par_obs);
858
 
1715 raphael 859
		foreach($champs_supp_par_obs as &$v) {
860
			$v = self::champsEtendus_aplatir($v);
861
		}
862
		self::$cache['champsEtendus']['data'] = $champs_supp_par_obs;
863
		// ce return est temporaire,
864
		// le temps que toutes les fonctions bougent ici et utilise plutôt le cache statique
1716 raphael 865
		// encore utilisé pour les entêtes (self::$cache['champsEtendus']['header'])
1715 raphael 866
		return self::$cache['champsEtendus'];
867
	}
868
 
869
	// XXX: PHP-5.3, fonction anonyme + array_map
1791 raphael 870
	static function champsEtendus_prefixHeader($array) {
871
		return array_map(create_function('$v', 'return "' . PREFIX_CHAMPS_ETENDUS . '".$v;'), $array);
872
	}
873
 
874
	// XXX: PHP-5.3, fonction anonyme + array_map
1715 raphael 875
	static function champsEtendus_aplatir($ligne_champs_etendus) {
876
		$champs_etendus_fmt = array();
877
		if(!$ligne_champs_etendus) return $champs_etendus_fmt;
878
		foreach($ligne_champs_etendus as $champ) {
1791 raphael 879
			$champs_etendus_fmt[PREFIX_CHAMPS_ETENDUS . $champ->cle] = $champ->valeur;
1715 raphael 880
		}
881
		return $champs_etendus_fmt;
882
	}
1716 raphael 883
 
1765 raphael 884
	static function champsEtendus_ligne($obs, &$ligne) {
1716 raphael 885
		// si header n'est pas défini, aucune observation ne possède de champ étendu
886
		// et nous n'ajoutons ni colonnes, ni valeurs.
887
		if(! isset(self::$cache['champsEtendus']['header'])) return;
1736 raphael 888
		$ligne_etendue_aplatie = @self::$cache['champsEtendus']['data'][$obs['id_observation']];
1716 raphael 889
 
890
		$ligne_supp = array_fill(0, count(self::$cache['champsEtendus']['header']), '');
891
		$ligne_etendue_fmt = array();
892
 
893
		// si, cependant cette seule observation n'a pas de champs étendus,
894
		// nous devons rajouter des blancs (notamment dans le cas ou d'autres
895
		// champs viennent à être ajoutés en aval à l'avenir
896
		// cf: $fonction_dynamique dans FormateurGroupeColonne::GenColInfo()
897
		if(! $ligne_etendue_aplatie) {
898
			$ligne = array_merge($ligne, $ligne_supp);
899
			return;
900
		}
901
 
902
		foreach(self::$cache['champsEtendus']['header'] as $colonne) {
903
			if(!isset($ligne_etendue_aplatie[$colonne])) {
2143 jpm 904
				$ligne_etendue_fmt[$colonne] = '';
1716 raphael 905
			} else {
906
				$ligne_etendue_fmt[$colonne] = $ligne_etendue_aplatie[$colonne];
907
			}
908
		}
909
 
910
		// XXX/ array_merge() ?
911
		$ligne += $ligne_etendue_fmt;
912
	}
1741 raphael 913
 
914
	/* HELPERS */
915
 
916
	// http://stackoverflow.com/questions/348410/sort-an-array-based-on-another-array
917
	// XXX; redéfinition, utilisé aussi par ExportXLS
918
	static function sortArrayByArray($array, $orderArray) {
919
		$ordered = array();
920
		foreach($orderArray as $key) {
921
			if(array_key_exists($key, $array)) {
922
				$ordered[$key] = $array[$key];
923
				unset($array[$key]);
924
			}
925
		}
926
		return $ordered + $array;
927
	}
2461 jpm 928
}