Subversion Repositories Applications.referentiel

Rev

Rev 337 | Rev 382 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 337 Rev 380
Line 1... Line 1...
1
<?php
1
<?php
2
// Encodage : UTF-8
-
 
3
// +-------------------------------------------------------------------------------------------------------------------+
-
 
4
/**
2
/**
5
* Importation d'un fichier ref-tax dans une bdnt
3
 * Indexation dans Algolia des référentiels
6
*
4
 *
7
* Description : classe permettant de versionner les référentiels selon le manuel technique
5
 * Description : formate les données des référentiels choisis et envoie tout ça
-
 
6
 * dans Algolia
-
 
7
 * 
8
* Utilisation : php script.php comparaison -r bdnff -a tout -f fichier.txt
8
 * Utilisation : php script.php algolia [-ref "ref1,ref2,..."]
-
 
9
 *   -ref (optionnel): liste de codes de référentiels séparés par des virgules;
-
 
10
 *                     par défaut: "apd,bdtfx,bdtxa,isfan"
9
*
11
 * 
-
 
12
 * Exemples:
10
//Auteur original :
13
 *   php script.php algolia
11
* @author       Jean-Pascal MILCENT <jpm@tela-botanica.org>
14
 *   php script.php algolia -ref "bdtfx,isfan"
-
 
15
 * 
12
* @copyright	Tela-Botanica 1999-2010
16
 * @note: ignorer le paramètre fasciste -a : on ne s'en sert pas
-
 
17
 *
13
* @link			http://www.tela-botanica.org/wikini/RTaxMethodo/wakka.php?wiki=MaNuel
18
 * @author       Tela Botanica <equipe-dev@tela-botanica.org>
14
* @licence		GPL v3 & CeCILL v2
19
 * @licence		GPL v3 & CeCILL v2
-
 
20
 */
-
 
21
restore_error_handler();
-
 
22
restore_exception_handler();
-
 
23
ini_set("display_errors","1");
15
* @version		$Id$
24
error_reporting(E_ALL);
16
*/
25
 
-
 
26
// composer autoload
17
// +-------------------------------------------------------------------------------------------------------------------+
27
require dirname(__FILE__) . '/../../../vendor/autoload.php';
-
 
28
 
18
class Importation extends ScriptCommande {
29
class Algolia extends ScriptCommande {
19
	
30
 
20
	const SCRIPT_NOM = 'importation';
31
	const SCRIPT_NOM = 'algolia';
21
	const MANUEL_VERSION = '4.3';
-
 
22
	
32
 
23
	private $referentiel = null;
-
 
24
	/*public $parametres = array(
33
	public $parametres = array(
25
		'-r' => array(true, true, 'referentiel de base'),
34
		'-ref' => array(false, false, 'Celui qui lit ça est un con')
26
		'-f' => array(true, true, 'fichier à comparer'));*/
-
 
27
	private $noms_supprimes = null;
-
 
28
	private $noms_colonnes = array();
-
 
29
	private $rangs_bdnt_taxref = null;
-
 
30
	private $statuts_bdnt_taxref = null;
-
 
31
	private $correspondance_colonnes = array("CD_NOM" => "", "CD_SUP" => "", "CD_REF" => "",
-
 
32
		"RANG" => "rang", "LB_NOM" => "nom_sci", "LB_AUTEUR" => array("auteur","annee"),
-
 
33
		"FR" => "presence",
35
	);
34
		"FR-FRA" => "presence_Ga", "FR-COR" => "presence_Co", "REU" => "presence",
-
 
35
		"GUA" => "presence_Guadeloupe", "SMSB" => array("presence_Saint_Martin", "presence_Saint_Barthelemy"), 
-
 
36
		"SM" => "presence_Saint_Martin", "SB" => "presence_Saint_Barthelemy",  "MAR" => "presence_Martinique",
-
 
37
		"GF" => "presence", "MAY" => "presence_Mayotte", "TAAF" => "presence_Taaf",
-
 
38
		"SPM" => "presence_Guadeloupe", "PF" => "presence_Polynesie", "NC" => "presence_Nouvelle_Caledonie",
-
 
39
		"BIBLIO" => "biblio_origine", "BDNGM" => "num_nom", "NUM_NOM" => "num_nom", "NOM_VERN" => "nom_francais");
-
 
40
	
36
 
41
	private $sans_correspondance = array(
-
 
42
			"FG_VALIDITE", "habitat", "WF", "CLI", "EPA",
37
	/** connexion PDO à la BDD "referentiels" */
43
			"EU", "WLD", "ORACLE",
38
	protected $bdd;
44
			"DATE_CREA", "ORIGINE_CREA",
-
 
45
			"NOM_COMPLET", "NOM_COMPLET_HTML",
-
 
46
			"GENRE", "ESPECE", "SOUS_ESPECE", "ANNEE");
-
 
47
	
39
 
48
	/*public function executer() {
-
 
49
		$this->referentiel = $this->getParam('r');
-
 
50
		// Lancement du test demandé
40
	/** client API Algolia */
51
		$fichier = $this->getParam('f');
-
 
52
		if (file_exists($fichier)) {
-
 
53
			$manuel_chemin = Config::get('chemin_appli').DS.'..'.DS.'configurations'.DS;
-
 
54
			$manuel_config_nom = 'referentiel_v'.self::MANUEL_VERSION.'.ini';
-
 
55
			$this->manuel = parse_ini_file($manuel_chemin.$manuel_config_nom);
-
 
56
			$this->creerCorrespondanceRangBdntTaxref();
-
 
57
			$donnees = $this->traiterFichierTaxref($fichier);
-
 
58
			Debug::printr("Fin du traitement du fichier.");
-
 
59
			$this->connecterPDO();
41
	protected $algolia;
60
			$this->creerTableTaxref();
42
	protected $indexAlgolia;
61
			$this->ajouterColonneCDNOM();
-
 
62
			Debug::printr("Fin de la création de la table.");
-
 
63
			$this->ajouterDonneesTaxRef($donnees);
-
 
64
			Debug::printr("Fin de l'insertion des données.");
-
 
65
			$this->creerTableComparaison();
-
 
66
			Debug::printr("Fin de la création de la table comparaison.");
-
 
67
		}
-
 
68
	}*/
