Subversion Repositories eFlore/Applications.cel

Compare Revisions

No changes between revisions

Ignore whitespace Rev 1761 → Rev 1762

/branches/topic-dbsingleton/jrest/services/ImportXLS.php
196,7 → 196,7
$fichier = $infos_fichier['tmp_name'];
$extension = pathinfo($infos_fichier['name'], PATHINFO_EXTENSION);
if( (strlen($extension) == 3 || strlen($extension) == 4) &&
(@rename($fichier, $fichier . '.' . $extension))) {
(@rename($fichier, $fichier . '.' . $extension))) { // XXX: @ safe-mode
$fichier = $fichier . '.' . $extension;
}
 
295,10 → 295,11
restore_error_handler();
 
if($this->bilan) echo implode("\n", $this->bilan) . "\n";
$summary = sprintf("%d observation(s) ajoutée(s)\n%d image(s) attachée(s)\n%d mot(s)-clé ajouté(s) [TODO]\n",
$summary = sprintf("%d observation(s) ajoutée(s)\n%d image(s) attachée(s)\n%d mot(s)-clé ajouté(s) [TODO]\ncolonnes non-traitées: %s\n",
$obs_ajouts,
$nb_images_ajoutees,
$nb_mots_cle_ajoutes);
$nb_mots_cle_ajoutes,
implode(', ', $filtre->exclues));
 
die("$summary");
}
444,13 → 445,14
*/
static function chargerLigne($ligne, $dernier_ordre, $cel) {
// en premier car le résultat est utile pour
// traiter longitude et latitude (traiterLonLat())
$referentiel = self::identReferentiel($ligne[C_NOM_REFERENTIEL]);
// * traiter espèce (traiterEspece())
// * traiter longitude et latitude (traiterLonLat())
$referentiel = self::identReferentiel(trim(strtolower($ligne[C_NOM_REFERENTIEL])), $ligne);
 
// $espece est rempli de plusieurs informations
$espece = Array(C_NOM_SEL => NULL, C_NOM_SEL_NN => NULL, C_NOM_RET => NULL,
C_NOM_RET_NN => NULL, C_NT => NULL, C_FAMILLE => NULL);
self::traiterEspece($ligne, $espece, $cel);
self::traiterEspece($ligne, $espece, $referentiel, $cel);
 
// $localisation est rempli à partir de plusieurs champs: C_ZONE_GEO et C_CE_ZONE_GEO
$localisation = Array(C_ZONE_GEO => NULL, C_CE_ZONE_GEO => NULL);
481,21 → 483,21
// $ligne: uniquement pour les infos en cas de gestion d'erreurs (date incompréhensible)
"date_observation" => self::traiterDateObs($ligne[C_DATE_OBSERVATION], $ligne),
 
"lieudit" => trim($ligne[C_LIEUDIT]),
"station" => trim($ligne[C_STATION]),
"milieu" => trim($ligne[C_MILIEU]),
"lieudit" => isset($ligne[C_LIEUDIT]) ? trim($ligne[C_LIEUDIT]) : NULL,
"station" => isset($ligne[C_STATION]) ? trim($ligne[C_STATION]) : NULL,
"milieu" => isset($ligne[C_MILIEU]) ? trim($ligne[C_MILIEU]) : NULL,
 
"mots_cles_texte" => NULL, // TODO: foreign-key
// XXX: @ contre "Undefined index"
"commentaire" => @trim($ligne[C_COMMENTAIRE]),
"commentaire" => isset($ligne[C_COMMENTAIRE]) ? trim($ligne[C_COMMENTAIRE]) : NULL,
 
"transmission" => $transmission,
"date_transmission" => $transmission ? date("Y-m-d H:i:s") : NULL, // pas de fonction SQL dans un PDO statement, <=> now()
 
// $ligne: uniquement pour les infos en cas de gestion d'erreurs (lon/lat incompréhensible)
"latitude" => self::traiterLonLat(NULL, $ligne[C_LATITUDE], $referentiel, $ligne),
"longitude" => self::traiterLonLat($ligne[C_LONGITUDE], NULL, $referentiel, $ligne),
"altitude" => intval($ligne[C_ALTITUDE]),
"latitude" => isset($ligne[C_LATITUDE]) ? self::traiterLonLat(NULL, $ligne[C_LATITUDE], $referentiel, $ligne) : NULL,
"longitude" => isset($ligne[C_LONGITUDE]) ? self::traiterLonLat($ligne[C_LONGITUDE], NULL, $referentiel, $ligne) : NULL,
"altitude" => isset($ligne[C_ALTITUDE]) ? intval($ligne[C_ALTITUDE]) : NULL, // TODO: guess alt from lon/lat
 
// @ car potentiellement optionnelles ou toutes vides => pas d'index dans PHPExcel (tableau optimisé)
"abondance" => @$ligne[C_ABONDANCE],
521,9 → 523,9
//array_walk($liste_images, '__anonyme_4');
array_walk($liste_images, array(__CLASS__, '__anonyme_4'));
$requete = sprintf(
"SELECT id_image, nom_original FROM cel_images WHERE ce_utilisateur = %d AND nom_original IN (\"%s\")",
"SELECT id_image, nom_original FROM cel_images WHERE ce_utilisateur = %d AND nom_original IN (%s)",
$id_utilisateur,
implode('","', $liste_images));
implode(',', $liste_images));
 
$resultat = Cel::db()->requeter($requete);
 
580,7 → 582,12
else {
// attend l'un des formats de
// http://www.php.net/manual/fr/datetime.formats.date.php
// le plus simple: YYYY/MM/DD (utilisé à l'export)
// le plus simple: YYYY/MM/DD (utilisé à l'export), mais DD-MM-YYYY est aussi supporté
$matches = NULL;
// et on essaie d'être sympa et supporter aussi DD/MM/YYYY
if(preg_match(';^([0-3]?\d)/([01]\d)/([12]\d\d\d)$;', $date, $matches)) {
$date = $matches[3] . '/' . $matches[2] . '/' . $matches[1];
}
$timestamp = strtotime($date);
if(! $timestamp) {
if($date) trigger_error("ligne \"{$ligne[C_NOM_SEL]}\": Attention: date erronée ($date)", E_USER_NOTICE);
590,15 → 597,17
}
}
 
