New file |
0,0 → 1,656 |
<?php |
/** |
* Exemple lancement: |
* /opt/lampp/bin/php -d memory_limit=3500M cli.php import -n |
*/ |
class Import extends Script { |
private $bdd = null; |
private $auteurs = array(); |
protected $parametres_autorises = array( |
'-n' => array(true, false, 'Nom du fichier à importer.'), |
'-u' => array(false, false, 'Infos utilisateur sous forme de JSON contenant : id, session et ip')); |
|
protected $table_publication = null; |
protected $table_auteur = null; |
protected $table_publication_a_auteur = null; |
protected $table_meta = null; |
protected $table_structure = 'coel_structure'; // @TODO configurer |
protected $table_collection = 'coel_collection'; // @TODO configurer |
protected $table_collection_bota = 'coel_collection_botanique'; // @TODO configurer |
|
protected $id_table_publication = null; |
protected $id_table_publication_personne = null; |
|
protected $id_role_auteur = null; |
|
protected $colonnes_obligatoires = array(); |
protected $colonnes_acceptees = array(); |
|
protected $cache_auteur = array(); |
protected $auteurs_a_publis = array(); |
protected $publis_a_auteurs = array(); |
|
protected $id_utilisateur = 0; |
protected $id_session = 0; |
protected $ip_utilisateur = "127.0.01"; |
|
const ETAT_AJOUTER = 1; |
|
public function __construct($script_nom, $parametres) { |
parent::__construct($script_nom, $parametres); |
$this->bdd = new Bdd(); |
} |
|
public function executer() { |
try { |
$this->initialiserScript(); |
$cmd = $this->getParametre('a'); |
$fichier = $this->getParametre('n'); |
$utilisateur = $this->getParametre('u'); |
|
$this->traiterInfosUtilisateur($utilisateur); |
|
switch ($cmd) { |
case "collections" : |
$resultat = $this->chargerCollections($fichier); break; |
case "publi" : |
$resultat = $this->chargerPubli($fichier); break; |
default : |
$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd)); |
} |
} catch (Exception $erreur) { |
$this->traiterErreur($erreur->getMessage()); |
} |
|
// renvoi du résultat vers la sortie php |
// car le script est surtout destiné à être appelé par un web service |
echo $resultat; |
exit; |
} |
|
private function traiterInfosUtilisateur($utilisateur) { |
$utilisateur_infos = json_decode($utilisateur, true); |
if(!empty($utilisateur_infos)) { |
$this->id_utilisateur = !empty($utilisateur_infos['id']) ? $utilisateur_infos['id'] : $this->id_utilisateur; |
$this->id_session = !empty($utilisateur_infos['session']) ? $utilisateur_infos['session'] : $this->id_session; |
$this->ip_utilisateur = !empty($utilisateur_infos['ip']) ? $utilisateur_infos['ip'] : $this->ip_utilisateur; |
} |
} |
|
private function initialiserScript() { |
$fichierIni = $this->getScriptChemin().'import.ini'; |
if (file_exists($fichierIni)) { |
Config::charger($fichierIni); |
} else { |
$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'); |
|
$tables = Config::get('tables'); |
$this->table_publication = $tables['publication']; |
$this->table_auteur = $tables['auteur']; |
$this->table_publication_a_auteur = $tables['publication_a_auteur']; |
$this->table_meta = $tables['meta']; |
|
$this->id_table_publication = $tables['id_table_publication']; |
$this->id_table_publication_personne = $tables['id_table_publication_personne']; |
|
$this->id_role_auteur = $tables['id_role_auteur']; |
} |
|
/** |
* Importe des collections botaniques à partir de deux fichiers : $fichier-collections.csv et |
* $fichier-collections-bota.csv |
* Il faut donc fournir en paramètre seulement le début du nom de fichier. Ex : |
* fichiers: |
* - rhone-alpes-collections.csv |
* - rhone-alpes-collections-bota.csv |
* commande : |
* - php cli.php import -a collections -n rhone-alpes |
*/ |
private function chargerCollections($fichier) { |
|
$separateur = "\t"; // @TODO configurer |
$fichierCollections = Config::get('dossiertmp').$fichier . '-collections.csv'; |
$fichierCollectionsBota = Config::get('dossiertmp').$fichier . '-collections-bota.csv'; |
|
// vérification existence fichiers |
if(!file_exists($fichierCollections)) { |
throw new Exception("Le fichier ".Config::get('dossiertmp').$fichierCollections." n'existe pas."); |
} |
if(!file_exists($fichierCollectionsBota)) { |
throw new Exception("Le fichier ".Config::get('dossiertmp').$fichierCollectionsBota." n'existe pas."); |
} |
|
//ouvrir le fichier - collection |
$pointeurCollections = fopen($fichierCollections, "r"); |
// Chargement de la première colonne (qui contient les noms de colonnes à importer) |
$colonnes = fgetcsv($pointeurCollections, 0, $separateur); |
$colonnesParNom = array_flip($colonnes); |
//var_dump($colonnes); |
//var_dump($colonnesParNom); |
|
// vérifier le nom des colonnes |
// @TODO on verra plus tard |
/*if(count($colonnes) < 2 || !array_intersect(array_keys($this->colonnes_obligatoires), $colonnes)) { |
// Vérification des colonnes obligatoires et en même temps du séparateur |
$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); |
}*/ |
|
$idCollectionsParIdTemp = array(); |
// parcours du fichier "-collections.csv" |
while($ligne = fgetcsv($pointeurCollections, 0, $separateur)) { |
//var_dump($ligne); |
$nomStructure = $ligne[$colonnesParNom['cc_ce_structure']]; |
if (empty($nomStructure) || is_numeric($nomStructure)) { |
echo "- omission de la structure pour cause de nom chelou [$nomStructure]\n"; |
continue; |
} |
// tester l'existence de la structure |
$idStructure = $this->verifierExistenceStructureParNom($nomStructure); |
// si oui récupérer l'id |
//sinon créer la structure et récupérer son id |
if ($idStructure === false) { |
$idStructure = $this->creerStructure($nomStructure); |
} |
// remplacer le nom de la structure par son id |
// créer les collections et récupérer leur id |
// @TODO vérifier qu'elles existent pour ne pas insérer de doublons en relançant le script !! |
$idCollection = $this->creerCollection($idStructure, $ligne, $colonnesParNom); |
$idCollectionsParIdTemp[$ligne[$colonnesParNom['id']]] = $idCollection; |
} |
|
// mettre à jour le GUID des collections et des structures |
$this->mettreAJourGUIDCollections(); |
$this->mettreAJourGUIDStructures(); |
|
//ouvrir le fichier collection botanique |
$pointeurCollectionsBota = fopen($fichierCollectionsBota, "r"); |
// Chargement de la première colonne (qui contient les noms de colonnes à importer) |
$colonnesBota = fgetcsv($pointeurCollectionsBota, 0, $separateur); |
$colonnesBotaParNom = array_flip($colonnesBota); |
//var_dump($colonnesBota); |
//var_dump($colonnesBotaParNom); |
|
// vérifier les colonnes |
// @TODO on verra plus tard |
|
// parcours du fichier "-collections-bota.csv" |
while($ligne = fgetcsv($pointeurCollectionsBota, 0, $separateur)) { |
// remplacer les noms des collections par leur id (créé précédemment) |
$ligne[$colonnesBotaParNom['ccb_id_collection']] = $idCollectionsParIdTemp[$ligne[$colonnesBotaParNom['ccb_id_collection']]]; |
// créer/importer |
// @TODO vérifier qu'elles existent pour ne pas insérer de doublons en relançant le script !! |
$this->creerCollectionBota($ligne, $colonnesBotaParNom); |
} |
|
} |
|
/** |
* Si une structure ayant pour nom $nomStructure existe, retourne son |
* identifiant numérique, sinon retourne false |
*/ |
protected function verifierExistenceStructureParNom($nomStructure) { |
$idStructure = false; |
$nsp = $this->bdd->proteger($nomStructure); |
$requete = "SELECT cs_id_structure FROM " . $this->table_structure |
. " WHERE cs_nom = $nsp"; |
|
$resultat = $this->bdd->recupererTous($requete); |
// var_dump($resultat); |
if (count($resultat) > 0) { |
$idStructure = $resultat[0]['cs_id_structure']; |
} |
return $idStructure; |
} |
|
/** |
* Crée une structure portant le nom $nomStructure, sans rien fournir d'autre, et |
* retourne l'identifiant numérique du novueau tuple |
*/ |
protected function creerStructure($nomStructure) { |
$nsp = $this->bdd->proteger($nomStructure); |
$requete = "INSERT INTO " . $this->table_structure . " (cs_nom)" |
. " VALUES ($nsp)"; |
//echo "REQ INS: $requete\n"; |
$this->bdd->executer($requete); |
$idStructure = $this->bdd->recupererIdDernierAjout(); |
|
return $idStructure; |
} |
|
/** |
* Crée une collection en la rattachant à la structure d'id $idStrucutre; la remplit |
* avec les données issues de $ligne en se servant de $colonnesParNom pour accéder |
* aux valeurs par clés textuelles; retourne l'identifiant numérique du novueau tuple |
*/ |
protected function creerCollection($idStructure, $ligne, $colonnesParNom) { |
//echo "Insertion ! : "; var_dump($ligne); echo "<br/>"; |
$nom = $this->bdd->proteger($ligne[$colonnesParNom['cc_nom']]); |
$desc = $this->bdd->proteger($ligne[$colonnesParNom['cc_description']]); |
$type = $this->bdd->proteger($ligne[$colonnesParNom['cc_ce_type']]); |
$pcd = $this->bdd->proteger($ligne[$colonnesParNom['cc_periode_constitution_debut']]); |
$pcf = $this->bdd->proteger($ligne[$colonnesParNom['cc_periode_constitution_fin']]); |
$tcl = $this->bdd->proteger($ligne[$colonnesParNom['cc_truk_couverture_lieu']]); |
$cst = $this->bdd->proteger($ligne[$colonnesParNom['cc_ce_specimen_type']]); |
|
$requete = "INSERT INTO " . $this->table_collection |
. " (cc_ce_structure, cc_nom, cc_description, cc_ce_type, cc_periode_constitution_debut, cc_periode_constitution_fin, cc_truk_couverture_lieu, cc_ce_specimen_type)" |
. " VALUES ($idStructure, $nom, $desc, $type, $pcd, $pcf, $tcl, $cst)"; |
//echo "REQ INS: $requete\n"; |
$this->bdd->executer($requete); |
$idCollection = $this->bdd->recupererIdDernierAjout(); |
|
return $idCollection; |
} |
|
/** |
* Reconstruit les GUID des structures à partir de leurs ID |
*/ |
protected function mettreAJourGUIDStructures() { |
$requete = "UPDATE coel_structure SET cs_guid = CONCAT('urn:lsid:tela-botanica.org:str', cs_id_structure)"; |
$this->bdd->executer($requete); |
} |
|
/** |
* Reconstruit les GUID des collections à partir de leurs ID |
*/ |
protected function mettreAJourGUIDCollections() { |
$requete = "UPDATE coel_collection SET cc_guid = CONCAT('urn:lsid:tela-botanica.org:coll', cc_id_collection)"; |
$this->bdd->executer($requete); |
} |
|
/** |
* Crée une collection botanique; la remplit avec les données issues de $ligne en se |
* servant de $colonnesParNom pour accéder aux valeurs par clés textuelles |
*/ |
protected function creerCollectionBota($ligne, $colonnesBotaParNom) { |
//echo "Insertion ! : "; var_dump($ligne); echo "<br/>"; |
$id = $this->bdd->proteger($ligne[$colonnesBotaParNom['ccb_id_collection']]); |
$ceg = $this->bdd->proteger($ligne[$colonnesBotaParNom['ccb_ce_etat_general']]); |
$ne = $this->bdd->proteger($ligne[$colonnesBotaParNom['ccb_nbre_echantillon']]); |
$spec = $this->bdd->proteger($ligne[$colonnesBotaParNom['ccb_specialite']]); |
$ac = $this->bdd->proteger($ligne[$colonnesBotaParNom['ccb_annotation_classement']]); |
$ct = $this->bdd->proteger($ligne[$colonnesBotaParNom['ccb_ce_traitement']]); |
$ci = $this->bdd->proteger($ligne[$colonnesBotaParNom['ccb_ce_inventaire']]); |
$ii = $this->bdd->proteger($ligne[$colonnesBotaParNom['ccb_inventaire_info']]); |
$aur = $this->bdd->proteger($ligne[$colonnesBotaParNom['ccb_autres_unite_rangement']]); |
$nph = $this->bdd->proteger($ligne[$colonnesBotaParNom['ccb_nb_planches_herbiers']]); |
$tcpt = $this->bdd->proteger($ligne[$colonnesBotaParNom['ccb_truk_conservation_papier_type']]); |
|
// @TODO comment gérer la colonne "Nombre de parts" ? Faut la mettre dans quoi ? |
$requete = "INSERT INTO " . $this->table_collection_bota |
. " (ccb_id_collection, ccb_ce_etat_general, ccb_nbre_echantillon, ccb_specialite, ccb_annotation_classement, ccb_ce_traitement, ccb_ce_inventaire," |
. " ccb_inventaire_info, ccb_autres_unites_rangement, ccb_nb_planches_herbiers, ccb_truk_conservation_papier_type)" |
. " VALUES ($id, $ceg, $ne, $spec, $ac, $ct, $ci, $ii, $aur, $nph, $tcpt)"; |
//echo "REQ INS: $requete\n"; |
$this->bdd->executer($requete); |
} |
|
private function chargerPubli($fichier) { |
|
// 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); |
} |
|
|
//TODO: vérifier si les deux index ci dessous ne font pas double emploi |
|
// Création d'un index des colonnes qui seront importées dans la fiche en les associant |
// au numéro de colonne dans la feuille csv |
$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]); |
} |
|
$roles_a_num_colonnes = array_flip($index_colonnes_importees); |
|
// Ajout de la colonne nom complet aux champs de la requête |
$colonnes_importees[] = 'cpu_fmt_nom_complet'; |
|
$nb_publis_inserees = 0; |
$lignes = array(); |
while($ligne = fgetcsv($pointeur, 0, ";")) { |
$ligne_inseree = array(); |
|
// Traitement des champs suivant leur role |
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 |
$nom_complet = $this->bdd->proteger($this->formaterNomComplet($ligne, $index_colonnes_importees)); |
$ligne_inseree[] = $nom_complet; |
|
$id_publication = $this->insererPublication($colonnes_importees, $ligne_inseree); |
// TODO: quoi faire en cas d'échec pour une publication ? |
if(!empty($id_publication)) { |
$nb_publis_inserees++; |
// Pour aller plus vite on pourrait éventuellement faire une grosse requete d'ajout des publications |
// à personne à la fin, mais ça nous priverait de faire une transaction (TODO: faire une transaction) |
$nb_auteurs_lies = $this->insererLiensPublicationAuteurs($id_publication, $ligne[$roles_a_num_colonnes['auteur']]); |
} |
|
} |
|
return $nb_publis_inserees; |
} |
|
|
private function insererPublication(&$colonnes, &$publication) { |
$requete = "INSERT INTO ".$this->table_publication." ". |
"(".implode(',', $colonnes).") ". |
"VALUES (".implode(",", $publication).")"; |
|
$insertion = $this->bdd->executer($requete); |
$id_publi = $this->bdd->recupererIdDernierAjout(); |
|
// Historisation de l'ajout |
$histo = $this->creerXmlHisto(array_combine($colonnes, $publication)); |
$id_meta = $this->historiser($this->id_table_publication, $id_publi, $histo); |
// Affectation des méta données concernat l'ajout à la publication |
$requete_affectation_meta = "UPDATE ".$this->table_publication." ". |
"SET cpu_ce_meta = ".$id_meta." ". |
"WHERE cpu_id_publication = ".$id_publi; |
|
$this->bdd->executer($requete_affectation_meta); |
|
return $id_publi; |
} |
|
protected function insererLiensPublicationAuteurs($id_publication, &$auteurs) { |
$colonnes = array('cpuap_id_publication', 'cpuap_id_personne', 'cpuap_id_role', 'cpuap_ce_truk_type', 'cpuap_ordre', 'cpuap_ce_meta'); |
$requete = "INSERT IGNORE INTO ".$this->table_publication_a_auteur." ". |
"(".implode(",", $colonnes).") VALUES "; |
|
// L'ordre des auteurs commence à 1 |
$ordre_auteur = 1; |
|
// Découpage des différents auteurs |
$auteurs_tab = explode(',', $auteurs); |
$auteurs_tab = array_filter($auteurs_tab); |
|
// Les auteurs sont normalement cités dans l'ordre dans l'import |
foreach($auteurs_tab as $auteur) { |
// si les infos auteurs sont un tableau dans le cache alors l'id existe bien en base de données |
if(is_array($this->cache_auteur[$auteur])) { |
$id_auteur = $this->cache_auteur[$auteur]['cp_id_personne']; |
|
$valeurs = array($id_publication, $id_auteur, $this->id_role_auteur, "NULL", $ordre_auteur, "0"); |
|
$requete_insertion = $requete." (".implode(',', $valeurs).") "; |
$liaison = $this->bdd->executer($requete_insertion); |
|
// Historisation de l'ajout |
$histo = $this->creerXmlHisto(array_combine($colonnes, $liaison)); |
$cle_liaison = $id_publication.'-'.$this->id_role_auteur.'-'.$id_auteur; |
$id_meta = $this->historiser($this->id_table_publication_personne, $cle_liaison, $histo); |
|
// Affectation des méta données concernant l'ajout à la publication à auteur |
$requete_affectation_meta = "UPDATE ".$this->table_publication_a_auteur." ". |
"SET cpuap_ce_meta = ".$id_meta; |
$this->bdd->executer($requete_affectation_meta); |
} |
// L'ordre des auteurs est conservé même pour ceux qui n'existe pas dans la bdd |
$ordre_auteur++; |
} |
} |
|
protected function creerXmlHisto($donnees) { |
// Création du xml de l'enregistrement à historiser |
$info = null; |
$xml_tpl = '<?xml version="1.0" encoding="UTF-8" ?>'."\n<resultset>\n<row>\n%s</row>\n</resultset>"; |
$xml = null; |
|
foreach ($donnees as $cle => $valeur) { |
// Pour éviter un éventuel double échappement des valeurs |
$valeur = stripslashes($valeur); |
$valeur = trim($valeur, "'"); |
if (!is_null($valeur) && $valeur != '') { |
$xml .= "<$cle>$valeur</$cle>\n"; |
} |
} |
if ($xml !== null) { |
$info = sprintf($xml_tpl, $xml); |
$info = $this->bdd->proteger($info); |
} |
|
return $info; |
} |
|
protected function historiser($table_id, $ligne_cle, $info) { |
date_default_timezone_set('Europe/Paris'); |
// Pré-traitement des variables |
$info = (is_null($info)) ? 'NULL' : $info; |
|
// Historisation (Ajout des méta-données) |
$requete = 'INSERT INTO coel_meta_historique_ligne '. |
' (cmhl_ce_table, cmhl_cle_ligne, cmhl_enregistrement, cmhl_date_modification, cmhl_ce_modifier_par, cmhl_ce_etat, cmhl_ip, cmhl_session_id) '. |
'VALUES ('. |
" $table_id, ". |
' "'.$ligne_cle.'", '. |
" $info, ". |
' "'.date('Y-m-d H:i:s', time()).'", '. |
" $this->id_utilisateur, ". |
" ".self::ETAT_AJOUTER.", ". |
' "'.$this->ip_utilisateur.'", '. |
' "'.$this->id_session.'") '; |
$resultat = $this->bdd->executer($requete); |
return $this->bdd->recupererIdDernierAjout(); |
} |
|
protected function formaterNomComplet($ligne, $roles) { |
|
$roles = array_flip($roles); |
|
// Intitulé de la publication complet : fmt_auteur, date_parution(année). titre. Editeur (nom), collection, fascicule, indication_nvt. pages. |
// indication_nvt = serie_tome |
$champs_nom_complet = array('auteur', 'annee', 'titre', 'editeur', 'intitule_revue', 'fascicule', 'serie_tome', 'pages'); |
$champs_fmt = array(); |
|
$fmt_nom_complet = ""; |
|
foreach($champs_nom_complet as $champ) { |
$index = $roles[$champ]; |
if(!isset($ligne[$index])) { |
$champs_fmt[$champ] = ""; |
} else { |
$champs_fmt[$champ] = $ligne[$index]; |
} |
} |
|
$indication_nvt_pages = array($champs_fmt['serie_tome'], $champs_fmt['pages']); |
$indication_nvt_pages = array_filter($indication_nvt_pages, 'strlen'); |
$indication_nvt_pages = trim(implode(". ", $indication_nvt_pages)); |
$indication_nvt_pages .= !empty($indication_nvt_pages) ? "." : ""; |
|
$annee_titre_editeur = array($champs_fmt['annee'], $champs_fmt['titre'], $champs_fmt['editeur']); |
$annee_titre_editeur = array_filter($annee_titre_editeur, 'strlen'); |
$annee_titre_editeur = trim(implode(". ", $annee_titre_editeur)); |
|
$fmt_nom_complet = array($champs_fmt['auteur'], |
$annee_titre_editeur, |
$champs_fmt['intitule_revue'], |
$champs_fmt['fascicule'], |
$indication_nvt_pages); |
|
$fmt_nom_complet = array_filter($fmt_nom_complet, 'strlen'); |
$fmt_nom_complet = implode(", ", $fmt_nom_complet); |
|
return $fmt_nom_complet; |
} |
|
private function traiterChamp($valeur, $role) { |
switch($role) { |
case 'auteur': |
$valeur = $this->traiterChampAuteur($valeur); |
break; |
case 'editeur': |
$valeur = 'AUTRE##'.$valeur; |
break; |
} |
|
return $this->bdd->proteger($valeur); |
} |
|
private function traiterChampAuteur($auteur_intitule) { |
$auteurs_fmt = array(); |
$auteurs_tab = explode(',', $auteur_intitule); |
foreach($auteurs_tab as $auteur) { |
if(!empty(trim($auteur))) { |
$auteurs_fmt[] = $this->obtenirInfosAuteur($auteur); |
} |
} |
|
return implode(', ', $auteurs_fmt); |
} |
|
private function obtenirInfosAuteur($auteur_intitule) { |
$retour = $auteur_intitule; |
// Si on déjà recherché et trouvé (ou non l'auteur) |
if(isset($this->cache_auteur[$auteur_intitule])) { |
// On renvoie son nom complet formaté s'il existe en bdd ou sinon |
// le nom qui a été donné dans la feuille csv |
$retour = !empty($this->cache_auteur[$auteur_intitule]['cp_fmt_nom_complet']) ? |
$this->cache_auteur[$auteur_intitule]['cp_fmt_nom_complet'] : |
$auteur_intitule; |
} else { |
// Recherche de l'auteur sur un maximum du combinaisons possible des variations |
// de son nom et prénom |
$auteur = $this->fabriquerCombinaisonsAuteur($auteur_intitule); |
$auteur_req = "(".implode(', ', $auteur).")"; |
|
$requete = "SELECT cp_id_personne, cp_fmt_nom_complet FROM ".$this->table_auteur." WHERE cp_fmt_nom_complet IN ".$auteur_req; |
$infos_auteur = $this->bdd->recupererTous($requete); |
|
// Stockage en cache de la ligne de bdd si trouvé, |
// de la valeur brute sinon |
if(!empty($infos_auteur)) { |
$retour = $infos_auteur[0]['cp_fmt_nom_complet']; |
$this->cache_auteur[$auteur_intitule] = $infos_auteur[0]; |
// Stocker le nom d'auteur sous les deux formes (fmt nom complet et tel que saisi), facilite la recherche |
// plus tard lors de la liaison des publications aux auteurs |
$this->cache_auteur[$infos_auteur[0]['cp_fmt_nom_complet']] = $infos_auteur[0]; |
} else { |
$retour = $auteur_intitule; |
$this->cache_auteur[$auteur_intitule] = $auteur_intitule; |
} |
} |
|
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]))); |
} |
|
$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; |
} |
} |
?> |