Subversion Repositories eFlore/Applications.cel

Compare Revisions

Ignore whitespace Rev 1635 → Rev 1636

/trunk/jrest/services/ImportXLS.php
New file
0,0 → 1,210
<?php
 
/**
* @category PHP
* @package jrest
* @author Raphaël Droz <raphael@tela-botania.org>
* @copyright 2013 Tela-Botanica
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
*/
 
/**
* Service d'import de données d'observation du CEL au format XLS
*/
 
// sont define()'d commme n° de colonne tous les slugs retournés par ExportXLS::fieldSetsToColumns()
// préfixés par C_ cf: detectionEntete()
 
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(dirname(realpath(__FILE__))) . '/lib');
// TERM
error_reporting(-1);
ini_set('html_errors', 0);
ini_set('xdebug.cli_color', 2);
require_once('lib/PHPExcel/Classes/PHPExcel.php');
require_once('ExportXLS.php');
 
class MyReadFilter implements PHPExcel_Reader_IReadFilter {
public $excludes = array();
public function __construct() {}
public function readCell($column, $row, $worksheetName = '') {
if(@$this->excludes[$column]) return false;
if($row == 1) return false;
return true;
}
}
 
class ImportXLS extends Cel {
 
static $ordre_BDD = Array(
"ce_utilisateur",
"prenom_utilisateur",
"nom_utilisateur",
"courriel_utilisateur",
"ordre",
"nom_sel",
"nom_sel_nn",
"nom_ret",
"nom_ret_nn",
"nt",
"famille",
"nom_referentiel",
"zone_geo",
"ce_zone_geo",
"date_observation",
"lieudit",
"station",
"milieu",
"commentaire",
"transmission",
"date_creation",
"date_modification",
"latitude",
"longitude");
 
function ExportXLS($config) {
parent::__construct($config);
}
 
function createElement($pairs) {
if(!isset($pairs['utilisateur']) || trim($pairs['utilisateur']) == '') {
echo '0'; exit;
}
if(!isset($_SESSION)) session_start();
$this->controleUtilisateur($pairs['utilisateur']);
 
$this->utilisateur = $this->getInfosComplementairesUtilisateur($pairs['utilisateur']);
 
$infos_fichier = array_pop($_FILES);
/*$objPHPExcel = PHPExcel_IOFactory::load($infos_fichier['tmp_name']);
$sheetData = $objPHPExcel->getActiveSheet()->toArray(NULL,FALSE,FALSE,TRUE);*/
 
/*$objReader = PHPExcel_IOFactory::createReader("Excel5");
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load($infos_fichier['tmp_name']);*/
 
//var_dump($sheetData);
 
$objReader = PHPExcel_IOFactory::createReader("Excel5");
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load($infos_fichier['tmp_name']);
$sheetData = $objPHPExcel->getActiveSheet()->toArray(NULL,FALSE,FALSE,TRUE);
 
$filterSubset = new MyReadFilter();
$filterSubset->excludes = self::detectionEntete($sheetData[1]);
$objReader->setReadFilter($filterSubset);
 
// recharge avec le filtre sur colonnes actif
// (exclue les colonnes inutiles/inutilisables)
$objPHPExcel = $objReader->load($infos_fichier['tmp_name']);
$sheetData = $objPHPExcel->getActiveSheet()->toArray(NULL,FALSE,FALSE,TRUE);
self::charger($sheetData);
}
 
static function detectionEntete($entete) {
$colonnes_reconnues = Array();
$cols = ExportXLS::fieldSetsToColumns('standard');
foreach($entete as $k => $v) {
$entete_simple = iconv('UTF-8', 'ASCII//TRANSLIT', strtolower(trim($v)));
foreach($cols as $col) {
$entete_officiel_simple = iconv('UTF-8', 'ASCII//TRANSLIT', strtolower(trim($col['nom'])));
$entete_officiel_slug = $col['slug'];
if($entete_simple == $entete_officiel_simple || $entete_simple == $entete_officiel_slug) {
define("C_" . strtoupper($entete_officiel_slug), $k);
$colonnes_reconnues[$k] = 1;
break;
}
}
}
 
// eg: 'I' => "rien"
$colonnesID_non_reconnues = array_diff_key($entete, $colonnes_reconnues);
 
$colonnes_automatiques = array_filter($cols, function($v) { return !$v['importable']; });
// ne conserve que le nom long pour matcher avec la ligne XLS d'entête
array_walk($colonnes_automatiques, function(&$v) { $v = $v['nom']; });
$colonnesID_a_exclure = array_intersect($entete, $colonnes_automatiques);
// TODO: pourquoi ne pas comparer avec les slugs aussi
 
return array_merge($colonnesID_non_reconnues, $colonnesID_a_exclure);
}
 
static function charger($donnees) {
// TODO: chunkfilter
$chunks = 30;
$i = 2;
$end = $i + $chunks;
while($i < $end && isset($donnees[$i])) {
$record = self::chargerLigne($donnees[$i]);
$req = implode(', ', self::sortArrayByArray($record, self::$ordre_BDD));
$i++;
}
}
 
// TODO: bouger les valeurs fixes comme valeurs de self::$ordre_BDD
// et compter sur un array_merge()
 
// TODO, théoriquement, l'ordre des index peut-être changé si nécessaire car
// nous utilisons self::sortArrayByArray()
static function chargerLigne($ligne) {
// en premier car le résultat est utile pour
// traiter longitude et latitude (traiterLonLat())
$referentiel = self::identReferentiel($ligne[C_REFERENTIEL]);
 
return Array(
"ce_utilisateur" => XXX,
"prenom_utilisateur" => XXX,
"nom_utilisateur" => XXX,
"courriel_utilisateur" => XXX,
"ordre" => YYY,
"nom_sel" => TODO,
"nom_sel_nn" => TODO,
"nom_ret" => TODO,
"nom_ret_nn" => TODO,
"nt" => TODO,
"famille" => TODO,
"nom_referentiel" => $referentiel,
"zone_geo" => TODO,
"ce_zone_geo" => TODO,
"date_observation" => self::traiterDateObs($ligne[C_DATE_OBSERVATION]),
"lieudit" => trim($ligne[C_LIEUDIT]),
"station" => trim($ligne[C_STATION]),
"milieu" => trim($ligne[C_MILIEU]),
"commentaire" => trim($ligne[C_COMMENTAIRE]),
 
// XXX: fixe
"transmission" => 0, // cf commentaire dans ExportXLS::fieldSetsToColumns()
"date_creation" => date("Y-m-d H:i:s"),
"date_modification" => date("Y-m-d H:i:s"),
 
"latitude" => self::traiterLonLat(NULL, $ligne[C_LATITUDE], $referentiel),
"longitude" => self::traiterLonLat($ligne[C_LONGITUDE], NULL, $referentiel)
);
}
 
static function traiterDateObs($date) {
return NULL; // TODO
}
 
static function identReferentiel($referentiel) {
return NULL; // TODO
}
 
static function traiterLonLat($lon = NULL, $lat = NULL, $referentiel = 'bdtfx:v1.01') {
// verifier format decimal +
// + limite france si bdtfx ou bdtxa
}
 
// http://stackoverflow.com/questions/348410/sort-an-array-based-on-another-array
static function sortArrayByArray($array,$orderArray) {
$ordered = array();
foreach($orderArray as $key) {
if(array_key_exists($key, $array)) {
$ordered[$key] = $array[$key];
unset($array[$key]);
}
}
return $ordered + $array;
}
}