-
 
Line 69... Line 43...
69
	
43
	
70
	public function executer() {
44
	public function executer() {
-
 
45
		echo "Indexation des référentiels dans Algolia" . PHP_EOL;
71
		// Récupération du dernier traitement demandé
46
 
72
		$this->traitementDao = new TraitementDao();
-
 
73
		$this->traitement = $this->traitementDao->getDernierTraitement('tout', self::SCRIPT_NOM);
-
 
74
		if (isset($this->traitement)) {
-
 
75
			$this->referentiel = $this->traitement['referentiel_code']; // Récupération du nom de projet
47
		// Bibliothèque Algolia PHP pour appeler l'API
76
			$fichier = $this->traitement['script_parametres'];
-
 
77
			if (file_exists($fichier)) {
-
 
78
				Debug::printr('Debute:'.$this->traitementDao->debuterTraitement($this->traitement['id_traitement']));
-
 
79
				// Nettoyage des traitements obsolètes
48
		Config::charger(dirname(__FILE__) . '/algolia.ini');
80
				$traitements_obsoletes = $this->traitementDao->getTraitementsObsoletes($this->referentiel, self::SCRIPT_NOM);
-
 
81
				if (isset($traitements_obsoletes)) {
49
		$this->algolia = new \AlgoliaSearch\Client(Config::get('algolia_application_id'), Config::get('algolia_api_key'));
82
					Debug::printr('Supp. obsoletes:'.$this->traitementDao->supprimer($traitements_obsoletes));
50
		$this->indexAlgolia = $this->algolia->initIndex(Config::get('algolia_index'));
83
				}
-
 
84
				Debug::printr("Début du traitement du fichier.");
-
 
85
				$manuel_chemin = Config::get('chemin_appli').DS.'..'.DS.'configurations'.DS;
-
 
86
				$manuel_config_nom = 'referentiel_v'.self::MANUEL_VERSION.'.ini';
-
 
87
				$this->manuel = parse_ini_file($manuel_chemin.$manuel_config_nom);
51
 
88
				$this->creerCorrespondanceRangBdntTaxref();
-
 
89
				$donnees = $this->traiterFichierTaxref($fichier);
-
 
90
				Debug::printr("Fin du traitement du fichier.");
52
		// Connexion à la base
91
				$this->connecterPDO();
-
 
-
 
53
		$this->connecterPDO();
92
				$this->creerTableTaxref();
54
 
93
				$this->ajouterColonneCDNOM();
55
		// Liste des référentiels à fusionner
94
				Debug::printr("Fin de la création de la table.");
56
		$refsTexte = Config::get('algolia_referentiels');
-
 
57
		$refs = explode(",", $refsTexte);
95
				$this->ajouterDonneesTaxRef($donnees);
58
 
96
				Debug::printr("Fin de l'insertion des données.");
59
		// Liste des référentiels à mettre à jour
97
				$this->decouperNomSciTaxRef();
60
		$refsMajTexte = $this->getParam("ref");
98
				$this->creerTableComparaison();
61
		if ($refsMajTexte === false) {
99
				Debug::printr("Fin de la création de la table comparaison.");
-
 
100
				Debug::printr('Termine:'.$this->traitementDao->terminerTraitement($this->traitement['id_traitement']));
62
			// si le paramètre est vide, on met tout à jour
101
			} else {
-
 
102
				Debug::printr("Fichier introuvable".$fichier);
-
 
103
				Debug::printr('Termine:'.$this->traitementDao->terminerTraitement($this->traitement['id_traitement']));
-
 
104
			}
63
			$refsMaj = $refs;
105
		} else {
64
		} else {
106
			Debug::printr("Pas de traitement");
65
			$refsMaj = explode(",", $refsMajTexte);
107
		}
-
 
108
	}
-
 
Line 109... Line -...
109
	
-
 
110
 
-
 
111
// +-------------------------------------------------------------------------------------------------------------------+
-
 
112
	private function creerTableTaxref() {
-
 
113
		$requete = "DROP TABLE IF EXISTS {$this->referentiel}_taxref; ".
-
 
114
			"CREATE TABLE  {$this->referentiel}_taxref AS SELECT * FROM {$this->referentiel};".
-
 
115
			"ALTER TABLE  {$this->referentiel}_taxref ADD PRIMARY KEY (num_nom);";
-
 
116
		$resultat = $this->executerRequeter($requete);
-
 
117
	}
-
 
118
	
-
 
119
	private function ajouterColonneCDNOM() {
-
 
120
		$requete = "ALTER TABLE  {$this->referentiel}_taxref ADD ".
-
 
121
			"`CD_NOM` INT( 15 ) NULL DEFAULT NULL COMMENT 'numéro correspondant dans la base taxref.';";
-
 
122
		$resultat = $this->executerRequeter($requete);
-
 
123
	}
-
 
124
	
66
		}
125
	private function ajouterDonneesTaxRef($liste_noms) {
67
 
126
		$i = 0; $j = 0; $requete = "";
-
 
127
		foreach ($liste_noms as $nom) { $i++;
-
 
128
			$requete .= "UPDATE  {$this->referentiel}_taxref SET ".implode(' , ', $nom).
68
		// Déniaisage 1
129
					" WHERE {$nom['num_nom']} ;";//echo $requete;
-
 
130
			if ($i == 1000 || ($j*1000+$i) == count($liste_noms) ) { $j++;
69
		foreach ($refs as $k => $r) {
131
				$resultat = $this->executerRequeter($requete.'commit;');
70
			$fichierRequete = dirname(__FILE__) . "/algolia_" . $r . ".sql";
132
				if ($resultat == null) {
-
 
133
					$resultat = $this->executerRequeter($requete.'commit;');
71
			if (! file_exists($fichierRequete)) {
134
				}
72
				echo "- fichier [$fichierRequete] non trouvé, fusion de [$r] ignorée" . PHP_EOL;
135
				$i = 0; $requete = "";
73
				unset($refs[$k]);
136
			}
-
 
137
		}
-
 
138
	}
-
 
139
	
-
 
140
	private function creerTableComparaison() {
-
 
141
		foreach ($this->noms_colonnes as $colonne) {
-
 
142
			if (isset($this->correspondance_colonnes[$colonne]) && $this->correspondance_colonnes[$colonne] != "") {
74
			}
143
				$nom_champ = $this->correspondance_colonnes[$colonne];
-
 
144
				if (is_array($nom_champ)) {
-
 
145
					foreach ($nom_champ as $nom) {
-
 
146
						$champs_tax[] = "t.{$nom} AS tax_{$nom}";
75
		}
147
						$champs_tax[] = "b.{$nom} AS {$nom}";
76
		if (empty($refs)) {
148
						$concat[] = "IF(t.{$nom} != b.{$nom}, '{$nom}, ', '')";
-
 
149
					}
-
 
150
				} else {
-
 
151
					$champs_tax[] = "t.{$nom_champ} AS tax_{$nom_champ}";
-
 
152
					$champs_tax[] = "b.{$nom_champ} AS {$nom_champ}";
-
 
153
					$concat[] = "IF(t.{$nom_champ} != b.{$nom_champ}, '{$nom_champ}, ', '')";
-
 
154
				}
77
			echo "Aucun référentiel à fusionner" . PHP_EOL;
155
			}
-
 
156
		}
-
 
157
		date_default_timezone_set('Europe/London');
-
 
158
		$requete = "CREATE TABLE  {$this->referentiel}_comparaison_".date("Y_m_d_H_i_s")." AS".
-
 
159
					" SELECT CONCAT(".implode(', ', $concat).") AS difference, ".implode(', ', $champs_tax).
-
 
160
					" FROM {$this->referentiel} b, {$this->referentiel}_taxref t".
-
 
161
					" WHERE b.num_nom = t.num_nom AND (b.nom_sci != t.nom_sci or b.auteur != t.auteur or b.annee != t.annee);";
-
 
162
		//echo $requete;
-
 
163
		$resultat = $this->executerRequeter($requete);
78
			exit;
164
	}
-
 
165
	
-
 
166
// +-------------------------------------------------------------------------------------------------------------------+
-
 
167
	private function traiterFichierTaxref($fichier) {
-
 
168
		$donnees = array();
-
 
169
		if (($pointeur = fopen($fichier, "r")) !== FALSE) {
-
 
170
			$this->noms_colonnes = fgetcsv($pointeur, 1000, chr(9));
-
 
171
			$num_nom = 0;//print_r($this->noms_colonnes);
-
 
172
			while (($ligne = fgetcsv($pointeur, 1000, chr(9))) !== FALSE) {
-
 
173
				$nombreChamps = count($ligne);
-
 
174
				$taxref[$ligne[0]] = $ligne;//print_r($ligne);
-
 
175
				for ($c=0; $c < $nombreChamps; $c++) {
-
 
176
					if (isset($this->correspondance_colonnes[$this->noms_colonnes[$c]])) {
-
 
177
						if (is_array($this->correspondance_colonnes[$this->noms_colonnes[$c]])) {
-
 
178
							if ($this->noms_colonnes[$c] == 'LB_AUTEUR') {
-
 
179
								if (preg_match('/(.*), +([0-9]{4})/', utf8_encode($ligne[$c]), $matches) == 1) {
-
 
180
									$nom['auteur'] = 'auteur="'.$matches[1].'"';
79
		}
181
									$nom['annee'] = 'annee="'.trim($matches[2]).'"';
-
 
182
								} else {
-
 
183
									$nom['auteur'] = 'auteur="'.utf8_encode($ligne[$c]).'"';
-
 
184
									$nom['annee'] = 'annee=""';
-
 
185
								}
-
 
186
							} else {
-
 
187
								foreach ($this->correspondance_colonnes[$this->noms_colonnes[$c]] as $a=>$nom_colonne) {
-
 
188
									$nom[$nom_colonne] = $nom_colonne.'="'.$ligne[$c].'"';
-
 
189
								}
-
 
190
							}
-
 
191
						} elseif ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "") {
-
 
192
							$nom[$this->noms_colonnes[$c]] = $ligne[$c];
-
 
193
						} else {
-
 
194
							if ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "rang") {
-
 
195
								$rang = $this->rangs_bdnt_taxref[$ligne[$c]];
-
 
196
								// à remettre si on décide de prendre les rangs taxref
-
 
197
								//$nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] = 
-
 
198
									//$this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.$this->rangs_bdnt_taxref[$ligne[$c]].'"';
80
 
199
							} elseif ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "num_nom") {
-
 
200
								$num_nom = $ligne[$c];
-
 
201
								$nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] = 
-
 
202
									$this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.$ligne[$c].'"';
81
		// Déniaisage 2
203
							} elseif ($this->correspondance_colonnes[$this->noms_colonnes[$c]] == "nom_sci") {
-
 
204
								$nom_sci = $ligne[$c];
-
 
205
								$nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] =
-
 
206
									$this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.trim($ligne[$c]).'"';
-
 
207
							} else  {
82
		foreach ($refsMaj as $k => $r) {
208
								$nom[$this->correspondance_colonnes[$this->noms_colonnes[$c]]] = 
-
 
209
									$this->correspondance_colonnes[$this->noms_colonnes[$c]].'="'.trim(utf8_encode($ligne[$c])).'"';
-
 
210
							}
-
 
211
						}
-
 
212
					}
-
 
213
				}
