New file |
0,0 → 1,409 |
<?php |
/** |
* Service fournissant la liste des structures et leurs informations. |
* |
* @author Raphaël Droz <raphael@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @Copyright (c) 2009, 2013 Tela Botanica (accueil@tela-botanica.org) |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
*/ |
class CoelStructure extends Coel { |
|
static $optional_bool_fields = array( |
'cs_nbre_personne', |
'csc_mark_formation', 'csc_mark_formation_interet', |
'csc_mark_collection_commune', 'csc_mark_acces_controle', 'csc_mark_restauration', 'csc_mark_traitement', |
'csc_mark_acquisition_collection', 'csc_mark_acquisition_echantillon', |
'csv_mark_action', 'csv_mark_action_future', 'csv_mark_recherche', 'csv_mark_acces_ss_motif', 'csv_mark_visite_avec_motif', |
'cs_latitude', 'cs_longitude', |
); |
|
// ATTENTION : tjrs garder la table principale en premier, puis mettre les tables spécialisées. |
protected $tables = array( 120 => array( |
'nom' => 'coel_structure', |
'prefixe' => 'cs', |
'id' => array('cs_id_structure')), |
122 => array( |
'nom' => 'coel_structure_conservation', |
'prefixe' => 'csc', |
'id' => array('csc_id_structure')), |
123 => array( |
'nom' => 'coel_structure_valorisation', |
'prefixe' => 'csv', |
'id' => array('csv_id_structure'))); |
|
/** |
* Méthode principale appelée avec une requête de type GET. |
*/ |
public function getElement($param = array()) { |
// Initialisation des variables |
$info = array(); |
|
// Nour recherchons le type de requête demandé |
$type = $param[0]; |
|
if ($type == '*' || is_numeric($type)) { |
// Pré traitement des paramêtres |
$p = $this->traiterParametresUrl(array('id_structure', 'recherche'), $param); |
$info = $this->getElementParDefaut($p); |
} else { |
$methode = 'getElement'.$type; |
if (method_exists($this, $methode)) { |
array_shift($param); |
$info = $this->$methode($param); |
} else { |
$this->messages[] = "Le type d'information demandé '$type' n'est pas disponible."; |
} |
} |
|
// Envoie sur la sortie standard |
$this->envoyer($info); |
} |
|
/** |
* Méthode par défaut pour garder la compatibilité avec Coel. |
* Appelée avec les paramêtres d'url suivant : |
* /CoelStructure/_/_/_ |
* ou les _ représentent dans l'ordre : id_structure et nom |
* Si un des paramêtres est abscent, il prendre la valeur * |
*/ |
public function getElementParDefaut($p) { |
// Initialisation des variables |
$info = array(); |
|
$whereClause = array(); |
if(isset($p['id_structure'])) $whereClause[] = "cs_id_structure = {$p['id_structure']}"; |
|
if(isset($p['recherche'])) { |
if(@$this->searchCity && trim($this->searchCity) == 'true') { |
$whereClause[] = "(" . implode(" OR ", array("cs_nom LIKE {$p['recherche']}", "cs_ville LIKE {$p['recherche']}")) . ")"; |
} else { |
$whereClause[] = "cs_nom LIKE {$p['recherche']}"; |
} |
} |
|
// Construction de la requête |
$requete = sprintf( |
'SELECT SQL_CALC_FOUND_ROWS %s cs.*, csc.*, csv.*, cmhl_date_modification, cmhl_notes, cmhl_source, cmhl_ce_modifier_par, cmhl_ce_etat, cmhl_ip ' |
. ' FROM coel_structure AS cs ' |
. ' LEFT JOIN coel_meta_historique_ligne ON (cs_ce_meta = cmhl_id_historique_ligne) ' |
. ' LEFT JOIN coel_structure_conservation AS csc ON (cs_id_structure = csc_id_structure) ' |
. ' LEFT JOIN coel_structure_valorisation AS csv ON (cs_id_structure = csv_id_structure) ' |
. ' WHERE %s ORDER BY %s LIMIT %d, %d -- %s:%d', |
|
$this->distinct ? 'DISTINCT' : '', |
$whereClause ? implode(" AND ", $whereClause) : TRUE, |
is_null($this->orderby) ? 'cs.cs_nom ASC' : $this->orderby, |
$this->start, $this->limit, |
__FILE__, __LINE__); |
|
// Récupération des résultats |
try { |
// SPÉCIAL : |
// Lorsqu'on cherche une seule structure avec un id passé en paramêtre, nous devons renvoyer un objet |
$donnees = ($this->formatRetour == 'objet' && isset($p['id_structure'])) ? $this->bdd->query($requete)->fetch(PDO::FETCH_OBJ) : $this->bdd->query($requete)->fetchAll(PDO::FETCH_ASSOC); |
if ($donnees === false) { |
$this->messages[] = "La requête a retourné aucun résultat."; |
} |
|
// l'UI java n'aime pas les NULL |
if(!is_array($donnees)) { |
// $donnees est un objet PHP |
array_walk($donnees, create_function('&$val', '$val = is_null($val) ? "" : $val;')); |
} |
else { |
// $donnees est un tableau d'objets PHP |
foreach($donnees as &$structure) { |
array_walk($structure, create_function('&$val', '$val = is_null($val) ? "" : $val;')); |
} |
} |
|
$elements_nbre = $this->bdd->query("SELECT FOUND_ROWS() AS c")->fetch(PDO::FETCH_ASSOC); |
$info['nbElements'] = intval($elements_nbre['c']); |
$info['structures'] = $donnees; |
} catch (PDOException $e) { |
$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage()); |
} |
|
return $info; |
} |
|
/* Méthode pour récupérer le nombre de structure par zone géographique. |
* Appelée avec les paramêtres d'url suivant : |
* /CoelStructure/ParZoneGeo/_ |
* ou les _ représentent dans l'ordre : type. |
* ou type peut valoir: FRD (= département français) |
* Si un des paramêtres est abscent, il prendre la valeur * |
*/ |
public function getElementParZoneGeo($param) { |
// Pré traitement des paramêtres |
$p = $this->traiterParametresUrl(array('type'), $param); |
if (!isset($p['type'])) { |
$this->messages[] = "Il est obligatoire d'indiquer type de recherche pour utiliser ce service."; |
return array(); |
} |
|
// Construction de la requête |
$requete = (($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' '. |
' IF ( SUBSTRING( cs_code_postal FROM 1 FOR 2 ) >= 96, '. |
' SUBSTRING( cs_code_postal FROM 1 FOR 3 ), '. |
' SUBSTRING( cs_code_postal FROM 1 FOR 2 ) ) AS id, '. |
' COUNT( cs_id_structure ) AS nbre '. |
'FROM coel_structure '. |
'WHERE cs_ce_truk_pays = 2654 '. |
'GROUP BY IF ( SUBSTRING( cs_code_postal FROM 1 FOR 2 ) >= 96, '. |
' SUBSTRING( cs_code_postal FROM 1 FOR 3 ), '. |
' SUBSTRING( cs_code_postal FROM 1 FOR 2 ) ) '. |
'ORDER BY '.((!is_null($this->orderby)) ? $this->orderby : 'id ASC').' '; |
|
// Récupération des résultats |
try { |
$donnees = $this->bdd->query($requete)->fetchAll(PDO::FETCH_ASSOC); |
} catch (PDOException $e) { |
$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage()); |
} |
|
if ($donnees === false) { |
$this->messages[] = "La requête a retourné aucun résultat."; |
return array(); |
} |
|
$info = array(); |
foreach ($donnees as $donnee) { |
$info[$donnee['id']] = $donnee['nbre']; |
} |
return $info; |
} |
|
|
static function NULLifNotNum(&$params, $keys_to_null) { |
foreach($keys_to_null as $v) { |
if(! array_key_exists($v, $params)) continue; |
if(!is_numeric($params[$v]) && ! preg_match('/^-?\d+,\d*$/', $params[$v])) { |
$params[$v] = NULL; |
} |
else { |
$params[$v] = str_replace(',', '.', $params[$v]); |
} |
|
} |
} |
|
/** |
* Méthode appelée pour ajouter un élément. |
*/ |
public function createElement($params) { |
// Identification de l'utilisateur |
list($id_utilisateur, $id_session) = $this->getIdentification($params); |
|
// Contrôle du non détournement de l'utilisateur |
if (!$this->etreAutorise($id_utilisateur)) { |
$this->envoyer(); |
return; |
} |
try { |
$form_needs_refresh = self::callNominatim($params, $this->bdd); |
|
self::NULLifNotNum($params, self::$optional_bool_fields); |
|
// Vérification des tables à vraiment mettre à jour en fonction des données passées. |
$tables_a_modifier = $this->recupererTablesAModifier($params); |
reset($tables_a_modifier); |
|
$id_structure = null; |
while (list($table_id, $table) = each($tables_a_modifier)) { |
if (is_null($table['champs'])) continue; |
if ($this->avoirCleComplete($table)) { |
$this->mettreAJourAvecCle($id_utilisateur, $id_session, $table_id, $table); |
continue; |
} |
|
// Ajout des données à la table des données |
$id_structure = $this->ajouter($table); |
if ($id_structure === false) continue; |
|
$table['champs_valeurs_id']['cs_id_structure'] = $id_structure; |
$table['champs_valeurs_brut']['cs_id_structure'] = $id_structure; |
$tables_a_modifier[122]['champs_valeurs_id']['csc_id_structure'] = $id_structure; |
$tables_a_modifier[122]['champs_valeurs_brut']['csc_id_structure'] = $id_structure; |
$tables_a_modifier[122]['champs_valeurs_protege']['csc_id_structure'] = $this->bdd->quote($id_structure); |
$tables_a_modifier[123]['champs_valeurs_id']['csv_id_structure'] = $id_structure; |
$tables_a_modifier[123]['champs_valeurs_brut']['csv_id_structure'] = $id_structure; |
$tables_a_modifier[123]['champs_valeurs_protege']['csv_id_structure'] = $this->bdd->quote($id_structure); |
|
// Historisation (Ajout des méta-données) |
$etat = 1; // Ajout |
$cle = $this->recupererCle($table); |
$info = $this->creerXmlHisto($table['champs_valeurs_brut']); |
$id_meta = $this->historiser($table_id, $cle, $info, $id_utilisateur, $etat, $id_session); |
|
// Liaison de la table des données à ses méta-données |
$champ_meta = "{$table['prefixe']}_ce_meta"; |
$table['champs_valeurs_protege'] = array($champ_meta => $id_meta); |
$this->modifier($table); |
} |
|
if(isset($params['cpr_abreviation']) && !empty($params['cpr_abreviation'])) { |
$this->ajouterGuid($params['cpr_abreviation'], $id_structure); |
} |
} catch (PDOException $e) { |
$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete); |
} |
|
if($form_needs_refresh) { // coordonnées mises à jour en DB: en informer le formulaire |
$this->envoyer($this->getElementParDefaut(array('id_structure' => $id_structure))); |
exit; |
} |
|
$this->envoyer($id_structure); |
} |
|
/** |
* Méthode appelée pour mettre à jour un élément |
*/ |
public function updateElement($uid, $params) { |
// Vérification de la présence des id passés par l'url |
if (!isset($uid[0])) { |
$this->messages[] = "Identifiant de structure manquant. Vous ne devriez pas avoir accès à ce service."; |
$this->envoyer(); |
return; |
} |
|
// Identification de l'utilisateur |
list($id_utilisateur, $id_session) = $this->getIdentification($params); |
// Contrôle du non détournement de l'utilisateur |
if (!$this->etreAutorise($id_utilisateur)) { |
$this->envoyer(); |
return; |
} |
try { |
$form_needs_refresh = self::callNominatim($params, $this->bdd); |
|
self::NULLifNotNum($params, self::$optional_bool_fields); |
|
// Vérification des tables à vraiment mettre à jour en fonction des données passées. |
$tables_a_modifier = $this->recupererTablesAModifier($params); |
// Pour chaque table du module nous lançons si nécessaire l'historisation puis la mise à jour |
foreach ($tables_a_modifier as $table_id => $table) { |
if(@$table['nom'] == 'coel_structure' && !$this->avoirCleComplete($table)) { |
error_log("tentative d'UPDATE sans contrainte de WHERE, \$table = " . print_r($table, TRUE)); |
continue; // ne pas mettre à jour sans contrainte de WHERE |
} |
$this->mettreAJourAvecCle($id_utilisateur, $id_session, $table_id, $table); |
} |
} catch (PDOException $e) { |
$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage()); |
} |
|
// Envoie sur la sortie standard |
|
if($form_needs_refresh) { // coordonnées mises à jour en DB: en informer le formulaire (si resté ouvert) |
$this->envoyer($this->getElementParDefaut(array('id_structure' => $uid[0]))); |
exit; |
} |
$this->envoyer(); // OK par défaut |
} |
|
/** |
* Méthode appelée pour supprimer un élément |
*/ |
public function deleteElement($uid) { |
// NOTES : une structure ne peut pas être supprimée si elle possède des collections liées. |
// Vérification de la présence des id passés par l'url |
if (!isset($uid[0]) || !isset($uid[1])) { |
$this->messages[] = "Identifiant de structure ou d'utilisateur manquant. Vous ne devriez pas avoir accès à ce service."; |
$this->envoyer(); |
return; |
} |
|
// Identification de l'utilisateur |
list($id_utilisateur, $id_session) = $this->getIdentification($uid[0]); |
// Contrôle du non détournement de l'utilisateur |
if (! $this->etreAutorise($id_utilisateur)) { |
$this->envoyer(); |
return; |
} |
|
// Récupération des id passés par l'url |
$identifiants = explode(',', rtrim($uid[1], ',')); |
|
if (count($identifiants) == 0) { |
$this->messages[] = "Aucun enregistrement n'a été supprimé."; |
$this->envoyer(); |
return; |
} |
|
try { |
foreach ($identifiants as $id_structure) { |
// Vérification que la structure ne possède pas de collections liées |
if (self::verifierPresenceCollection($this->bdd, $id_structure)) { |
$this->messages[] = "La structure '$id_structure' ne peut pas être supprimée car elle possède des collections liées."; |
continue; |
} |
|
$params = array('cs_id_structure' => $id_structure, 'csc_id_structure' => $id_structure, 'csv_id_structure' => $id_structure); |
$tables_a_modifier = $this->recupererTablesAModifier($params); |
|
foreach ($tables_a_modifier as $table_id => $table) { |
if (! $this->avoirEnregistrement($table)) continue; |
|
if ($this->supprimer($table) === true) { |
// Historisation (Ajout des méta-données) |
$cle = $this->recupererCle($table); |
$this->historiser($table_id, $cle, 'NULL', $id_utilisateur, 3, $id_session); |
} |
} |
} |
} catch (PDOException $e) { |
$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete); |
} |
|
// Envoie sur la sortie standard |
$this->envoyer(); |
} |
|
static function verifierPresenceCollection($db, $id_structure) { |
// Vérification que la structure ne possède pas de collections liées |
return ($db->query(sprintf( |
'SELECT COUNT(cc_id_collection) AS nbre_collection FROM coel_collection ' . |
' WHERE cc_ce_structure = %d GROUP BY cc_ce_structure ', |
$id_structure))->fetchColumn() != 0); |
} |
|
static function callNominatim(&$params, $db = NULL) { |
// lon/lat déjà saisies ? |
if (@$params['cs_latitude'] && @$params['cs_longitude']) return FALSE; |
|
// ni adresse, ni CP, ni ville ? rien n'est possible |
if (!@$params['cs_adresse_01'] && !@$params['cs_code_postal'] && !@$params['cs_ville']) return FALSE; |
|
$lonlat = array(); |
if(Coel::coordGuess(Coel::addrReStruct($params, $db), $lonlat)) { |
$params['cs_latitude'] = $lonlat['lat']; |
$params['cs_longitude'] = $lonlat['lon']; |
return TRUE; |
} |
|
// second guess, sans code postal |
if(@$params['cs_code_postal']) { |
$params2 = $params; |
unset($params2['cs_code_postal']); |
if(Coel::coordGuess(Coel::addrReStruct($params2, $db), $lonlat)) { |
$params['cs_latitude'] = $lonlat['lat']; |
$params['cs_longitude'] = $lonlat['lon']; |
return TRUE; |
} |
} |
return FALSE; |
} |
|
private function ajouterGuid($id_structure) { |
if ($id_structure !== false) { |
$table_guid = $this->tables[120]; |
$table_guid['champs_valeurs_id']['cs_id_structure'] = $id_structure; |
$table_guid['champs_valeurs_protege']['cs_guid'] = $this->bdd->quote(sprintf($this->config['coel']['guid'], 'str'.$id_structure)); |
$this->modifier($table_guid); |
} |
} |
} |