Subversion Repositories eFlore/Applications.cel

Rev

Rev 1638 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1636 raphael 1
<?php
2
 
3
/**
4
* @category  PHP
5
* @package   jrest
6
* @author    Raphaël Droz <raphael@tela-botania.org>
7
* @copyright 2013 Tela-Botanica
8
* @license   http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
9
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
10
*/
11
 
12
/**
13
 * Service d'import de données d'observation du CEL au format XLS
14
 */
15
 
16
// sont define()'d commme n° de colonne tous les slugs retournés par ExportXLS::fieldSetsToColumns()
17
// préfixés par C_  cf: detectionEntete()
18
 
19
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(dirname(realpath(__FILE__))) . '/lib');
20
// TERM
21
error_reporting(-1);
22
ini_set('html_errors', 0);
23
ini_set('xdebug.cli_color', 2);
24
require_once('lib/PHPExcel/Classes/PHPExcel.php');
25
require_once('ExportXLS.php');
26
 
27
class MyReadFilter implements PHPExcel_Reader_IReadFilter {
28
	public $excludes = array();
29
	public function __construct() {}
30
    public function readCell($column, $row, $worksheetName = '') {
31
		if(@$this->excludes[$column]) return false;
32
		if($row == 1) return false;
33
		return true;
34
    }
35
}
36
 