83
			if (! in_array($r, $refs)) {
214
				$nom['exclure_taxref'] = 'exclure_taxref="0"';
-
 
215
				$donnees[$num_nom] = $nom;
84
				echo "- le référentiel à mettre à jour [$r] n'est pas présent dans la liste à fusionner, il sera ignoré" . PHP_EOL;
216
				$correspondance_taxref_bdnt[$nom['CD_NOM']] = $num_nom;
-
 
217
			}
-
 
218
			fclose($pointeur);
85
				unset($refsMaj[$k]);
219
			$donnees = $this->changerNumerotation($donnees, $correspondance_taxref_bdnt, $taxref);
86
			}
220
		}
-
 
221
		return $donnees;
-
 
222
	}
-
 
223
	
-
 
224
	private function changerNumerotation($donnees, $correspondance, $taxref) {
-
 
225
		$i=0;$j=0;$k=0;
87
		}
226
		foreach ($donnees as $num_nom=>$infos) {
-
 
227
			if (isset($correspondance[$infos['CD_SUP']])) {
88
		if (empty($refsMaj)) {
228
				$donnees[$num_nom]['num_tax_sup'] = "num_tax_sup=".$correspondance[$infos['CD_SUP']];
-
 
229
				$i++;
-
 
230
			} elseif ($infos['CD_SUP'] != '') {
-
 
231
				$donnees[$num_nom]['num_tax_sup'] = "num_tax_sup=''";
-
 
232
				//$sup[$infos['CD_NOM']] = $taxref[$infos['CD_NOM']];
-
 
233
				$sup[$infos['CD_SUP']] = $infos['CD_SUP'];
-
 
234
			}
-
 
235
			unset($donnees[$num_nom]['CD_SUP']);
-
 
236
			if (isset($correspondance[$infos['CD_REF']])) {
-
 
237
				$donnees[$num_nom]['num_nom_retenu'] = "num_nom_retenu=".$correspondance[$infos['CD_REF']];
-
 
238
				$j++;
-
 
239
			} elseif ($infos['CD_REF'] != '') {$k++;
-
 
240
				$donnees[$num_nom]['num_nom_retenu'] = "num_nom_retenu=''";
-
 
241
				//$ref[$infos['CD_NOM']] = $taxref[$infos['CD_NOM']];
-
 
242
				$ref[$infos['CD_REF']] = $infos['CD_REF'];
-
 
243
			} else {
-
 
244
				Debug::printr($infos['CD_NOM']."n'a pas de valeur pour CD_REF");
-
 
245
			}
-
 
246
			unset($donnees[$num_nom]['CD_REF']);
-
 
247
			$donnees[$num_nom]['CD_NOM'] = 'CD_NOM='.$donnees[$num_nom]['CD_NOM'];
-
 
248
		}echo "les ".count($sup)." taxons supérieurs manquants :".implode(" ,", $sup)." \nles "."retenus ".implode(" ,", $ref);
-
 
249
		//$this->ecrireFichierCsv($ref, './retenu_absent.csv');
-
 
250
		//$this->ajouterTaxonAbsent($abs);
-
 
251
		//$this->ecrireFichierCsv($sup, './superieur_absent.csv');
-
 
252
		echo "$j correspondance pour nom retenu $i correspondance pour nom sup $k non pas de correspondance retenu";
-
 
253
		return $donnees;
-
 
254
	}
