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; |
} |
} |