Subversion Repositories eFlore/Applications.cel

Rev

Rev 1640 | Rev 1646 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1640 Rev 1642
Line 85... Line 85...
85
		"latitude",
85
		"latitude",
86
		"longitude");
86
		"longitude");
Line 87... Line 87...
87
 
87
 
88
	/*
88
	/*
89
	  Ces colonnes:
89
	  Ces colonnes:
90
	  - sont propre à tous les enregistrements uploadés
90
	  - sont propres à l'ensemble des enregistrements uploadés
91
	  - sont indépendantes du numéro de lignes
91
	  - sont indépendantes du numéro de lignes
92
	  - n'ont pas de valeur par défaut dans la structure de la table
92
	  - n'ont pas de valeur par défaut dans la structure de la table
93
	  - nécessitent une initialisation dans le cadre de l'upload
93
	  - nécessitent une initialisation dans le cadre de l'upload
94
	*/
94
	*/
95
	public $colonnes_statiques = Array(
95
	public $colonnes_statiques = Array(
96
		"ce_utilisateur" => NULL,
96
		"ce_utilisateur" => NULL,
97
		"prenom_utilisateur" => NULL,
97
		"prenom_utilisateur" => NULL,
98
		"nom_utilisateur" => NULL,
98
		"nom_utilisateur" => NULL,
Line -... Line 99...
-
 
99
		"courriel_utilisateur" => NULL,
99
		"courriel_utilisateur" => NULL,
100
 
100
 
101
		// fixes (fonction SQL)
101
		// XXX: fixes (mais pourraient varier dans le futur si la mise-à-jour
102
		// XXX future: mais pourraient varier dans le futur si la mise-à-jour
102
		// d'observation est implémentée
103
		// d'observation est implémentée
103
		"date_creation" => NULL, // ne peut initialiser d'une date ici
104
		"date_creation" => "now()",
Line -... Line 105...
-
 
105
		"date_modification" => "now()",
-
 
106
	);
-
 
107
 
-
 
108
	public $id_utilisateur = NULL;
104
		"date_modification" => NULL, // idem, cf initialiser_colonnes_statiques()
109
	// erreurs d'import
105
	);
110
	public $bilan = Array();
106
 
111
 
Line 107... Line 112...
107
	function ExportXLS($config) {
112
	function ExportXLS($config) {
108
		parent::__construct($config);
113
		parent::__construct($config);
109
	}
114
	}
110
 
115
 