-
 
255
	
-
 
256
	// rechercher dans reftax les numéros absent dans la base
-
 
257
	// modifier les tableaux ref et sup pour modifier $donnees (ajout + modif)
-
 
258
	private function ajouterTaxonAbsent($abs) {
-
 
259
		$requete = "SELECT ".implode(",", $this->noms_colonnes)." FROM taxref_v5 where CD_NOM IN (".implode(",", $abs).")";
-
 
260
		echo $requete;
-
 
261
	}
-
 
262
	
-
 
263
	private function creerCorrespondanceRangBdntTaxref() {
-
 
264
		$rangs = explode(',', $this->manuel['rangs_bdnt_taxref']);
-
 
265
		foreach ($rangs as $rang) {
-
 
266
			list($id_bdnt, $code_taxref) = explode(':', trim($rang));
89
			echo "Aucun référentiel à mettre à jour" . PHP_EOL;
-
 
90
			exit;
-
 
91
		}
-
 
92
 
-
 
93
		// Confirmation
-
 
94
		//$this->confirmer("Fusion des référentiels [" . implode(',', $refs) . "] et mise à jour de [" . implode(',', $refsMaj) . "]. Continuer ?");
-
 
95
 
-
 
96
		//var_dump($refs);
-
 
97
		$donneesBrutes = array();
-
 
98
		// Exécution des requêtes pour chaque référentiel
-
 
99
		foreach ($refs as $ref) {
-
 
100
			$fichierRequete = dirname(__FILE__) . "/algolia_" . $ref . ".sql";
-
 
101
			// Exécution de la requête
-
 
102
			$requete = file_get_contents($fichierRequete);
-
 
103
			$resultat = $this->requete($requete);
-
 
104
			/*while ($ligne = $resultat->fetch()) {
-
 
105
				var_dump($ligne);
-
 
106
				break;
-
 
107
			}*/
-
 
108
			$donneesBrutes[$ref] = $resultat->fetchAll();
-
 
109
 
-
 
110
			// Info utilisation mémoire
-
 
111
			$mem = memory_get_usage(true);
-
 
112
			$memMio = round($mem / (1024 * 1024));
-
 
113
			echo "Mémoire utilisée : $memMio Mio" . PHP_EOL;
-
 
114
		}
-
 
115
 
-
 
116
		// Fusion !
-
 
117
		$index = $this->fusionnerReferentiels($donneesBrutes);
-
 
118
		//$this->extrait($index, array('Acacia dealbata Link','Acacia Mill.','Fabaceae'));
-
 
119
 
-
 
120
		// Mise en forme
-
 
121
		$index = $this->mettreEnForme($index);
-
 
122
		$this->extrait($index, 3);
-
 
123
 
-
 
124
		// Stats
-
 
125
		$taille = count($index);
-
 
126
		echo "Taille de l'index: [$taille] lignes !" . PHP_EOL;
-
 
127
		//file_put_contents("couscous.json", json_encode($index));
-
 
128
 
-
 
129
		// Calcul des différences ?
-
 
130
		// Insertion ?
-
 
131
		$this->insererDansAlgolia($index);
-
 
132
 
-
 
133
		// Info utilisation mémoire totale
-
 
134
		$mem = memory_get_peak_usage(true);
267
			$this->rangs_bdnt_taxref[$code_taxref] = $id_bdnt;
135
		$memMio = round($mem / (1024 * 1024));
268
		}
