Subversion Repositories eFlore/Applications.cel

Rev

Rev 1625 | Rev 1659 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?php
/**
* Service fournissant des informations concernant le CEL au format RSS1, RSS2 ou ATOM.
* Encodage en entrée : utf8
* Encodage en sortie : utf8
* Format du service :
* /CelWidgetExport/format
* /CelWidgetExport/csv
*
* Les paramêtres :
*  - "start" indique le numéro du premier item à afficher
*  - "limit" nombre d'items à afficher
*
* @author Aurélien Peronnet <aurelien@tela-botanica.org>
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
* @version $Id$
* @copyright 2012
*/

set_include_path(get_include_path() . PATH_SEPARATOR . dirname(dirname(realpath(__FILE__))) . '/lib');
// la sortie est binaire (xls), mais OLE n'est pas compatible E_ALL en PHP-5.4
//error_reporting(error_reporting() ^ E_STRICT);
require_once("lib/OLE.php");
require_once("lib/Spreadsheet/Excel/Writer.php");

class CelWidgetExport extends Cel {
        
        private $nom_fichier_export = 'cel_export';
        private $champs_a_exclure = array(
                'ce_utilisateur' => true, 
                'courriel_utilisateur' => true,
                'transmission' => true,
                'code_insee_calcule' => true);
        private $correspondance_champs = array(
                'id_observation' => 'Identifiant Observation',
                'ordre' => 'Ordre Observation',
                'prenom_utilisateur' => 'Prénom',
                'nom_utilisateur' => 'Nom',
                'nom_sel' => 'Nom Sélectionné',
                'nom_sel_nn' => 'Numéro Nomenclatural Nom Selectionné',
                'nom_ret' => 'Nom Retenu',
                'nom_ret_nn' => 'Numéro Nomenclatural Nom Retenu',
                'nt' => 'Numéro Taxonomique',
                'famille' => 'Famille',
                'nom_referentiel' => 'Référentiel Taxonomique',
                'ce_zone_geo' => 'Code Insee',
                'zone_geo' => 'Commune',
                'lieudit' => 'Lieu-Dit',
                'station' => 'Station',
                'milieu' => 'Milieu',
                'latitude' => 'Latitude',
                'longitude' => 'Longitude',
                'altitude' => 'Altitude',
                'geodatum' => 'Référentiel Géographique',
                'date_observation' => 'Date Observation',
                'mots_cles_texte' => 'Mots Clés',
                'commentaire' => 'Commentaires',
                'date_creation' => 'Date Création',
                'date_modification' => 'Date Modification',
                'date_transmission' => 'Date Transmission',
                'abondance' => 'Abondance',
                'certitude' => 'Certitude',
                'phenologie' => 'Phénologie'
                );
        private $parametres_autorises = array(
                'utilisateur' => 'courriel_utilisateur',
                'commune' => 'zone_geo',
                'dept' => 'departement',
                'projet' => 'mots_cles',
                'num_taxon' => 'nt',
                'date_debut' => 'date_debut',
                'date_fin' => 'date_fin',
                'taxon' => 'taxon',
                'debut' => 'debut',
                'limite' => 'limite',
                'format' => 'format'
        );
        
        private $limite_decoupage_defaut = 9000; 
        
        private $format = 'csv';
        
        public function getRessource() {
                return $this->getElement(array());
        }
                
        /**
         * Méthode appelée avec une requête de type GET.
         */
        public function getElement($params = array()) {         
                if(count($params) > 0) {
                        switch(strtolower($params[0])) {
                                case 'calcul':
                                        $this->getCalcul();
                                break;
                                
                                case 'export':
                                        $this->getExport();
                                break;
                                
                                default:
                                        $this->getExport();
                        }
                } else {
                        $this->getExport();
                }
        }
        
        private function getCalcul() {
                $criteres = $this->traiterParametresAutorises($_GET);
                // Seulement les observation publiques
                $criteres['transmission'] = 1;
                $chercheur_observations = new RechercheObservation($this->config);
                
                $numero_page = isset($criteres['debut']) ? $criteres['debut'] : 0;
                $limite = isset($criteres['limite']) ? $criteres['limite'] : 0;
                
                unset($criteres['limite']);
                unset($criteres['debut']);
                unset($criteres['format']);
                
                $nb_observations = $chercheur_observations->compterObservations(null, $criteres);
                $limite_decoupage = $this->calculerNbLignesMaxParFichier();
                
                $url_telechargements = array();
                $intervalle = 0;
                
                $params_url = $criteres;
                unset($params_url['transmission']);
                do {
                        $base_url = $this->config['settings']['baseURLAbsolu'].'CelWidgetExport/export';
                        $params_url['debut'] = $intervalle;
                        $params_url['limite'] = $limite_decoupage;
                        $url_telechargement_fichier = $base_url;
                        $url_telechargements[] = $base_url.'?'.http_build_query($params_url).'&format='.$this->format;
                        $intervalle += $limite_decoupage;
                        $nb_observations -= $limite_decoupage;
                } while($nb_observations >= $limite_decoupage);
                
                $this->envoyerJson($url_telechargements);
        }
        