37
class ImportXLS extends Cel  {
38
 
39
	static $ordre_BDD = Array(
40
		"ce_utilisateur",
41
		"prenom_utilisateur",
42
		"nom_utilisateur",
43
		"courriel_utilisateur",
44
		"ordre",
45
		"nom_sel",
46
		"nom_sel_nn",
47
		"nom_ret",
48
		"nom_ret_nn",
49
		"nt",
50
		"famille",
51
		"nom_referentiel",
52
		"zone_geo",
53
		"ce_zone_geo",
54
		"date_observation",
55
		"lieudit",
56
		"station",
57
		"milieu",
58
		"commentaire",
59
		"transmission",
60
		"date_creation",
61
		"date_modification",
62
		"latitude",
63
		"longitude");
64
 
65
	function ExportXLS($config) {
66
		parent::__construct($config);
67
	}
68
 
69
	function createElement($pairs) {
70
		if(!isset($pairs['utilisateur']) || trim($pairs['utilisateur']) == '') {
71
			echo '0'; exit;
72
		}
73
		if(!isset($_SESSION)) session_start();
74
        $this->controleUtilisateur($pairs['utilisateur']);
75
 
76
        $this->utilisateur = $this->getInfosComplementairesUtilisateur($pairs['utilisateur']);
77
 
78
		$infos_fichier = array_pop($_FILES);
79
 
80
		/*$objPHPExcel = PHPExcel_IOFactory::load($infos_fichier['tmp_name']);
81
		  $sheetData = $objPHPExcel->getActiveSheet()->toArray(NULL,FALSE,FALSE,TRUE);*/
82
 
83
		/*$objReader = PHPExcel_IOFactory::createReader("Excel5");
84
		$objReader->setReadDataOnly(true);
85
		$objPHPExcel = $objReader->load($infos_fichier['tmp_name']);*/
86
 
87
		//var_dump($sheetData);
88
 
89
		$objReader = PHPExcel_IOFactory::createReader("Excel5");
90
		$objReader->setReadDataOnly(true);
91
		$objPHPExcel = $objReader->load($infos_fichier['tmp_name']);
92
		$sheetData = $objPHPExcel->getActiveSheet()->toArray(NULL,FALSE,FALSE,TRUE);
93
 
94
		$filterSubset = new MyReadFilter();
95
		$filterSubset->excludes = self::detectionEntete($sheetData[1]);
96
		$objReader->setReadFilter($filterSubset);
97
 
98
		// recharge avec le filtre sur colonnes actif
99
		// (exclue les colonnes inutiles/inutilisables)
100
		$objPHPExcel = $objReader->load($infos_fichier['tmp_name']);
101
		$sheetData = $objPHPExcel->getActiveSheet()->toArray(NULL,FALSE,FALSE,TRUE);
102
		self::charger($sheetData);
103
	}
104
 
105
	static function detectionEntete($entete) {
106
		$colonnes_reconnues = Array();
107
		$cols = ExportXLS::fieldSetsToColumns('standard');
108
		foreach($entete as $k => $v) {
109
			$entete_simple = iconv('UTF-8', 'ASCII//TRANSLIT', strtolower(trim($v)));
110
			foreach($cols as $col) {
111
				$entete_officiel_simple = iconv('UTF-8', 'ASCII//TRANSLIT', strtolower(trim($col['nom'])));
112
				$entete_officiel_slug = $col['slug'];
113
				if($entete_simple == $entete_officiel_simple || $entete_simple == $entete_officiel_slug) {
114
					define("C_" . strtoupper($entete_officiel_slug), $k);
115
					$colonnes_reconnues[$k] = 1;
116
					break;
117
				}
118
			}
119
		}
120
 
121
		// eg: 'I' => "rien"
122
		$colonnesID_non_reconnues = array_diff_key($entete, $colonnes_reconnues);
123
 
124
		$colonnes_automatiques = array_filter($cols, function($v) {	return !$v['importable']; });
125
		// ne conserve que le nom long pour matcher avec la ligne XLS d'entête
126
		array_walk($colonnes_automatiques, function(&$v) {	$v = $v['nom']; });
127
		$colonnesID_a_exclure = array_intersect($entete, $colonnes_automatiques);
128
		// TODO: pourquoi ne pas comparer avec les slugs aussi
129
 
130
		return array_merge($colonnesID_non_reconnues, $colonnesID_a_exclure);
131
	}
132
 
133
	static function charger($donnees) {
134
		// TODO: chunkfilter
135
		$chunks = 30;
136
		$i = 2;
137
		$end = $i + $chunks;
138
		while($i < $end && isset($donnees[$i])) {
139
			$record = self::chargerLigne($donnees[$i]);
140
			$req = implode(', ', self::sortArrayByArray($record, self::$ordre_BDD));
141
			$i++;
142
		}
143
	}
144
 
145
	// TODO: bouger les valeurs fixes comme valeurs de self::$ordre_BDD
146
	// et compter sur un array_merge()
147
 
148
	// TODO, théoriquement, l'ordre des index peut-être changé si nécessaire car
149
	// nous utilisons self::sortArrayByArray()
150
	static function chargerLigne($ligne) {
151
		// en premier car le résultat est utile pour
152
		// traiter longitude et latitude (traiterLonLat())
153
		$referentiel = self::identReferentiel($ligne[C_REFERENTIEL]);
154
 
155
		return Array(
156
			"ce_utilisateur" => XXX,
157
			"prenom_utilisateur" => XXX,
158
			"nom_utilisateur" => XXX,
159
			"courriel_utilisateur" => XXX,
160
			"ordre" => YYY,
161
			"nom_sel" => TODO,
162
			"nom_sel_nn" => TODO,
163
			"nom_ret" => TODO,
164
			"nom_ret_nn" => TODO,
165
			"nt" => TODO,
166
			"famille" => TODO,
167
			"nom_referentiel" => $referentiel,
168
			"zone_geo" => TODO,
169
			"ce_zone_geo" => TODO,
170
			"date_observation" => self::traiterDateObs($ligne[C_DATE_OBSERVATION]),
171
			"lieudit" => trim($ligne[C_LIEUDIT]),
172
			"station" => trim($ligne[C_STATION]),
173
			"milieu" => trim($ligne[C_MILIEU]),
174
			"commentaire" => trim($ligne[C_COMMENTAIRE]),
175
 
176
			// XXX: fixe
177
			"transmission" => 0, // cf commentaire dans ExportXLS::fieldSetsToColumns()
178
			"date_creation" => date("Y-m-d H:i:s"),
179
			"date_modification" => date("Y-m-d H:i:s"),
180
 
181
			"latitude" => self::traiterLonLat(NULL, $ligne[C_LATITUDE], $referentiel),
182
			"longitude" => self::traiterLonLat($ligne[C_LONGITUDE], NULL, $referentiel)
183
		);
184
	}
185
 
186
	static function traiterDateObs($date) {
187
		return NULL; // TODO
188
	}
189
 
190
	static function identReferentiel($referentiel) {
191
		return NULL; // TODO
192
	}
193
 
194
	static function traiterLonLat($lon = NULL, $lat = NULL, $referentiel = 'bdtfx:v1.01') {
195
		// verifier format decimal +
196
		// + limite france si bdtfx ou bdtxa
197
	}
198
 
199
	// http://stackoverflow.com/questions/348410/sort-an-array-based-on-another-array
200
	static function sortArrayByArray($array,$orderArray) {
201
		$ordered = array();
202
		foreach($orderArray as $key) {
203
			if(array_key_exists($key, $array)) {
204
				$ordered[$key] = $array[$key];
205
				unset($array[$key]);
206
			}
207
		}
208
		return $ordered + $array;
209
	}
210
}