static function identReferentiel($referentiel) {
static function identReferentiel($referentiel, $ligne) {
// SELECT DISTINCT nom_referentiel, COUNT(id_observation) AS count FROM cel_obs GROUP BY nom_referentiel ORDER BY count DESC;
if(strpos(strtolower($referentiel), 'bdtfx') !== FALSE) return 'bdtfx:v1.01';
if(strpos(strtolower($referentiel), 'bdtxa') !== FALSE) return 'bdtxa:v1.00';
if(strpos(strtolower($referentiel), 'bdnff') !== FALSE) return 'bdnff:4.02';
if(strpos(strtolower($referentiel), 'isfan') !== FALSE) return 'isfan:v1.00';
if(strpos($referentiel, 'bdtfx') !== FALSE) return 'bdtfx:v1.01';
if(strpos($referentiel, 'bdtxa') !== FALSE) return 'bdtxa:v1.00';
if(strpos($referentiel, 'bdnff') !== FALSE) return 'bdnff:4.02';
if(strpos($referentiel, 'isfan') !== FALSE) return 'isfan:v1.00';
if(strpos($referentiel, 'autre') !== FALSE) return 'autre';
 
if($referentiel) {
trigger_error("ligne \"{$ligne[C_NOM_SEL]}\": Attention: référentiel inconnu", E_USER_NOTICE);
return 'autre';
}
return NULL;
/* TODO: cf story,
646,13 → 655,13
TODO: s'affranchir du webservice pour la détermination du nom scientifique en s'appuyant sur cel_references,
pour des questions de performances
*/
static function traiterEspece($ligne, Array &$espece, $cel) {
static function traiterEspece($ligne, Array &$espece, $referentiel, $cel) {
if(!$ligne[C_NOM_SEL]) return;
 
// nom_sel reste toujours celui de l'utilisateur
$espece[C_NOM_SEL] = trim($ligne[C_NOM_SEL]);
 
$taxon_info_webservice = new RechercheInfosTaxonBeta($cel->config);
$taxon_info_webservice = new RechercheInfosTaxonBeta($cel->config, $referentiel);
 
$ascii = iconv('UTF-8', 'ASCII//TRANSLIT', $ligne[C_NOM_SEL]);
 
668,11 → 677,14
 
SELECT nom_sci, num_nom_retenu, nom_sci_html, auteur, annee, biblio_origine FROM bdtfx_v1_01 WHERE num_nom = 31468
*/
$resultat_recherche_espece = $taxon_info_webservice->rechercherInformationsComplementairesSurNom($ligne[C_NOM_SEL]);
// $resultat_recherche_espece = $taxon_info_webservice->rechercherInformationsComplementairesSurNom($ligne[C_NOM_SEL]);
// permet une reconnaissance de BDNFFnnXXXX
$resultat_recherche_espece = $taxon_info_webservice->rechercherInfosSurTexteCodeOuNumTax(trim($ligne[C_NOM_SEL]));
 
// on supprime les noms retenus et renvoi tel quel
// on réutilise les define pour les noms d'indexes, tant qu'à faire
if (! $resultat_recherche_espece) {
// note: rechercherInfosSurTexteCodeOuNumTax peut ne retourner qu'une seule clef "nom_sel"
if (! $resultat_recherche_espece || !isset($resultat_recherche_espece['en_id_nom'])) {
// on supprime les noms retenus et renvoi tel quel
// on réutilise les define pour les noms d'indexes, tant qu'à faire
// XXX; tout à NULL sauf C_NOM_SEL ci-dessus ?
$espece[C_NOM_SEL_NN] = $ligne[C_NOM_SEL_NN];
$espece[C_NOM_RET] = $ligne[C_NOM_RET];
684,11 → 696,11
}
 
// succès de la détection = écrasement du numéro nomenclatural saisi...
$espece[C_NOM_SEL_NN] = $resultat_recherche_espece[0][0];
$espece[C_NOM_SEL_NN] = $resultat_recherche_espece['en_id_nom'];
// et des info complémentaires
 
// echo "rechercherInformationsComplementairesSurNumNom()\n";
$complement = $taxon_info_webservice->rechercherInformationsComplementairesSurNumNom($resultat_recherche_espece[0][0]);
$complement = $taxon_info_webservice->rechercherInformationsComplementairesSurNumNom($resultat_recherche_espece['en_id_nom']);
/*
// GET /service:eflore:0.1/bdtfx/noms/31468?retour.champs=nom_sci,auteur,id,nom_retenu_complet,nom_retenu.id,num_taxonomique,famille
/home/raphael/eflore/projets/services/modules/0.1/bdtfx/Noms.php:280
740,13 → 752,13
 
$localisation[C_ZONE_GEO] = $localisation[C_ZONE_GEO];
$localisation[C_CE_ZONE_GEO] = $localisation[C_CE_ZONE_GEO];
 
return;
}
 
 
$select = "SELECT DISTINCT nom, code FROM cel_zones_geo";
if (preg_match('/(.*) \((\d+)\)/', $identifiant_commune, $elements)) {
if (preg_match('/(.+) \((\d+)\)/', $identifiant_commune, $elements)) {
// commune + departement : montpellier (34)
$nom_commune=$elements[1];
$code_commune=$elements[2];
866,6 → 878,7
/* HELPERS */
 
// http://stackoverflow.com/questions/348410/sort-an-array-based-on-another-array
// XXX; utilisé aussi (temporairement ?) par FormateurGroupeColonne.
static function sortArrayByArray($array, $orderArray) {
$ordered = array();
foreach($orderArray as $key) {
/branches/topic-dbsingleton/jrest/services/CelWidgetExport.php
154,6 → 154,7
$criteres['transmission'] = 1;
if($this->doitEtPeutExporterObsPrivees($criteres)) {
unset($criteres['transmission']);
$this->id_utilisateur = $criteres['ce_utilisateur'];
}
$chercheur_observations = new RechercheObservation($this->config);
/branches/topic-dbsingleton/jrest/services/InventoryImportExcel.php
276,7 → 276,7
case ESPECE:
// suppression des accents éventuels
$line[ESPECE][$i] = iconv('UTF-8', 'ASCII//TRANSLIT', $line[ESPECE][$i]);
$resultat_recherche_espece = $this->chercheur_infos_taxon->rechercherInfosSurTexteCodeOuNumTax($line[ESPECE][$i]);
$resultat_recherche_espece = $this->chercheur_infos_taxon->rechercherInfosSurTexteCodeOuNumTax(utf8_encode(trim($line[ESPECE][$i])));
if (isset($resultat_recherche_espece['en_id_nom']) && $resultat_recherche_espece['en_id_nom'] != '') {
$info_espece['nom_sel'] = $resultat_recherche_espece['nom_sel'];
$info_espece['nom_sel_nn'] = $resultat_recherche_espece['en_id_nom'];
/branches/topic-dbsingleton/jrest/services/InventoryExport.php
82,6 → 82,11
$limite = isset($criteres['limite']) ? $criteres['limite'] : 0;
 
$observations = $chercheur_observations->rechercherObservations($uid[0], $criteres, $numero_page, $limite)->get();
if(!$observations) {
header('HTTP/1.0 204 No Content');
exit;
}
 
$ids_obs = array();
$indices_lignes_obs = array();
/branches/topic-dbsingleton/jrest/services/ExportXLS.php
84,7 → 84,7
$parametres['debut'] = isset($params['debut']) ? intval($params['debut']) : 0;
$parametres['limite'] = isset($params['limite']) ? intval($params['limite']) : 0;
$parametres['id_utilisateur'] = $this->traiterIdUtilisateur($uid);
$parametres['groupe_champs'] = isset($criteres['colonnes']) ? $criteres['colonnes'] : 'standard,avance';
$parametres['groupe_champs'] = isset($params['colonnes']) ? $params['colonnes'] : 'standard,avance';
return $parametres;
}
190,7 → 190,7
$no_colonne = 0;
foreach($colonnes as $abbrev => $colonne) {
$valeur = null;
if($colonne['extra'] == 2) continue;
if($colonne['extra'] == 2 || ! is_null($colonne['dyna'])) continue;
// valeur direct depuis cel_obs ?
if(isset($obs[$abbrev])) $valeur = $obs[$abbrev];
/branches/topic-dbsingleton/jrest/services/User.php
69,6 → 69,7
$utilisateur= $this->chargerInfosUtilisateur($uid[0]);
$utilisateur['connecte'] = true;
}
// TODO: utilisateur inexistant ?
}
else {
$utilisateur = $this->chargerInfosUtilisateur($utilisateur);
107,17 → 108,20
}
private function envoyerInfosUtilisateur($utilisateur) {
$utilisateur['connecte'] = ($utilisateur['connecte']) ? true : false;
$utilisateur['licence_acceptee'] = ($utilisateur['licence_acceptee']) ? true : false;
$utilisateur['admin'] = ($utilisateur['admin']) ? true : false;
if(!$utilisateur) {
$this->envoyerJson((array('connecte' => false, 'licence_acceptee' => false, 'admin' => false)));
return true;
}
$utilisateur['connecte'] = ($utilisateur['connecte']) ? true : false;
$utilisateur['licence_acceptee'] = ($utilisateur['licence_acceptee']) ? true : false;
$utilisateur['admin'] = ($utilisateur['admin']) ? true : false;
$this->envoyerJson($utilisateur);
return true;
$this->envoyerJson($utilisateur);
return true;
}
function chargerInfosUtilisateur($login) {
 
$requete_selection_utilisateur = 'SELECT * FROM cel_utilisateurs cu '.
'WHERE courriel = '.Cel::db()->proteger($login);
 
/branches/topic-dbsingleton/jrest/services/InventoryImageLink.php
30,6 → 30,7
{
// Controle detournement utilisateur
$this->controleUtilisateur($pairs['ce_utilisateur']);
if(!isset($pairs['id_image'])) exit;
 
$ids_images = $pairs['id_image'] ;
$ids_images = rtrim($ids_images,',') ;
/branches/topic-dbsingleton/jrest/lib/GestionObservation.php
89,6 → 89,7
"AND ordre = ".Cel::db()->proteger($ordre)." ";
$dernier_id = Cel::db()->executerRequete($requete_selection_dernier_id);
if(!$dernier_id) return NULL;
return $dernier_id[0]['id_observation'];
}
106,6 → 107,16
$retour = true;
$requete_modification = "UPDATE cel_obs SET " ;
 
/* TODO:
* si (à l'origine) pas de nom_sel_nn (donc pas de référentiel) POSTé
* et aucun nom déterminés, alors on supprime les données automatiques:
* alors on test une différence de réferentiel...
nom_sel_nn = IF(SUBSTR(nom_referentiel, 1, 5) != "{$parametre['referentiel']}", NULL, nom_sel_nn),
nom_ret_nn = IF(SUBSTR(nom_referentiel, 1, 5) != "{$parametre['referentiel']}", NULL, nom_ret_nn),
nom_ret = IF(SUBSTR(nom_referentiel, 1, 5) != "{$parametre['referentiel']}", NULL, nom_ret),
nt = IF(SUBSTR(nom_referentiel, 1, 5) != "{$parametre['referentiel']}", NULL, nt),
famille = IF(SUBSTR(nom_referentiel, 1, 5) != "{$parametre['referentiel']}", NULL, famille)
*/
$sous_requete_modification = $this->traiterParametresObservationEtConstruireSousRequeteMaj($parametres);
$requete_modification .= $sous_requete_modification;
 
134,7 → 145,12
* @return true ou false suivant le succès de l'opération
*/
public function modifierObservationPublique($utilisateur, $id, $parametres) {
$base_param = array('nom_sel_nn' => NULL,
'nom_sel' => NULL,
'nom_ret_nn' => NULL,
'nom_referentiel' => NULL);
$parametres = array_merge($base_param, $parametres);
 
$retour = true;
$requete_modification = "UPDATE cel_obs SET " ;
297,44 → 313,58
* @return $parametres le tableau modifié selon ce qu'il contenait
*/
private function formaterParametresObservation(&$parametres) {
 
$code_referentiel = 'bdtfx';
if(!isset($parametres['nom_referentiel'])) {
$parametres['nom_referentiel'] = 'bdtfx:v1.01';
if(!$parametres['nom_referentiel']) {
$parametres['nom_referentiel'] = Cel::$default_referentiel;
}
$code_referentiel = substr($parametres['nom_referentiel'], 0, 5);
if($this->estUnNomRetenuSansSaisi($parametres)) {
echo $this->estUnNomRetenuSansSaisi($parametres, 'nom_ret_nn');exit;
$parametres['nom_ret']= "";
$parametres['nom_ret_nn']= "";
$parametres['nt']= "";
$parametres['famille']= "";
$code_referentiel = substr(trim($parametres['nom_referentiel']), 0, 5);
 
// TODO/XXX: quoi ?!
if(!$parametres['nom_sel_nn'] && !$parametres['nom_sel'] && $parametres['nom_ret_nn']) {
$parametres['nom_ret'] = $parametres['nom_ret_nn'] = $parametres['nt'] = $parametres['famille'] = "";
}
if ($this->estUnNomSolitaire($parametres)) {
$chercheur_infos_complementaires = new RechercheInfosTaxonBeta($this->config, $code_referentiel);
// Utilisation d'un nom sans numéro nomenclatural, recherche d'une correspondance sur le nom
$complement = $chercheur_infos_complementaires->rechercherInformationsComplementairesSurNom($parametres['nom_sel']);
 
// Si l'on a trouvé un résultat sur la recherche, il s'agit vraisemblablement d'un copié-collé
// de nom de taxon qui n'a pas été validé par la selection
if(count($complement) > 0) {
$parametres['nom_sel_nn'] = $complement[0][0];
/* pour un nom saisi sans autocomplétion 3 cas de figure existent:
1) référentiel bdtfx
1.1) trouvé par le webservice => ref = bdtfx
1.2) pas trouvé par le webservice => ref = autre
2) si le référentiel est inconnu (explicitement mis à "autre"), alors pas d'appel au webservice => ref = autre */
if(in_array($code_referentiel, Cel::$referentiels_valides)) {
// nom saisi sans numéro
if ($parametres['nom_sel'] && !$parametres['nom_sel_nn']) {
$chercheur_infos_complementaires = new RechercheInfosTaxonBeta($this->config, $code_referentiel);
// Utilisation d'un nom sans numéro nomenclatural, recherche d'une correspondance sur le nom
 
$complement = $chercheur_infos_complementaires->rechercherInformationsComplementairesSurNom($parametres['nom_sel']);
 
// Si l'on a trouvé un résultat sur la recherche, il s'agit vraisemblablement d'un copié-collé
// de nom de taxon qui n'a pas été validé par la selection
if(count($complement) > 0) {
$parametres['nom_sel_nn'] = $complement[0][0];
}
else {
// pas de résultat de recherche sur le référentiel demandé, le webservice doit peut-être être corrigé
// mais en tout état de cause nous n'insérerons PAS de données incertaines associé à un référentiel !
$code_referentiel = Cel::$fallback_referentiel;
// note: 'nom_sel_nn' devrait être NULL, donc parametreNumNomEstPresent() ci-dessous ne devrait pas advenir
}
}
}
 
if ($this->parametreNumNomEstPresent($parametres)) {
// Utilisation d'un nom faisant parti du referentiel : recherche du nom valide correspondant
$chercheur_infos_complementaires = new RechercheInfosTaxonBeta($this->config , $code_referentiel);
$complement = $chercheur_infos_complementaires->rechercherInformationsComplementairesSurNumNom($parametres['nom_sel_nn']);
if ($parametres['nom_sel_nn']) {
// Utilisation d'un nom faisant parti du referentiel : recherche du nom valide correspondant
$chercheur_infos_complementaires = new RechercheInfosTaxonBeta($this->config , $code_referentiel);
$complement = $chercheur_infos_complementaires->rechercherInformationsComplementairesSurNumNom($parametres['nom_sel_nn']);
$parametres['nom_ret']=$complement['Nom_Retenu'];
$parametres['nom_ret_nn']=$complement['Num_Nom_Retenu'];
$parametres['nt']=$complement['Num_Taxon'];
$parametres['famille']=$complement['Famille'];
$parametres['nom_ret']=$complement['Nom_Retenu'];
$parametres['nom_ret_nn']=$complement['Num_Nom_Retenu'];
$parametres['nt']=$complement['Num_Taxon'];
$parametres['famille']=$complement['Famille'];
}
}
 
// mise à jour du référentiel utilisé, sans n° de version
$parametres['nom_referentiel'] = $code_referentiel;
if(isset($parametres['ce_utilisateur'])) {
377,41 → 407,6
}
private function estUnNomRetenuSansSaisi($parametres) {
return $this->parametreNumNomPasPresent($parametres) &&
$this->parametreNomSelPasPresent($parametres) &&
$this->parametreEstPresentEtValide($parametres, 'nom_ret_nn');
}
private function parametreEstPresentEtValide($parametres, $index) {
return (isset($parametres[$index]) &&
$parametres[$index] != null &&
$parametres[$index] != '' &&
$parametres[$index] != 0);
}
private function estUnNomSolitaire($parametres) {
return $this->parametreNumNomPasPresent($parametres) && isset($parametres['nom_sel']) && $parametres['nom_sel'] != '';
}
private function parametreNumNomEstPresent($parametres) {
return !$this->parametreNumNomPasPresent($parametres);
}
private function parametreNumNomPasPresent($parametres) {
return (!isset($parametres['nom_sel_nn']) ||
$parametres['nom_sel_nn'] == null ||
$parametres['nom_sel_nn'] == '' ||
$parametres['nom_sel_nn'] == 0);
}
private function parametreNomSelPasPresent($parametres) {
return (!isset($parametres['nom_sel']) ||
$parametres['nom_sel'] == null ||
$parametres['nom_sel'] == '' ||
$parametres['nom_sel'] == 0);
}
/**
* Assemble une sous requete pour un ajout, tout en formatant les paramètres et en recherchant
* les infos complémentaires
425,7 → 420,7
$sous_requete = '';
 
$parametres = $this->formaterParametresObservation($parametres);
 
$champs = '';
$valeurs = '';
461,7 → 456,7
* @return string une sous requete utilisable pour la modification d'une observation
* selon la syntaxe UPDATE table SET colonne1 = valeur1, colonne2 = valeur2 WHERE condition
*/
private function traiterParametresObservationEtConstruireSousRequeteMAJ($parametres) {
private function traiterParametresObservationEtConstruireSousRequeteMaj($parametres) {
$sous_requete = '';
 
/branches/topic-dbsingleton/jrest/lib/ImageRecreation.php
482,6 → 482,19
return $destruction_formats_fichier;
}
 
// recopie de Cel->logger() (pas d'extends pour ça)
public function logger($index,$chaine) {
if(!class_exists('Log')) {
Log::getInstance();
}
 
Log::setCheminLog($this->config['log']['cheminlog']);
Log::setTimeZone($this->config['log']['timezone']);
Log::setTailleMax($this->config['log']['taillemax']);
 
Log::ajouterEntree($index,$chaine);
}
 
/*
* edge-maximizing crop
* determines center-of-edginess, then tries different-sized crops around it.
/branches/topic-dbsingleton/jrest/lib/RechercheObservation.php
131,7 → 131,7
$id_obs = Cel::db()->proteger($id_obs);
$requete = "SELECT courriel_utilisateur FROM cel_obs WHERE id_observation = $id_obs";
 
$utilisateur_courriel = Cel::db()->executerRequete($requete);
$utilisateur_courriel = Cel::db()->executerRequete($requete . ' -- ' . __FILE__ . ':' . __LINE__);
 
$retour = false;
if (!empty($utilisateur_courriel) && isset($utilisateur_courriel[0]['courriel_utilisateur'])) {
/branches/topic-dbsingleton/jrest/lib/GestionImage.php
276,7 → 276,7
 
$manipulateur_image = new ImageRecreation($this->config);
$tableau_ids_image = explode(',',$ids_images);
$tableau_ids_image = explode(',',$chaine_ids_images);
foreach($tableau_ids_image as $id_image_a_detruire) {
$destruction_fichier_image = $manipulateur_image->detruireImageSurDisque($id_image_a_detruire);
/branches/topic-dbsingleton/jrest/lib/RechercheInfosTaxonBeta.php
224,9 → 224,7
// texte libre, nom scientifique,
// ou code nomenclatural (format BDNFFnn999999)
// ou code taxonomique (format BDNFFnt999999)
$identifiant_espece=trim($identifiant_espece);
$identifiant_espece=utf8_encode($identifiant_espece);
 
$retour = array();
//TODO: voir ce qu'on fait pour l'import de différent référentiels
preg_match('/BDNFFnn([0-9][0-9]*)/',$identifiant_espece, $elements);
/branches/topic-dbsingleton/jrest/lib/Cel.php
38,6 → 38,10
protected $start;
protected $limit;
 
static $referentiels_valides = array('bdtfx', 'bdtxa', 'isfan');
static $default_referentiel = 'bdtfx:v1.01';
static $fallback_referentiel = 'autre';
 
public function __construct($config) {
 
@session_start();
297,7 → 301,7
return true;
}
 
public function logger($index,$chaine) {
public function logger($index,$chaine = 'err') {
if(!class_exists('Log')) {
Log::getInstance();
}
/branches/topic-dbsingleton/jrest/lib/FormateurGroupeColonne.php
8,7 → 8,7
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
*/
define('SEPARATEUR_IMAGES', ",");
define('SEPARATEUR_IMAGES', " / ");
 
Class FormateurGroupeColonne {
 
43,6 → 43,32
"syntaxon" => "Syntaxon",
);
 
// TODO: dirty, ordre des champs étendus... souhaité pour florilèges:
static $ordre_champ_etendus_Florileges = array(
"personneStructure",
"personneService",
"personneFonction",
"adresse",
"latitudeDebutRue",
"longitudeDebutRue",
"latitudeFinRue",
"longitudeFinRue",
"typoUrbaine",
"revetementSol",
"presenceZoneVegetalise",
"hauteurBatimentAvoisinant",
"intensiteGestion",
"periodiciteTraitementPhyto",
"dateArretTraitementPhyto",
"itineraireGestion",
"dateDerniereIntervention",
"hauteurPlante",
"resistanceTraitementPhyto",
"vitesseCroissance",
"perceptionTechnicien",
"perceptionRiverainMauvaise",
);
 
static function colGroupsValidation($groupe_de_champs = 'standard,avance') {
if(! $groupe_de_champs) return FALSE;
if(is_string($groupe_de_champs)) {
71,7 → 97,9
* clé: abbrev [machine-name] de la colonne (eg: "espece" ou "mot-clef")
* valeur: des données relative à cette colonne, cf GenColInfo
*
* @TODO: noms communs à part, gestion des champs étendus
* Si la colonne n'utilise pas de fonction de récupération particulière
* (ie: si le champ exportés [ou importé] correspond exactement au champ dans la base de donnée)
* Alors 'abbrev' doit avoir la même valeur que le nom de la colonne dans la table mysql `cel_obs`.
*
*/
static function nomEnsembleVersListeColonnes($groupe_de_champs = 'standard') {
93,55 → 121,136
if(isset($groupe_de_champs['standard'])) {
$colonnes += Array(
'nom_sel' => self::GenColInfo('nom_sel', 'Espèce'),
'nom_sel_nn' => self::GenColInfo('nom_sel_nn', 'Numéro nomenclatural', 0, NULL, NULL, FALSE),
'nom_ret' => self::GenColInfo('nom_ret', 'Nom retenu', 0, NULL, NULL, FALSE),
'nom_ret_nn' => self::GenColInfo('nom_ret_nn', 'Numéro nomenclatural nom retenu', 0, NULL, NULL, FALSE),
'nt' => self::GenColInfo('nt', 'Numéro taxonomique', 0, NULL, NULL, FALSE),
'famille' => self::GenColInfo('famille', 'Famille', 0, NULL, NULL, FALSE),
'nom_referentiel' => self::GenColInfo('nom_referentiel', 'Referentiel taxonomique'),
'zone_geo' => self::GenColInfo('zone_geo', 'Commune'),
'ce_zone_geo' => self::GenColInfo('ce_zone_geo', 'Identifiant Commune', 0, 'convertirCodeZoneGeoVersDepartement'),
'date_observation' => self::GenColInfo('date_observation', 'Date', 0, 'formaterDate'),
'lieudit' => self::GenColInfo('lieudit', 'Lieu-dit'),
'station' => self::GenColInfo('station', 'Station'),
'milieu' => self::GenColInfo('milieu', 'Milieu'),
'commentaire' => self::GenColInfo('commentaire', 'Notes'),
'latitude' => self::GenColInfo('latitude', 'Latitude', 1),
'longitude' => self::GenColInfo('longitude', 'Longitude', 1),
'altitude' => self::GenColInfo('altitude', 'Altitude', 1),
'geodatum' => self::GenColInfo('geodatum', 'Référentiel Géographique', 1, NULL, NULL, FALSE),
'nom_sel' => self::GenColInfo(Array('abbrev' => 'nom_sel',
'nom' => 'Espèce')),
'nom_sel_nn' => self::GenColInfo(Array('abbrev' => 'nom_sel_nn',
'nom' => 'Numéro nomenclatural',
'importable' => FALSE)),
'nom_ret' => self::GenColInfo(Array('abbrev' => 'nom_ret',
'nom' => 'Nom retenu',
'importable' => FALSE)),
'nom_ret_nn' => self::GenColInfo(Array('abbrev' => 'nom_ret_nn',
'nom' => 'Numéro nomenclatural nom retenu',
'importable' => FALSE)),
'nt' => self::GenColInfo(Array('abbrev' => 'nt',
'nom' => 'Numéro taxonomique',
'importable' => FALSE)),
'famille' => self::GenColInfo(Array('abbrev' => 'famille',
'nom' => 'Famille',
'importable' => FALSE)),
'nom_referentiel' => self::GenColInfo(Array('abbrev' => 'nom_referentiel',
'nom' => 'Referentiel taxonomique')),
'zone_geo' => self::GenColInfo(Array('abbrev' => 'zone_geo',
'nom' => 'Commune')),
'ce_zone_geo' => self::GenColInfo(Array('abbrev' => 'ce_zone_geo',
'nom' => 'Identifiant Commune',
'fonction' => 'convertirCodeZoneGeoVersDepartement')),
'date_observation' => self::GenColInfo(Array('abbrev' => 'date_observation',
'nom' => 'Date',
'fonction' => 'formaterDate')),
'lieudit' => self::GenColInfo(Array('abbrev' => 'lieudit',
'nom' => 'Lieu-dit')),
'station' => self::GenColInfo(Array('abbrev' => 'station',
'nom' => 'Station')),
'milieu' => self::GenColInfo(Array('abbrev' => 'milieu',
'nom' => 'Milieu')),
'commentaire' => self::GenColInfo(Array('abbrev' => 'commentaire',
'nom' => 'Notes')),
'latitude' => self::GenColInfo(Array('abbrev' => 'latitude',
'nom' => 'Latitude',
'extra' => 1,
'fonction' => 'trim0')),
'longitude' => self::GenColInfo(Array('abbrev' => 'longitude',
'nom' => 'Longitude',
'extra' => 1,
'fonction' => 'trim0')),
'altitude' => self::GenColInfo(Array('abbrev' => 'altitude',
'nom' => 'Altitude',
'extra' => 1,
'fonction' => 'trim0')),
'geodatum' => self::GenColInfo(Array('abbrev' => 'geodatum',
'nom' => 'Référentiel Géographique',
'extra' => 1,
'importable' => FALSE)),
);
}
if(isset($groupe_de_champs['avance'])) {
$colonnes += array(
// TODO: importable = FALSE car pas de merge de données importées
'ordre' => self::GenColInfo('ordre', 'Ordre', 1, NULL, NULL, FALSE),
'id_observation' => self::GenColInfo('id_observation', 'Identifiant', 1, NULL, NULL, FALSE),
// TODO: importable = FALSE car pas de merge de données importées
'ordre' => self::GenColInfo(Array('abbrev' => 'ordre',
'nom' => 'Ordre',
'extra' => 1,
'importable' => FALSE)),
'id_observation' => self::GenColInfo(Array('abbrev' => 'id_observation',
'nom' => 'Identifiant',
'extra' => 1,
'importable' => FALSE)),
 
'mots_cles_texte' => self::GenColInfo('mots_cles_texte', 'Mots Clés', 1),
'commentaire' => self::GenColInfo('commentaire', 'Commentaires', 1),
'date_creation' => self::GenColInfo('date_creation', 'Date Création', 1, NULL, NULL, FALSE),
'date_modification' => self::GenColInfo('date_modification', 'Date Modification', 1, NULL, NULL, FALSE),
'mots_cles_texte' => self::GenColInfo(Array('abbrev' => 'mots_cles_texte',
'nom' => 'Mots Clés',
'extra' => 1)),
'date_creation' => self::GenColInfo(Array('abbrev' => 'date_creation',
'nom' => 'Date Création',
'extra' => 1,
'importable' => FALSE)),
'date_modification' => self::GenColInfo(Array('abbrev' => 'date_modification',
'nom' => 'Date Modification',
'extra' => 1,
'importable' => FALSE)),
 
// rappel transmission = 1, signifie simplement "public"
// des données importées peuvent être d'emblée "publiques"
// "importable" = TRUE
'transmission' => self::GenColInfo('transmission', 'Transmis', 1),
'date_transmission' => self::GenColInfo('date_transmission', 'Date Transmission', 1, NULL, NULL, FALSE),
'abondance' => self::GenColInfo('abondance', 'Abondance', 1),
'certitude' => self::GenColInfo('certitude', 'Certitude', 1),
'phenologie' => self::GenColInfo('phenologie', 'Phénologie', 1),
// rappel transmission = 1, signifie simplement "public"
// des données importées peuvent être d'emblée "publiques"
// "importable" = TRUE
'transmission' => self::GenColInfo(Array('abbrev' => 'transmission',
'nom' => 'Transmis',
'extra' => 1,
'fonction' => 'boolOuiNon')),
'date_transmission' => self::GenColInfo(Array('abbrev' => 'date_transmission',
'nom' => 'Date Transmission',
'extra' => 1,
'importable' => FALSE)),
'abondance' => self::GenColInfo(Array('abbrev' => 'abondance',
'nom' => 'Abondance',
'extra' => 1)),
'certitude' => self::GenColInfo(Array('abbrev' => 'certitude',
'nom' => 'Certitude',
'extra' => 1)),
'phenologie' => self::GenColInfo(Array('abbrev' => 'phenologie',
'nom' => 'Phénologie',
'extra' => 1)),
// XXX: getImages() dépend du contexte de Cel, et doit être appelée comme cas particulier
// cf ExportXLS::traiterLigneObservation()
'images' => self::GenColInfo(Array('abbrev' => 'images',
'nom' => 'Image(s)',
'extra' => 1,
'fonction_data' => NULL /* cas particulier 'getImages' */,
'importable' => TRUE,
//'preload' => array(__CLASS__, 'getImages_preload')//TODO
)),
 
// XXX: getImages() dépend du contexte de Cel, et doit être appelée comme cas particulier
// cf ExportXLS::traiterLigneObservation()
'images' => self::GenColInfo('images', 'Image(s)', 1, NULL, NULL /* cas particulier 'getImages' */, TRUE),
/* 'nom_commun' => self::GenColInfo(Array('abbrev' => 'nom_commun',
'nom' => 'Nom Commun',
'extra' => 1,
'fonction_data' => 'getNomCommun',
'importable' => FALSE),
 
/* 'nom_commun' => self::GenColInfo('nom_commun', 'Nom Commun', 1, NULL, 'getNomCommun', FALSE),
'nom-commun' => self::GenColInfo('nom-commun', 'Nom Commun', 1, NULL, 'getNomCommun_v2'),
'nom-commun' => self::GenColInfo('nom-commun', 'Nom Commun', 1, NULL, 'getNomCommun_v3'), */
'nom-commun' => self::GenColInfo('nom-commun', 'Nom Commun', 1, NULL, NULL /* cas particu 'getNomCommun_v4' */, TRUE, array(__CLASS__, 'getNomCommun_preload')),
'nom-commun' => self::GenColInfo(Array('abbrev' => 'nom-commun',
'nom' => 'Nom Commun',
'extra' => 1,
'fonction_data' => 'getNomCommun_v2'),
 
'nom-commun' => self::GenColInfo(Array('abbrev' => 'nom-commun',
'nom' => 'Nom Commun',
'extra' => 1,
'fonction_data' => 'getNomCommun_v3'),
'importable' => FALSE), */
'nom-commun' => self::GenColInfo(Array('abbrev' => 'nom-commun',
'nom' => 'Nom Commun',
'extra' => 1,
'fonction_data' => NULL /* cas particu 'getNomCommun_v4' */,
'preload' => array(__CLASS__, 'getNomCommun_preload')))
);
}
 
148,7 → 257,12
if(isset($groupe_de_champs['baseflor'])) {
$colonnes += array(
// champ dynamique
'baseflor' => self::GenColInfo('baseflor', '', 1, NULL, NULL, FALSE, array(__CLASS__, 'baseflor_preload'), array(__CLASS__, 'baseflor_ligne')),
'baseflor' => self::GenColInfo(Array('abbrev' => 'baseflor',
'nom' => '',
'extra' => 1,
'importable' => FALSE,
'preload' => array(__CLASS__, 'baseflor_preload'),
'dyna' => array(__CLASS__, 'baseflor_ligne'))),
);
}
 
155,10 → 269,14
if(isset($groupe_de_champs['etendu'])) {
$colonnes += array(
// champ dynamique
'etendu' => self::GenColInfo('etendu', '', 1, NULL, NULL, FALSE, array(__CLASS__, 'champsEtendus_preload'), array(__CLASS__, 'champsEtendus_ligne')),
'etendu' => self::GenColInfo(Array('abbrev' => 'etendu',
'nom' => '',
'extra' => 1,
'importable' => FALSE,
'preload' => array(__CLASS__, 'champsEtendus_preload'),
'dyna' => array(__CLASS__, 'champsEtendus_ligne'))),
);
}
 
return $colonnes;
}
 
181,7 → 299,7
}
 
public static function getLigneObservation(&$obs, &$colonnes, $cel = false) {
 
$ligne_formatee = array();
foreach($colonnes as $abbrev => $colonne) {
$valeur = null;
277,16 → 395,17
* La fonction doit TOUJOURS alterer la ligne en lui ajoutant une nombre CONSTANT d'éléments (NULL ou non)
* La fonction doit prendre comme arguments ($obs, &$ligne_formatee)
*/
static function GenColInfo($abbrev, $nom, $is_extra = 0, $fonction = NULL, $fonction_data = NULL, $importable = TRUE, $preload = NULL, $fonction_dynamique = NULL) {
return Array('abbrev' => $abbrev,
'nom' => $nom,
'extra' => $is_extra ? 1 : 0,
'fonction' => $fonction,
'fonction_data' => $fonction_data,
'importable' => $importable,
'preload' => $preload,
'dyna' => $fonction_dynamique,
);
static function GenColInfo($args) {
$default = Array('abbrev' => NULL,
'nom' => NULL,
'extra' => 0,
'fonction' => NULL,
'fonction_data' => NULL,
'importable' => TRUE,
'preload' => NULL,
'dyna' => NULL);
$ret = array_intersect_key($args, $default);
return array_merge($default, $ret);
}
static function formaterDate($date_heure_mysql) {
307,17 → 426,37
if(!$date_formatee) return "00/00/0000";
return $date_formatee;
}
 
static function getImages_preload($cel, $obsids) {
if(!$obsids) return;
$rec = $cel->requeter(
sprintf("SELECT o.id_observation, GROUP_CONCAT(nom_original ORDER BY nom_original ASC SEPARATOR '%s') AS i " .
"FROM cel_images i LEFT JOIN cel_obs_images oi ON (i.id_image = oi.id_image) LEFT JOIN cel_obs o ON (oi.id_observation = o.id_observation) " .
"WHERE o.ce_utilisateur = %d AND o.id_observation IN (%s) " .
"GROUP BY id_observation",
SEPARATEUR_IMAGES,
$cel->id_utilisateur,
implode(',', $obsids)));
foreach($rec as $v) {
self::$cache['getImages'][$v['id_observation']] = $v['i'];
}
return NULL;
}
 
static function getImages($obs, $id_utilisateur) {
if(! $id_utilisateur) return NULL;
if(isset(self::$cache['getImages'][$obs['id_observation']]))
return self::$cache['getImages'][$obs['id_observation']];
 
$rec = Cel::db()->requeter(
sprintf("SELECT GROUP_CONCAT(nom_original SEPARATOR '%s') FROM cel_images i"
sprintf("SELECT GROUP_CONCAT(nom_original ORDER BY nom_original ASC SEPARATOR '%s') AS i FROM cel_images i"
." LEFT JOIN cel_obs_images oi ON (i.id_image = oi.id_image)"
." LEFT JOIN cel_obs o ON (oi.id_observation = o.id_observation)"
." WHERE ce_utilisateur = %d",
." WHERE o.ce_utilisateur = %d AND o.id_observation = %d LIMIT 1",
SEPARATEUR_IMAGES,
$id_utilisateur));
return $rec ? array_pop($rec) : NULL;
$id_utilisateur,
$obs['id_observation']));
return $rec ? $rec[0]['i'] : NULL;
}
public static function convertirCodeZoneGeoVersDepartement($code_zone_geo) {
328,6 → 467,14
return $code_departement;
}
 
public static function trim0($lonlat) {
return trim(trim($lonlat, "0"), ".");
}
 
public static function boolOuiNon($transmission) {
return $transmission ? 'oui' : '';
}
public static function estUnCodeInseeDepartement($code_a_tester) {
return preg_match('/^INSEE-C:[0-9]{5}/',$code_a_tester);
489,9 → 636,12
list($referentiel) = explode(':', strtolower($obs['nom_referentiel']));
$cache_id = $referentiel . '-' . $obs['nt'] . '-' . $langue;
 
if(isset(self::$cache['getNomCommun'][$cache_id])) return self::$cache['getNomCommun'][$cache_id];
// XXX: problème de valeurs NULL ?
if(array_key_exists($cache_id, self::$cache['getNomCommun'])) return self::$cache['getNomCommun'][$cache_id];
// cache:
if(isset($cache['getNomCommun'])) {
if(isset(self::$cache['getNomCommun'][$cache_id])) return self::$cache['getNomCommun'][$cache_id];
// XXX: problème de valeurs NULL ?
if(array_key_exists($cache_id, self::$cache['getNomCommun'])) return self::$cache['getNomCommun'][$cache_id];
}
 
// pas de cache:
$nom = Cel::db()->executerRequete(sprintf("SELECT nom_commun FROM cel_references " .
577,11 → 727,18
static function champsEtendus_preload($cel, $obsids) {
$gestion_champs_etendus = new GestionChampsEtendus($cel->config, 'obs');
$colonnes_champs_supp_par_obs = $gestion_champs_etendus->consulterClesParLots($obsids);
// ces deux lignes réordonnent l'ordre des colonnes des champs étendus en fonction de l'ordre (très spécifique)
// de self::$ordre_champ_etendus_Florileges, les champs non-mentionnés sont ajoutés à la fin.
$colonnes_champs_supp_par_obs = self::sortArrayByArray(array_flip($colonnes_champs_supp_par_obs),
self::$ordre_champ_etendus_Florileges);
$colonnes_champs_supp_par_obs = array_keys($colonnes_champs_supp_par_obs);
 
// si le SELECT des clefs ne retourne rien, une autre requêtes est inutile
// TODO: optimize, 1 seule requête
if(!$colonnes_champs_supp_par_obs) return Array('header' => array(), 'data' => array());
 
$champs_supp_par_obs = $gestion_champs_etendus->consulterParLots($obsids);
 
self::$cache['champsEtendus']['header'] = $colonnes_champs_supp_par_obs;
foreach($champs_supp_par_obs as &$v) {
$v = self::champsEtendus_aplatir($v);
632,4 → 789,20
// XXX/ array_merge() ?
$ligne += $ligne_etendue_fmt;
}
 
/* HELPERS */
 
// http://stackoverflow.com/questions/348410/sort-an-array-based-on-another-array
// XXX; redéfinition, utilisé aussi par ExportXLS
static function sortArrayByArray($array, $orderArray) {
$ordered = array();
foreach($orderArray as $key) {
if(array_key_exists($key, $array)) {
$ordered[$key] = $array[$key];
unset($array[$key]);
}
}
return $ordered + $array;
}
 
}
/branches/topic-dbsingleton/src/org/tela_botanica/client/vues/image/GalerieImageVue.java
206,7 → 206,7
 
for (int i = 0; i < selection.length; i++) {
 
id_selection[i] = selection[i].getAsString("num_image");
id_selection[i] = selection[i].getAsString("id_image");
}
 
return id_selection;
Property changes:
Deleted: svn:mergeinfo
/branches/topic-dbsingleton/src/org/tela_botanica/client/modeles/objets/InfosReferentielNom.java
15,8 → 15,12
String[] codeVersion = codeCompletIntitule[0].split(":");
code = codeVersion[0];
version = codeVersion[1];
versionCourte = formaterVersionCourte(version);
if(codeVersion.length > 1) {
version = codeVersion[1];
versionCourte = formaterVersionCourte(version);
} else {
version = versionCourte = null;
}
}
public InfosReferentielNom(String code, String version, String intitule) {
/branches/topic-dbsingleton/war/config.defaut.js
9,7 → 9,7
utiliseRedirectionImage:"1",
referentielGeo:"WGS84",
cleGoogleMaps:"ABQIAAAADBUAHF9l14gI02QVAbUYJBRqPsByHDhzHLE0yoC9hASLZaFmoRT4_9Zkiscf-BaH_gEy7DVHX5BxwQ",
referentielsDispos:"bdtfx:v1.01,Métropole (BDTFX);bdtxa:v1.00,Antilles Françaises (BDTXA);isfan:v1.00,Afrique du Nord (ISFAN)",
referentielsDispos:"bdtfx:v1.01,Métropole (BDTFX);bdtxa:v1.00,Antilles Françaises (BDTXA);isfan:v1.00,Afrique du Nord (ISFAN);autre,Autre/Inconnu",
refTaxVersion:"1",
lienEfloreBaseUrl:"www.tela-botanica.org/eflore",
licence:"",
/branches/topic-dbsingleton/war/modele_import.xls
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/topic-dbsingleton
Property changes:
Modified: svn:mergeinfo
Merged /trunk:r1740-1761