Subversion Repositories eFlore/Applications.coel

Rev

Rev 1856 | Rev 1862 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1856 Rev 1857
1
<?php
1
<?php
2
/**
2
/**
3
 * Exemple lancement:
3
 * Exemple lancement:
4
 * /opt/lampp/bin/php -d memory_limit=3500M cli.php import -n
4
 * /opt/lampp/bin/php -d memory_limit=3500M cli.php import -n
5
 */
5
 */
6
class Import extends Script {
6
class Import extends Script {
7
	private $bdd = null;
7
	private $bdd = null;
8
	private $auteurs = array();
8
	private $auteurs = array();
9
	protected $parametres_autorises = array(
9
	protected $parametres_autorises = array(
10
			'-n' => array(true, false, 'Nom du fichier à importer.'));
10
			'-n' => array(true, false, 'Nom du fichier à importer.'));
-
 
11
	
-
 
12
	protected $table_publication = null;
-
 
13
	protected $table_auteur = null;
11
	
14
	
12
	protected $colonnes_obligatoires = array();
15
	protected $colonnes_obligatoires = array();
13
	protected $colonnes_acceptees = array();
16
	protected $colonnes_acceptees = array();
14
	
17
	
15
	protected $cache_auteur = array();
18
	protected $cache_auteur = array();
16
	
19
	
17
	public function __construct($script_nom, $parametres) {
20
	public function __construct($script_nom, $parametres) {
18
		parent::__construct($script_nom, $parametres);
21
		parent::__construct($script_nom, $parametres);
19
		$this->bdd = new Bdd();
22
		$this->bdd = new Bdd();
20
	}
23
	}
21
	
24
	
22
	public function executer() {
25
	public function executer() {
23
		try {
26
		try {
24
			$this->initialiserScript();
27
			$this->initialiserScript();
25
			$cmd = $this->getParametre('a');
28
			$cmd = $this->getParametre('a');
26
			$fichier = $this->getParametre('n');
29
			$fichier = $this->getParametre('n');
27
			switch ($cmd) {
30
			switch ($cmd) {
28
				case "import" :
31
				case "import" :
29
					//testerauteur
-
 
30
					$this->charger($fichier); break;
32
					$resultat = $this->charger($fichier); break;
31
				default :
33
				default :
32
					$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
34
					$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
33
			}
35
			}
34
		} catch (Exception $erreur) {
36
		} catch (Exception $erreur) {
35
			$this->traiterErreur($erreur->getMessage());
37
			$this->traiterErreur($erreur->getMessage());
36
		}
38
		}
-
 
39
		
-
 
40
		// renvoi du résultat vers la sortie php
-
 
41
		echo $resultat;
37
	}
42
	}
38
	
43
	
39
	private function initialiserScript() {
44
	private function initialiserScript() {
40
		$fichierIni = $this->getScriptChemin().'import.ini';
45
		$fichierIni = $this->getScriptChemin().'import.ini';
41
		if (file_exists($fichierIni)) {
46
		if (file_exists($fichierIni)) {
42
			Config::charger($fichierIni);
47
			Config::charger($fichierIni);
43
		} else {
48
		} else {
44
			$erreur = "Veuillez configurer le projet en créant le fichier 'import.ini' ".
49
			$erreur = "Veuillez configurer le projet en créant le fichier 'import.ini' ".
45
					"dans le dossier du module de script du projet à partir du fichier 'import.defaut.ini'.";
50
					"dans le dossier du module de script du projet à partir du fichier 'import.defaut.ini'.";
46
			throw new Exception($erreur);
51
			throw new Exception($erreur);
47
		}
52
		}
48
		
53
		
49
		$this->colonnes_obligatoires= Config::get('champs_obligatoires');
54
		$this->colonnes_obligatoires= Config::get('champs_obligatoires');
50
		$this->colonnes_acceptees = Config::get('champs');
55
		$this->colonnes_acceptees = Config::get('champs');
-
 
56
		
-
 
57
		$tables = Config::get('tables');
-
 
58
		$this->table_publication = $tables['publication'];
-
 
59
		$this->table_auteur = $tables['auteur'];
51
	}
60
	}
52
 
61
 
53
	private function charger($fichier) {
62
	private function charger($fichier) {
54
		
63
		
55
		// vérification existence fichier
64
		// vérification existence fichier
56
		if(!file_exists(Config::get('dossiertmp').$fichier)) {
65
		if(!file_exists(Config::get('dossiertmp').$fichier)) {
57
			$erreur = "Le fichier ".Config::get('dossiertmp').$fichier." n'existe pas.";
66
			$erreur = "Le fichier ".Config::get('dossiertmp').$fichier." n'existe pas.";
58
			throw new Exception($erreur);
67
			throw new Exception($erreur);
59
		}
68
		}
60
		
69
		
61
		$pointeur = fopen(Config::get('dossiertmp').$fichier, "r");
70
		$pointeur = fopen(Config::get('dossiertmp').$fichier, "r");
62
		// Chargement de la première colonne (qui contient les noms de colonnes à importer
71
		// Chargement de la première colonne (qui contient les noms de colonnes à importer
63
		$colonnes = fgetcsv($pointeur, 0, ";");
72
		$colonnes = fgetcsv($pointeur, 0, ";");
64
 
73
 
65
		// Vérification des colonnes obligatoires et en même temps du séparateur 
74
		// Vérification des colonnes obligatoires et en même temps du séparateur 
66
		if(count($colonnes) < 2 || !array_intersect(array_keys($this->colonnes_obligatoires), $colonnes)) {
75
		if(count($colonnes) < 2 || !array_intersect(array_keys($this->colonnes_obligatoires), $colonnes)) {
67
			$erreur = "Le fichier ne contient pas les colonnes obligatoires : ".implode(',', array_keys($this->colonnes_obligatoires))."\n";
76
			$erreur = "Le fichier ne contient pas les colonnes obligatoires : ".implode(',', array_keys($this->colonnes_obligatoires))."\n";
68
			$erreur .= "ou bien n'est pas séparé par le caractère ';' ";
77
			$erreur .= "ou bien n'est pas séparé par le caractère ';' ";
69
			throw new Exception($erreur);
78
			throw new Exception($erreur);
70
		}
79
		}
71
		
80
		
72
		$index_colonnes_importees = array_intersect(array_keys($this->colonnes_acceptees), $colonnes);
81
		$index_colonnes_importees = array_intersect(array_keys($this->colonnes_acceptees), $colonnes);
73
		$colonnes_importees = array();
82
		$colonnes_importees = array();
74
		foreach($index_colonnes_importees as $index_colonne_importee) {
83
		foreach($index_colonnes_importees as $index_colonne_importee) {
75
			$colonnes_importees[] = $this->colonnes_acceptees[$index_colonne_importee];
84
			$colonnes_importees[] = $this->colonnes_acceptees[$index_colonne_importee];
76
		}
85
		}
77
		
86
		
78
		$index_colonnes_refusees = array_keys(array_diff($colonnes, array_keys($this->colonnes_acceptees)));
87
		$index_colonnes_refusees = array_keys(array_diff($colonnes, array_keys($this->colonnes_acceptees)));
79
		// Création d'un index associant chaque numéro de colonne importée à son rôle
88
		// Création d'un index associant chaque numéro de colonne importée à son rôle
80
		// pour y apporter des traitement spécifiques
89
		// pour y apporter des traitement spécifiques
81
		$index_colonnes_importees = $colonnes;
90
		$index_colonnes_importees = $colonnes;
82
		foreach($index_colonnes_refusees as $colonne_refusee) {
91
		foreach($index_colonnes_refusees as $colonne_refusee) {
83
			unset($index_colonnes_importees[$colonne_refusee]);
92
			unset($index_colonnes_importees[$colonne_refusee]);
84
		}
93
		}
85
 
94
 
86
		$lignes = array();
95
		$lignes = array();
87
		while($ligne = fgetcsv($pointeur, 0, ";")) {
96
		while($ligne = fgetcsv($pointeur, 0, ";")) {
88
			$ligne_inseree = array();
97
			$ligne_inseree = array();
89
			foreach($ligne as $index => &$valeur) {
98
			foreach($ligne as $index => &$valeur) {
90
				if(!in_array($index, $index_colonnes_refusees)) {
99
				if(!in_array($index, $index_colonnes_refusees)) {
91
					$ligne_inseree[] = $this->traiterChamp($valeur, $index_colonnes_importees[$index]);
100
					$ligne_inseree[] = $this->traiterChamp($valeur, $index_colonnes_importees[$index]);
92
				}
101
				}
93
			}
102
			}
94
			// Ajout du nom complet formaté de la publication
103
			// Ajout du nom complet formaté de la publication
95
			$ligne_inseree[] = $this->formaterNomComplet($ligne, $index_colonnes_importees);
104
			$ligne_inseree[] = $this->bdd->proteger($this->formaterNomComplet($ligne, $index_colonnes_importees));
96
			$lignes[] = "(".implode(",", $ligne_inseree).")";
105
			$lignes[] = "(".implode(",", $ligne_inseree).")";
97
		}
106
		}
98
		
107
		
99
		// Ajout de la colonne nom complet aux champs de la requête
108
		// Ajout de la colonne nom complet aux champs de la requête
100
		$colonnes_importees[] = 'cpu_fmt_nom_complet';
109
		$colonnes_importees[] = 'cpu_fmt_nom_complet';
-
 
110
		
-
 
111
		// le script renvoie le nombre de publications importées
101
		$this->insererPublications($colonnes_importees, $lignes);
112
		return $this->insererPublications($colonnes_importees, $lignes);
102
	}
113
	}
103
	
114
	
104
	protected function formaterNomComplet($ligne, $roles) {
115
	protected function formaterNomComplet($ligne, $roles) {
-
 
116
		
-
 
117
		$roles = array_flip($roles);
-
 
118
		
-
 
119
		// Intitulé de la publication complet : fmt_auteur, date_parution(année). titre. Editeur (nom), collection, fascicule, indication_nvt. pages.
105
		// TODO: écrire la fonction
120
		// indication_nvt = serie_tome 
-
 
121
		$champs_nom_complet = array('auteur', 'annee', 'titre', 'editeur', 'intitule_revue', 'fascicule', 'serie_tome', 'pages');
-
 
122
		$champs_fmt = array();
-
 
123
		
-
 
124
		$fmt_nom_complet = "";
-
 
125
		
-
 
126
		foreach($champs_nom_complet as $champ) {
-
 
127
			$index = $roles[$champ];
-
 
128
			if(!isset($ligne[$index])) {				
-
 
129
				$champs_fmt[$champ] = "";
-
 
130
			} else {
-
 
131
				$champs_fmt[$champ] = $ligne[$index];
-
 
132
			}
-
 
133
		}
-
 
134
		
-
 
135
		$indication_nvt_pages = array($champs_fmt['serie_tome'], $champs_fmt['pages']);
-
 
136
		$indication_nvt_pages = array_filter($indication_nvt_pages, 'strlen');
-
 
137
		$indication_nvt_pages = trim(implode(". ", $indication_nvt_pages));
-
 
138
		$indication_nvt_pages .= !empty($indication_nvt_pages) ? "." : "";
-
 
139
		
-
 
140
		$annee_titre_editeur = array($champs_fmt['annee'], $champs_fmt['titre'], $champs_fmt['editeur']);
-
 
141
		$annee_titre_editeur = array_filter($annee_titre_editeur, 'strlen');
-
 
142
		$annee_titre_editeur = trim(implode(". ", $annee_titre_editeur));
-
 
143
		
-
 
144
		$fmt_nom_complet =  array($champs_fmt['auteur'], 
-
 
145
							$annee_titre_editeur, 
-
 
146
							$champs_fmt['intitule_revue'],
-
 
147
							$champs_fmt['fascicule'],
-
 
148
							$indication_nvt_pages);
-
 
149
		
-
 
150
		$fmt_nom_complet = array_filter($fmt_nom_complet, 'strlen');
-
 
151
		$fmt_nom_complet = implode(", ", $fmt_nom_complet);
-
 
152
		
106
		return 'aaaaa';
153
		return $fmt_nom_complet;
107
	}
154
	}
108
	
155
	
109
	private function insererPublications(&$colonnes, &$publications) {
156
	private function insererPublications(&$colonnes, &$publications) {
110
		$requete = "INSERT INTO $table ".
157
		$requete = "INSERT INTO ".$this->table_publication." ".
111
				   	"(".implode(',', $colonnes).") ".
158
				   	"(".implode(',', $colonnes).") ".
112
				   "VALUES ".implode(","."\n", $publications)."\n";
159
				   "VALUES ".implode(","."\n", $publications)."\n";
113
		
160
		
114
		echo $requete;exit;
161
		return $this->bdd->executer($requete);
115
	}
162
	}
116
	
163
	
117
	private function traiterChamp($valeur, $role) {
164
	private function traiterChamp($valeur, $role) {
118
		switch($role) {
165
		switch($role) {
119
			case 'auteur':
166
			case 'auteur':
120
				$valeur = $this->obtenirInfosAuteur($valeur);
167
				$valeur = $this->obtenirInfosAuteur($valeur);
121
			break;
168
			break;
122
			case 'editeur':
169
			case 'editeur':
123
				$valeur = 'AUTRES##'.$valeur;
170
				$valeur = 'AUTRES##'.$valeur;
124
			break;
171
			break;
125
		}
172
		}
126
		
173
		
127
		return $this->bdd->proteger($valeur);
174
		return $this->bdd->proteger($valeur);
128
	}
175
	}
129
	
176
	
130
	private function obtenirInfosAuteur($auteur) {
177
	private function obtenirInfosAuteur($auteur_intitule) {
131
		$retour = $auteur;
178
		$retour = $auteur_intitule;
-
 
179
		if(isset($this->cache_auteur[$auteur_intitule])) {
-
 
180
			$retour = !empty($this->cache_auteur[$auteur_intitule]['cp_id_personne']) ?
132
		if(isset($cache_auteur[$auteur])) {
181
				$this->cache_auteur[$auteur_intitule]['cp_id_personne'] :
133
			$retour = $cache_auteur[$auteur];
182
				$this->cache_auteur[$auteur_intitule];
134
		} else {
183
		} else {
135
			$auteur = $this->fabriquerCombinaisonsAuteur($auteur);
184
			$auteur = $this->fabriquerCombinaisonsAuteur($auteur_intitule);
136
			$auteur_req = "(".implode(', ', $auteur).")";
185
			$auteur_req = "(".implode(', ', $auteur).")";
137
			
186
			
138
			$requete = "SELECT cp_id_personne FROM coel_personne WHERE cp_fmt_nom_complet IN ".$auteur_req;
187
			$requete = "SELECT cp_id_personne, cp_fmt_nom_complet FROM ".$this->table_auteur." WHERE cp_fmt_nom_complet IN ".$auteur_req;
139
			$infos_auteur = $this->bdd->recupererTous($requete);
188
			$infos_auteur = $this->bdd->recupererTous($requete);
140
			
189
			
141
			if(!empty($infos_auteur)) {
190
			if(!empty($infos_auteur)) {
142
				$retour = $infos_auteur[0]['cp_id_personne'];
191
				$retour = $infos_auteur[0]['cp_id_personne'];
143
				$cache_auteur[$auteur] = $infos_auteur[0]['cp_id_personne'];
192
				$this->cache_auteur[$auteur_intitule] = $infos_auteur[0];
144
			} else {
193
			} else {
-
 
194
				$retour = $auteur_intitule;
145
				$cache_auteur[$auteur] = $auteur;
195
				$this->cache_auteur[$auteur_intitule] = $auteur_intitule;
146
			}
196
			}
147
		}
197
		}
148
		
198
		
149
		return $retour;
199
		return $retour;
150
	}
200
	}
151
			
201
			
152
	private function fabriquerCombinaisonsAuteur($auteur) {
202
	private function fabriquerCombinaisonsAuteur($auteur) {
153
		
203
		
154
		$auteur = trim($auteur);
204
		$auteur = trim($auteur);
155
		$auteurs_formates = array($this->bdd->proteger($auteur));
205
		$auteurs_formates = array($this->bdd->proteger($auteur));
156
		
206
		
157
		// Séparation des élements de l'auteur des espaces pour obtenir
207
		// Séparation des élements de l'auteur des espaces pour obtenir
158
		// les noms et prénoms (Ex. "Carl Von Linné" => "Carl", "Von", "Linné")
208
		// les noms et prénoms (Ex. "Carl Von Linné" => "Carl", "Von", "Linné")
159
		$auteur_tab = explode(' ', $auteur);
209
		$auteur_tab = explode(' ', $auteur);
160
		$auteur_tab = array_filter($auteur_tab);
210
		$auteur_tab = array_filter($auteur_tab);
161
		
211
		
162
		$combinaisons = array();
212
		$combinaisons = array();
163
		foreach($auteur_tab as &$element_auteur) {
213
		foreach($auteur_tab as &$element_auteur) {
164
			$combinaisons[] = array(
214
			$combinaisons[] = array(
165
								// élement tel quel (Ex: "Linné")
215
								// élement tel quel (Ex: "Linné")
166
								$element_auteur,
216
								$element_auteur,
167
								// possibilité de l'initiale seule (Ex: "L")
217
								// possibilité de l'initiale seule (Ex: "L")
168
								substr($element_auteur, 0, 1),
218
								substr($element_auteur, 0, 1),
169
								// possibilité de l'initiale avec un point du genre (Ex: "L.")
219
								// possibilité de l'initiale avec un point du genre (Ex: "L.")
170
								substr($element_auteur, 0, 1)."."
220
								substr($element_auteur, 0, 1)."."
171
							);
221
							);
172
		}
222
		}
173
		
223
		
174
		// Fabrication de toutes les combinaisons possibles des parties de noms ci-dessus 
224
		// Fabrication de toutes les combinaisons possibles des parties de noms ci-dessus 
175
		// pour deux et trois élements en faisant plusieurs produits cartésiens
225
		// pour deux et trois élements en faisant plusieurs produits cartésiens
176
		// car le nom peut être combiné différement de celui en base de données
226
		// car le nom peut être combiné différement de celui en base de données
177
		// (Ex. : "Carl Von Linné" VS "C. Von Linné" ou "C. V. Linné" ou encore "Von Linné C." etc...)
227
		// (Ex. : "Carl Von Linné" VS "C. Von Linné" ou "C. V. Linné" ou encore "Von Linné C." etc...)
178
		
228
		
179
		// C'est moche et pas très élégant mais bon ça marche dans 90% des cas
229
		// C'est moche et pas très élégant mais bon ça marche dans 90% des cas
180
		// On ne teste pas plus que 3 combinaisons, car ça serait très très couteux
230
		// On ne teste pas plus que 3 combinaisons, car ça serait très très couteux
181
		// TODO: faire mieux et factoriser les appels ci dessous
231
		// TODO: faire mieux et factoriser les appels ci dessous
182
		if(count($auteur_tab) > 2) {
232
		if(count($auteur_tab) > 2) {
183
			// Cas du nom à trois parties (genre "Carl Von Linné")
233
			// Cas du nom à trois parties (genre "Carl Von Linné")
184
			$possibilites_auteurs = $this->cartesian(array($combinaisons[0], $combinaisons[1], $combinaisons[2]));
234
			$possibilites_auteurs = $this->cartesian(array($combinaisons[0], $combinaisons[1], $combinaisons[2]));
185
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[0], $combinaisons[2], $combinaisons[1])));
235
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[0], $combinaisons[2], $combinaisons[1])));
186
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[1], $combinaisons[2], $combinaisons[0])));
236
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[1], $combinaisons[2], $combinaisons[0])));
187
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[1], $combinaisons[0], $combinaisons[2])));
237
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[1], $combinaisons[0], $combinaisons[2])));
188
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[2], $combinaisons[1], $combinaisons[0])));
238
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[2], $combinaisons[1], $combinaisons[0])));
189
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[2], $combinaisons[0], $combinaisons[1])));
239
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[2], $combinaisons[0], $combinaisons[1])));
190
		} else {
240
		} else {
191
			// Cas du nom à trois parties (genre "Carl Linné")
241
			// Cas du nom à trois parties (genre "Carl Linné")
192
			$possibilites_auteurs = $this->cartesian(array($combinaisons[0], $combinaisons[1]));
242
			$possibilites_auteurs = $this->cartesian(array($combinaisons[0], $combinaisons[1]));
193
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[1], $combinaisons[0])));
243
			$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[1], $combinaisons[0])));
