154,10 → 154,12 |
* @param array $parametres les paramètres situés après le ? dans l'url |
**/ |
public function consulter($ressources, $parametres) { |
// SELECT, à terme, pourrait affecter getInfos(), mais en aucune manière getIdObs() |
$req = array('select' => array(), 'join' => array(), 'where' => array(), 'groupby' => array(), 'having' => array()); |
|
// toujours nécessaire puisque nous tapons sur v_del_image qui INNER JOIN cel_images, or nous voulons certes |
// toutes les images, mais nous voulons $limite observations uniques. |
$req['groupby'][] = 'dob.id_observation'; |
$req['groupby'][] = 'vdi.id_observation'; |
|
$db = $this->bdd; |
|
165,6 → 167,7 |
$params = self::requestFilterParams($parametres, self::$parametres_autorises, $this->conteneur); |
// création des contraintes (masques) |
self::sqlAddConstraint($params, $db, $req, $this->conteneur); |
self::sqlAddMasqueConstraint($params, $db, $req, $this->conteneur); |
|
// 1) grunt-work: *la* requête de récupération des id valides (+ SQL_CALC_FOUND_ROWS) |
$idobs_tab = self::getIdObs($params, $req, $db); |
175,6 → 178,8 |
$total = $db->recuperer('SELECT FOUND_ROWS() AS c'); $total = intval($total['c']); |
|
// 2) récupération des données nécessaires pour ces observations (obs + images) |
// ici les champs récupérés sont issus de self::$sql_fields_liaisons mais sans préfixes |
// car tout provient de v_del_image |
$obs_unfmt = self::getInfos($idobs, $db); |
|
// 3) suppression, merge des données en tableau assez représentatif du futur JSON en output |
222,7 → 227,7 |
*/ |
static function getIdObs($p, $req, $db) { |
$req_s = sprintf('SELECT SQL_CALC_FOUND_ROWS id_observation' . |
' FROM v_del_image dob'. |
' FROM v_del_image vdi'. |
' %s' . // LEFT JOIN if any |
' WHERE %s'. // where-clause ou TRUE |
' %s'. // group-by |
238,6 → 243,7 |
|
$p['tri'], strtoupper($p['ordre']), |
// date_transmission peut-être NULL et nous voulons de la consistence |
// (sauf après r1860 de Cel) |
$p['tri'] == 'date_transmission' ? ', id_observation' : '', |
|
$p['navigation.depart'], $p['navigation.limite'], __FILE__ . ':' . __LINE__); |
256,18 → 262,20 |
/* |
Champs récupérés: |
Pour del_images, la vue retourne déjà ce que nous recherchons de cel_obs et cel_images |
(cel_obs.* et cel_images.{id_observation, doi.id_image, date_prise_de_vue AS date, hauteur , largeur}) |
(cel_obs.* et cel_[obs_]images.{id_observation, id_image, date_prise_de_vue AS date, hauteur, largeur}) |
Pour del_commentaires: nous voulons * |
Reste ensuite à formatter |
Reste ensuite à formatter. |
Note: le préfixe de table utilisé ici (vdi) n'impacte *aucune* autre partie du code car rien |
n'en dépend pour l'heure. (inutilisation de $req['select']) |
*/ |
static function getInfos($idobs, $db) { |
/*$select_fields = implode(',', array_merge( |
array_map(create_function('$a', 'return "dob.".$a;'), self::$sql_fields_liaisons['dob']), |
array_map(create_function('$a', 'return "di.".$a;'), self::$sql_fields_liaisons['di']), |
array_map(create_function('$a', 'return "vdi.".$a;'), self::$sql_fields_liaisons['dob']), |
array_map(create_function('$a', 'return "vdi.".$a;'), self::$sql_fields_liaisons['di']), |
array_map(create_function('$a', 'return "du.".$a;'), self::$sql_fields_liaisons['du'])));*/ |
$select_fields = array_merge(self::$sql_fields_liaisons['dob'], |
self::$sql_fields_liaisons['di']); |
$req_s = sprintf('SELECT %s FROM v_del_image di'. |
$req_s = sprintf('SELECT %s FROM v_del_image vdi'. |
// ' LEFT JOIN del_commentaire AS dc ON di.id_observation = dc.ce_observation AND dc.nom_sel IS NOT NULL'. |
' WHERE id_observation IN (%s)', |
implode(',', $select_fields), |
278,7 → 286,8 |
|
/** |
* - Rempli le tableau des contraintes "where" et "join" nécessaire |
* à la *recherche* des observations demandées ($req) |
* à la *recherche* des observations demandées ($req) utilisées par self::getIdObs() |
* |
* Attention, cela signifie que toutes les tables ne sont pas *forcément* |
* join'ées, par exemple si aucune contrainte ne le nécessite. |
* $req tel qu'il est rempli ici est utile pour récupéré la seule liste des |
286,14 → 295,13 |
* Pour la récupération effective de "toutes" les données correspondante, il faut |
* réinitialiser $req["join"] afin d'y ajouter toutes les autres tables. |
* |
* Note: toujours rajouter les préfixes de table (dob,du,doi ou di) |
* le préfix de del_observation est "dob" |
* le préfix de del_utilisateur sur id_utilisateur = dob.ce_utilisateur est "du" |
* le préfix de del_obs_image sur id_observation = dob.id_observation est "doi" |
* le préfix de v_del_image sur id_image = doi.id_image est "di" |
* Note: toujours rajouter les préfixes de table (vdi,du,doi ou di), en fonction de ce que défini |
* les JOIN qui sont utilisés. |
* le préfix de v_del_image est "vdi" (cf: "FROM" de self::getIdObs()) |
* le préfix de del_utilisateur sur id_utilisateur = vdi.ce_utilisateur est "du" |
* |
* @param $p les paramètres (notamment de masque) passés par l'URL et déjà traités/filtrés (sauf quotes) |
* @param $req le tableau représentant les composants de la requête à bâtir |
* @param $req le tableau, passé par référence représentant les composants de la requête à bâtir |
* @param $c conteneur, utilisé soit pour l'appel récursif à requestFilterParams() en cas de param "masque" |
* soit pour la définition du type (qui utilise la variable nb_commentaires_discussion) |
*/ |
300,16 → 308,16 |
static function sqlAddConstraint($p, $db, &$req, Conteneur $c = NULL) { |
if(!empty($p['masque.auteur'])) { |
// id du poster de l'obs |
$req['join'][] = 'LEFT JOIN del_utilisateur AS du ON du.id_utilisateur = dob.ce_utilisateur'; |
$req['join'][] = 'LEFT JOIN del_utilisateur AS du ON du.id_utilisateur = vdi.ce_utilisateur'; |
// id du poster de l'image... NON, c'est le même que le posteur de l'obs |
// Cette jointure de table est ignoré ci-dessous pour les recherches d'auteurs |
// $req['join'][] = 'LEFT JOIN del_utilisateur AS dui ON dui.id_utilisateur = dob.i_ce_utilisateur'; |
// $req['join'][] = 'LEFT JOIN del_utilisateur AS dui ON dui.id_utilisateur = vdi.i_ce_utilisateur'; |
|
if(is_numeric($p['masque.auteur'])) { |
$req['where'][] = sprintf('(du.id_utilisateur = %1$d OR dob.id_utilisateur = %1$d )', $p['masque.auteur']); |
$req['where'][] = sprintf('(du.id_utilisateur = %1$d OR vdi.id_utilisateur = %1$d )', $p['masque.auteur']); |
} |
elseif(preg_match(';^.{5,}@[a-z0-9-.]{5,}$;i', $p['masque.auteur'])) { |
$req['where'][] = sprintf('(du.courriel LIKE %1$s OR dob.courriel LIKE %1$s )', |
$req['where'][] = sprintf('(du.courriel LIKE %1$s OR vdi.courriel LIKE %1$s )', |
$db->proteger($p['masque.auteur'] . '%')); |
} |
else { |
319,10 → 327,10 |
|
if(!empty($p['masque.date'])) { |
if(is_integer($p['masque.date']) && $p['masque.date'] < 2030 && $p['masque.date'] > 1600) { |
$req['where'][] = sprintf("YEAR(dob.date_observation) = %d", $p['masque.date']); |
$req['where'][] = sprintf("YEAR(vdi.date_observation) = %d", $p['masque.date']); |
} |
else { |
$req['where'][] = sprintf("DATE_FORMAT(dob.date_observation, '%%Y-%%m-%%d') = %s", |
$req['where'][] = sprintf("DATE_FORMAT(vdi.date_observation, '%%Y-%%m-%%d') = %s", |
$db->proteger(strftime('%Y-%m-%d', $p['masque.date']))); |
} |
} |
329,33 → 337,33 |
|
// TODO: avoir des champs d'entrée distinct |
if(!empty($p['masque.departement'])) { |
$req['where'][] = sprintf("dob.ce_zone_geo = %s", $db->proteger('INSEE-C:'.$p['masque.departement'])); |
$req['where'][] = sprintf("vdi.ce_zone_geo = %s", $db->proteger('INSEE-C:'.$p['masque.departement'])); |
} |
if(!empty($p['masque.id_zone_geo'])) { |
$req['where'][] = sprintf("dob.ce_zone_geo = %s", $db->proteger($p['masque.id_zone_geo'])); |
$req['where'][] = sprintf("vdi.ce_zone_geo = %s", $db->proteger($p['masque.id_zone_geo'])); |
} |
if(!empty($p['masque.genre'])) { |
$req['where'][] = 'dob.nom_sel LIKE '.$db->proteger('%' . $p['masque.genre'].'% %'); |
$req['where'][] = 'vdi.nom_sel LIKE '.$db->proteger('%' . $p['masque.genre'].'% %'); |
} |
if(!empty($p['masque.famille'])) { |
$req['where'][] = 'dob.famille = '.$db->proteger($p['masque.famille']); |
$req['where'][] = 'vdi.famille = '.$db->proteger($p['masque.famille']); |
} |
if(!empty($p['masque.ns'])) { |
$req['where'][] = 'dob.nom_sel LIKE '.$db->proteger($p['masque.ns'].'%'); |
$req['where'][] = 'vdi.nom_sel LIKE '.$db->proteger($p['masque.ns'].'%'); |
} |
if(!empty($p['masque.nn'])) { |
$req['where'][] = sprintf('dob.nom_sel_nn = %1$d OR dob.nom_ret_nn = %1$d', $p['masque.nn']); |
$req['where'][] = sprintf('vdi.nom_sel_nn = %1$d OR vdi.nom_ret_nn = %1$d', $p['masque.nn']); |
} |
if(!empty($p['masque.referentiel'])) { |
$req['where'][] = sprintf('dob.nom_referentiel LIKE %s', $db->proteger($p['masque.referentiel'].'%')); |
$req['where'][] = sprintf('vdi.nom_referentiel LIKE %s', $db->proteger($p['masque.referentiel'].'%')); |
} |
if(!empty($p['masque.commune'])) { |
$req['where'][] = 'dob.zone_geo LIKE '.$db->proteger($p['masque.commune'].'%'); |
$req['where'][] = 'vdi.zone_geo LIKE '.$db->proteger($p['masque.commune'].'%'); |
} |
if(!empty($p['masque.tag'])) { |
// i_mots_cles_texte provient de la VIEW v_del_image |
$req['where'][] = sprintf('CONCAT(%s) REGEXP %s', |
self::sqlAddIfNullPourConcat(array('dob.mots_cles_texte', 'dob.i_mots_cles_texte')), |
self::sqlAddIfNullPourConcat(array('vdi.mots_cles_texte', 'vdi.i_mots_cles_texte')), |
$db->proteger($p['masque.tag'])); |
} |
|
362,11 → 370,13 |
if(!empty($p['masque.type'])) { |
self::addTypeConstraints($p['masque.type'], $db, $req, $c); |
} |
} |
|
/* Le masque fait une recherche générique parmi de nombreux champs ci-dessus. |
Nous initialisons donc ces paramètres (excepté masque biensur), et nous rappelons |
récursivement. À la seule différence que nous n'utiliserons que $or_req['where'] |
imploded par des " OR ". */ |
static function sqlAddMasqueConstraint($p, $db, &$req, Conteneur $c = NULL) { |
if(!empty($p['masque'])) { |
$or_params = array('masque.auteur' => $p['masque'], |
'masque.departement' => $p['masque'], |
376,7 → 386,7 |
'masque.famille' => $p['masque'], |
'masque.date' => $p['masque'], |
'masque.genre' => $p['masque'], |
/* milieu: TODO */ ); |
/* milieu: TODO ? */ ); |
$or_masque = self::requestFilterParams($or_params, array_keys($or_params), $c); |
// $or_req = array('select' => array(), 'join' => array(), 'where' => array(), 'groupby' => array(), 'having' => array()); |
$or_req = array('join' => array(), 'where' => array()); |
410,7 → 420,7 |
|
/* |
Retourne une clausse where du style: |
CONCAT(IF(du.prenom IS NULL, "", du.prenom), [...] dob.i_nomutilisateur) REGEXP 'xxx' |
CONCAT(IF(du.prenom IS NULL, "", du.prenom), [...] vdi.i_nomutilisateur) REGEXP 'xxx' |
Note; i_(nom|prenom_utilisateur), alias pour cel_images.(nom|prenom), n'est pas traité |
car cette information est redondante dans cel_image et devrait être supprimée. |
*/ |
418,11 → 428,11 |
@list($a, $b) = explode(' ', $val, 2); |
// un seul terme |
$champs_n = array('du.prenom', // info user authentifié de l'obs depuis l'annuaire |
'dob.prenom_utilisateur', // info user anonyme de l'obs |
/* 'dob.i_prenom_utilisateur' */ ); // info user anonyme de l'image |
'vdi.prenom_utilisateur', // info user anonyme de l'obs |
/* 'vdi.i_prenom_utilisateur' */ ); // info user anonyme de l'image |
$champs_p = array('du.nom', // idem pour le nom |
'dob.nom_utilisateur', |
/* 'dob.i_nom_utilisateur' */ ); |
'vdi.nom_utilisateur', |
/* 'vdi.i_nom_utilisateur' */ ); |
if(! $b) { |
$where[] = sprintf('CONCAT(%s) REGEXP %s', |
self::sqlAddIfNullPourConcat($champs_n). |
446,17 → 456,17 |
if(array_key_exists('adeterminer', $val)) { |
//On récupère toutes les observations qui on le tag "aDeterminer" *ou* qui n'ont pas de nom d'espèce |
$req['where'][] = '(' . implode(' OR ', array( |
'dob.certitude = "aDeterminer"', |
'dob.mots_cles_texte LIKE "%aDeterminer%"', |
'dob.nom_sel_nn IS NULL', // TODO: ensure pas d'entrée à 0 |
'vdi.certitude = "aDeterminer"', |
'vdi.mots_cles_texte LIKE "%aDeterminer%"', |
'vdi.nom_sel_nn IS NULL', // TODO: ensure pas d'entrée à 0 |
)) . ')'; |
} |
if(array_key_exists('aconfirmer', $val)) { |
//On récupère toutes les observations qui ne sont pas "aDeterminer" *et* qui ont un nom d'espèce |
$req['where'][] = '(' . implode(' AND ', array( |
'dob.nom_sel IS NOT NULL', |
'dob.certitude != "aDeterminer"', |
'(dob.mots_cles_texte IS NULL OR dob.mots_cles_texte NOT LIKE "%aDeterminer%"', |
'vdi.nom_sel IS NOT NULL', |
'vdi.certitude != "aDeterminer"', |
'(vdi.mots_cles_texte IS NULL OR vdi.mots_cles_texte NOT LIKE "%aDeterminer%"', |
)) . ')'; |
} |
|
465,8 → 475,8 |
//Si on veut les observations en discussion, |
// on va récupérer les ids des observations dont le nombre de commentaire est supérieur à N |
$req['select'][] = 'COUNT(dc.id_commentaire) AS comm_count'; |
$req['join'][] = 'INNER JOIN del_commentaire AS dc ON dob.id_observation = dc.ce_observation'; |
$req['groupby'][] = 'dob.id_observation'; |
$req['join'][] = 'INNER JOIN del_commentaire AS dc ON vdi.id_observation = dc.ce_observation'; |
$req['groupby'][] = 'vdi.id_observation'; |
$req['having'][] = "COUNT(id_commentaire) > " . $c->getParametre('nb_commentaires_discussion'); |
} |
|