136
		echo "Mémoire maximale utilisée : $memMio Mio" . PHP_EOL;
-
 
137
	}
269
	}
138
 
-
 
139
	/**
270
	
140
	 * Génère un index unique pour Algolia à partir des données de n référentiels
271
// +-------------------------------------------------------------------------------------------------------------------+
-
 
272
	private function decouperNomSciTaxRef() {
141
	 */
273
		$requete = "SELECT num_nom, nom_sci, rang, type_epithete FROM {$this->referentiel}_taxref WHERE CD_NOM != ''";
142
	protected function fusionnerReferentiels(&$donneesRefs) {
274
		$resultats = $this->executerRequeter($requete);
143
		$index = array();
275
		foreach ($resultats as $nom) {
144
		foreach ($donneesRefs as $ref => &$d) {
276
			extract($nom);
-
 
277
			$nomen =array('nom_supra_generique' => 'nom_supra_generique=""', 'genre' => 'genre=""', 
-
 
278
				'epithete_infra_generique' => 'epithete_infra_generique=""', 'epithete_sp' => 'epithete_sp=""', 
-
 
-
 
145
			$nbTaxons = count($d);
279
				'type_epithete' => 'type_epithete=""', 'epithete_infra_sp' => 'epithete_infra_sp=""', 
146
			echo "-- fusion du référentiel [$ref] : $nbTaxons taxons --" . PHP_EOL;
280
				'cultivar_groupe' => 'cultivar_groupe=""', 'cultivar' => 'cultivar=""', 'nom_commercial' => 'nom_commercial=""');
147
 
281
			$parties_noms = explode(' ', $nom_sci);
148
			$fusions = 0;
282
			if ($rang < 220) {
149
			foreach ($d as $taxon) {
283
				$nomen['nom_supra_generique'] = 'nom_supra_generique="'.$nom_sci.'"';
150
				$nomSci = $taxon[$ref . '_nom_sci'];
284
			} elseif ($rang == 220) {
151
				//$nn = $taxon[$ref . '_num_nom'];
285
				$nomen['genre'] = 'genre="'.trim($nom_sci).'"';
152
				// Ajout du nom d'auteur pour éviter les collisions dans un même référentiel
286
			} elseif ($rang < 290) {
-
 
287
				$nomen['genre'] = 'genre="'.$parties_noms[0].'"';
153
				if (! empty ($taxon[$ref . '_auteur'])) {
-
 
154
					$nomSci .= ' ' . $taxon[$ref . '_auteur'];
288
				$nomen['epithete_infra_generique'] = 'epithete_infra_generique="'.$parties_noms[1].'"';
155
				}
289
			} else {
156
 
290
				$nomen = array_merge($nomen, $this->decouperEspece($parties_noms));
157
				// -- ÉLIMINATION DES NOMS SANS CORRESPONDANCE
291
				$hybride = $this->etreHybride($parties_noms);
158
				if (empty($taxon[$ref . '_num_nom_retenu'])) {
292
				if (isset($parties_noms[2]) && ($hybride === false || $hybride > 2)) {
159
					//echo "XX élimination du nom sans correspondance : [$nomSci] (nn $nn)" . PHP_EOL;
-
 
160
					continue;
-
 
161
				}
-
 
162
 
-
 
163
				if (! isset($index[$nomSci])) {
-
 
164
					$index[$nomSci] = array(
-
 
165
						'objectID' => $nomSci,
-
 
166
						'referentiels' => array()
-
 
167
					);
-
 
168
				} else {
-
 
169
					//echo "> fusion sur [$nomSci] (nn $nn)" . PHP_EOL;
-
 
170
					$fusions++;
-
 
171
				}
-
 
172
				$index[$nomSci] = array_merge($index[$nomSci], $taxon);
293
					$nomen = array_merge($nomen, $this->decouperSousEspece($parties_noms));
173
				$index[$nomSci]['referentiels'][] = $ref;
294
				}
174
				//break;
295
			}
175
			}
296
			$update = "UPDATE {$this->referentiel}_taxref SET ".implode(' , ', $nomen)." WHERE num_nom = ".$num_nom;
176
			$taille = count($index);
297
			$resultat = $this->executerRequeter($update);
177
			echo "- taille de l'index après ajout de [$ref]: [$taille] lignes ($fusions fusions)" . PHP_EOL;
298
		}
178
		}
299
		return $nomen;
179
		return $index;
-
 
180
	}