111
	function createElement($pairs) {
116
	function createElement($pairs) {
-
 
117
		if(!isset($pairs['utilisateur']) || trim($pairs['utilisateur']) == '') {
Line 112... Line 118...
112
		if(!isset($pairs['utilisateur']) || trim($pairs['utilisateur']) == '') {
118
			echo '0'; exit;
113
			echo '0'; exit;
119
		}
Line 114... Line 120...
114
		}
120
		$id_utilisateur = intval($pairs['utilisateur']);
Line 130... Line 136...
130
		$objReader->setReadDataOnly(true);
136
		$objReader->setReadDataOnly(true);
131
		$objPHPExcel = $objReader->load($infos_fichier['tmp_name']);*/
137
		$objPHPExcel = $objReader->load($infos_fichier['tmp_name']);*/
Line 132... Line 138...
132
 
138
 
Line -... Line 139...
-
 
139
		//var_dump($donnees);
-
 
140
 
-
 
141
		// renomme le fichier pour lui ajouter son extension initiale, ce qui
-
 
142
		// permet (une sorte) d'autodétection du format.
-
 
143
		$fichier = $infos_fichier['tmp_name'];
-
 
144
		$extension = pathinfo($infos_fichier['name'], PATHINFO_EXTENSION);
-
 
145
		if( (strlen($extension) == 3 || strlen($extension) == 4) &&
-
 
146
			(rename($fichier, $fichier . '.' . $extension))) {
-
 
147
			$fichier = $fichier . '.' . $extension;
133
		//var_dump($donnees);
148
		}
134
 
149
 
Line -... Line 150...
-
 
150
		$objReader = PHPExcel_IOFactory::createReaderForFile($fichier);
-
 
151
		$objReader->setReadDataOnly(true);
-
 
152
 
-
 
153
		if(is_a($objReader, 'PHPExcel_Reader_CSV')) {
-
 
154
			$objReader->setDelimiter(',')
-
 
155
				->setEnclosure('"')
-
 
156
				->setLineEnding("\n")
135
		$objReader = PHPExcel_IOFactory::createReader("Excel5");
157
				->setSheetIndex(0);
136
		$objReader->setReadDataOnly(true);
158
		}
137
 
159
 
138
		// on ne conserve que l'en-tête
160
		// on ne conserve que l'en-tête
Line 139... Line 161...
139
		$filtre = new MyReadFilter();
161
		$filtre = new MyReadFilter();
140
		$filtre->def_interval(1, 2);
162
		$filtre->def_interval(1, 2);
141
		$objReader->setReadFilter($filtre);
163
		$objReader->setReadFilter($filtre);
142
 
164
 
Line 143... Line 165...
143
		$objPHPExcel = $objReader->load($infos_fichier['tmp_name']);
165
		$objPHPExcel = $objReader->load($fichier);
144
		$obj_infos = $objReader->listWorksheetInfo($infos_fichier['tmp_name']);
166
		$obj_infos = $objReader->listWorksheetInfo($fichier);
Line 152... Line 174...
152
		$obs_maj = 0;
174
		$obs_maj = 0;
153
		$dernier_ordre = $this->requeter("SELECT MAX(ordre) AS ordre FROM cel_obs WHERE ce_utilisateur = $id_utilisateur");
175
		$dernier_ordre = $this->requeter("SELECT MAX(ordre) AS ordre FROM cel_obs WHERE ce_utilisateur = $id_utilisateur");
154
		$dernier_ordre = intval($dernier_ordre[0]['ordre']) + 1;
176
		$dernier_ordre = intval($dernier_ordre[0]['ordre']) + 1;
155
		if(! $dernier_ordre) $dernier_ordre = 0;
177
		if(! $dernier_ordre) $dernier_ordre = 0;
Line -... Line 178...
-
 
178
 
-
 
179
		// on catch to les trigger_error(E_USER_NOTICE);
-
 
180
		set_error_handler(array($this, 'erreurs_stock'), E_USER_NOTICE);
156
 
181
 
157
		// lecture par morceaux (chunks), NB_LIRE_LIGNE_SIMUL lignes à fois
182
		// lecture par morceaux (chunks), NB_LIRE_LIGNE_SIMUL lignes à fois
158
		// pour aboutir des requêtes SQL d'insert groupés.
183
		// pour aboutir des requêtes SQL d'insert groupés.
159
		for($ligne = 2; $ligne < $nb_lignes + NB_LIRE_LIGNE_SIMUL; $ligne += NB_LIRE_LIGNE_SIMUL) {
184
		for($ligne = 2; $ligne < $nb_lignes + NB_LIRE_LIGNE_SIMUL; $ligne += NB_LIRE_LIGNE_SIMUL) {
160
			$filtre->def_interval($ligne, NB_LIRE_LIGNE_SIMUL);
185
			$filtre->def_interval($ligne, NB_LIRE_LIGNE_SIMUL);
Line 161... Line 186...
161
			$objReader->setReadFilter($filtre);
186
			$objReader->setReadFilter($filtre);
162
 
187
 
163
			/* recharge avec $filtre actif (filtre sur lignes colonnes):
188
			/* recharge avec $filtre actif (filtre sur lignes colonnes):
164
			   - exclue les colonnes inutiles/inutilisables)
189
			   - exclue les colonnes inutiles/inutilisables)
165
			   - ne selectionne que les lignes dans le range [$ligne - $ligne + NB_LIRE_LIGNE_SIMUL] */
190
			   - ne selectionne que les lignes dans le range [$ligne - $ligne + NB_LIRE_LIGNE_SIMUL] */
Line 166... Line 191...
166
			$objPHPExcel = $objReader->load($infos_fichier['tmp_name']);
191
			$objPHPExcel = $objReader->load($fichier);
167
			$donnees = $objPHPExcel->getActiveSheet()->toArray(NULL, FALSE, FALSE, TRUE);
192
			$donnees = $objPHPExcel->getActiveSheet()->toArray(NULL, FALSE, FALSE, TRUE);
Line 168... Line 193...
168
 
193
 
169
			// ici on appel la fonction qui fera effectivement l'insertion multiple
194
			// ici on appel la fonction qui fera effectivement l'insertion multiple
-
 
195
			// à partir des (au plus) NB_LIRE_LIGNE_SIMUL lignes
170
			// à partir des (au plus) NB_LIRE_LIGNE_SIMUL lignes
196
 
-
 
197
			// TODO: passer $this, ne sert que pour appeler des méthodes public qui pourraient être statiques
-
 
198
			// notamment dans RechercheInfosTaxonBeta.php
-
 
199
			list($enregistrements, $images) =
-
 
200
				self::chargerLignes($this, $donnees, $this->colonnes_statiques, $dernier_ordre);
-
 
201
			if(! $enregistrements) break;
-
 
202
 
171
 
203
			$dernier_autoinc = self::stockerEnregistrements($this, $enregistrements);
-
 
204
			$obs_ajouts += count($enregistrements);
172
			// TODO: passer $this, ne sert que pour appeler des méthodes public qui pourraient être statiques
205
			// $obs_maj += count($enregistrements_a_MAJ);
-
 
206
			self::stockerImages($this, $enregistrements, $images, $dernier_autoinc);
-
 
207
		}
-
 
208
 
-
 
209
		restore_error_handler();
173
			// notamment dans RechercheInfosTaxonBeta.php
210
 
Line 174... Line 211...
174
			self::chargerLignes($donnees, $this->colonnes_statiques, $dernier_ordre, $this, $obs_ajouts, $obs_maj);
211
		if($this->bilan) echo implode("\n", $this->bilan) . "\n";
175
		}
212
		// fin: renvoi summary
176
		die('end');
213
		die("$obs_ajouts observations ajoutées");
Line 183... Line 220...
183
			$entete_simple = iconv('UTF-8', 'ASCII//TRANSLIT', strtolower(trim($v)));
220
			$entete_simple = iconv('UTF-8', 'ASCII//TRANSLIT', strtolower(trim($v)));
184
			foreach($cols as $col) {
221
			foreach($cols as $col) {
185
				$entete_officiel_simple = iconv('UTF-8', 'ASCII//TRANSLIT', strtolower(trim($col['nom'])));
222
				$entete_officiel_simple = iconv('UTF-8', 'ASCII//TRANSLIT', strtolower(trim($col['nom'])));
186
				$entete_officiel_abbrev = $col['abbrev'];
223
				$entete_officiel_abbrev = $col['abbrev'];
187
				if($entete_simple == $entete_officiel_simple || $entete_simple == $entete_officiel_abbrev) {
224
				if($entete_simple == $entete_officiel_simple || $entete_simple == $entete_officiel_abbrev) {
188
					// debug echo "define C_" . strtoupper($entete_officiel_abbrev) . ", $k\n";
225
					//debug echo "define C_" . strtoupper($entete_officiel_abbrev) . ", $k ($v)\n";
189
					define("C_" . strtoupper($entete_officiel_abbrev), $k);
226
					define("C_" . strtoupper($entete_officiel_abbrev), $k);
190
					$colonnes_reconnues[$k] = 1;
227
					$colonnes_reconnues[$k] = 1;
191
					break;
228
					break;
192
				}
229
				}
193
			}
230
			}
Line 217... Line 254...
217
	}
254
	}
