Line 3... |
Line 3... |
3 |
* @author Raphaël Droz <raphael@tela-botanica.org>
|
3 |
* @author Raphaël Droz <raphael@tela-botanica.org>
|
4 |
* @copyright Copyright (c) 2013, Tela Botanica (accueil@tela-botanica.org)
|
4 |
* @copyright Copyright (c) 2013, Tela Botanica (accueil@tela-botanica.org)
|
5 |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
|
5 |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
|
6 |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
|
6 |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
|
7 |
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=ApiIdentiplante01Images
|
7 |
* @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=ApiIdentiplante01Images
|
- |
|
8 |
* @see http://www.tela-botanica.org/wikini/identiplante/wakka.php?wiki=IdentiPlante_PictoFlora_MoteurRecherche
|
8 |
*
|
9 |
*
|
9 |
* Backend pour PictoFlora (del.html#page_recherche_images)
|
10 |
* Backend pour PictoFlora (del.html#page_recherche_images)
|
10 |
*
|
11 |
*
|
11 |
*
|
12 |
*
|
12 |
* == Notes ==
|
13 |
* == Notes ==
|
Line 358... |
Line 359... |
358 |
$req['where'][] = sprintf("CONCAT(vdi.mots_cles_texte,vdi.i_mots_cles_texte) REGEXP %s",
|
359 |
$req['where'][] = sprintf("CONCAT(vdi.mots_cles_texte,vdi.i_mots_cles_texte) REGEXP %s",
|
359 |
$db->proteger(implode('|', $p['masque.tag_cel']['OR'])));
|
360 |
$db->proteger(implode('|', $p['masque.tag_cel']['OR'])));
|
360 |
}
|
361 |
}
|
361 |
}
|
362 |
}
|
Line 362... |
Line -... |
362 |
|
- |
|
363 |
|
- |
|
364 |
// XXX: utiliser tag plutôt que tag_normalise ?
|
363 |
|
- |
|
364 |
if($p['masque.tag_pictoflora']) {
|
- |
|
365 |
// inutilisable pour l'instant
|
- |
|
366 |
// self::sqlAddPictoFloraTagConstraint1($p, $db, $req);
|
365 |
if($p['masque.tag_pictoflora']) {
|
367 |
|
366 |
// pas de LEFT JOIN ? ou bien peut-être en cas de tri, mais nous parlons bien ici d'un masque
|
368 |
// intéressante, mais problème d'optimiseur MySQL 5.5 (dependant subquery)
|
- |
|
369 |
// self::sqlAddPictoFloraTagConstraint2($p, $db, $req);
|
367 |
/* $req['join'][] = 'LEFT JOIN del_image_tag dit ON dit.ce_image = vdi.id_image';
|
370 |
|
- |
|
371 |
// approche fiable mais sous-optimale
|
- |
|
372 |
self::sqlAddPictoFloraTagConstraint3($p, $db, $req);
|
- |
|
373 |
}
|
Line -... |
Line 374... |
- |
|
374 |
}
|
- |
|
375 |
|
- |
|
376 |
/* approche intéressante si les deux problèmes suivants peuvent être résolu:
|
- |
|
377 |
- LEFT JOIN => dup => *gestion de multiples GROUP BY* (car in-fine un LIMIT est utilisé)
|
- |
|
378 |
- dans le cas d'un ET logique, comment chercher les observations correspondantes ? */
|
- |
|
379 |
static function sqlAddPictoFloraTagConstraint1($p, $db, &$req) {
|
- |
|
380 |
// XXX: utiliser tag plutôt que tag_normalise ?
|
- |
|
381 |
$req['join'][] = 'LEFT JOIN del_image_tag dit ON dit.ce_image = vdi.id_image';
|
- |
|
382 |
$req['where'][] = 'dit.actif = 1';
|
- |
|
383 |
$req['groupby'][] = 'vdi.id_image'; // TODO: nécessaire (car dup') mais risque de conflict en cas de tri (multiple GROUP BY)
|
- |
|
384 |
// XXX: en cas de ET, possibilité du GROUP_CONCAT(), mais probablement sans grand intérêt, d'où une boucle
|
- |
|
385 |
if(isset($p['masque.tag_pictoflora']['AND'])) {
|
- |
|
386 |
// TODO/XXX : comment matcher les observations ayant tous les mots-clef passés ?
|
- |
|
387 |
// ... le LEFT-JOIN n'y semble pas adapté
|
- |
|
388 |
}
|
- |
|
389 |
else {
|
- |
|
390 |
$protected_tags = array();
|
- |
|
391 |
foreach($p['masque.tag_pictoflora']['OR'] as $tag) $protected_tags[] = $db->proteger(strtolower($tag));
|
- |
|
392 |
$req['where'][] = sprintf('tag_normalise IN (%s)', implode(',', $protected_tags));
|
Line -... |
Line 393... |
- |
|
393 |
}
|
- |
|
394 |
}
|
368 |
$req['where'][] = 'dit.actif = 1'; */
|
395 |
|
369 |
|
396 |
// inutilisé pour l'instant pour cause de soucis d'optimiseur MySQL (cf commentaire en intro)
|
370 |
|
397 |
static function sqlAddPictoFloraTagConstraint2($p, $db, &$req) {
|
371 |
// Note à propos des 4 "@ instruction" ci-dessous (notamment sur recupererTous())
|
398 |
// Note à propos des 4 "@ instruction" ci-dessous (notamment sur recupererTous())
|
372 |
// REGEXP permet un puissant mécanisme de sélection des obs/image à qui sait
|
399 |
// REGEXP permet un puissant mécanisme de sélection des obs/image à qui sait
|
373 |
// l'utiliser, mais peut sortir une erreur en cas de REGEXP invalide
|
400 |
// l'utiliser, mais peut sortir une erreur en cas de REGEXP invalide
|
374 |
// ex: REGEX "^(".
|
401 |
// ex: REGEX "^(".
|
375 |
// Pour l'heure nous ignorons ce type d'erreur car aucun de nos champ de recherche
|
- |
|
376 |
// ne peuvent (ou ne devrait) comporter des meta-caractères
|
- |
|
377 |
// ([])?*+\\
|
- |
|
378 |
|
- |
|
379 |
|
402 |
// Pour l'heure nous ignorons ce type d'erreur car aucun de nos champ de recherche
|
380 |
// ==== commenté pour l'instant pour cause de soucis d'optimiseur MySQL (cf commentaire en intro) ====
|
403 |
// ne peuvent (ou ne devrait) comporter des meta-caractères
|
381 |
/*
|
404 |
// ([])?*+\\
|
382 |
if(isset($p['masque.tag_pictoflora']['AND'])) {
|
405 |
if(isset($p['masque.tag_pictoflora']['AND'])) {
|
383 |
// optimsation: en cas de "AND" on sort() l'input et le GROUP_CONCAT()
|
406 |
// optimsation: en cas de "AND" on sort() l'input et le GROUP_CONCAT()
|
Line 392... |
Line 415... |
392 |
$req['where'][] = sprintf("vdi.id_image IN (SELECT ce_image FROM del_image_tag WHERE actif = 1".
|
415 |
$req['where'][] = sprintf("vdi.id_image IN (SELECT ce_image FROM del_image_tag WHERE actif = 1".
|
393 |
" GROUP BY ce_image".
|
416 |
" GROUP BY ce_image".
|
394 |
" HAVING GROUP_CONCAT(tag_normalise) REGEXP %s)",
|
417 |
" HAVING GROUP_CONCAT(tag_normalise) REGEXP %s)",
|
395 |
$db->proteger(implode('|', $p['masque.tag_pictoflora']['OR'])));
|
418 |
$db->proteger(implode('|', $p['masque.tag_pictoflora']['OR'])));
|
396 |
}
|
419 |
}
|
397 |
*/
|
420 |
}
|
Line 398... |
Line 421... |
398 |
|
421 |
|
- |
|
422 |
// si l'on est bassiné par les "DEPENDENT SUBQUERY", nous la faisons donc indépendemment via cette fonction
|
399 |
// ==== XXX: puisque on est bassiné par cette "DEPENDENT SUBQUERY", nous la faisons donc indépendemment ====
|
423 |
static function sqlAddPictoFloraTagConstraint3($p, $db, &$req) {
|
400 |
if(isset($p['masque.tag_pictoflora']['AND'])) {
|
424 |
if(isset($p['masque.tag_pictoflora']['AND'])) {
|
401 |
// optimsation: en cas de "AND" on sort() l'input et le GROUP_CONCAT()
|
425 |
// optimsation: en cas de "AND" on sort() l'input et le GROUP_CONCAT()
|
402 |
// donc nous utilisons des ".*" plutôt que de multiples conditions et "|"
|
426 |
// donc nous utilisons des ".*" plutôt que de multiples conditions et "|"
|
Line 422... |
Line 446... |
422 |
$db->proteger(implode('|', $p['masque.tag_pictoflora']['OR']))));
|
446 |
$db->proteger(implode('|', $p['masque.tag_pictoflora']['OR']))));
|
Line 423... |
Line 447... |
423 |
|
447 |
|
424 |
$ids = @array_map(create_function('$e', 'return $e["ce_image"];'), $ids);
|
448 |
$ids = @array_map(create_function('$e', 'return $e["ce_image"];'), $ids);
|
425 |
if($ids) $req['where'][] = sprintf("vdi.id_image IN (%s)", implode(',', $ids));
|
449 |
if($ids) $req['where'][] = sprintf("vdi.id_image IN (%s)", implode(',', $ids));
|
426 |
}
|
- |
|
427 |
|
450 |
}
|
428 |
}
|
- |
|
429 |
}
|
- |
|
Line 430... |
Line 451... |
430 |
|
451 |
}
|
431 |
|
452 |
|
432 |
static function getIdImages($p, $req, $db) {
|
453 |
static function getIdImages($p, $req, $db) {
|
433 |
return $db->recupererTous(sprintf(
|
454 |
return $db->recupererTous(sprintf(
|