-
 
181
 
-
 
182
	/**
-
 
183
	 * Organise les données de chaque objet conformément à la structure de
-
 
184
	 * l'index Algolia
-
 
185
	 * 
-
 
186
	 * Voir commentaires sur cette page :
-
 
187
	 * http://taiga.tela-botanica.net/project/mathias-site-web/task/75
-
 
188
	 * 
300
	}
189
	 * L'objectID est le MD5 de la "clef" (nom scientifique avec auteur)
-
 
190
	 */
-
 
191
	protected function mettreEnForme($index) {
-
 
192
		$nouvelIndex = array();
-
 
193
		foreach ($index as $nomSci => $taxon) {
-
 
194
			$nouveauTaxon = array(
-
 
195
				'objectID' => md5($nomSci),
301
	
196
				'referentiels' => $taxon['referentiels']
-
 
197
			);
-
 
198
			foreach ($taxon['referentiels'] as $ref) {
-
 
199
				// ingrédients
-
 
200
				$nn = $taxon[$ref . '_num_nom'];
-
 
201
				$ns = $taxon[$ref . '_nom_sci'];
-
 
202
				$nts = $taxon[$ref . '_num_tax_sup'];
-
 
203
				$rang = $taxon[$ref . '_rang'];
-
 
204
				$auteur = $taxon[$ref . '_auteur'];
-
 
205
				$annee = $taxon[$ref . '_annee'];
-
 
206
				$biblio = $taxon[$ref . '_biblio'];
-
 
207
				$nom_supra_generique = $taxon[$ref . '_nom_supra_generique'];
302
	private function decouperSousEspece($parties_noms) {
208
				$genre = $taxon[$ref . '_genre'];
303
		if ($this->etreTypeSousEpithete($parties_noms[2]) == true) {
209
				$epithete_sp = $taxon[$ref . '_epithete_sp'];
304
			$nomen['type_epithete'] = 'type_epithete="'.$parties_noms[2].'"';
210
				$type_epithete = $taxon[$ref . '_type_epithete'];
305
			$nomen['epithete_infra_sp'] = 'epithete_infra_sp="'.$parties_noms[3].'"';
211
				$epithete_infra_sp = $taxon[$ref . '_epithete_infra_sp'];
-
 
212
				$cultivar = $taxon[$ref . '_cultivar'];
306
		} elseif (strpos($parties_noms[2], '(') === 0) {
213
				$cultivar_groupe = $taxon[$ref . '_cultivar_groupe'];
307
			$nomen['cultivar_groupe'] = 'cultivar_groupe="'.trim($parties_noms[2], "(").'"';
214
				$nomCommun = (isset($taxon[$ref . '_nom_francais']) ? $taxon[$ref . '_nom_francais'] : '');
308
		} elseif (strpos($parties_noms[2], "'") === 0) {
215
				$url = $taxon[$ref . '_url'];
309
			$nomen['cultivar'] = 'cultivar="'.trim($parties_noms[2], "'").'"';
216
				$synonymes = json_decode($taxon[$ref . '_synonymes'], true);
310
		} elseif (ctype_upper($parties_noms[2]) === true) {
217
				$raccourcis = json_decode($taxon[$ref . '_shortcuts'], true);
-
 
218
				$raccourcis = array_values(array_unique($raccourcis)); // array_values réindexe pour obtenir une liste en JSON et non un objet
311
			$nomen['nom_commercial'] = 'nom_commercial="'.$parties_noms[2].'"';
219
				// garniture
312
		} else {
220
				$donneesRef = array(
313
			$nomen['epithete_infra_sp'] = 'epithete_infra_sp="'.$parties_noms[2].'"';
221
					'nomenclatural_number' => intval($nn),
314
		}
-
 
315
		return $nomen;
-
 
316
	}
222
					'scientific_name' => $ns,
317
	
223
					'common_name' => $nomCommun,
318
	private function etreTypeSousEpithete($chaine) {
224
					'synonyms' => $synonymes,
319
		$type = false;
225
					'url' => $url,
320
		$types_epithete = array('subsp.', 'infra-sp.', 'var.', 'subvar.', 'f.', 'subf.', 'f. sp.', 'race', 'proles');
226
					'parent_taxon_number' => intval($nts),
-
 
227
					'rank' => intval($rang),
321
		if (in_array(utf8_encode($chaine), $types_epithete)) {
228
					'author' => $auteur,
-
 
229
					'year' => intval($annee),
322
			$type = true;
230
					'biblio' => $biblio,
323
		}
-
 
324
		return $type;
-
 
325
	}
231
					'supra_genus_name' => $nom_supra_generique,
326
	
232
					'genus' => $genre,
327
	private function decouperEspece($parties_noms) {
233
					'species_attribute' => $epithete_sp,
328
		$nomen['genre'] = 'genre="'.$parties_noms[0].'"';
234
					'attribute_type' => $type_epithete,
329
		$nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[1].'"';
235
					'infra_species_attribute' => $epithete_infra_sp,
-
 
236
					'cultivar' => $cultivar,
330
		$hybride = $this->etreHybride($parties_noms);
237
					'cultivar_groupe' => $cultivar_groupe
331
		$chimere = array_search('+', $parties_noms);
238
				);
-
 
239
				$nouveauTaxon[$ref] = $donneesRef;
-
 
240
				$nouveauTaxon['shortcuts'] = $raccourcis;
332
		if ($hybride != false || $hybride===0) {
241
			}
333
			$nomen = $this->decouperEspeceHybride($hybride, $parties_noms);
242
			$nouvelIndex[] = $nouveauTaxon;
334
		}
-
 
335
		return $nomen;
-
 
336
	}
-
 
337
	
-
 
338
	private function etreHybride($parties_noms) {
-
 
339
		$hybride = array_search('x', $parties_noms);
243
		}
340
		return $hybride;
244
		return $nouvelIndex;
341
	}
245
	}
