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