Subversion Repositories eFlore/Applications.cel

Compare Revisions

Ignore whitespace Rev 3130 → Rev 3131

/trunk/jrest/services/CelWidgetExport.php
30,77 → 30,80
require_once 'lib/Spreadsheet/Excel/Writer.php';
 
class CelWidgetExport extends Cel {
 
private $nom_fichier_export = 'cel_export';
// certains paramètres apparaissent plusieurs fois car ils ont des alias
// dans certains widgets
private $parametres_autorises = array(
'id_utilisateur' => 'ce_utilisateur',
'utilisateur' => 'courriel_utilisateur',
'courriel_utilisateur' => 'courriel_utilisateur',
'pays' => 'pays',
'commune' => 'zone_geo',
'zone_geo' => 'zone_geo',
'dept' => 'departement',
'departement' => 'departement',
'lieudit' => 'lieudit',
'station' => 'station',
'projet' => 'mots_cles',
'num_taxon' => 'nt',
'date_debut' => 'date_debut',
'date_fin' => 'date_fin',
'taxon' => 'taxon',
'annee' => 'annee',
'mois' => 'mois',
'jour' => 'jour',
'recherche' => 'recherche',
'id_mots_cles' => 'id_mots_cles',
'mots_cles' => 'mots_cles',
'debut' => 'debut',
'limite' => 'limite',
'format' => 'format',
'colonnes' => 'colonnes',
'transmission' => 'transmission',
'obsids' => 'obsids',
'id_utilisateur' => 'ce_utilisateur',
'utilisateur' => 'courriel_utilisateur',
'courriel_utilisateur' => 'courriel_utilisateur',
'pays' => 'pays',
'commune' => 'zone_geo',
'zone_geo' => 'zone_geo',
'dept' => 'departement',
'departement' => 'departement',
'lieudit' => 'lieudit',
'station' => 'station',
'projet' => 'mots_cles',
'programme' => 'programme',
'num_taxon' => 'nt',
'date_debut' => 'date_debut',
'date_fin' => 'date_fin',
'taxon' => 'taxon',
'identiplante' => 'validation_identiplante',
'validation_identiplante' => 'validation_identiplante',
'annee' => 'annee',
'mois' => 'mois',
'jour' => 'jour',
'recherche' => 'recherche',
'id_mots_cles' => 'id_mots_cles',
'mots_cles' => 'mots_cles',
'debut' => 'debut',
'limite' => 'limite',
'format' => 'format',
'colonnes' => 'colonnes',
'transmission' => 'transmission',
'obsids' => 'obsids',
);
 
private $limite_decoupage_defaut = 9000;
 
private $format = 'csv';
 
public $id_utilisateur = null;
 
public $export_prive = false;
 
// un cache, initialisé par certaines fonctions de préchargement, à la manière
// de ce qui est fait par FormateurGroupeColonne
static $cache = Array();
 
public function getRessource() {
return $this->getElement(array());
}
 
/**
* Méthode appelée avec une requête de type GET.
*/
public function getElement($params = array()) {
switch(@strtolower($params[0])) {
case 'calcul':
$this->getCalcul();
break;
 
case 'export':
$this->getExport();
break;
default:
$this->getExport();
case 'calcul':
$this->getCalcul();
break;
case 'export':
$this->getExport();
break;
default:
$this->getExport();
}
}
 
private function getCalcul() {
$criteres = $this->traiterParametresAutorises($_GET);
$criteres['transmission'] = 1;
 
// Définit si l'on exporte les obs privées ainsi que les champs étendus privés
$this->export_prive = $this->doitEtPeutExporterObsPrivees($criteres);
if($this->export_prive) {
107,23 → 110,22
unset($criteres['transmission']);
$this->id_utilisateur = $criteres['id_utilisateur'];
}
$chercheur_observations = new RechercheObservation($this->config);
 
$chercheur_observations = new RechercheObservationExport($this->config);
$numero_page = isset($criteres['debut']) ? $criteres['debut'] : 0;
$limite = isset($criteres['limite']) ? $criteres['limite'] : 0;
$colonnes = @FormateurGroupeColonne::colGroupsValidation($criteres['colonnes']);
 
unset($criteres['limite']);
unset($criteres['debut']);
unset($criteres['format']);
unset($criteres['colonnes']);
 
$nb_observations = $chercheur_observations->compterObservations(null, $criteres);
$limite_decoupage = $this->calculerNbLignesMaxParFichier(explode(',', $colonnes));
 
$url_telechargements = array();
$intervalle = 0;
 
$params_url = $criteres;
unset($params_url['transmission']);
do {
135,13 → 137,13
$intervalle += $limite_decoupage;
$nb_observations -= $limite_decoupage;
} while($nb_observations > 0);
 
$this->envoyerJson($url_telechargements);
}
 
private function calculerNbLignesMaxParFichier($colonnes) {
$limite = $this->limite_decoupage_defaut;
 
switch($this->format) {
case 'csv':
$limite = 20000;
153,10 → 155,10
$limite = 300;
break;
}
 
return $limite;
}
 
private function getExport() {
$criteres = $this->traiterParametresAutorises($_GET);
// ne pas faire de super-requête en cas d'absence de paramètres
163,75 → 165,75
// par exemple "format", au minimum, devrait être défini
if(!$criteres) die('erreur: pas de paramètre reçu');
if(!in_array($this->format, array('pdf','csv','xls'))) die('erreur: format invalide');
 
$criteres['transmission'] = 1;
//$criteres['transmission'] = 1;
// Définit si l'on exporte les obs privées ainsi que les champs étendus privés
$this->export_prive = $this->doitEtPeutExporterObsPrivees($criteres);
if($this->export_prive) {
unset($criteres['transmission']);
//unset($criteres['transmission']);
$this->id_utilisateur = $criteres['ce_utilisateur'];
}
$chercheur_observations = new RechercheObservation($this->config);
 
$chercheur_observations = new RechercheObservationExport($this->config);
$debut = isset($criteres['debut']) ? intval($criteres['debut']) : 0;
$limite = isset($criteres['limite']) ? intval($criteres['limite']) : 0;
$groupes = @FormateurGroupeColonne::colGroupsValidation($criteres['colonnes']);
$groupes .= ',auteur';
 
if(!$groupes) die('erreur: Ne peut identifier les groupes de champs demandés.');
 
 
if($criteres['obsids']) $criteres['sql_brut'] = sprintf('id_observation IN (%s)',
implode(',', $criteres['obsids']));
 
implode(',', $criteres['obsids']));
unset($criteres['limite']);
unset($criteres['debut']);
unset($criteres['format']);
unset($criteres['colonnes']);
unset($criteres['obsids']);
 
$observations = $chercheur_observations->rechercherObservations(null, $criteres, $debut, $limite, TRUE)->get();
$ids = array();
foreach($observations as &$obs) {
$ids[] = $obs['id_observation'];
}
 
if($this->format == 'pdf') {
$pdf = $this->convertirEnPdf($observations);
$pdf->pdf->Output('etiquettes.pdf', 'I');
exit;
}
 
// cas XLS et CSV: on peut avoir besoin des champs étendus, des noms communs et des champs baseflor:
 
// Obtention des colonnes correspondantes aux groupes de champs
$colonnes = FormateurGroupeColonne::nomEnsembleVersListeColonnes($groupes);
 
/*
Champs étendus et noms communs, si demandés.
* Pour "nom commun", "preload" retourne NULL, car c'est le cache statique de FormateurGroupeColonne
qu'il initialise et utilise en interne sans qu'un passage par paramètre dans le contexte de CelWidgetExport
ne soit nécessaire.
* Pour les champs étendus, c'est CelWidgetExport::$cache qui est utilisé, aussi bien pour les en-têtes que
pour les données préchargées, cf self::traiterLigneEtendue()
*/
Champs étendus et noms communs, si demandés.
* Pour "nom commun", "preload" retourne NULL, car c'est le cache statique de FormateurGroupeColonne
qu'il initialise et utilise en interne sans qu'un passage par paramètre dans le contexte de CelWidgetExport
ne soit nécessaire.
* Pour les champs étendus, c'est CelWidgetExport::$cache qui est utilisé, aussi bien pour les en-têtes que
pour les données préchargées, cf self::traiterLigneEtendue()
*/
self::$cache = FormateurGroupeColonne::preload($colonnes, $this, $ids);
 
// TODO: tous les champs étendus et les paramètres supplémentaires devraient être passés en un seul
// tableau (et chaque formateur csv, xls etc... pourrait également être dans une classe à part)
// TODO: tous les champs étendus et les paramètres supplémentaires devraient être passés en un seul
// tableau (et chaque formateur csv, xls etc... pourrait également être dans une classe à part)
switch($this->format) {
case 'csv':
$csv = $this->convertirEnCsv($observations, $colonnes);
$this->envoyerCsv($csv);
break;
case 'xls':
$xls = $this->convertirEnXls($observations, $colonnes);
$this->envoyerXls($xls);
break;
default:
case 'csv':
$csv = $this->convertirEnCsv($observations, $colonnes);
$this->envoyerCsv($csv);
break;
case 'xls':
$xls = $this->convertirEnXls($observations, $colonnes);
$this->envoyerXls($xls);
break;
default:
}
}
 