342
	
-
 
343
	private function decouperEspeceHybride($hybride, $parties_noms) {
-
 
344
		if ($hybride == 0) {
-
 
345
			$nomen['genre'] = 'genre="'.$parties_noms[0].' '.$parties_noms[1].'"';
-
 
346
			$nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[2].'"';
-
 
347
		} elseif ($hybride == 1 && count($parties_noms) == 4) {
-
 
348
			$nomen['genre'] = 'genre="'.$parties_noms[0].' '.$parties_noms[1].' '.$parties_noms[2].'"';
246
 
349
			$nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[3].'"';
247
	protected function insererDansAlgolia($index) {
350
		} elseif ($hybride == 1 && count($parties_noms) == 3) {
-
 
351
			$nomen['genre'] = 'genre="'.$parties_noms[0].'"';
248
		echo "++++ Insertion dans Algolia !! ++++" . PHP_EOL;
352
			$nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[1].' '.$parties_noms[2].'"';
249
		$tranche = array_slice($index, 0, 500);
353
		} elseif ($hybride == 2) {
250
		//var_dump($tranche);
354
			$nomen['genre'] = 'genre="'.$parties_noms[0].'"';
-
 
355
			$nomen['epithete_sp'] = 'epithete_sp="'.$parties_noms[1].' '.$parties_noms[2].' '.$parties_noms[3].'"';
251
		//$trancheJSON = json_encode($tranche);
356
		}
252
		$this->indexAlgolia->addObjects($tranche);
357
		return $nomen;
253
		//$this->algolia->
358
	}
254
	}
