Subversion Repositories eFlore/Applications.cel

Rev

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

Rev Author Line No. Line
1374 aurelien 1
<?php
2
/**
3
* Service fournissant des informations concernant le CEL au format RSS1, RSS2 ou ATOM.
4
* Encodage en entrée : utf8
5
* Encodage en sortie : utf8
6
* Format du service :
7
* /CelWidgetExport/format
8
* /CelWidgetExport/csv
9
*
10
* Les paramêtres :
11
*  - "start" indique le numéro du premier item à afficher
12
*  - "limit" nombre d'items à afficher
13
*
14
* @author Aurélien 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
* @version $Id$
18
* @copyright 2012
19
*/
1610 raphael 20
 
21
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(dirname(realpath(__FILE__))) . '/lib');
22
// la sortie est binaire (xls), mais OLE n'est pas compatible E_ALL en PHP-5.4
1617 aurelien 23
//error_reporting(error_reporting() ^ E_STRICT);
1610 raphael 24
require_once("lib/OLE.php");
25
require_once("lib/Spreadsheet/Excel/Writer.php");
26
 
1374 aurelien 27
class CelWidgetExport extends Cel {
28
 
1408 aurelien 29
	private $nom_fichier_export = 'cel_export';
1671 aurelien 30
	// certains paramètres apparaissent plusieurs fois car ils ont des alias
31
	// dans certains widgets
1376 aurelien 32
	private $parametres_autorises = array(
1654 aurelien 33
		'id_utilisateur' => 'ce_utilisateur',
1376 aurelien 34
		'utilisateur' => 'courriel_utilisateur',
35
		'commune' => 'zone_geo',
1671 aurelien 36
		'zone_geo' => 'zone_geo',
1376 aurelien 37
		'dept' => 'departement',
1654 aurelien 38
		'departement' => 'departement',
39
		'lieudit' => 'lieudit',
40
		'station' => 'station',
1376 aurelien 41
		'projet' => 'mots_cles',
1379 aurelien 42
		'num_taxon' => 'nt',
1378 aurelien 43
		'date_debut' => 'date_debut',
1387 aurelien 44
		'date_fin' => 'date_fin',
1625 aurelien 45
		'taxon' => 'taxon',
1654 aurelien 46
		'annee' => 'annee',
47
		'mois' => 'mois',
48
		'jour' => 'jour',
49
		'recherche' => 'recherche',
50
		'id_mots_cles' => 'id_mots_cles',
1662 aurelien 51
		'mots_cles' => 'mots_cles',
1625 aurelien 52
		'debut' => 'debut',
53
		'limite' => 'limite',
1654 aurelien 54
		'format' => 'format',
55
		'colonnes' => 'colonnes',
56
		'transmission' => 'transmission'
1376 aurelien 57
	);
1402 aurelien 58
 
1625 aurelien 59
	private $limite_decoupage_defaut = 9000;
60
 
1402 aurelien 61
	private $format = 'csv';
1579 aurelien 62
 
1659 aurelien 63
	public $id_utilisateur = null;
64
 
1579 aurelien 65
	public function getRessource() {
66
		return $this->getElement(array());
67
	}
1374 aurelien 68
 
69
	/**
70
	 * Méthode appelée avec une requête de type GET.
71
	 */
1625 aurelien 72
	public function getElement($params = array()) {
73
		if(count($params) > 0) {
74
			switch(strtolower($params[0])) {
75
				case 'calcul':
76
					$this->getCalcul();
77
				break;
78
 
79
				case 'export':
80
					$this->getExport();
81
				break;
82
 
83
				default:
84
					$this->getExport();
85
			}
86
		} else {
87
			$this->getExport();
88
		}
89
	}
90
 
91
	private function getCalcul() {
1611 raphael 92
		$criteres = $this->traiterParametresAutorises($_GET);
1654 aurelien 93
 
1374 aurelien 94
		$criteres['transmission'] = 1;
1654 aurelien 95
		if($this->doitEtPeutExporterObsPrivees($criteres)) {
96
			unset($criteres['transmission']);
1659 aurelien 97
			$this->id_utilisateur = $criteres['id_utilisateur'];
1654 aurelien 98
		}
1374 aurelien 99
		$chercheur_observations = new RechercheObservation($this->config);
100
 
1379 aurelien 101
		$numero_page = isset($criteres['debut']) ? $criteres['debut'] : 0;
102
		$limite = isset($criteres['limite']) ? $criteres['limite'] : 0;
1654 aurelien 103
		$colonnes = isset($criteres['colonnes']) ? $criteres['colonnes'] : 'standard,avance';
1374 aurelien 104
 
105
		unset($criteres['limite']);
106
		unset($criteres['debut']);
1625 aurelien 107
		unset($criteres['format']);
1654 aurelien 108
		unset($criteres['colonnes']);
1625 aurelien 109
 
110
		$nb_observations = $chercheur_observations->compterObservations(null, $criteres);
111
		$limite_decoupage = $this->calculerNbLignesMaxParFichier();
112
 
113
		$url_telechargements = array();
114
		$intervalle = 0;
115
 
116
		$params_url = $criteres;
117
		unset($params_url['transmission']);
118
		do {
119
			$base_url = $this->config['settings']['baseURLAbsolu'].'CelWidgetExport/export';
120
			$params_url['debut'] = $intervalle;
121
			$params_url['limite'] = $limite_decoupage;
122
			$url_telechargement_fichier = $base_url;
1654 aurelien 123
			$url_telechargements[] = $base_url.'?'.http_build_query($params_url).'&format='.$this->format.'&colonnes='.$colonnes;
1625 aurelien 124
			$intervalle += $limite_decoupage;
125
			$nb_observations -= $limite_decoupage;
126
		} while($nb_observations >= $limite_decoupage);
127
 
128
		$this->envoyerJson($url_telechargements);
129
	}
1374 aurelien 130
 
1625 aurelien 131
	private function calculerNbLignesMaxParFichier() {
132
		$limite = $this->limite_decoupage_defaut;
1402 aurelien 133
		switch($this->format) {
134
			case 'csv':
1625 aurelien 135
				$limite = 20000;
136
				break;
137
			case 'xls':
138
				$limite = 8000;
139
				break;
1660 raphael 140
			case 'pdf':
141
				$limite = 300;
142
				break;
1625 aurelien 143
		}
144
		return $limite;
145
	}
146
 
147
	private function getExport() {
148
		$criteres = $this->traiterParametresAutorises($_GET);
149
		$criteres['transmission'] = 1;
1654 aurelien 150
		if($this->doitEtPeutExporterObsPrivees($criteres)) {
151
			unset($criteres['transmission']);
152
		}
1625 aurelien 153
		$chercheur_observations = new RechercheObservation($this->config);
154
 
155
		$debut = isset($criteres['debut']) ? $criteres['debut'] : 0;
156
		$limite = isset($criteres['limite']) ? $criteres['limite'] : 0;
1654 aurelien 157
		$colonnes = isset($criteres['colonnes']) ? $criteres['colonnes'] : 'standard,avance';
1625 aurelien 158
 
159
		unset($criteres['limite']);
160
		unset($criteres['debut']);
161
		unset($criteres['format']);
1654 aurelien 162
		unset($criteres['colonnes']);
1625 aurelien 163
 
1631 raphael 164
		$observations = $chercheur_observations->rechercherObservations(null, $criteres, $debut, $limite)->get();
1659 aurelien 165
		$ids = array();
166
		foreach($observations as &$obs) {
167
			$ids[] = $obs['id_observation'];
168
		}
169
 
1662 aurelien 170
		if($this->format != 'pdf') {
171
			$gestion_champs_etendus = new GestionChampsEtendus($this->config, 'obs');
172
    		$champs_supp_par_obs = $gestion_champs_etendus->consulterParLots($ids);
173
    		$colonnes_champs_supp_par_obs = $gestion_champs_etendus->consulterClesParLots($ids);
174
		}
175
 
1659 aurelien 176
    	// TODO: tous les champs étendus et les paramètres supplémentaires devraient être passés en un seul
177
    	// tableau (et chaque formateur csv, xls etc... pourrait également être dans une classe à part)
1625 aurelien 178
		switch($this->format) {
1660 raphael 179
		case 'csv':
180
			$csv = $this->convertirEnCsv($observations, $colonnes, $colonnes_champs_supp_par_obs, $champs_supp_par_obs);
181
			$this->envoyerCsv($csv);
182
			break;
183
		case 'xls':
184
			$xls = $this->convertirEnXls($observations, $colonnes, $colonnes_champs_supp_par_obs, $champs_supp_par_obs);
185
			$this->envoyerXls($xls);
186
			break;
187
		case 'pdf':
1662 aurelien 188
			$pdf = $this->convertirEnPdf($observations);
189
			$this->envoyerPdf($pdf);
1660 raphael 190
			break;
191
		default:
1402 aurelien 192
		}
1374 aurelien 193
	}
194
 
1611 raphael 195
	protected function traiterParametresAutorises(Array $parametres) {
1376 aurelien 196
		$parametres_traites = array();
1402 aurelien 197
		$this->format = (isset($parametres['format']) && $parametres['format'] != '') ? $parametres['format'] : $this->format;
1376 aurelien 198
		foreach($parametres as $cle => $valeur) {
199
			if(trim($valeur) != '' && isset($this->parametres_autorises[$cle])) {
200
				$parametres_traites[$this->parametres_autorises[$cle]] = $valeur;
201
			}
202
		}
203
		return $parametres_traites;
204
	}
205
 
1374 aurelien 206
	private function envoyerCsv($csv) {
207
		header('Content-Type: text/csv; charset=UTF-8');
1408 aurelien 208
		header('Content-Disposition: attachment;filename='.$this->nom_fichier_export.'.csv');
1374 aurelien 209
		echo $csv;
1376 aurelien 210
		exit;
1374 aurelien 211
	}
212
 
1402 aurelien 213
	private function envoyerXls($workbook) {
214
		$workbook->close();
215
		exit;
216
	}
217
 
1662 aurelien 218
	private function convertirEnCsv(&$data, &$colonnes, &$colonnes_supplementaires, &$champs_supplementaires = array())
1374 aurelien 219
	{
220
		$chemin_temp = "php://temp";
221
		$outstream = fopen($chemin_temp, 'r+');
222
		$intitule_champs = array();
1659 aurelien 223
		$nb_colonnes_supp = count($colonnes_supplementaires);
1654 aurelien 224
		$groupe_colonnes = FormateurGroupeColonne::nomEnsembleVersListeColonnes($colonnes);
1617 aurelien 225
		foreach($data as &$ligne) {
1659 aurelien 226
			$id_obs = $ligne['id_observation'];
1429 aurelien 227
			$ligne = $this->filtrerDonneesSensibles($ligne);
1659 aurelien 228
			$ligne = FormateurGroupeColonne::getLigneObservation($ligne, $groupe_colonnes, $this);
229
			$ligne_supp = $nb_colonnes_supp > 0 ? array_fill(0, $nb_colonnes_supp, '') : array();
230
			if(isset($champs_supplementaires[$id_obs])) {
231
				$ligne_supp = $this->traiterLigneEtendue($colonnes_supplementaires, $champs_supplementaires[$id_obs]);
232
			}
233
			$ligne += $ligne_supp;
1374 aurelien 234
			if(empty($intitule_champs)) {
1654 aurelien 235
				$intitule_champs = FormateurGroupeColonne::getIntitulesColonnes($groupe_colonnes);
1659 aurelien 236
				foreach($colonnes_supplementaires as $colonne_sup) {
237
					$intitule_champs[] = $colonne_sup;
238
				}
1374 aurelien 239
				fputcsv($outstream, $intitule_champs, ',', '"');
240
			}
241
			fputcsv($outstream, $ligne, ',', '"');
242
		}
243
		rewind($outstream);
244
		$csv = stream_get_contents($outstream);
245
		fclose($outstream);
246
		return $csv;
247
	}
248
 
1662 aurelien 249
	private function convertirEnXls(&$data, &$colonnes,  &$colonnes_supplementaires, &$champs_supplementaires = array()) {
1402 aurelien 250
		$this->extendSpreadsheetProductor = new SpreadsheetProductor();
251
		$this->extendSpreadsheetProductor->initSpreadsheet();
252
 
1659 aurelien 253
		$nb_colonnes_supp = count($colonnes_supplementaires);
254
 
1402 aurelien 255
		$workbook = new Spreadsheet_Excel_Writer();
1625 aurelien 256
		$worksheet = $workbook->addWorksheet('Liste');
257
		$workbook->setTempDir($this->config['cel']['chemin_stockage_temp']);
1612 raphael 258
		$workbook->setVersion(8);
1402 aurelien 259
 
1612 raphael 260
		$worksheet->setInputEncoding('utf-8');
1408 aurelien 261
		$workbook->send($this->nom_fichier_export.'.xls');
1402 aurelien 262
 
263
		$nb_lignes = 1;
1654 aurelien 264
		$groupe_colonnes = FormateurGroupeColonne::nomEnsembleVersListeColonnes($colonnes);
1617 aurelien 265
		foreach($data as &$ligne) {
1659 aurelien 266
			$id_obs = $ligne['id_observation'];
1429 aurelien 267
			$ligne = $this->filtrerDonneesSensibles($ligne);
1659 aurelien 268
			$ligne = FormateurGroupeColonne::getLigneObservation($ligne, $groupe_colonnes, $this);
1402 aurelien 269
			if(empty($intitule_champs)) {
270
				$indice = 0;
1654 aurelien 271
				$intitule_champs = FormateurGroupeColonne::getIntitulesColonnes($groupe_colonnes);
1659 aurelien 272
				foreach($colonnes_supplementaires as $colonne_sup) {
273
					$intitule_champs[] = $colonne_sup;
274
				}
1617 aurelien 275
				foreach ($intitule_champs as &$intitule) {
1465 aurelien 276
					$colonne = $intitule_champs[$indice];
277
					$worksheet->write(0,$indice,$colonne);
1402 aurelien 278
					$indice++;
279
				}
280
			}
1659 aurelien 281
			$ligne_supp = $nb_colonnes_supp > 0 ? array_fill(0, $nb_colonnes_supp, '') : array();
282
			if(isset($champs_supplementaires[$id_obs])) {
283
				$ligne_supp = $this->traiterLigneEtendue($colonnes_supplementaires, $champs_supplementaires[$id_obs]);
284
			}
285
			$ligne += $ligne_supp;
1402 aurelien 286
			$indice = 0;
1617 aurelien 287
			foreach($ligne as &$champ) {
1402 aurelien 288
				$worksheet->write($nb_lignes,$indice,$champ);
289
				$indice++;
290
			}
291
			$nb_lignes++;
292
		}
293
		return $workbook;
294
	}
295
 
1662 aurelien 296
	private function convertirEnPdf(&$observations) {
297
		if(count($observations) > 300) die('trop de données');
298
		//require_once('GenerateurPDF.php');
299
		$pdf = new GenerateurPDF();
300
		$pdf->export($observations);
301
		return $pdf;
302
	}
303
 
304
	private function envoyerPdf(&$pdf) {
305
		$pdf->pdf->Output('etiquettes.pdf', 'I');
306
		exit;;
307
	}
308
 
1659 aurelien 309
	private function traiterLigneEtendue(&$colonnes_etendues, &$ligne_champs_etendus) {
310
		$ligne_etendue_aplatie = $this->aplatirChampsEtendus($ligne_champs_etendus);
311
		$ligne_etendue_fmt = array();
312
		foreach($colonnes_etendues as $colonne) {
313
			if(!isset($ligne_etendue_aplatie[$colonne])) {
314
				$ligne_etendue_fmt[$colonne] = '';
315
			} else {
316
				$ligne_etendue_fmt[$colonne] = $ligne_etendue_aplatie[$colonne];
317
			}
318
		}
319
		return $ligne_etendue_fmt;
320
	}
321
 
322
	private function aplatirChampsEtendus(&$ligne_champs_etendus) {
323
		$champs_etendus_fmt = array();
324
		foreach($ligne_champs_etendus as $champ) {
325
			$champs_etendus_fmt[$champ->cle] = $champ->valeur;
326
		}
327
		return $champs_etendus_fmt;
328
	}
329
 
1429 aurelien 330
	private function filtrerDonneesSensibles($ligne) {
331
		if(stripos($ligne['mots_cles_texte'], 'sensible') !== false) {
332
			$ligne['latitude'] = '';
333
			$ligne['longitude'] = '';
334
		}
335
		return $ligne;
336
	}
337
 
1401 aurelien 338
	private function nettoyerChaine($chaine) {
339
		$chaine = str_replace("\n",' ',$chaine);
340
		$chaine = str_replace("\t",'',$chaine);
341
		return $chaine;
342
	}
1654 aurelien 343
 
344
	private function doitEtPeutExporterObsPrivees($criteres) {
345
		return isset($criteres['ce_utilisateur']) &&
346
					$this->peutExporterObsPrivees($criteres['ce_utilisateur']);
347
	}
348
 
349
	private function peutExporterObsPrivees($id_utilisateur) {
350
		$gestion_utilisateur = new User($this->config);
351
		$utilisateur = $gestion_utilisateur->obtenirIdentiteConnectee();
352
		return $utilisateur['connecte'] &&
353
				$utilisateur['id_utilisateur'] != '' &&
354
				$id_utilisateur == $utilisateur['id_utilisateur'];
355
	}
1374 aurelien 356
}
357
?>