Skip to content

Fonctions personnalisées pour les jointures

tcharlss a demandé de fusionner issue_1_rechercher_jointures vers master

Ticket #1 : ajout de la possibilité de déclarer des fonctions personnalisées pour traiter les cas spéciaux de jointures sur les tables ayant des index fulltext.

On reprend la même nomenclature que la recherche standard de spip en suffixant avec _fulltext :

  • rechercher_joints_${table}_${table_liee}_fulltext
  • rechercher_joints_objet_${table_liee}_fulltext
  • rechercher_joints_${table}_objet_lie_fulltext

Attention, dans la recherche standard les fonctions perso doivent retourner un tableau avec une sélection sql (le résultat de sql_select). Ici elles doivent retourner uniquement du texte qui sera ajouté au SELECT : ça doit ajouter une jointure retournant un score qui sera additionné au reste.

Exemple de retour :

LEFT JOIN (SELECT xxx FROM xxx WHERE xxx) AS o1 ON o1.id_auteur = t.id_auteur

De fait la signature diffère également : on donne les paramètres permettant de construire cette expression :

  • $table : objet initial
  • $table_liee : objet pour la jointure
  • $subscore : expression retournant le score : MATCH xxx AS score
  • $alias_subscore : alias utilisé dans le $subscore
  • $alias_join : alias à utiliser pour la jointure : JOIN (…) AS $alias_join

Exemple d'implémentation pour la recherche d'auteurs : prendre en compte les noms des organisations associées.

/**
 * Jointure sur les organisations pour la recherche des auteurs : version fulltext
 *
 * Complément de `rechercher_jointures` dans declarer_tables_objets_sql()
 * Par défaut ça provoque une jointure sur les auteurs-orgas eux mêmes,
 * Hors on veut chercher dans les orgas *liées* aux auteurs-contacts.
 *
 * @param string $table
 *     `auteur`
 * @param string $table_liee
 *     `organisation`
 * @param string $subscore
 *     Expression qui donne le score dans le select
 * @param string $alias_subscore
 *     Alias de la table pour le match dans le subscore
 * @param string $alias_join
 *     Alias à donner à la jointure : `JOIN (…) AS $alias_join`
 * @param int $index
 * @return string
 */
function inc_rechercher_joints_auteur_organisation_fulltext(string $table, string $table_liee, string $subscore, string $alias_subscore, string $alias_join): string {

	$quote_contact = sql_quote('contact');
	$poids = 2; // pour augmenter arbitrairement le poids

	$join = "LEFT JOIN (
		SELECT
			C.id_auteur AS id_auteur,
			$subscore * $poids AS score
		FROM
			spip_contacts AS C
			INNER JOIN spip_organisations_liens L ON L.id_objet = C.id_contact AND L.objet = $quote_contact
			INNER JOIN spip_organisations AS $alias_subscore ON $alias_subscore.id_organisation = L.id_organisation
		WHERE
			$subscore > 0
		ORDER BY score DESC LIMIT "._FULLTEXT_MAX_RESULTS_JOINTURES
	.") AS $alias_join ON $alias_join.id_auteur = t.id_auteur";
	
	return $join;
}

Rapports de requête de fusion