Line 80... |
Line 80... |
80 |
class ListeImages {
|
80 |
class ListeImages {
|
Line 81... |
Line 81... |
81 |
|
81 |
|
82 |
// TODO: PHP-x.y, ces variables devrait être des "const"
|
82 |
// TODO: PHP-x.y, ces variables devrait être des "const"
|
Line 83... |
Line 83... |
83 |
static $format_image_possible = array('O','CRX2S','CRS','CXS','CS','XS','S','M','L','XL','X2L','X3L');
|
83 |
static $format_image_possible = array('O','CRX2S','CRS','CXS','CS','XS','S','M','L','XL','X2L','X3L');
|
Line 84... |
Line 84... |
84 |
|
84 |
|
85 |
static $tri_possible = array('date_transmission', 'date_observation', 'votes', 'tags');
|
85 |
static $tri_possible = array('date_transmission', 'date_observation', 'votes', 'tags', 'points');
|
Line 86... |
Line 86... |
86 |
|
86 |
|
87 |
// en plus de ceux dans DelTk
|
87 |
// en plus de ceux dans DelTk
|
88 |
static $parametres_autorises = array('protocole', 'masque.tag_cel', 'masque.tag_pictoflora', 'masque.milieu');
|
88 |
static $parametres_autorises = array('protocole', 'masque.tag_cel', 'masque.tag_pictoflora', 'masque.milieu');
|
89 |
|
89 |
|
Line 90... |
Line 90... |
90 |
static $default_params = array('navigation.depart' => 0, 'navigation.limite' => 10,
|
90 |
static $default_params = array('navigation.depart' => 0, 'navigation.limite' => 10,
|
Line 91... |
Line 91... |
91 |
'tri' => 'date_transmission', 'ordre' => 'desc',
|
91 |
'tri' => 'date_transmission', 'ordre' => 'desc',
|
92 |
// spécifiques à PictoFlora:
|
92 |
// spécifiques à PictoFlora:
|
93 |
'format' => 'XL');
|
93 |
'format' => 'XL');
|
94 |
|
94 |
|
Line 122... |
Line 122... |
122 |
'i_mots_cles_texte' => 1
|
122 |
'i_mots_cles_texte' => 1
|
123 |
));
|
123 |
));
|
Line 124... |
Line 124... |
124 |
|
124 |
|
125 |
|
125 |
|
126 |
public function __construct(Conteneur $conteneur = null) {
|
126 |
public function __construct(Conteneur $conteneur = null) {
|
127 |
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
|
127 |
$this->conteneur = $conteneur == null ? new Conteneur() : $conteneur;
|
128 |
$this->conteneur->chargerConfiguration('config_images.ini');
|
128 |
$this->conteneur->chargerConfiguration('config_images.ini');
|
129 |
$this->gestionBdd = $conteneur->getGestionBdd();
|
129 |
$this->gestionBdd = $conteneur->getGestionBdd();
|
Line 130... |
Line 130... |
130 |
$this->bdd = $this->gestionBdd->getBdd();
|
130 |
$this->bdd = $this->gestionBdd->getBdd();
|
131 |
}
|
131 |
}
|
132 |
|
132 |
|
Line 212... |
Line 212... |
212 |
// idobs est une liste (toujours ordonnée) des id d'observations recherchées
|
212 |
// idobs est une liste (toujours ordonnée) des id d'observations recherchées
|
213 |
$idobs = array_values(array_map(create_function('$a', 'return $a["id_image"];'), $idobs_tab));
|
213 |
$idobs = array_values(array_map(create_function('$a', 'return $a["id_image"];'), $idobs_tab));
|
214 |
$total = $db->recuperer('SELECT FOUND_ROWS() AS c'); $total = intval($total['c']);
|
214 |
$total = $db->recuperer('SELECT FOUND_ROWS() AS c'); $total = intval($total['c']);
|
Line 215... |
Line 215... |
215 |
|
215 |
|
- |
|
216 |
$liaisons = self::chargerImages($db, $idobs);
|
- |
|
217 |
|
- |
|
218 |
// debug: infos de score
|
- |
|
219 |
/*$infosScore = array();
|
- |
|
220 |
foreach ($idobs_tab as $iot) {
|
- |
|
221 |
$infosScore[$iot['id_image']] = array(
|
- |
|
222 |
'nb_votes' => $iot['nb_votes'],
|
- |
|
223 |
'nb_points' => $iot['nb_points'],
|
- |
|
224 |
'moyenne' => $iot['moyenne']
|
- |
|
225 |
);
|
216 |
$liaisons = self::chargerImages($db, $idobs);
|
226 |
}*/
|
217 |
/*
|
227 |
/*
|
218 |
// Q&D
|
228 |
// Q&D
|
219 |
$images = array();
|
229 |
$images = array();
|
220 |
$o = new Observation($this->conteneur);
|
230 |
$o = new Observation($this->conteneur);
|
Line 254... |
Line 264... |
254 |
* Cependant il est impensable de joindre sur un AVG() des valeurs des votes pour
|
264 |
* Cependant il est impensable de joindre sur un AVG() des valeurs des votes pour
|
255 |
* *chaque* couple (id_image, protocole) de la base afin de trouver les images
|
265 |
* *chaque* couple (id_image, protocole) de la base afin de trouver les images
|
256 |
* les "mieux notées", ou bien les images ayant le "plus de tags" (COUNT())
|
266 |
* les "mieux notées", ou bien les images ayant le "plus de tags" (COUNT())
|
257 |
*/
|
267 |
*/
|
258 |
static function sqlOrderBy($p, $db, &$req) {
|
268 |
static function sqlOrderBy($p, $db, &$req) {
|
259 |
// parmi self::$tri_possible
|
269 |
// parmi self::$tri_possible
|
260 |
if($p['tri'] == 'votes') { // LEFT JOIN sur "dis" ci-dessous
|
270 |
if($p['tri'] == 'votes') { // LEFT JOIN sur "dis" ci-dessous
|
261 |
$req['orderby'] = 'dis.moyenne ' . $p['ordre'] . ', dis.nb_votes ' . $p['ordre'];
|
271 |
$req['orderby'] = 'dis.moyenne ' . $p['ordre'] . ', dis.nb_votes ' . $p['ordre'];
|
- |
|
272 |
return;
|
- |
|
273 |
}
|
- |
|
274 |
|
- |
|
275 |
if($p['tri'] == 'points') { // LEFT JOIN sur "dis" ci-dessous
|
- |
|
276 |
$req['orderby'] = 'dis.nb_points ' . $p['ordre'] . ', dis.moyenne ' . $p['ordre'] . ', dis.nb_votes ' . $p['ordre'];
|
262 |
return;
|
277 |
return;
|
263 |
}
|
278 |
}
|
264 |
|
279 |
|
265 |
if($p['tri'] == 'tags') { // LEFT JOIN sur "dis" ci-dessous
|
280 |
if($p['tri'] == 'tags') { // LEFT JOIN sur "dis" ci-dessous
|
266 |
$req['orderby'] = 'dis.nb_tags ' . $p['ordre'];
|
281 |
$req['orderby'] = 'dis.nb_tags ' . $p['ordre'];
|
267 |
return;
|
282 |
return;
|
268 |
}
|
283 |
}
|
269 |
|
284 |
|
270 |
if($p['tri'] == 'date_observation') {
|
285 |
if($p['tri'] == 'date_observation') {
|
271 |
$req['orderby'] = 'date_observation ' . $p['ordre'] . ', id_observation ' . $p['ordre'];
|
286 |
$req['orderby'] = 'date_observation ' . $p['ordre'] . ', id_observation ' . $p['ordre'];
|
272 |
return;
|
287 |
return;
|
273 |
}
|
288 |
}
|
274 |
|
289 |
|
275 |
// tri == 'date_transmission'
|
290 |
// tri == 'date_transmission'
|
276 |
// avant cel:r1860, date_transmission pouvait être NULL
|
291 |
// avant cel:r1860, date_transmission pouvait être NULL
|
277 |
// or nous voulons de la consistence (notamment pour phpunit)
|
292 |
// or nous voulons de la cohérence (notamment pour phpunit)
|
278 |
$req['orderby'] = 'date_transmission ' . $p['ordre'] . ', id_observation ' . $p['ordre'];
|
293 |
$req['orderby'] = 'date_transmission ' . $p['ordre'] . ', id_observation ' . $p['ordre'];
|
279 |
}
|
294 |
}
|
Line 280... |
Line 295... |
280 |
|
295 |
|
281 |
/*
|
296 |
/*
|
282 |
* in $p: un tableau de paramètres, dont:
|
297 |
* in $p: un tableau de paramètres, dont:
|
Line 316... |
Line 331... |
316 |
Dénormaliser cette valeur et l'intégrer à `cel_images` ferait économiser cette couteuse
|
331 |
Dénormaliser cette valeur et l'intégrer à `cel_images` ferait économiser cette couteuse
|
317 |
jointure, ... lorsqu'aucun masque portant sur `cel_obs` n'est utilisé
|
332 |
jointure, ... lorsqu'aucun masque portant sur `cel_obs` n'est utilisé
|
318 |
3) non-problème: l'ordre des joins est forcé par l'usage de la vue:
|
333 |
3) non-problème: l'ordre des joins est forcé par l'usage de la vue:
|
319 |
(cel_images/cel_obs_images/cel_obs/del_image_stat)
|
334 |
(cel_images/cel_obs_images/cel_obs/del_image_stat)
|
320 |
Cependant c'est à l'optimiseur de définir son ordre préféré. */
|
335 |
Cependant c'est à l'optimiseur de définir son ordre préféré. */
|
321 |
if($p['tri'] == 'votes') {
|
336 |
if($p['tri'] == 'votes' || $p['tri'] == 'points') {
|
322 |
// $p['protocole'] *est* défini (cf requestFilterParams())
|
337 |
// $p['protocole'] *est* défini (cf requestFilterParams())
|
323 |
// petite optimisation: INNER JOIN si ordre DESC car les 0 à la fin
|
338 |
// petite optimisation: INNER JOIN si ordre DESC car les 0 à la fin
|
324 |
if($p['ordre'] == 'desc') {
|
339 |
if($p['ordre'] == 'desc') {
|
325 |
// pas de group by nécessaire pour cette jointure
|
340 |
// pas de group by nécessaire pour cette jointure
|
326 |
// PRIMARY KEY (`ce_image`, `ce_protocole`)
|
341 |
// PRIMARY KEY (`ce_image`, `ce_protocole`)
|
Line 456... |
Line 471... |
456 |
}
|
471 |
}
|
Line 457... |
Line 472... |
457 |
|
472 |
|
458 |
static function getIdImages($p, $req, $db) {
|
473 |
static function getIdImages($p, $req, $db) {
|
459 |
return $db->recupererTous(sprintf(
|
474 |
return $db->recupererTous(sprintf(
|
- |
|
475 |
'SELECT SQL_CALC_FOUND_ROWS id_image' .
|
460 |
'SELECT SQL_CALC_FOUND_ROWS id_image' .
|
476 |
//', dis.moyenne, dis.nb_points, dis.nb_votes' . // debug
|
461 |
' FROM v_del_image vdi'.
|
477 |
' FROM v_del_image vdi'.
|
462 |
' %s' . // LEFT JOIN if any
|
478 |
' %s' . // LEFT JOIN if any
|
463 |
' WHERE %s'. // where-clause ou TRUE
|
479 |
' WHERE %s'. // where-clause ou TRUE
|
464 |
' %s'. // group-by
|
480 |
' %s'. // group-by
|
Line 474... |
Line 490... |
474 |
|
490 |
|
475 |
$p['navigation.depart'], $p['navigation.limite'], __FILE__ . ':' . __LINE__));
|
491 |
$p['navigation.depart'], $p['navigation.limite'], __FILE__ . ':' . __LINE__));
|
Line 476... |
Line 492... |
476 |
}
|
492 |
}
|
477 |
|
493 |
|
478 |
static function chargerImages($db, $idImg) {
|
494 |
static function chargerImages($db, $idImg) {
|
479 |
$obs_fields = DelTk::sqlFieldsToAlias(self::$mappings['observations'], NULL);
|
495 |
$obs_fields = DelTk::sqlFieldsToAlias(self::$mappings['observations'], NULL);
|
480 |
$image_fields = DelTk::sqlFieldsToAlias(self::$mappings['images'], NULL);
|
496 |
$image_fields = DelTk::sqlFieldsToAlias(self::$mappings['images'], NULL);
|
481 |
|
497 |
|
482 |
return $db->recupererTous(sprintf('SELECT '.
|
498 |
return $db->recupererTous(sprintf('SELECT '.
|
483 |
' CONCAT(id_image, "-", id_observation) AS jsonindex,'.
|
499 |
' CONCAT(id_image, "-", id_observation) AS jsonindex,'.
|
- |
|
500 |
' %1$s, %2$s FROM v_del_image '.
|
484 |
' %1$s, %2$s FROM v_del_image '.
|
501 |
' WHERE %3$s'.
|
485 |
' WHERE %3$s'.
|
502 |
' ORDER BY %4$s'. // important car MySQL ne conserve par l'ordre du IN()
|
486 |
' -- %4$s',
|
503 |
' -- %5$s',
|
- |
|
504 |
$obs_fields, $image_fields,
|
487 |
$obs_fields, $image_fields,
|
505 |
sprintf('id_image IN (%s)', implode(',', $idImg)),
|
488 |
sprintf('id_image IN (%s)', implode(',', $idImg)),
|
- |
|
489 |
__FILE__ . ':' . __LINE__));
|
506 |
sprintf('FIELD(id_image, %s)', implode(',', $idImg)),
|
Line 490... |
Line 507... |
490 |
|
507 |
__FILE__ . ':' . __LINE__));
|
491 |
}
|
508 |
}
|
492 |
|
509 |
|
Line 513... |
Line 530... |
513 |
'masque.famille' => $p['masque'],
|
530 |
'masque.famille' => $p['masque'],
|
514 |
'masque.date' => $p['masque'],
|
531 |
'masque.date' => $p['masque'],
|
515 |
'masque.genre' => $p['masque'],
|
532 |
'masque.genre' => $p['masque'],
|
516 |
'masque.milieu' => $p['masque'],
|
533 |
'masque.milieu' => $p['masque'],
|
517 |
'masque.tag_cel' => $p['masque'],
|
534 |
'masque.tag_cel' => $p['masque'],
|
518 |
'masque.tag_pictoflora' => $p['masque'],
|
535 |
'masque.tag_pictoflora' => $p['masque'],
|
Line 519... |
Line 536... |
519 |
|
536 |
|
520 |
// tri est aussi nécessaire car affecte les contraintes de JOIN
|
537 |
// tri est aussi nécessaire car affecte les contraintes de JOIN
|
521 |
'tri' => $p['tri'],
|
538 |
'tri' => $p['tri'],
|
Line 563... |
Line 580... |
563 |
|
580 |
|
564 |
|
581 |
|
565 |
// cf Observation::reformateObservationSimpleIndex() et ListeObservations::reformateObservation()
|
582 |
// cf Observation::reformateObservationSimpleIndex() et ListeObservations::reformateObservation()
|
566 |
// (trop de variétés de formatage, à unifier côté client pour unifier côté backend ...)
|
583 |
// (trop de variétés de formatage, à unifier côté client pour unifier côté backend ...)
|
567 |
static function reformateImagesDoubleIndex($obs, $url_pattern = '', $image_format = 'XL') {
|
584 |
static function reformateImagesDoubleIndex($obs, $url_pattern = '', $image_format = 'XL') {
|
568 |
// XXX: cf Observation.php::consulter(), nous pourriouns ici
|
585 |
// XXX: cf Observation.php::consulter(), nous pourriouns ici
|
569 |
// conserver les valeurs vides (pour les phptests notamment, ou non)
|
586 |
// conserver les valeurs vides (pour les phptests notamment, ou non)
|
570 |
// $obs = array_map('array_filter', $obs);
|
587 |
// $obs = array_map('array_filter', $obs);
|
571 |
$obs_merged = $obs_keyed_by_id_image = array();
|
588 |
$obs_merged = $obs_keyed_by_id_image = array();
|
572 |
foreach($obs as $o) {
|
589 |
foreach($obs as $o) {
|
573 |
// ceci nous complique la tâche pour le reste du processing...
|
590 |
// ceci nous complique la tâche pour le reste du processing...
|
574 |
$id = $o['jsonindex'];
|
591 |
$id = $o['jsonindex'];
|
575 |
// ainsi nous utilisons deux tableaux: le final, indexé par couple d'id(image-obs)
|
592 |
// ainsi nous utilisons deux tableaux: le final, indexé par couple d'id(image-obs)
|
576 |
// et celui indexé par simple id_image qui est fort utile pour mapVotesToImages()
|
593 |
// et celui indexé par simple id_image qui est fort utile pour mapVotesToImages()
|
577 |
// mais tout deux partage leur référence à "protocole"
|
594 |
// mais tout deux partage leur référence à "protocole"
|
578 |
$image = array(
|
595 |
$image = array(
|
579 |
'id_image' => $o['id_image'],
|
596 |
'id_image' => $o['id_image'],
|
580 |
'binaire.href' => sprintf($url_pattern, $o['id_image'], $image_format),
|
597 |
'binaire.href' => sprintf($url_pattern, $o['id_image'], $image_format),
|
- |
|
598 |
'mots_cles_texte' => @$o['i_mots_cles_texte'], // @, peut avoir été filtré par array_map() ci-dessus
|
581 |
'mots_cles_texte' => @$o['i_mots_cles_texte'], // @, peut avoir été filtré par array_map() ci-dessus
|
599 |
);
|
582 |
);
|
600 |
|
583 |
unset($o['id_image'], $o['i_mots_cles_texte'], $o['jsonindex']);
|
601 |
unset($o['id_image'], $o['i_mots_cles_texte'], $o['jsonindex']);
|
584 |
if(!isset($obs_merged[$id])) $obs_merged[$id] = $image;
|
602 |
if(!isset($obs_merged[$id])) $obs_merged[$id] = $image;
|
585 |
$obs_merged[$id]['observation'] = $o;
|
603 |
$obs_merged[$id]['observation'] = $o;
|
586 |
$obs_merged[$id]['protocoles_votes'] = array();
|
604 |
$obs_merged[$id]['protocoles_votes'] = array();
|
587 |
|
605 |
|
588 |
$obs_keyed_by_id_image[$image['id_image']]['protocoles_votes'] = &$obs_merged[$id]['protocoles_votes'];
|
606 |
$obs_keyed_by_id_image[$image['id_image']]['protocoles_votes'] = &$obs_merged[$id]['protocoles_votes'];
|
589 |
}
|
607 |
}
|
590 |
|
608 |
|
Line 591... |
Line 609... |
591 |
return array($obs_merged,$obs_keyed_by_id_image);
|
609 |
return array($obs_merged,$obs_keyed_by_id_image);
|
Line 609... |
Line 627... |
609 |
// compatibilité
|
627 |
// compatibilité
|
610 |
if(isset($params['masque.tag'])) {
|
628 |
if(isset($params['masque.tag'])) {
|
611 |
$params['masque.tag_cel'] = $params['masque.tag_pictoflora'] = $params['masque.tag'];
|
629 |
$params['masque.tag_cel'] = $params['masque.tag_pictoflora'] = $params['masque.tag'];
|
612 |
}
|
630 |
}
|
Line 613... |
Line 631... |
613 |
|
631 |
|
614 |
if($p['tri'] == 'votes' || $p['tri'] == 'tags') {
|
632 |
if($p['tri'] == 'votes' || $p['tri'] == 'tags' || $p['tri'] == 'points') {
|
615 |
// ces critère de tri des image à privilégier ne s'applique qu'à un protocole donné
|
633 |
// ces critère de tri des image à privilégier ne s'applique qu'à un protocole donné
|
616 |
if(!isset($params['protocole']) || !is_numeric($params['protocole']))
|
634 |
if(!isset($params['protocole']) || !is_numeric($params['protocole']))
|
617 |
$p['protocole'] = self::$default_proto;
|
635 |
$p['protocole'] = self::$default_proto;
|
618 |
else
|
636 |
else
|
Line 642... |
Line 660... |
642 |
EOF
|
660 |
EOF
|
643 |
);
|
661 |
);
|
644 |
}
|
662 |
}
|
Line 645... |
Line 663... |
645 |
|
663 |
|
- |
|
664 |
static function revOrderBy($orderby) {
|
646 |
static function revOrderBy($orderby) {
|
665 |
// @TODO plutôt 'desc' ? '' : 'desc', non ?
|
647 |
return $orderby == 'asc' ? 'desc' : 'asc';
|
666 |
return $orderby == 'asc' ? 'desc' : 'asc';
|
648 |
}
|
667 |
}
|