-
 
255
 
359
	
256
	// ---------------- utilitaires --------------------------------------------
360
// +-------------------------------------------------------------------------------------------------------------------+
257
 
361
	private function ecrireFichierCsv(&$contenu, $fichier) {
258
	protected function extrait($index, $clefsOuNombre) {
362
		$retour = true;
259
		// Debug
363
		$fichier = fopen($fichier, "w");
260
		echo PHP_EOL . "---- extrait des données --" . PHP_EOL;
364
		fputcsv($fichier, $this->noms_colonnes, chr('9'));
261
		if (is_array($clefsOuNombre)) {
-
 
262
			foreach ($clefsOuNombre as $k) {
-
 
263
				var_dump($index[$k]);
365
		foreach ($contenu as $ligne) {
264
			}
366
			if (fputcsv($fichier, $ligne, chr('9')) == false) {
265
		} else {
367
				$e = "Une erreur est survenu lors de l'écriture du fichier : $fichier";
-
 
368
				Debug::printr($e);
266
			for ($i=0; $i < $clefsOuNombre; $i++) {
369
				$retour = false;
267
				var_dump($index[$i]);
370
			}
-
 
371
		}
-
 
372
		$contenu = null;
268
			}
373
		return $retour;
-
 
374
	}
269
		}
375
	
270
	}
376
	
271
 
377
	private function connecterPDO() {
272
	protected function connecterPDO() {
378
		Config::charger('./configurations/bdd.ini');
273
		Config::charger(dirname(__FILE__) . '/../../configurations/bdd.ini');
379
		try {
274
		try {
380
			$dsn = Config::get('bdd_type').':dbname='.Config::get('bdd_nom').';host='.
-
 
381
				Config::get('bdd_hote');
275
			$dsn = Config::get('bdd_type').':dbname='.Config::get('bdd_nom').';host='.
-
 
276
				Config::get('bdd_hote');
-
 
277
			$this->bdd = new PDO($dsn, Config::get('bdd_utilisateur'), Config::get('bdd_mot_de_passe'));
-
 
278
			// Passe en UTF-8 la connexion à la BDD
-
 
279
			$this->bdd->exec("SET NAMES 'utf8'");
382
			//$dsn = "mysql:dbname=referentiels;host=localhost";
280
			// Affiche les erreurs détectées par PDO (sinon mode silencieux => aucune erreur affiché)
383
			$this->bdd = new PDO($dsn, Config::get('bdd_utilisateur'), Config::get('bdd_mot_de_passe'));
281
			$this->bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
384
		} catch (PDOException $e) {
282
		} catch (PDOException $e) {
-
 
283
			//print_r($e);
385
			print_r($e);
284
			echo 'La connexion à la base de données via PDO a échoué : ' . $e->getMessage() . PHP_EOL;
386
			echo 'La connexion à la base de donnée via PDO a échouée : ' . $e->getMessage();
-
 
387
		}
-
 
388
		// Passe en UTF-8 la connexion à la BDD
-
 
389
		$this->bdd->exec("SET NAMES 'utf8'");
-
 
390
		// Affiche les erreurs détectées par PDO (sinon mode silencieux => aucune erreur affiché)
285
			exit;
391
		$this->bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
286
		}
392
	}
287
	}
393
	
288
 
394
	protected function executerRequeter($requete) {
289
	protected function requete($requete) {
395
		$infos = null;
290
		$infos = null;
396
		try {
291
		try {
397
			$infos = $this->bdd->query($requete);
292
			$infos = $this->bdd->query($requete, PDO::FETCH_ASSOC);
398
			if ($infos === false) {
293
			/*if ($infos === false) {
399
				echo $requete;
294
				echo $requete;
400
			}
295
			}*/
401
		} catch (PDOException $e) {
296
		} catch (PDOException $e) {
402
			echo sprintf($e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), $requete);
297
			echo sprintf($e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), $requete);
403
		}
298
		}
-
 
299
		return $infos;
-
 
300
	}
-
 
301
 
-
 
302
	/**
-
 
303
	 * Demande confirmation, et sort du script à moins qu'on tape ce qui est
-
 
304
	 * indiqué (par défaut "o" pour "oui")
-
 
305
	 */
-
 
306
	protected function confirmer($question='Continuer ?', $codeAcceptation='o', $messageAnnulation='annulation') {
-
 
307
		echo $question . ' ("' . $codeAcceptation . '" pour confirmer, autre chose pour annuler)' . PHP_EOL;
-
 
308
		$handle = fopen ("php://stdin","r");
-
 
309
		$line = fgets($handle);
-
 
310
		if(strtolower(trim($line)) != strtolower($codeAcceptation)) {
-
 
311
			echo $messageAnnulation . PHP_EOL;
-
 
312
			exit;
-
 
313
		}
404
		return $infos;
314
		fclose($handle);
405
	}
315
	}
406
}
316
}