Subversion Repositories eFlore/Applications.del

Compare Revisions

Ignore whitespace Rev 1415 → Rev 1416

/trunk/services/modules/0.1/observations/ListeObservations2.php
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 ". */
/* 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');
}