Line 218... Line 255...
218
 
255
 
219
	/*
256
	/*
220
	 * charge un groupe de lignes
257
	 * charge un groupe de lignes
221
	 */
258
	 */
222
	static function chargerLignes($lignes, $colonnes_statiques, &$dernier_ordre, $cel, &$inserted, &$updated) {
259
	static function chargerLignes($cel, $lignes, $colonnes_statiques, &$dernier_ordre) {
223
		$enregistrement = NULL;
260
		$enregistrement = NULL;
224
		$enregistrements = Array();
261
		$enregistrements = Array();
Line 225... Line 262...
225
		$images = Array();
262
		$toutes_images = Array();
226
 
263
 
227
		foreach($lignes as $ligne) {
264
		foreach($lignes as $ligne) {
-
 
265
			//$ligne = array_filter($ligne, function($cell) { return !is_null($cell); });
-
 
266
			//if(!$ligne) continue;
Line 228... Line 267...
228
			$ligne = array_filter($ligne, function($cell) { return !is_null($cell); });
267
			// on a besoin des NULL pour éviter des notice d'index indéfini
229
			if(!$ligne) continue;
268
			if(! array_filter($ligne, function($cell) { return !is_null($cell); })) continue;
Line 230... Line 269...
230
 
269
 
231
			if( ($enregistrement = self::chargerLigne($ligne, $colonnes_statiques, $dernier_ordre, $cel)) ) {
270
			if( ($enregistrement = self::chargerLigne($ligne, $dernier_ordre, $cel)) ) {
-
 
271
				$enregistrements[] = array_merge($colonnes_statiques, $enregistrement);
232
				$enregistrements[] = $enregistrement;
272
 
233
 
273
				if(isset($enregistrement['_images'])) {
234
				if(isset($enregistrement['_images'])) {
274
					$pos = count($enregistrements) - 1;
235
					$pos = count($enregistrements) - 1;
275
					$last = &$enregistrements[$pos];
236
					// ne dépend pas de cel_obs, et seront insérées *après* les enregistrements
276
					// ne dépend pas de cel_obs, et seront insérées *après* les enregistrements
237
					// mais nous ne voulons pas nous priver de faire des INSERT multiples pour autant
277
					// mais nous ne voulons pas nous priver de faire des INSERT multiples pour autant
238
					$images[] = Array("text" => $enregistrements[$pos]['_images'],
278
					$toutes_images[] = Array("images" => $last['_images'],
239
									  "obs_pos" => $pos);
279
											 "obs_pos" => $pos);
Line 240... Line 280...
240
					// ce champ n'a pas a faire partie de l'insertion dans cel_obs,
280
					// ce champ n'a pas a faire partie de l'insertion dans cel_obs,
241
					// mais est utile pour cel_obs_images
281
					// mais est utile pour cel_obs_images
242
					unset($enregistrements[$pos]['_images']);
282
					unset($last['_images']);
Line -... Line 283...
-
 
283
				}
243
				}
284
 
-
 
285
				$dernier_ordre++;
Line 244... Line -...
244
 
-
 
Line -... Line 286...
-
 
286
			}
-
 
287
		}
Line 245... Line 288...
245
				$dernier_ordre++;
288
 
246
			}
289
		// XXX future: return Array($enregistrements_a_inserer, $enregistrements_a_MAJ, $toutes_images);
-
 
290
		return Array($enregistrements, $toutes_images);
-
 
291
	}
247
		}
292
 
-
 
293
 
-
 
294
	static function stockerEnregistrements($cel, $enregistrements) {
-
 
295
		$req = '';
-
 
296
 
Line 248... Line 297...
248
 
297
		foreach($enregistrements as $enregistrement) {
249
		if(!$enregistrements) die('AIE // XXX');
298
			$enregistrement = self::sortArrayByArray($enregistrement, self::$ordre_BDD);
250
 
299
			array_walk($enregistrement,
-
 
300
					   function(&$item, $k, $obj) { $item = is_null($item) ? "NULL" : $item; },
-
 
301
					   $cel);
-
 
302
			$req .= implode(', ', $enregistrement) . "\n";
-
 
303
		}
-
 
304
		echo "$req\n";
-
 
305
		// TODO: insert
-
 
306
 
-
 
307
		// $cel->executer($req);
-
 
308
		// transactionnel + auto-inc
-
 
309
		return $cel->bdd->lastInsertId();
-
 
310
	}
-
 
311
 
251
		$req = '';
312
 
252
 
313
	static function stockerImages($cel, $enregistrements, $toutes_images, $lastid) {
253
 
314
		if(! $lastid) $lastid = rand();
254
		foreach($enregistrements as $enregistrement)
315
 
255
			$req .= implode(', ', self::sortArrayByArray($enregistrement, self::$ordre_BDD));
316
		$images_insert =
-
 
317
			'INSERT INTO cel_obs_images (id_image, id_observation) VALUES'
-
 
318
			.' %s '
-
 
319
			.'ON DUPLICATE KEY UPDATE id_image = id_image';
-
 
320
		$images_obs_assoc = Array();
-
 
321
 
-
 
322
		foreach($toutes_images as $images_pour_obs) {
-
 
323
			$obs = $enregistrements[$images_pour_obs["obs_pos"]];
-
 
324
			$id_obs = $lastid // dernier autoinc inséré
-
 
325
				- count($enregistrements) - 1 // correspondrait au premier autoinc
256
		print_r($req);
326
				+ $images_pour_obs["obs_pos"]; // ordre d'insertion = ordre dans le tableau $enregistrements
257
 
327
			foreach($images_pour_obs['images'] as $image) {
258
		// $cel->executer($req);
328
				$images_obs_assoc[] = sprintf('(%d,%d)',
Line 259... Line 329...
259
		// transactionnel + auto-inc
329
											  $image['id_image'], // intval() useless
260
		$lastid = $cel->bdd->lastInsertId();
330
											  $id_obs); // intval() useless
261
		foreach($images as $image) {
331
			}
262
			$obs = $enregistrements[$image["obs_pos"]];
332
		}
Line 263... Line 333...
263
			$id_obs = $lastid // dernier autoinc inséré
333
 
264
				- count($enregistrements) - 1 // correspondrait au premier autoinc
334
		if($images_obs_assoc) {
-
 
335
			$requete = sprintf($images_insert, implode(', ', $images_obs_assoc));
265
				+ $image["obs_pos"]; // ordre d'insertion = ordre dans le tableau $enregistrements
336
			echo "$requete\n";
Line -... Line 337...
-
 
337
		}
-
 
338
	}
266
			// TODO: INSERT
339
 
-
 
340
 
267
		}
341
	static function chargerLigne($ligne, $dernier_ordre, $cel) {
268
	}
342
		// en premier car le résultat est utile pour
269
 
343
		// traiter longitude et latitude (traiterLonLat())
270
 
344
		$referentiel = self::identReferentiel($ligne[C_NOM_REFERENTIEL]);
271
	static function chargerLigne($ligne, $colonnes_statiques, $dernier_ordre, $cel) {
345
 
-
 
346
		// $espece est rempli de plusieurs informations
272
		// en premier car le résultat est utile pour
347
		$espece = Array(C_NOM_SEL => NULL, C_NOM_SEL_NN => NULL, C_NOM_RET => NULL,
273
		// traiter longitude et latitude (traiterLonLat())
348
						C_NOM_RET_NN => NULL, C_NT => NULL, C_FAMILLE => NULL);
274
		$referentiel = self::identReferentiel($ligne[C_NOM_REFERENTIEL]);
349
		self::traiterEspece($ligne, $espece, $cel);
275
 
350
 
276
		// $espece est rempli de plusieurs informations
351
		// $localisation est rempli à partir de plusieurs champs: C_ZONE_GEO et C_CE_ZONE_GEO
277
		$espece = Array();
352
		$localisation = Array(C_ZONE_GEO => NULL, C_CE_ZONE_GEO => NULL);
278
		self::traiterEspece($ligne, $espece, $cel);
353
		self::traiterLocalisation($ligne, $localisation, $cel);
279
 
354
 
280
		return array_merge($colonnes_statiques,
355
		// Dans ce tableau, seules devraient apparaître les données variable pour chaque ligne.
-
 
356
		// Dans ce tableau, l'ordre des clefs n'importe pas (cf: self::sortArrayByArray())
281
						   // Dans ce tableau, seules devraient apparaître les données variable pour chaque ligne.
357
		$enregistrement = Array(
282
						   // Dans ce tableau, l'ordre des clefs n'importe pas (cf: self::sortArrayByArray())
358
			"ordre" => $dernier_ordre,
283
						   Array(
359
 
-
 
360
			// $this->quoteNonNull() est déjà appliquée dans traiterEspece()
284
							   "ordre" => $dernier_ordre,
361
			"nom_sel" => $espece[C_NOM_SEL],
-
 
362
			"nom_sel_nn" => $espece[C_NOM_SEL_NN],
285
 
363
			"nom_ret" => $espece[C_NOM_RET],
286
							   "nom_sel" => $espece[C_NOM_SEL],
364
			"nom_ret_nn" => $espece[C_NOM_RET_NN],
287
							   "nom_sel_nn" => $espece[C_NOM_SEL_NN],
365
			"nt" => $espece[C_NT],
288
							   "nom_ret" => $espece[C_NOM_RET],
366
			"famille" => $espece[C_FAMILLE],
-
 
367
 
289
							   "nom_ret_nn" => $espece[C_NOM_RET_NN],
368
			"nom_referentiel" => $cel->quoteNonNull($referentiel),
290
							   "nt" => $espece[C_NT],
369
 
291
							   "famille" => $espece[C_FAMILLE],
370
			// $this->quoteNonNull() est déjà appliquée dans traiterLocalisation()
-
 
371
			"zone_geo" => $localisation[C_ZONE_GEO],
292
 
372
			"ce_zone_geo" => $localisation[C_CE_ZONE_GEO],
293
							   "nom_referentiel" => $referentiel,
373
 
294
 
374
			// $ligne: uniquement pour les infos en cas de gestion d'erreurs (date incompréhensible)
-
 
375
			"date_observation" => $cel->quoteNonNull(self::traiterDateObs($ligne[C_DATE_OBSERVATION], $ligne)),
-
 
376
 
-
 
377
			"lieudit" => $cel->quoteNonNull(trim($ligne[C_LIEUDIT])),
-
 
378
			"station" => $cel->quoteNonNull(trim($ligne[C_STATION])),
-
 
379
			"milieu" => $cel->quoteNonNull(trim($ligne[C_MILIEU])),
-
 
380
			"commentaire" => $cel->quoteNonNull(trim($ligne[C_COMMENTAIRE])), // TODO: foreign-key
-
 
381
 
295
							   "zone_geo" => TODO,
382
 
-
 
383
			"transmission" => in_array(strtolower(trim($ligne[C_TRANSMISSION])), array(1, 'oui')) ? 1 : 0,
-
 
384
 
-
 
385
			// $ligne: uniquement pour les infos en cas de gestion d'erreurs (lon/lat incompréhensible)
-
 
386
			"latitude" => self::traiterLonLat(NULL, $ligne[C_LATITUDE], $referentiel, $ligne),
-
 
387
			"longitude" => self::traiterLonLat($ligne[C_LONGITUDE], NULL, $referentiel, $ligne),
-
 
388
		);
-
 
389
 
-
 
390
		// passage de $enregistrement par référence, ainsi ['_images'] n'est défini
-
 
391
		// que si des résultats sont trouvés
-
 
392
		// "@" car PHPExcel supprime les colonnes null sur toute la feuille (ou tout le chunk)
Line -... Line 393...
-
 
393
		if(@$ligne[C_IMAGES]) self::traiterImage($ligne[C_IMAGES], $cel, $enregistrement);
-
 
394
 
-
 
395
		return $enregistrement;
-
 
396
	}
Line 296... Line 397...
296
							   "ce_zone_geo" => self::traiterDepartement(trim($ligne[C_CE_ZONE_GEO])),
397
 
Line 297... Line 398...
297
 
398
	static function traiterImage($str, $cel, &$enregistrement) {
298
							   "date_observation" => self::traiterDateObs($ligne[C_DATE_OBSERVATION]),
399
		$liste_images = array_filter(explode("/", $str));
299
							   "lieudit" => trim($ligne[C_LIEUDIT]),
400
		array_walk($liste_images,
300
							   "station" => trim($ligne[C_STATION]),
401
				   function($item, $key, $obj) { $item = $obj->quoteNonNull(trim($item)); },
301
							   "milieu" => trim($ligne[C_MILIEU]),
402
				   $cel);
302
							   "commentaire" => trim($ligne[C_COMMENTAIRE]), // TODO: foreign-key
403
		$requete = sprintf(
303
 
404
			"SELECT id_image, nom_original FROM cel_images WHERE ce_utilisateur = %d AND nom_original IN (\"%s\")",
304
							   "transmission" => in_array(strtolower(trim($ligne[C_TRANSMISSION])), array(1, 'oui')) ? 1 : 0,
405
			$cel->id_utilisateur,
-
 
406
			implode('","', $liste_images));
-
 
407
 
-
 
408
		$resultat = $cel->requeter($requete);
-
 
409
 
305
 
410
		if($resultat) $enregistrement['_images'] = $resultat;
Line 306... Line 411...
306
							   "latitude" => self::traiterLonLat(NULL, $ligne[C_LATITUDE], $referentiel),
411
	}
307
							   "longitude" => self::traiterLonLat($ligne[C_LONGITUDE], NULL, $referentiel),
412
 
308
						   ));
413
 
Line 330... Line 435...
330
 
435
 
331
			// echo strftime("%Y/%m/%d 00:00:00", $timestamp); // NON
436
			// echo strftime("%Y/%m/%d 00:00:00", $timestamp); // NON
332
		}
