Subversion Repositories eFlore/Applications.del

Compare Revisions

Ignore whitespace Rev 1523 → Rev 1564

/trunk/services/modules/0.1/images/VotesImage.php
147,27 → 147,10
self::updateStats($this->bdd, $ressources[0],$infos_vote['ce_protocole']);
}
}
 
// intermédiaire pour la méthode contenue dans "Commun"
static function updateStats($db, $id_image, $id_proto) {
$id_image = intval($id_image);
$id_proto = intval($id_proto);
if(!$id_image || !$id_proto) throw new Exception("Ne peut mettre à jour les statistiques de vote",
RestServeur::HTTP_CODE_ERREUR);
/* REPLACE ... SELECT: réinitalise les champs non-défini (MySQL 5.1)
REPLACE ... SET a=b, c=d: idem ou plusieurs requête
Du coup il faut récupérer les données actuelles mais REPLACE ne le permet pas
(http://dev.mysql.com/doc/refman/5.5/en/replace.html :
You cannot refer to values from the current row and use them in the new row.)
D'où INSERT ... ON DUPLICATE KEY UPDATE. Notons que VALUES() récupère la valeur
*associée* au champ passé en paramètre, c'est à dire VALUES(moyenne) == divo.moyenne */
$db->requeter(sprintf('INSERT INTO del_image_stat (ce_image, ce_protocole, moyenne, nb_votes)'.
' SELECT ce_image, ce_protocole, AVG(valeur) AS moyenne, COUNT(valeur) AS nb_votes'.
' FROM del_image_vote divo'.
' WHERE ce_image = %d AND ce_protocole = %d GROUP BY ce_image, ce_protocole'.
' ON DUPLICATE KEY UPDATE moyenne = VALUES(moyenne), nb_votes = VALUES(nb_votes)',
$id_image, $id_proto));
 
return TelaBotanica\Del\Commun\Stats::updateStats($db, $id_image, $id_proto);
}
 
/*-------------------------------------------------------------------------------
/trunk/services/modules/0.1/images/ListeImages.php
82,7 → 82,7
// TODO: PHP-x.y, ces variables devrait être des "const"
static $format_image_possible = array('O','CRX2S','CRS','CXS','CS','XS','S','M','L','XL','X2L','X3L');
 
static $tri_possible = array('date_transmission', 'date_observation', 'votes', 'tags');
static $tri_possible = array('date_transmission', 'date_observation', 'votes', 'tags', 'points');
 
// en plus de ceux dans DelTk
static $parametres_autorises = array('protocole', 'masque.tag_cel', 'masque.tag_pictoflora', 'masque.milieu');
92,7 → 92,7
// spécifiques à PictoFlora:
'format' => 'XL');
 
static $default_proto = 3; // proto par défaut: capitalisation d'img (utilisé uniquement pour tri=(tags|votes))
static $default_proto = 3; // proto par défaut: capitalisation d'img (utilisé uniquement pour tri=(tags|votes|points))
 
static $mappings = array(
'observations' => array( // v_del_image
124,10 → 124,10
 
 
public function __construct(Conteneur $conteneur = null) {
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->conteneur->chargerConfiguration('config_images.ini');
$this->gestionBdd = $conteneur->getGestionBdd();
$this->bdd = $this->gestionBdd->getBdd();
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
$this->conteneur->chargerConfiguration('config_images.ini');
$this->gestionBdd = $conteneur->getGestionBdd();
$this->bdd = $this->gestionBdd->getBdd();
}
 
public function consulter($ressources, $parametres) {
214,6 → 214,16
$total = $db->recuperer('SELECT FOUND_ROWS() AS c'); $total = intval($total['c']);
 
$liaisons = self::chargerImages($db, $idobs);
// debug: infos de score
/*$infosScore = array();
foreach ($idobs_tab as $iot) {
$infosScore[$iot['id_image']] = array(
'nb_votes' => $iot['nb_votes'],
'nb_points' => $iot['nb_points'],
'moyenne' => $iot['moyenne']
);
}*/
/*
// Q&D
$images = array();
256,26 → 266,31
* les "mieux notées", ou bien les images ayant le "plus de tags" (COUNT())
*/
static function sqlOrderBy($p, $db, &$req) {
// parmi self::$tri_possible
if($p['tri'] == 'votes') { // LEFT JOIN sur "dis" ci-dessous
$req['orderby'] = 'dis.moyenne ' . $p['ordre'] . ', dis.nb_votes ' . $p['ordre'];
return;
}
if($p['tri'] == 'tags') { // LEFT JOIN sur "dis" ci-dessous
$req['orderby'] = 'dis.nb_tags ' . $p['ordre'];
return;
}
 
if($p['tri'] == 'date_observation') {
$req['orderby'] = 'date_observation ' . $p['ordre'] . ', id_observation ' . $p['ordre'];
return;
}
 
// tri == 'date_transmission'
// avant cel:r1860, date_transmission pouvait être NULL
// or nous voulons de la consistence (notamment pour phpunit)
$req['orderby'] = 'date_transmission ' . $p['ordre'] . ', id_observation ' . $p['ordre'];
// parmi self::$tri_possible
if($p['tri'] == 'votes') { // LEFT JOIN sur "dis" ci-dessous
$req['orderby'] = 'dis.moyenne ' . $p['ordre'] . ', dis.nb_votes ' . $p['ordre'];
return;
}
if($p['tri'] == 'points') { // LEFT JOIN sur "dis" ci-dessous
$req['orderby'] = 'dis.nb_points ' . $p['ordre'] . ', dis.moyenne ' . $p['ordre'] . ', dis.nb_votes ' . $p['ordre'];
return;
}
if($p['tri'] == 'tags') { // LEFT JOIN sur "dis" ci-dessous
$req['orderby'] = 'dis.nb_tags ' . $p['ordre'];
return;
}
if($p['tri'] == 'date_observation') {
$req['orderby'] = 'date_observation ' . $p['ordre'] . ', id_observation ' . $p['ordre'];
return;
}
// tri == 'date_transmission'
// avant cel:r1860, date_transmission pouvait être NULL
// or nous voulons de la cohérence (notamment pour phpunit)
$req['orderby'] = 'date_transmission ' . $p['ordre'] . ', id_observation ' . $p['ordre'];
}
 
