[SPIP] +spip v3.0.17
[lhc/web/clavette_www.git] / www / plugins-dist / svp / inc / svp_rechercher.php
1 <?php
2
3 /**
4 * Gestion des recherches de plugins
5 *
6 * @plugin SVP pour SPIP
7 * @license GPL
8 * @package SPIP\SVP\Recherche
9 **/
10
11 if (!defined("_ECRIRE_INC_VERSION")) return;
12 include_spip('inc/plugin');
13
14 // ----------------------- Recherches de plugins ---------------------------------
15
16 /**
17 * Calcule une liste des paquets en fonctions de critères de recherche
18 *
19 * Cette liste :
20 * - est sans doublons, ie on ne garde que la version la plus récente
21 * - correspond aux critères
22 * - est compatible avec la version SPIP installée sur le site
23 * - ne liste pas ceux étant déjà installés (ces paquets peuvent toutefois être affichés)
24 * - est triée par nom ou score
25 *
26 * @param string $phrase
27 * Texte de la recherche
28 * @param string $categorie
29 * Type de catégorie de plugin (auteur, date...)
30 * @param string $etat
31 * État de plugin (stable, test...)
32 * @param string|int $depot
33 * Identifiant de dépot
34 * @param string $version_spip
35 * Version de SPIP dont le paquet doit être compatible
36 * @param array $exclusions
37 * Liste d'identifiants de plugin à ne pas intégrer dans la liste
38 * @param bool $afficher_exclusions
39 * Afficher aussi les paquets déjà installés (true)
40 * ou ceux qui ne le sont pas (false) ?
41 * @param bool $doublon
42 * Afficher toutes les versions de paquet (true)
43 * ou seulement la plus récente (false) ?
44 * @param string $tri
45 * Ordre du tri : nom | score
46 *
47 * @return array
48 * Tableau classé par pertinence de résultat
49 * - 'prefixe' => tableau de description du paquet (si pas de doublons demandé)
50 * - n => tableau de descriptions du paquet (si doublons autorisés)
51 **/
52 function svp_rechercher_plugins_spip($phrase, $categorie, $etat, $depot, $version_spip='',
53 $exclusions=array(), $afficher_exclusions=false, $doublon=false, $tri='nom')
54 {
55
56 include_spip('inc/rechercher');
57
58 $plugins = array();
59 $scores = array();
60 $ids_paquets = array();
61
62 // On prepare l'utilisation de la recherche en base SPIP en la limitant aux tables spip_plugins
63 // et spip_paquets si elle n'est pas vide
64 if ($phrase) {
65 $liste = liste_des_champs();
66 $tables = array('plugin' => $liste['plugin']);
67 $options = array('jointures' => true, 'score' => true);
68
69 // On cherche dans tous les enregistrements de ces tables des correspondances les plugins qui
70 // correspondent a la phrase recherchee
71 // -- On obtient une liste d'id de plugins et d'id de paquets
72 $resultats = array('plugin' => array(), 'paquet' => array());
73 $resultats = recherche_en_base($phrase, $tables, $options);
74 // -- On prepare le tableau des scores avec les paquets trouves par la recherche
75 if ($resultats) {
76 // -- On convertit les id de plugins en id de paquets
77 $ids = array();
78 if (isset($resultats['plugin']) and $resultats['plugin']) {
79 $ids_plugin = array_keys($resultats['plugin']);
80 $where[] = sql_in('id_plugin', $ids_plugin);
81 $ids = sql_allfetsel('id_paquet, id_plugin', 'spip_paquets', $where);
82 }
83 // -- On prepare les listes des id de paquet et des scores de ces memes paquets
84 if (isset($resultats['paquet']) and $resultats['paquet']) {
85 $ids_paquets = array_keys($resultats['paquet']);
86 foreach ($resultats['paquet'] as $_id => $_score) {
87 $scores[$_id] = intval($resultats['paquet'][$_id]['score']);
88 }
89 }
90 // -- On merge les deux tableaux de paquets sans doublon en mettant a jour un tableau des scores
91 foreach ($ids as $_ids) {
92 $id_paquet = intval($_ids['id_paquet']);
93 $id_plugin = intval($_ids['id_plugin']);
94 if (array_search($id_paquet, $ids_paquets) === false) {
95 $ids_paquets[] = $id_paquet;
96 $scores[$id_paquet] = intval($resultats['plugin'][$id_plugin]['score']);
97 }
98 else {
99 $scores[$id_paquet] = intval($resultats['paquet'][$id_paquet]['score'])
100 + intval($resultats['plugin'][$id_plugin]['score']);
101 }
102 }
103 }
104 }
105 else {
106 if ($ids_paquets = sql_allfetsel('id_paquet', 'spip_paquets')) {
107 $ids_paquets = array_map('reset', $ids_paquets);
108 foreach ($ids_paquets as $_id)
109 $scores[$_id] = 0;
110 }
111 }
112
113 // Maintenant, on continue la recherche en appliquant, sur la liste des id de paquets,
114 // les filtres complementaires : categorie, etat, exclusions et compatibilite spip
115 // si on a bien trouve des resultats precedemment ou si aucune phrase n'a ete saisie
116 // -- Preparation de la requete
117 if ($ids_paquets) {
118 $from = array('spip_plugins AS t1', 'spip_paquets AS t2', 'spip_depots AS t3');
119 $select = array('t1.nom AS nom', 't1.slogan AS slogan', 't1.prefixe AS prefixe', 't1.id_plugin AS id_plugin',
120 't2.id_paquet AS id_paquet', 't2.description AS description', 't2.compatibilite_spip AS compatibilite_spip',
121 't2.lien_doc AS lien_doc',
122 't2.auteur AS auteur', 't2.licence AS licence', 't2.etat AS etat',
123 't2.logo AS logo', 't2.version AS version', 't2.nom_archive AS nom_archive',
124 't3.url_archives AS url_archives', );
125 $where = array('t1.id_plugin=t2.id_plugin', 't2.id_depot=t3.id_depot');
126 if ($ids_paquets)
127 $where[] = sql_in('t2.id_paquet', $ids_paquets);
128 if (($categorie) AND ($categorie != 'toute_categorie'))
129 $where[] = 't1.categorie=' . sql_quote($categorie);
130 if (($etat) AND ($etat != 'tout_etat'))
131 $where[] = 't2.etat=' . sql_quote($etat);
132 if (($depot) AND ($depot != 'tout_depot'))
133 $where[] = 't2.id_depot=' . sql_quote($depot);
134 if ($exclusions AND !$afficher_exclusions)
135 $where[] = sql_in('t2.id_plugin', $exclusions, 'NOT');
136
137 if ($resultats = sql_select($select, $from, $where)) {
138 while ($paquets = sql_fetch($resultats)) {
139 $prefixe = $paquets['prefixe'];
140 $version = $paquets['version'];
141 $nom = extraire_multi($paquets['nom']);
142 $slogan = extraire_multi($paquets['slogan']);
143 $description = extraire_multi($paquets['description']);
144 if (svp_verifier_compatibilite_spip($paquets['compatibilite_spip'], $version_spip)) {
145 // Le paquet remplit tous les criteres, on peut le selectionner
146 // -- on utilise uniquement la langue du site
147 $paquets['nom'] = $nom;
148 $paquets['slogan'] = $slogan;
149 $paquets['description'] = $description;
150 // -- on ajoute le score si on a bien saisi une phrase
151 if ($phrase)
152 $paquets['score'] = $scores[intval($paquets['id_paquet'])];
153 else
154 $paquets['score'] = 0;
155 // -- on construit l'url de l'archive
156 $paquets['url_archive'] = $paquets['url_archives'] . '/' . $paquets['nom_archive'];
157 // -- on gere les exclusions si elle doivent etre affichees
158 if ($afficher_exclusions AND in_array($paquets['id_plugin'], $exclusions))
159 $paquets['installe'] = true;
160 else
161 $paquets['installe'] = false;
162 // -- On traite les doublons (meme plugin, versions differentes)
163 if ($doublon)
164 // ajout systematique du paquet
165 $plugins[] = $paquets;
166 else {
167 // ajout
168 // - si pas encore trouve
169 // - ou si sa version est inferieure (on garde que la derniere version)
170 if (!isset($plugins[$prefixe])
171 OR !$plugins[$prefixe]
172 OR ($plugins[$prefixe] AND spip_version_compare($plugins[$prefixe]['version'], $version, '<'))) {
173 $plugins[$prefixe] = $paquets;
174 }
175 }
176 }
177 }
178 }
179
180 // On trie le tableau par score décroissant ou nom croissant
181 $fonction = 'svp_trier_par_' . $tri;
182 if ($doublon)
183 usort($plugins, $fonction);
184 else
185 uasort($plugins, $fonction);
186 }
187
188 return $plugins;
189 }
190
191
192 /**
193 * Récupère les identifiants des plugins déjà installés
194 *
195 * @return int[]
196 * Liste d'identifiants de plugins
197 */
198 function svp_lister_plugins_installes(){
199
200 $ids = array();
201
202 // On recupere la liste des plugins installes physiquement sur le site
203 // Pour l'instant ce n'est pas possible avec les fonctions natives de SPIP
204 // donc on se contente des plugins actifs
205 // - liste des prefixes en lettres majuscules des plugins actifs
206 $plugins = liste_plugin_actifs();
207
208 // - liste des id de plugin correspondants
209 // Il se peut que certains plugins ne soient pas trouves dans la bdd car aucun zip n'est disponible
210 // (donc pas inclus dans archives.xml). C'est le cas des plugins_dist du core
211 $ids = sql_allfetsel('id_plugin', 'spip_plugins', sql_in('prefixe', array_keys($plugins)));
212 $ids = array_map('reset', $ids);
213 $ids = array_map('intval', $ids);
214
215 return $ids;
216 }
217
218
219 /**
220 * Teste la compatibilité d'un intervalle de compatibilité avec une version
221 * donnée de SPIP
222 *
223 * @param string $intervalle
224 * Intervalle de compatibilité, tel que [2.1;3.0]
225 * @param string $version_spip
226 * Version de SPIP, tel que 3.0.4 (par défaut la version de SPIP en cours)
227 * @return bool
228 * true si l'intervalle est compatible, false sinon
229 */
230 function svp_verifier_compatibilite_spip($intervalle, $version_spip = '') {
231 if (!$version_spip)
232 $version_spip = $GLOBALS['spip_version_branche'].".".$GLOBALS['spip_version_code'];
233 return plugin_version_compatible($intervalle, $version_spip,'spip');
234 }
235
236
237 /**
238 * Callback de tri pour trier les résultats de plugin par score décroissant.
239 *
240 * Cette fonction est appelée par un usort ou uasort
241 *
242 * @param array $p1
243 * Plugin à comparer
244 * @param array $p2
245 * Plugin à comparer
246 * @return int
247 */
248 function svp_trier_par_score($p1, $p2){
249 if ($p1['score'] == $p2['score'])
250 $retour = 0;
251 else
252 $retour = ($p1['score'] < $p2['score']) ? 1 : -1;
253 return $retour;
254 }
255
256
257 /**
258 * Callback de tri pour trier les résultats de plugin par nom (alphabétique).
259 *
260 * Si le nom est identique on classe par version decroissante
261 * Cette fonction est appelée par un usort ou uasort
262 *
263 * @param array $p1
264 * Plugin à comparer
265 * @param array $p2
266 * Plugin à comparer
267 * @return int
268 */
269 function svp_trier_par_nom($p1, $p2){
270 $c1 = strcasecmp($p1['nom'], $p2['nom']);
271 if ($c1 == 0) {
272 $c2 = spip_version_compare($p1['version'], $p1['version'], '<');
273 $retour = ($c2) ? 1 : -1;
274 }
275 else
276 $retour = ($c1 < 0) ? -1 : 1;
277 return $retour;
278 }
279
280 ?>