437
		}
333
		else {
438
		else {
334
			$timestamp = strtotime($date);
439
			$timestamp = strtotime($date);
-
 
440
			if(! $timestamp) {
-
 
441
				if($date) trigger_error("ligne \"{$ligne[C_NOM_SEL]}\": Attention: date erronée ($date)", E_USER_NOTICE);
-
 
442
				return NULL;
335
			if(!$timestamp) return NULL; // TODO: throw error
443
			}
336
			return strftime("%Y-%m-%d 00:00:00", strtotime($date));
444
			return strftime("%Y-%m-%d 00:00:00", strtotime($date));
337
		}
445
		}
Line 338... Line 446...
338
	}
446
	}
339
 
447
 
340
	static function identReferentiel($referentiel) {
448
	static function identReferentiel($referentiel) {
341
		// SELECT DISTINCT nom_referentiel, COUNT(id_observation) AS count FROM cel_obs GROUP BY nom_referentiel ORDER BY count DESC;
449
		// SELECT DISTINCT nom_referentiel, COUNT(id_observation) AS count FROM cel_obs GROUP BY nom_referentiel ORDER BY count DESC;
342
		if(strpos(strtolower($referentiel), 'bdtfx') !== FALSE) return 'bdtfx:v1.01';
450
		if(strpos(strtolower($referentiel), 'bdtfx') !== FALSE) return 'bdtfx:v1.01';
343
		if(strpos(strtolower($referentiel), 'bdtxa') !== FALSE) return 'bdtxa:v1.00';
451
		if(strpos(strtolower($referentiel), 'bdtxa') !== FALSE) return 'bdtxa:v1.00';
-
 
452
		if(strpos(strtolower($referentiel), 'bdnff') !== FALSE) return 'bdnff:4.02';
-
 
453
		if(strpos(strtolower($referentiel), 'isfan') !== FALSE) return 'isfan:v1.00';
-
 
454
 
-
 
455
		if($referentiel) {
344
		if(strpos(strtolower($referentiel), 'bdnff') !== FALSE) return 'bdnff:4.02';
456
			trigger_error("ligne \"{$ligne[C_NOM_SEL]}\": Attention: référentiel inconnu", E_USER_NOTICE);
345
		if(strpos(strtolower($referentiel), 'isfan') !== FALSE) return 'isfan:v1.00';
457
		}
346
		return NULL;
458
		return NULL;
-
 
459
		/* TODO: cf story,
347
		/* TODO: cf story,
460
		   En cas de NULL faire une seconde passe de détection à partir du nom saisi
Line -... Line 461...
-
 
461
		   + accepter les n° de version */
-
 
462
	}
-
 
463
 
-
 
464
	static function traiterLonLat($lon = NULL, $lat = NULL, $referentiel = 'bdtfx:v1.01', $ligne) {
348
		   En cas de NULL faire une seconde passe de détection à partir du nom saisie */
465
		// en CSV ces valeurs sont des string, avec séparateur en français (","; cf défauts dans ExportXLS)
349
	}
466
		if($lon && is_string($lon)) $lon = str_replace(',', '.', $lon);
350
 
467
		if($lat && is_string($lat)) $lat = str_replace(',', '.', $lat);
-
 
468
 
351
	/* NON!
469
		// sprintf applique une précision à 5 décimale (comme le ferait MySQL)
-
 
470
		// tout en uniformisant le format de séparateur des décimales (le ".")
352
	   Un taxon d'un référentiel donné peut être théoriquement observé n'importe où sur le globe.
471
		if($lon && is_numeric($lon) && $lon >= -180 && $lon <= 180) return sprintf('%.5F', $lon);
353
	   Il n'y a pas lieu d'effectuer des restriction ici.
472
		if($lat && is_numeric($lat) && $lat >= -90 && $lat <= 90) return sprintf('%.5F', $lat);
354
	   Cependant des erreurs fréquentes (0,0 ou lon/lat inversées) peuvent être détectés ici.
473
 
355
	   TODO */
474
		if($lon || $lat) {
-
 
475
			trigger_error("ligne \"{$ligne[C_NOM_SEL]}\": " .
-
 
476
						  "Attention: longitude ou latitude erronée",
Line -... Line 477...
-
 
477
						  E_USER_NOTICE);
-
 
478
		}
-
 
479
		return NULL;
-
 
480
 
-
 
481
		/* limite france métropole si bdtfx ? ou bdtxa ? ...
-
 
482
		   NON!
356
	static function traiterLonLat($lon = NULL, $lat = NULL, $referentiel = 'bdtfx:v1.01') {
483
		   Un taxon d'un référentiel donné peut être théoriquement observé n'importe où sur le globe.
357
		// verifier format decimal +
484
		   Il n'y a pas lieu d'effectuer des restriction ici.
Line 358... Line 485...
358
		// + limite france si bdtfx ou bdtxa
485
		   Cependant des erreurs fréquentes (0,0 ou lon/lat inversées) peuvent être détectés ici.
359
 
486
		   TODO */
Line 370... Line 497...
370
		}