/*
318,7 → 333,7
3) non-problème: l'ordre des joins est forcé par l'usage de la vue:
(cel_images/cel_obs_images/cel_obs/del_image_stat)
Cependant c'est à l'optimiseur de définir son ordre préféré. */
if($p['tri'] == 'votes') {
if($p['tri'] == 'votes' || $p['tri'] == 'points') {
// $p['protocole'] *est* défini (cf requestFilterParams())
// petite optimisation: INNER JOIN si ordre DESC car les 0 à la fin
if($p['ordre'] == 'desc') {
458,6 → 473,7
static function getIdImages($p, $req, $db) {
return $db->recupererTous(sprintf(
'SELECT SQL_CALC_FOUND_ROWS id_image' .
//', dis.moyenne, dis.nb_points, dis.nb_votes' . // debug
' FROM v_del_image vdi'.
' %s' . // LEFT JOIN if any
' WHERE %s'. // where-clause ou TRUE
476,18 → 492,19
}
 
static function chargerImages($db, $idImg) {
$obs_fields = DelTk::sqlFieldsToAlias(self::$mappings['observations'], NULL);
$image_fields = DelTk::sqlFieldsToAlias(self::$mappings['images'], NULL);
return $db->recupererTous(sprintf('SELECT '.
$obs_fields = DelTk::sqlFieldsToAlias(self::$mappings['observations'], NULL);
$image_fields = DelTk::sqlFieldsToAlias(self::$mappings['images'], NULL);
return $db->recupererTous(sprintf('SELECT '.
' CONCAT(id_image, "-", id_observation) AS jsonindex,'.
' %1$s, %2$s FROM v_del_image '.
' WHERE %3$s'.
' -- %4$s',
' ORDER BY %4$s'. // important car MySQL ne conserve par l'ordre du IN()
' -- %5$s',
$obs_fields, $image_fields,
sprintf('id_image IN (%s)', implode(',', $idImg)),
sprintf('FIELD(id_image, %s)', implode(',', $idImg)),
__FILE__ . ':' . __LINE__));
 
}
 
/* "masque" ne fait jamais que faire une requête sur la plupart des champs, (presque) tous traités
515,7 → 532,7
'masque.genre' => $p['masque'],
'masque.milieu' => $p['masque'],
'masque.tag_cel' => $p['masque'],
'masque.tag_pictoflora' => $p['masque'],
'masque.tag_pictoflora' => $p['masque'],
 
// tri est aussi nécessaire car affecte les contraintes de JOIN
'tri' => $p['tri'],
565,30 → 582,31
// cf Observation::reformateObservationSimpleIndex() et ListeObservations::reformateObservation()
// (trop de variétés de formatage, à unifier côté client pour unifier côté backend ...)
static function reformateImagesDoubleIndex($obs, $url_pattern = '', $image_format = 'XL') {
// XXX: cf Observation.php::consulter(), nous pourriouns ici
// conserver les valeurs vides (pour les phptests notamment, ou non)
// $obs = array_map('array_filter', $obs);
$obs_merged = $obs_keyed_by_id_image = array();
foreach($obs as $o) {
// ceci nous complique la tâche pour le reste du processing...
$id = $o['jsonindex'];
// ainsi nous utilisons deux tableaux: le final, indexé par couple d'id(image-obs)
// et celui indexé par simple id_image qui est fort utile pour mapVotesToImages()
// mais tout deux partage leur référence à "protocole"
$image = array(
'id_image' => $o['id_image'],
'binaire.href' => sprintf($url_pattern, $o['id_image'], $image_format),
'mots_cles_texte' => @$o['i_mots_cles_texte'], // @, peut avoir été filtré par array_map() ci-dessus
);
unset($o['id_image'], $o['i_mots_cles_texte'], $o['jsonindex']);
if(!isset($obs_merged[$id])) $obs_merged[$id] = $image;
$obs_merged[$id]['observation'] = $o;
$obs_merged[$id]['protocoles_votes'] = array();
$obs_keyed_by_id_image[$image['id_image']]['protocoles_votes'] = &$obs_merged[$id]['protocoles_votes'];
}
 
return array($obs_merged,$obs_keyed_by_id_image);
// XXX: cf Observation.php::consulter(), nous pourriouns ici
// conserver les valeurs vides (pour les phptests notamment, ou non)
// $obs = array_map('array_filter', $obs);
$obs_merged = $obs_keyed_by_id_image = array();
foreach($obs as $o) {
// ceci nous complique la tâche pour le reste du processing...
$id = $o['jsonindex'];
// ainsi nous utilisons deux tableaux: le final, indexé par couple d'id(image-obs)
// et celui indexé par simple id_image qui est fort utile pour mapVotesToImages()
// mais tout deux partage leur référence à "protocole"
$image = array(
'id_image' => $o['id_image'],
'binaire.href' => sprintf($url_pattern, $o['id_image'], $image_format),
'mots_cles_texte' => @$o['i_mots_cles_texte'], // @, peut avoir été filtré par array_map() ci-dessus
);
unset($o['id_image'], $o['i_mots_cles_texte'], $o['jsonindex']);
if(!isset($obs_merged[$id])) $obs_merged[$id] = $image;
$obs_merged[$id]['observation'] = $o;
$obs_merged[$id]['protocoles_votes'] = array();
$obs_keyed_by_id_image[$image['id_image']]['protocoles_votes'] = &$obs_merged[$id]['protocoles_votes'];
}
return array($obs_merged,$obs_keyed_by_id_image);
}
 
 
611,7 → 629,7
$params['masque.tag_cel'] = $params['masque.tag_pictoflora'] = $params['masque.tag'];
}
 
if($p['tri'] == 'votes' || $p['tri'] == 'tags') {
if($p['tri'] == 'votes' || $p['tri'] == 'tags' || $p['tri'] == 'points') {
// ces critère de tri des image à privilégier ne s'applique qu'à un protocole donné
if(!isset($params['protocole']) || !is_numeric($params['protocole']))
$p['protocole'] = self::$default_proto;
644,6 → 662,7
}
 
static function revOrderBy($orderby) {
return $orderby == 'asc' ? 'desc' : 'asc';
// @TODO plutôt 'desc' ? '' : 'desc', non ?
return $orderby == 'asc' ? 'desc' : 'asc';
}
}