Server : Apache System : Linux webd348.cluster026.gra.hosting.ovh.net 5.15.148-ovh-vps-grsec-zfs-classid #1 SMP Thu Feb 8 09:41:04 UTC 2024 x86_64 User : hednacluml ( 122243) PHP Version : 8.3.9 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl Directory : /home/hednacluml/chretien/ecrire/inc/ |
<?php /***************************************************************************\ * SPIP, Système de publication pour l'internet * * * * Copyright © avec tendresse depuis 2001 * * Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribué sous licence GNU/GPL. * \***************************************************************************/ /** * Gestion des préparatifs de recherches * * @package SPIP\Core\Recherche **/ if (!defined('_ECRIRE_INC_VERSION')) { return; } include_spip('inc/rechercher'); if (!defined('_DELAI_CACHE_resultats')) { define('_DELAI_CACHE_resultats', 600); } /** * Préparer les listes `id_article IN (...)` pour les parties WHERE * et calcul des `points` pour la partie SELECT des requêtes du moteur de recherche * * Le paramètre $serveur est utilisé pour savoir sur quelle base on cherche * mais l'index des résultats est toujours stocké sur le serveur principal * car on ne sait pas si la base distante dispose d'une table spip_resultats * ni meme si on aurait le droit d'ecrire dedans * * @param string $recherche * chaine recherchee * @param string $table * table dans laquelle porte la recherche * @param bool $cond * critere conditionnel sur {recherche?} * @param string $serveur * serveur de base de donnees * @param array $modificateurs * modificateurs de boucle, ie liste des criteres presents * @param string $primary * cle primaire de la table de recherche * @return array */ function inc_prepare_recherche_dist( $recherche, $table = 'articles', $cond = false, $serveur = '', $modificateurs = [], $primary = '' ) { $where = null; $rows = null; static $cache = []; $delai_fraicheur = min( \_DELAI_CACHE_resultats, time() - ($GLOBALS['meta']['derniere_modif'] ?? 0) ); // si recherche n'est pas dans le contexte, on va prendre en globals // ca permet de faire des inclure simple. if (!isset($recherche) and isset($GLOBALS['recherche'])) { $recherche = $GLOBALS['recherche']; } // traiter le cas {recherche?} if ($cond and !strlen($recherche)) { return [ '0 as points' /* as points */, /* where */ '' ]; } $rechercher = false; $where_resultat_recent = sql_date_proche('maj', (0 - ($delai_fraicheur + 100)), ' SECOND'); if (!isset($cache[$serveur][$table][$recherche])) { $hash_serv = ($serveur ? substr(md5($serveur), 0, 16) : ''); $hash = substr(md5($recherche . $table), 0, 16); $where = "(resultats.recherche='$hash' AND resultats.table_objet=" . sql_quote($table) . " AND resultats.serveur='$hash_serv')"; $row = sql_fetsel( 'recherche', 'spip_resultats AS resultats', $where . " AND $where_resultat_recent", '', '', '0,1' ); if ( !$row or (defined('_VAR_MODE') and _VAR_MODE == 'recalcul') ) { $rechercher = true; } } // si on n'a pas encore traite les donnees dans une boucle precedente if ($rechercher) { //$tables = liste_des_champs(); $x = objet_type($table); $points = recherche_en_base( $recherche, $x, [ 'score' => true, 'toutvoir' => true, 'jointures' => true ], $serveur ); // pas de résultat, pas de point $points = $points[$x] ?? []; // permettre aux plugins de modifier le resultat $points = pipeline('prepare_recherche', [ 'args' => [ 'type' => $x, 'recherche' => $recherche, 'serveur' => $serveur, 'modificateurs' => $modificateurs ], 'data' => $points ]); // supprimer les anciens resultats de cette recherche // et les resultats trop vieux avec une marge // pas de AS resultats dans un delete (mysql) $whered = str_replace( ['resultats.recherche', 'resultats.table_objet', 'resultats.serveur'], ['recherche', 'table_objet', 'serveur'], $where ); sql_delete( 'spip_resultats', "NOT($where_resultat_recent) OR ($whered)" ); // inserer les resultats dans la table de cache des resultats if (is_countable($points) ? count($points) : 0) { $tab_couples = []; foreach ($points as $id => $p) { $tab_couples[] = [ 'recherche' => $hash, 'id' => $id, 'points' => $p['score'], 'table_objet' => $table, 'serveur' => $hash_serv, ]; } sql_insertq_multi('spip_resultats', $tab_couples, []); } } if (!isset($cache[$serveur][$table][$recherche])) { if (!$serveur) { $cache[$serveur][$table][$recherche] = ['resultats.points AS points', $where]; } else { if (sql_countsel('spip_resultats as resultats', $where)) { $rows = sql_allfetsel('resultats.id,resultats.points', 'spip_resultats as resultats', $where); } $cache[$serveur][$table][$recherche] = generer_select_where_explicites($table, $primary, $rows, $serveur); } } return $cache[$serveur][$table][$recherche]; } /** * Generer le select et where qui contiennent explicitement * les id et points (ie comme dans SPIP 1.9.x) * quand on fait une recherche sur une table externe * * @param string $table * @param string $primary * @param array $rows * @param string $serveur * @return array */ function generer_select_where_explicites($table, $primary, $rows, $serveur) { # calculer le {id_article IN()} et le {... as points} if (!count($rows)) { return ["''", '0=1']; } else { $listes_ids = []; $select = '0'; foreach ($rows as $r) { $listes_ids[$r['points']][] = $r['id']; } foreach ($listes_ids as $p => $ids) { $select .= "+$p*(" . sql_in("$table.$primary", $ids, '', $serveur) . ') '; } return ["$select AS points ", sql_in("$table.$primary", array_map('reset', $rows), '', $serveur)]; } }