497
		}
371
	}
498
	}
Line 372... Line 499...
372
 
499
 
-
 
500
 
-
 
501
	static function traiterEspece($ligne, Array &$espece, $cel) {
373
 
502
		if(!$ligne[C_NOM_SEL]) return;
Line 374... Line 503...
374
	static function traiterEspece($ligne, Array &$espece, $cel) {
503
 
-
 
504
		$taxon_info_webservice = new RechercheInfosTaxonBeta($cel->config);
375
		$taxon_info_webservice = new RechercheInfosTaxonBeta($cel->config);
505
 
Line 376... Line 506...
376
 
506
		$ascii = iconv('UTF-8', 'ASCII//TRANSLIT', $ligne[C_NOM_SEL]);
377
		$ascii = iconv('UTF-8', 'ASCII//TRANSLIT', $ligne[C_NOM_SEL]);
507
		// FALSE = recherche étendue (LIKE x%)
378
		$resultat_recherche_espece = $taxon_info_webservice->rechercherInfosSurTexteCodeOuNumTax($ligne[C_NOM_SEL]);
508
		$resultat_recherche_espece = $taxon_info_webservice->rechercherInfosSurTexteCodeOuNumTax($ligne[C_NOM_SEL]);
379
 
509
 
380
		// on supprime les noms retenus et renvoi tel quel
-
 
Line -... Line 510...
-
 
510
		// on supprime les noms retenus et renvoi tel quel
381
		// on réutilise les define pour les noms d'indexes, tant qu'à faire
511
		// on réutilise les define pour les noms d'indexes, tant qu'à faire
-
 
512
		if (empty($resultat_recherche_espece['en_id_nom'])) {
382
		if (empty($resultat_recherche_espece['en_id_nom'])) {
513
			$espece[C_NOM_SEL] = $cel->quoteNonNull(trim($ligne[C_NOM_SEL]));
383
			$espece[C_NOM_SEL] = $ligne[C_NOM_SEL];
514
 
384
			$espece[C_NOM_SEL_NN] = $ligne[C_NOM_SEL_NN];
515
			// le reste reste à NULL
385
 
516
			// TODO: si empty(C_NOM_SEL) et !empty(C_NOM_SEL_NN) : recherche info à partir de C_NOM_SEL_NN
Line 386... Line 517...
386
			// TODO: si empty(C_NOM_SEL) et !empty(C_NOM_SEL_NN) : recherche info à partir de C_NOM_SEL_NN
517
			$espece[C_NOM_SEL_NN] = $ligne[C_NOM_SEL_NN];
387
			$espece[C_NOM_RET] = $ligne[C_NOM_RET];
518
			$espece[C_NOM_RET] = $ligne[C_NOM_RET];
Line 388... Line 519...
388
			$espece[C_NOM_RET_NN] = $ligne[C_NOM_RET_NN];
519
			$espece[C_NOM_RET_NN] = $ligne[C_NOM_RET_NN];
389
			$espece[C_NT] = $ligne[C_NT];
520
			$espece[C_NT] = $ligne[C_NT];
390
			$espece[C_FAMILLE] = $ligne[C_FAMILLE];
521
			$espece[C_FAMILLE] = $ligne[C_FAMILLE];
Line 391... Line 522...
391
 
522
 
392
			return;
523
			return;
393
		}
524
		}
394
 
525
 
395
		// succès de la détection, récupération des infos
526
		// succès de la détection, récupération des infos
396
		$espece[C_NOM_SEL] = $resultat_recherche_espece['nom_sel'];
527
		$espece[C_NOM_SEL] = $cel->quoteNonNull($resultat_recherche_espece['nom_sel']);
Line 397... Line 528...
397
		$espece[C_NOM_SEL_NN] = $resultat_recherche_espece['en_id_nom'];
528
		$espece[C_NOM_SEL_NN] = $cel->quoteNonNull($resultat_recherche_espece['en_id_nom']);
-
 
529
 
-
 
530
		$complement = $taxon_info_webservice->rechercherInformationsComplementairesSurNumNom($resultat_recherche_espece['en_id_nom']);
-
 
531
		$espece[C_NOM_RET] = $cel->quoteNonNull($complement['Nom_Retenu']);
-
 
532
		$espece[C_NOM_RET_NN] = $cel->quoteNonNull($complement['Num_Nom_Retenu']);
-
 
533
		$espece[C_NT] = $cel->quoteNonNull($complement['Num_Taxon']);
-
 
534
		$espece[C_FAMILLE] = $cel->quoteNonNull($complement['Famille']);
-
 
535
	}
-
 
536
 
-
 
537
 
-
 
538
	static function traiterLocalisation($ligne, Array &$localisation, $cel) {
-
 
539
	    $identifiant_commune = trim($ligne[C_ZONE_GEO]);
-
 
540
		if(!$identifiant_commune) {
-
 
541
			$departement = trim($ligne[C_CE_ZONE_GEO]);
-
 
542
			goto testdepartement;
-
 
543
		}
-
 
544
 
-
 
545
 
-
 
546
		$select = "SELECT DISTINCT nom, code  FROM cel_zones_geo";
-
 
547
	
-
 
548
		if (preg_match('/(.*) \((\d+)\)/', $identifiant_commune, $elements)) {
-
 
549
			// commune + departement : montpellier (34)
-
 
550
			$nom_commune=$elements[1];
-
 
551
			$code_commune=$elements[2];
-
 
552
	 	    $requete = sprintf("%s WHERE nom = %s AND code LIKE %s",
-
 
553
							   $select, $cel->quoteNonNull($nom_commune), $cel->quoteNonNull($code_commune.'%'));
-
 
554
		}
-
 
555
		elseif (preg_match('/^(\d+|(2[ab]\d+))$/i', $identifiant_commune, $elements)) {
-
 
556
			// Code insee seul  
-
 
557
			$code_insee_commune=$elements[1];
-
 
558
	 	    $requete = sprintf("%s WHERE code = %s", $select, $cel->quoteNonNull($code_insee_commune));
-
 
559
		}
-
 
560
		else {
-
 
561
			// Commune seule (le departement sera recupere dans la colonne departement si elle est presente)
-
 
562
			// on prend le risque ici de retourner une mauvaise Commune
-
 
563
			$nom_commune = str_replace(" ", "%", iconv('UTF-8', 'ASCII//TRANSLIT', $identifiant_commune));
-
 
564
	 	    $requete = sprintf("%s WHERE nom LIKE %s", $select, $cel->quoteNonNull($nom_commune.'%'));
-
 
565
		}
-
 
566
	
-
 
567
		$resultat_commune = $cel->requeter($requete);
-
 
568
		// TODO: levenstein sort ?
-
 
569
 
-
 
570
		// cas de la commune introuvable dans le référentiel
-
 
571
		// réinitialisation aux valeurs du fichier XLS
-
 
572
		if(! $resultat_commune) {
398
 
573
			$localisation[C_ZONE_GEO] = trim($ligne[C_ZONE_GEO]);
-
 
574
			$localisation[C_CE_ZONE_GEO] = trim($ligne[C_CE_ZONE_GEO]);
399
		$complement = $taxon_info_webservice->rechercherInformationsComplementairesSurNumNom($resultat_recherche_espece['en_id_nom']);
575
		} else {
400
		$espece[C_NOM_RET] = $complement['Nom_Retenu'];
576
			$localisation[C_ZONE_GEO] = $resultat_commune[0]['nom'];
401
		$espece[C_NOM_RET_NN] = $complement['Num_Nom_Retenu'];
577
			$localisation[C_CE_ZONE_GEO] = $resultat_commune[0]['code'];
402
		$espece[C_NT] = $complement['Num_Taxon'];
578
		}
-
 
579
 
403
		$espece[C_FAMILLE] = $complement['Famille'];
580
		$departement = &$localisation[C_CE_ZONE_GEO];
-
 
581
 
-
 
582
	testdepartement:
-
 
583
		if(strpos($departement, "INSEE-C:", 0) === 0) goto protectloc;
-
 
584
 
404
	}
585
		if(!is_numeric($departement)) goto protectloc; // TODO ?
Line -... Line 586...
-
 
586
		if(strlen($departement) == 4) $departement = "INSEE-C:0" . $departement;
405
 
587
		if(strlen($departement) == 5) $departement = "INSEE-C:" . $departement;
Line 406... Line 588...
406
 
588
		// if(strlen($departement) <= 9) return "INSEE-C:0" . $departement; // ? ... TODO
407
	static function traiterDepartement($departement) { 
589
 
408
		if(strpos($departement, "INSEE-C:", 0) === 0) return $departement;
590
		$departement = trim($departement); // TODO
Line 437... Line 619...
437
			'OUEST' => -5.2); // Ouessan
619
			'OUEST' => -5.2); // Ouessan