protected function traiterParametresAutorises(Array $parametres) {
$parametres_traites = array();
$this->format = (isset($parametres['format']) && $parametres['format'] != '') ? $parametres['format'] : $this->format;
244,7 → 246,7
$parametres_traites['obsids'] = @self::traiterObsIds($parametres['obsids']);
return $parametres_traites;
}
 
private function envoyerCsv($csv) {
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment;filename='.$this->nom_fichier_export.'.csv');
251,16 → 253,16
echo $csv;
exit;
}
 
private function envoyerXls($workbook) {
$workbook->close();
exit;
}
 
private function convertirEnCsv(&$data, $colonnes) {
$chemin_temp = "php://temp";
$outstream = fopen($chemin_temp, 'r+');
 
$intitule_champs = array_merge(FormateurGroupeColonne::getIntitulesColonnes($colonnes));
// en premier car utilisé génériquement dans getLigneObservation()
if(isset($colonnes['baseflor'])) {
270,7 → 272,7
if(isset($colonnes['etendu'])) {
$intitule_champs = array_merge($intitule_champs, array_values(self::$cache['etendu']['header']));
}
 
// header
fputcsv($outstream, $intitule_champs, ',', '"');
// lignes
284,22 → 286,22
fclose($outstream);
return $csv;
}
 
private function convertirEnXls(&$data, $colonnes) {
$this->extendSpreadsheetProductor = new SpreadsheetProductor();
$this->extendSpreadsheetProductor->initSpreadsheet();
 
$workbook = new Spreadsheet_Excel_Writer();
// avant la définition du titre de la worksheet !
$workbook->setVersion(8);
 
$worksheet = $workbook->addWorksheet('Liste');
$workbook->setTempDir($this->config['cel']['chemin_stockage_temp']);
$worksheet->setInputEncoding('utf-8');
$workbook->send($this->nom_fichier_export.'.xls');
 
$nb_lignes = 1;
 
$intitule_champs = array_merge(FormateurGroupeColonne::getIntitulesColonnes($colonnes));
// en premier car utilisé génériquement dans getLigneObservation()
if(isset($colonnes['baseflor'])) {
309,13 → 311,13
if(isset($colonnes['etendu'])) {
$intitule_champs = array_merge($intitule_champs, array_values(self::$cache['etendu']['header']));
}
 
// header
$indice = 0;
foreach ($intitule_champs as &$intitule) {
$worksheet->write(0,$indice++,$intitule);
}
 
foreach($data as &$ligne) {
$ligne = self::filtrerDonneesSensibles($ligne);
$ligne = FormateurGroupeColonne::getLigneObservation($ligne, $colonnes, $this);
327,7 → 329,7
}
return $workbook;
}
 
private function convertirEnPdf(&$observations) {
if(count($observations) > 300) die('erreur: trop de données');
//require_once('GenerateurPDF.php');
335,7 → 337,7
$pdf->export($observations);
return $pdf;
}
 
static function filtrerDonneesSensibles($ligne) {
if(stripos($ligne['mots_cles_texte'], 'sensible') !== false) {
$ligne['latitude'] = '';
343,18 → 345,18
}
return $ligne;
}
 
private function doitEtPeutExporterObsPrivees($criteres) {
return isset($criteres['ce_utilisateur']) &&
$this->peutExporterObsPrivees($criteres['ce_utilisateur']);
$this->peutExporterObsPrivees($criteres['ce_utilisateur']);
}
 
private function peutExporterObsPrivees($id_utilisateur) {
$gestion_utilisateur = new GestionUtilisateur($this->config);
$utilisateur = $gestion_utilisateur->obtenirIdentiteConnectee();
return ! empty($utilisateur['id_utilisateur']) && $id_utilisateur == $utilisateur['id_utilisateur'];
}
 
static function traiterObsIds($range_param) {
if (!isset($range_param)) return NULL;
// trim() car: `POST http://url<<<"range=*"`
361,7 → 363,7
if (trim($range_param) == '*') return NULL;
return self::rangeToList(trim($range_param));
}
 
/*
* @param $fieldSets: un range, eg: 1-5,8,32,58-101
* @return un tableau trié, eg: 1,2,3,4,5,8,32,58,...,101
370,7 → 372,7
static function rangeToList($in = '') {
$inSets = explode(',', trim($in, ','));
$outSets = array();
 
foreach($inSets as $inSet) {
list($start,$end) = explode('-', $inSet . '-' . $inSet);
// ignore les ranges trop importants