194
		}
244
		}
195
		// Elimination d'éventuels doublons	
-
 
196
		array_unique($possibilites_auteurs);	
-
 
197
		
245
		
198
		$auteurs_formates = array();
246
		$auteurs_formates = array();
199
		foreach($possibilites_auteurs as &$possibilite) {
247
		foreach($possibilites_auteurs as &$possibilite) {
200
			$initiales = true;
248
			$initiales = true;
201
			// Suppression des possibilités ne contenant que des initiales avec ou sans point
249
			// Suppression des possibilités ne contenant que des initiales avec ou sans point
202
			foreach($possibilite as &$chars) {
250
			foreach($possibilite as &$chars) {
203
				$initiales = $initiales && mb_strlen($chars) <= 2;
251
				$initiales = $initiales && mb_strlen($chars) <= 2;
204
			}
252
			}
205
 
253
 
206
			if(!$initiales) {
254
			if(!$initiales) {
207
				$auteurs_formates[] = $this->bdd->proteger(implode(" ", $possibilite));
255
				$auteurs_formates[] = $this->bdd->proteger(implode(" ", $possibilite));
208
			}
256
			}
209
		}
257
		}
210
 
258
 
211
		return $auteurs_formates;
259
		return $auteurs_formates;
212
	}
260
	}
213
 
261
 
214
	// http://stackoverflow.com/questions/6311779/finding-cartesian-product-with-php-associative-arrays
262
	// http://stackoverflow.com/questions/6311779/finding-cartesian-product-with-php-associative-arrays
215
	function cartesian($input) {
263
	function cartesian($input) {
216
		// filter out empty values
264
		// filter out empty values
217
		$input = array_filter($input);
265
		$input = array_filter($input);
218
	
266
	
219
		$result = array(array());
267
		$result = array(array());
220
	
268
	
221
		foreach ($input as $key => $values) {
269
		foreach ($input as $key => $values) {
222
			$append = array();
270
			$append = array();
223
	
271
	
224
			foreach($result as $product) {
272
			foreach($result as $product) {
225
				foreach($values as $item) {
273
				foreach($values as $item) {
226
					$product[$key] = $item;
274
					$product[$key] = $item;
227
					$append[] = $product;
275
					$append[] = $product;
228
				}
276
				}
229
			}
277
			}
230
	
278
	
231
			$result = $append;
279
			$result = $append;
232
		}
280
		}
233
	
281
	
234
		return $result;
282
		return $result;
235
	}
283
	}
236
}
284
}
237
?>
285
?>