Carnet Wiki

Utiliser l’API de recherche Faire l’équivalent du critère recherche avec l’API SQL

Version 2 — Mai 2023 tcharlss

Autrement dit : comment faire l’équivalent du critère {recherche} avec l’API SQL ?

Pourquoi ?

Pour faire simple on peut faire champ = 'ma recherche' ou bien champ LIKE '%ma recherche%'

Mais l’API de recherche présente des avantages, elle est optimisée :

-* Elle conserve les recherches en mémoire pour un résultat plus rapide

  • Elle sait dans quels champs rechercher et quel poid donner à chacun
  • Elle permet de classer les résultats en mettant les plus pertinents en premier
  • Elle bénéficie automatiquement des améliorations apportées par les plugins tels que Fulltext

Comment ?

include_spip('base/objets');
include_spip('base/abstract_sql');


// Le terme recherché
$search = _request('recherche');


// L'objet concerné par la recherche
$objet = 'article';
$table_objet_sql = table_objet_sql($objet); // spip_articles
$table_objet = table_objet($objet); // articles
$cle_objet = id_table_objet($objet); // id_article


// L'API de recherche fonctionne avec un alias `points` dans le SELECT, une jointure dans le FROM et une condition dans le WHERE
$prepare_recherche = charger_fonction('prepare_recherche', 'inc');
[$search_select, $search_where] = $prepare_recherche($search, $table_objets) ?: [];
$search_join = " INNER JOIN spip_resultats AS resultats ON (resultats.id = $table_objet_sql.$cle_objet)";


// Et la requête finale
$select = [$search_select, 'titre', 'date']; // ce qu'on veut en plus
$from = $table_objet_sql . $search_join; // pas le plus propre, exemple rapide
$where = [$search_where, 'statut = '.sql_quote('publie')]; // le statut publié dépend de chaque type d'objet, juste un exemple rapide
$groupby = $cle_objet;
$orderby = 'points DESC'; // résultats les plus pertinents en 1er
$collection = sql_allfetsel($select, $from, $where, $groupby, $orderby);