438
		return FALSE;
620
		return FALSE;
439
	}
621
	}
Line 440... Line 622...
440
 
622
 
441
 
623
 
442
	public function initialiser_colonnes_statiques($id_utisateur) {
624
	public function initialiser_colonnes_statiques() {
443
		$this->colonnes_statiques = array_merge($this->colonnes_statiques,
625
		$this->colonnes_statiques = array_merge($this->colonnes_statiques,
444
												Array(
626
												Array(
445
													"ce_utilisateur" => $id_utisateur,
627
													"ce_utilisateur" => $this->id_utilisateur,
446
													"prenom_utilisateur" => $this->utilisateur['prenom'],
628
													"prenom_utilisateur" => $this->quoteNonNull($this->utilisateur['prenom']),
447
													"nom_utilisateur" => $this->utilisateur['nom'],
-
 
448
													"courriel_utilisateur" => $this->utilisateur['courriel'],
-
 
449
 
-
 
450
													"date_creation" => date("Y-m-d H:i:s"),
629
													"nom_utilisateur" => $this->quoteNonNull($this->utilisateur['nom']),
Line 451... Line 630...
451
													"date_modification" => date("Y-m-d H:i:s"),
630
													"courriel_utilisateur" => $this->quoteNonNull($this->utilisateur['courriel']),
-
 
631
												));
-
 
632
 
-
 
633
	}
-
 
634
 
-
 
635
	// équivalent à CEL->Bdd->proteger() (qui wrap PDO::quote),
-
 
636
	// sans transformer NULL en ""
-
 
637
	private function quoteNonNull($chaine) {
-
 
638
		if(is_null($chaine)) return "NULL";
-
 
639
		if(!is_string($chaine)) die("erreur __FILE__, __LINE__");
-
 
640
		return $this->bdd->quote($chaine);
-
 
641
	}
-
 
642
 
452
												));
643
	public function erreurs_stock($errno, $errstr) {