        private function calculerNbLignesMaxParFichier() {
                $limite = $this->limite_decoupage_defaut;
                switch($this->format) {
                        case 'csv':
                                $limite = 20000;
                                break;
                        case 'xls':
                                $limite = 8000;
                                break;
                }
                return $limite;
        }
        
        private function getExport() {
                $criteres = $this->traiterParametresAutorises($_GET);

                // Seulement les observation publiques
                $criteres['transmission'] = 1;
                $chercheur_observations = new RechercheObservation($this->config);
                
                $debut = isset($criteres['debut']) ? $criteres['debut'] : 0;
                $limite = isset($criteres['limite']) ? $criteres['limite'] : 0;
                
                unset($criteres['limite']);
                unset($criteres['debut']);
                unset($criteres['format']);
                
                $observations = $chercheur_observations->rechercherObservations(null, $criteres, $debut, $limite)->get();
                switch($this->format) {
                        case 'csv':
                                $csv = $this->convertirEnCsv($observations);
                                $this->envoyerCsv($csv);
                                break;
                        case 'xls':
                                $xls = $this->convertirEnXls($observations);
                                $this->envoyerXls($xls);
                                break;
                        default:
                }
        }
        
        protected function traiterParametresAutorises(Array $parametres) {
                $parametres_traites = array();
                $this->format = (isset($parametres['format']) && $parametres['format'] != '') ? $parametres['format'] : $this->format;
                foreach($parametres as $cle => $valeur) {
                        if(trim($valeur) != '' && isset($this->parametres_autorises[$cle])) {
                                $parametres_traites[$this->parametres_autorises[$cle]] = $valeur;
                        }
                }
                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');
                echo $csv;
                exit;
        }
        
        private function envoyerXls($workbook) {
                $workbook->close();
                exit;
        }
        
        private function convertirEnCsv($data)
        {
                $chemin_temp = "php://temp";
                $outstream = fopen($chemin_temp, 'r+');
                $intitule_champs = array();
                foreach($data as &$ligne) {
                        $ligne = $this->filtrerDonneesSensibles($ligne);
                        $ligne = array_diff_key($ligne, $this->champs_a_exclure);
                        if(empty($intitule_champs)) {
                                $intitule_champs = $this->creerEntetesChamps($ligne);
                                fputcsv($outstream, $intitule_champs, ',', '"');                        
                        }
                        fputcsv($outstream, $ligne, ',', '"');
                }
                rewind($outstream);
                $csv = stream_get_contents($outstream);
                fclose($outstream);
                return $csv;
        }
        
        private function convertirEnXls($data) {                
                $this->extendSpreadsheetProductor = new SpreadsheetProductor();
                $this->extendSpreadsheetProductor->initSpreadsheet();
                
                $workbook = new Spreadsheet_Excel_Writer();
                $worksheet = $workbook->addWorksheet('Liste');
                $workbook->setTempDir($this->config['cel']['chemin_stockage_temp']);
                $workbook->setVersion(8);

                $worksheet->setInputEncoding('utf-8');
                $workbook->send($this->nom_fichier_export.'.xls');
                
                $nb_lignes = 1;
                                
                foreach($data as &$ligne) {
                        $ligne = $this->filtrerDonneesSensibles($ligne);
                        $ligne = array_diff_key($ligne, $this->champs_a_exclure);
                        if(empty($intitule_champs)) {
                                $intitule_champs = $this->creerEntetesChamps($ligne);
                                $indice = 0;
                                foreach ($intitule_champs as &$intitule) {      
                                        $colonne = $intitule_champs[$indice];
                                        $worksheet->write(0,$indice,$colonne);
                                        $indice++;
                                }
                        }
                        $indice = 0;
                        foreach($ligne as &$champ) {
                                $worksheet->write($nb_lignes,$indice,$champ);
                                $indice++;
                        }
                        $nb_lignes++;
                }
                return $workbook;
        }
        
        private function creerEntetesChamps($noms_colonnes) {
                $champs_presents = array_intersect_key($this->correspondance_champs, $noms_colonnes);
                return array_values($champs_presents);
        }
        
        private function filtrerDonneesSensibles($ligne) {
                if(stripos($ligne['mots_cles_texte'], 'sensible') !== false) {
                        $ligne['latitude'] = '';
                        $ligne['longitude'] = '';
                }
                return $ligne;
        }
        
        private function nettoyerChaine($chaine) {
                $chaine = str_replace("\n",' ',$chaine);
                $chaine = str_replace("\t",'',$chaine);
                return $chaine;
        }
}
?>