9,13 → 9,16 |
protected $parametres_autorises = array( |
'-n' => array(true, false, 'Nom du fichier à importer.')); |
|
protected $colonnes_obligatoires = array(); |
protected $colonnes_acceptees = array(); |
|
protected $cache_auteur = array(); |
|
public function __construct($script_nom, $parametres) { |
parent::__construct($script_nom, $parametres); |
$this->bdd = new Bdd(); |
} |
|
|
public function executer() { |
try { |
$this->initialiserScript(); |
38,35 → 41,197 |
if (file_exists($fichierIni)) { |
Config::charger($fichierIni); |
} else { |
$erreur = "Veuillez configurer le projet en créant le fichier 'communes.ini' ". |
"dans le dossier du module de script du projet à partir du fichier 'config.defaut.ini'."; |
$erreur = "Veuillez configurer le projet en créant le fichier 'import.ini' ". |
"dans le dossier du module de script du projet à partir du fichier 'import.defaut.ini'."; |
throw new Exception($erreur); |
} |
|
$this->colonnes_obligatoires= Config::get('champs_obligatoires'); |
$this->colonnes_acceptees = Config::get('champs'); |
} |
|
private function charger($fichier) { |
// vérifier si fichier existe |
// charger fichier |
// vérifier séparateur |
// vérifier nom colonne |
// vérifier si colonne "titre" et "auteur" sont bien présent |
// modifier champ editeur ajouter AUTRES## |
// vérifier si auteurs sont déjà présents et récupérer le numéro (publi_a_pers) |
// créer champ nom complet |
// faire un insert |
|
$chemin = Config::get('dossiertmp').$fichier; |
$table = Config::get('tables.publication'); |
$requete = "LOAD DATA INFILE '$chemin' ". |
" INTO TABLE $table ". |
'CHARACTER SET utf8 '. |
'FIELDS '. |
" TERMINATED BY ';' ". |
" ENCLOSED BY '\"' ". |
" ESCAPED BY '\\\' ". |
'IGNORE 0 LINES (`cpu_ce_truk_editeur`, `cpu_collection`, `cpu_indication_nvt`, `cpu_fascicule`, `cpu_date_parution`, `cpu_truk_pages`, `cpu_titre`, `cpu_fmt_auteur`, cpu_resume_motcle)'; |
$this->bdd->requeter($requete); |
// vérification existence fichier |
if(!file_exists(Config::get('dossiertmp').$fichier)) { |
$erreur = "Le fichier ".Config::get('dossiertmp').$fichier." n'existe pas."; |
throw new Exception($erreur); |
} |
|
$pointeur = fopen(Config::get('dossiertmp').$fichier, "r"); |
// Chargement de la première colonne (qui contient les noms de colonnes à importer |
$colonnes = fgetcsv($pointeur, 0, ";"); |
|
// Vérification des colonnes obligatoires et en même temps du séparateur |
if(count($colonnes) < 2 || !array_intersect(array_keys($this->colonnes_obligatoires), $colonnes)) { |
$erreur = "Le fichier ne contient pas les colonnes obligatoires : ".implode(',', array_keys($this->colonnes_obligatoires))."\n"; |
$erreur .= "ou bien n'est pas séparé par le caractère ';' "; |
throw new Exception($erreur); |
} |
|
$index_colonnes_importees = array_intersect(array_keys($this->colonnes_acceptees), $colonnes); |
$colonnes_importees = array(); |
foreach($index_colonnes_importees as $index_colonne_importee) { |
$colonnes_importees[] = $this->colonnes_acceptees[$index_colonne_importee]; |
} |
|
$index_colonnes_refusees = array_keys(array_diff($colonnes, array_keys($this->colonnes_acceptees))); |
// Création d'un index associant chaque numéro de colonne importée à son rôle |
// pour y apporter des traitement spécifiques |
$index_colonnes_importees = $colonnes; |
foreach($index_colonnes_refusees as $colonne_refusee) { |
unset($index_colonnes_importees[$colonne_refusee]); |
} |
|
$lignes = array(); |
while($ligne = fgetcsv($pointeur, 0, ";")) { |
$ligne_inseree = array(); |
foreach($ligne as $index => &$valeur) { |
if(!in_array($index, $index_colonnes_refusees)) { |
$ligne_inseree[] = $this->traiterChamp($valeur, $index_colonnes_importees[$index]); |
} |
} |
// Ajout du nom complet formaté de la publication |
$ligne_inseree[] = $this->formaterNomComplet($ligne, $index_colonnes_importees); |
$lignes[] = "(".implode(",", $ligne_inseree).")"; |
} |
|
// Ajout de la colonne nom complet aux champs de la requête |
$colonnes_importees[] = 'cpu_fmt_nom_complet'; |
$this->insererPublications($colonnes_importees, $lignes); |
} |
|
protected function formaterNomComplet($ligne, $roles) { |
// TODO: écrire la fonction |
return 'aaaaa'; |
} |
|
private function insererPublications(&$colonnes, &$publications) { |
$requete = "INSERT INTO $table ". |
"(".implode(',', $colonnes).") ". |
"VALUES ".implode(","."\n", $publications)."\n"; |
|
echo $requete;exit; |
} |
|
private function traiterChamp($valeur, $role) { |
switch($role) { |
case 'auteur': |
$valeur = $this->obtenirInfosAuteur($valeur); |
break; |
case 'editeur': |
$valeur = 'AUTRES##'.$valeur; |
break; |
} |
|
return $this->bdd->proteger($valeur); |
} |
|
private function obtenirInfosAuteur($auteur) { |
$retour = $auteur; |
if(isset($cache_auteur[$auteur])) { |
$retour = $cache_auteur[$auteur]; |
} else { |
$auteur = $this->fabriquerCombinaisonsAuteur($auteur); |
$auteur_req = "(".implode(', ', $auteur).")"; |
|
$requete = "SELECT cp_id_personne FROM coel_personne WHERE cp_fmt_nom_complet IN ".$auteur_req; |
$infos_auteur = $this->bdd->recupererTous($requete); |
|
if(!empty($infos_auteur)) { |
$retour = $infos_auteur[0]['cp_id_personne']; |
$cache_auteur[$auteur] = $infos_auteur[0]['cp_id_personne']; |
} else { |
$cache_auteur[$auteur] = $auteur; |
} |
} |
|
return $retour; |
} |
|
private function fabriquerCombinaisonsAuteur($auteur) { |
|
$auteur = trim($auteur); |
$auteurs_formates = array($this->bdd->proteger($auteur)); |
|
// Séparation des élements de l'auteur des espaces pour obtenir |
// les noms et prénoms (Ex. "Carl Von Linné" => "Carl", "Von", "Linné") |
$auteur_tab = explode(' ', $auteur); |
$auteur_tab = array_filter($auteur_tab); |
|
$combinaisons = array(); |
foreach($auteur_tab as &$element_auteur) { |
$combinaisons[] = array( |
// élement tel quel (Ex: "Linné") |
$element_auteur, |
// possibilité de l'initiale seule (Ex: "L") |
substr($element_auteur, 0, 1), |
// possibilité de l'initiale avec un point du genre (Ex: "L.") |
substr($element_auteur, 0, 1)."." |
); |
} |
|
// Fabrication de toutes les combinaisons possibles des parties de noms ci-dessus |
// pour deux et trois élements en faisant plusieurs produits cartésiens |
// car le nom peut être combiné différement de celui en base de données |
// (Ex. : "Carl Von Linné" VS "C. Von Linné" ou "C. V. Linné" ou encore "Von Linné C." etc...) |
|
// C'est moche et pas très élégant mais bon ça marche dans 90% des cas |
// On ne teste pas plus que 3 combinaisons, car ça serait très très couteux |
// TODO: faire mieux et factoriser les appels ci dessous |
if(count($auteur_tab) > 2) { |
// Cas du nom à trois parties (genre "Carl Von Linné") |
$possibilites_auteurs = $this->cartesian(array($combinaisons[0], $combinaisons[1], $combinaisons[2])); |
$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[0], $combinaisons[2], $combinaisons[1]))); |
$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[1], $combinaisons[2], $combinaisons[0]))); |
$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[1], $combinaisons[0], $combinaisons[2]))); |
$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[2], $combinaisons[1], $combinaisons[0]))); |
$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[2], $combinaisons[0], $combinaisons[1]))); |
} else { |
// Cas du nom à trois parties (genre "Carl Linné") |
$possibilites_auteurs = $this->cartesian(array($combinaisons[0], $combinaisons[1])); |
$possibilites_auteurs = array_merge($possibilites_auteurs, $this->cartesian(array($combinaisons[1], $combinaisons[0]))); |
} |
// Elimination d'éventuels doublons |
array_unique($possibilites_auteurs); |
|
$auteurs_formates = array(); |
foreach($possibilites_auteurs as &$possibilite) { |
$initiales = true; |
// Suppression des possibilités ne contenant que des initiales avec ou sans point |
foreach($possibilite as &$chars) { |
$initiales = $initiales && mb_strlen($chars) <= 2; |
} |
|
if(!$initiales) { |
$auteurs_formates[] = $this->bdd->proteger(implode(" ", $possibilite)); |
} |
} |
|
return $auteurs_formates; |
} |
|
// http://stackoverflow.com/questions/6311779/finding-cartesian-product-with-php-associative-arrays |
function cartesian($input) { |
// filter out empty values |
$input = array_filter($input); |
|
$result = array(array()); |
|
foreach ($input as $key => $values) { |
$append = array(); |
|
foreach($result as $product) { |
foreach($values as $item) { |
$product[$key] = $item; |
$append[] = $product; |
} |
} |
|
$result = $append; |
} |
|
return $result; |
} |
} |
?> |