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 |