[SPIP] v3.2.12 -> v3.2.12 - Reinstallation avec le spip_loader
[lhc/web/www.git] / www / plugins-dist / svp / svp_fonctions.php
1 <?php
2
3 /**
4 * Déclarations de fonctions
5 *
6 * @plugin SVP pour SPIP
7 * @license GPL
8 * @package SPIP\SVP\Fonctions
9 **/
10
11 function svp_importer_charset($texte) {
12 if ($GLOBALS['meta']['charset'] == 'utf-8') {
13 return $texte;
14 }
15
16 return importer_charset($texte, 'utf-8');
17 }
18
19 /**
20 * Retourne un texte expliquant l'intervalle de compatibilité avec un plugin ou SPIP
21 *
22 * Retourne par exemple "2.0 <= SPIP < 3.1"
23 *
24 * @param string $intervalle
25 * L'intervalle tel que déclaré dans paquet.xml. Par exemple "[2.1;3.0.*]"
26 * @param string $logiciel
27 * Nom du plugin pour qui est cette intervalle
28 * @return string
29 * Texte expliquant l'intervalle
30 **/
31 function svp_afficher_intervalle($intervalle, $logiciel) {
32 if (!strlen($intervalle)) {
33 return '';
34 }
35 if (!defined('_EXTRAIRE_INTERVALLE')) {
36 include_spip('inc/plugin');
37 }
38 if (!preg_match(_EXTRAIRE_INTERVALLE . 'Uis', $intervalle, $regs)) {
39 return false;
40 }
41
42 $mineure = $regs[1];
43
44 $majeure = preg_replace(',\.99$,', '.*', $regs[2]);
45 $mineure_inc = $intervalle[0] == "[";
46 $majeure_inc = substr($intervalle, -1) == "]";
47 if (strlen($mineure)) {
48 if (!strlen($majeure)) {
49 $version = _T('svp:info_logiciel_version', array(
50 'logiciel' => $logiciel,
51 'signe' => ($mineure_inc ? '&ge;' : '&gt;'),
52 'version' => $mineure,
53 ));
54 } else {
55 $version = _T('svp:info_logiciel_version_intervalle', array(
56 'logiciel' => $logiciel,
57 'signe_min' => ($mineure_inc ? '&ge;' : '&gt;'),
58 'version_min' => $mineure,
59 'signe_max' => ($majeure_inc ? '&le;' : '&lt;'),
60 'version_max' => $majeure,
61 ));
62 }
63 } else {
64 if (!strlen($majeure)) {
65 $version = $logiciel;
66 } else {
67 $version = _T('svp:info_logiciel_version', array(
68 'logiciel' => $logiciel,
69 'signe' => ($majeure_inc ? '&le;' : '&lt;'),
70 'version' => $majeure,
71 ));
72 }
73 }
74
75 return $version;
76 }
77
78 /**
79 * Traduit un type d'état de plugin
80 *
81 * Si l'état n'existe pas, prendra par défaut 'developpement'
82 *
83 * @see plugin_etat_en_clair()
84 * @param string $etat
85 * Le type d'état (stable, test, ...)
86 * @return string
87 * Traduction de l'état dans la langue en cours
88 **/
89 function svp_afficher_etat($etat) {
90 include_spip('plugins/afficher_plugin');
91
92 return plugin_etat_en_clair($etat);
93 }
94
95 /**
96 * Retourne un texte HTML présentant la liste des dépendances d'un plugin
97 *
98 * Des liens vers les plugins dépendants sont présents lorsque les plugins
99 * en dépendance sont connus dans notre base.
100 *
101 * @uses svp_afficher_intervalle()
102 * @param string $balise_serialisee
103 * Informations des dépendances (tableau sérialisé) tel que stocké
104 * en base dans la table spip_paquets
105 * @param string $dependance
106 * Type de dépendances à afficher (necessite ou utilise).
107 * Une autre valeur indique qu'on demande la liste des librairies dépendantes.
108 * @param string $sep
109 * Séparateur entre les noms de dépendances
110 * @param string $lien
111 * Type de lien affecté au plugin référencé dans la base locale. Prend les valeurs :
112 *
113 * - local : le lien pointe vers la page publique du plugin sur le site lui-même. Il faut
114 * donc que le site propose des pages publiques pour les plugins sinon une 404 sera affichée;
115 * - pluginspip : le lien pointe vers la page du plugin sur le site de référence Plugins SPIP;
116 * - non : aucun lien n'est affiché.
117 * @return string
118 * Texte informant des dépendances
119 **/
120 function svp_afficher_dependances($balise_serialisee, $dependance = 'necessite', $sep = '<br />', $lien = 'local') {
121 $texte = '';
122
123 $t = unserialize($balise_serialisee);
124 $dependances = $t[$dependance];
125 if (is_array($dependances)) {
126 ksort($dependances);
127
128 foreach ($dependances as $_compatibilite => $_dependance) {
129 $compatibilite = ($_compatibilite !== 0)
130 ? _T('svp:info_compatibilite_dependance',
131 array('compatibilite' => svp_afficher_intervalle($_compatibilite, 'SPIP')))
132 : '';
133 if ($compatibilite) {
134 $texte .= ($texte ? str_repeat($sep, 2) : '') . $compatibilite;
135 }
136 foreach ($_dependance as $_plugin) {
137 if ($texte) {
138 $texte .= $sep;
139 }
140 if (($dependance == 'necessite') or ($dependance == 'utilise')) {
141 if ($plugin = sql_fetsel('id_plugin, nom', 'spip_plugins', 'prefixe=' . sql_quote($_plugin['nom']))) {
142 $nom = extraire_multi($plugin['nom']);
143 if ($lien == 'non') {
144 $logiciel = $nom;
145 } else {
146 $url = ($lien == 'local')
147 ? generer_url_entite($plugin['id_plugin'], 'plugin')
148 : "https://plugins.spip.net/{$_plugin['nom']}.html";
149 $bulle = _T('svp:bulle_aller_plugin');
150 $logiciel = '<a href="' . $url . '" title="' . $bulle . '">' . $nom . '</a>';
151 }
152 } else {
153 // Cas ou le plugin n'est pas encore dans la base SVP.
154 // On affiche son préfixe, cependant ce n'est pas un affichage devant perdurer
155 $logiciel = $_plugin['nom'];
156 }
157 $intervalle = '';
158 if (isset($_plugin['compatibilite'])) {
159 $intervalle = svp_afficher_intervalle($_plugin['compatibilite'], $logiciel);
160 }
161 $texte .= ($intervalle) ? $intervalle : $logiciel;
162 } else // On demande l'affichage des librairies
163 {
164 $texte .= '<a href="' . $_plugin['lien'] . '" title="' . _T('svp:bulle_telecharger_librairie') . '">' . $_plugin['nom'] . '</a>';
165 }
166 }
167 }
168 }
169
170 return $texte;
171 }
172
173 /**
174 * Teste si un plugin possède des dépendances
175 *
176 * @param string $balise_serialisee
177 * Informations des dépendances (tableau sérialisé) tel que stocké
178 * en base dans la table spip_paquets
179 * @return bool
180 * Le plugin possède t'il des dépendances ?
181 **/
182 function svp_dependances_existe($balise_serialisee) {
183 $dependances = unserialize($balise_serialisee);
184 foreach ($dependances as $_dependance) {
185 if ($_dependance) {
186 return true;
187 }
188 }
189
190 return false;
191 }
192
193
194 /**
195 * Retourne un texte HTML présentant les crédits d'un plugin
196 *
197 * Des liens vers les crédits sont présents lorsqu'ils sont déclarés
198 * dans le paquet.xml.
199 *
200 * @param string $balise_serialisee
201 * Informations des crédits (tableau sérialisé) tel que stocké
202 * en base dans la table spip_paquets
203 * @param string $sep
204 * Séparateur entre les différents crédits
205 * @return string
206 * Texte informant des crédits
207 **/
208 function svp_afficher_credits($balise_serialisee, $sep = ', ') {
209 $texte = '';
210
211 $credits = unserialize($balise_serialisee);
212 if (is_array($credits)) {
213 foreach ($credits as $_credit) {
214 if ($texte) {
215 $texte .= $sep;
216 }
217 // Si le credit en cours n'est pas un array c'est donc un copyright
218 $texte .=
219 (!is_array($_credit))
220 ? PtoBR(propre($_credit)) // propre pour les [lien->url] des auteurs de plugin.xml ...
221 : ($_credit['url'] ? '<a href="' . $_credit['url'] . '">' : '') .
222 $_credit['nom'] .
223 ($_credit['url'] ? '</a>' : '');
224 }
225 }
226
227 return $texte;
228 }
229
230
231 /**
232 * Retourne un texte HTML présentant la liste des langues et traducteurs d'un plugin
233 *
234 * Des liens vers les traducteurs sont présents lorsqu'ils sont connus.
235 *
236 * @param array $langues
237 * Tableau code de langue => traducteurs
238 * @param string $sep
239 * Séparateur entre les différentes langues
240 * @return string
241 * Texte informant des langues et traducteurs
242 **/
243 function svp_afficher_langues($langues, $sep = ', ') {
244 $texte = '';
245
246 if ($langues) {
247 foreach ($langues as $_code => $_traducteurs) {
248 if ($texte) {
249 $texte .= $sep;
250 }
251 $traducteurs_langue = array();
252 foreach ($_traducteurs as $_traducteur) {
253 if (is_array($_traducteur)) {
254 $traducteurs_langue[] =
255 ($_traducteur['lien'] ? '<a href="' . $_traducteur['lien'] . '">' : '') .
256 $_traducteur['nom'] .
257 ($_traducteur['lien'] ? '</a>' : '');
258 }
259 }
260 $texte .= $_code . (count($traducteurs_langue) > 0 ? ' (' . implode(', ', $traducteurs_langue) . ')' : '');
261 }
262 }
263
264 return $texte;
265 }
266
267
268 /**
269 * Retourne un texte HTML présentant des statistiques d'un dépot
270 *
271 * Liste le nombre de plugins et de paquets d'un dépot
272 * Indique aussi le nombre de dépots si l'on ne demande pas de dépot particulier.
273 *
274 * @uses svp_compter()
275 * @param int $id_depot
276 * Identifiant du dépot
277 * @return string
278 * Code HTML présentant les statistiques du dépot
279 **/
280 function svp_afficher_statistiques_globales($id_depot = 0) {
281 $info = '';
282
283 $total = svp_compter('depot', $id_depot);
284 if (!$id_depot) {
285 // Si on filtre pas sur un depot alors on affiche le nombre de depots
286 $info = '<li id="stats-depot" class="item">
287 <div class="unit size4of5">' . ucfirst(trim(_T('svp:info_depots_disponibles', array('total_depots' => '')))) . '</div>
288 <div class="unit size1of5 lastUnit">' . $total['depot'] . '</div>
289 </li>';
290 }
291 // Compteur des plugins filtre ou pas par depot
292 $info .= '<li id="stats-plugin" class="item">
293 <div class="unit size4of5">' . ucfirst(trim(_T('svp:info_plugins_heberges', array('total_plugins' => '')))) . '</div>
294 <div class="unit size1of5 lastUnit">' . $total['plugin'] . '</div>
295 </li>';
296 // Compteur des paquets filtre ou pas par depot
297 $info .= '<li id="stats-paquet" class="item">
298 <div class="unit size4of5">' . ucfirst(trim(_T('svp:info_paquets_disponibles', array('total_paquets' => '')))) . '</div>
299 <div class="unit size1of5 lastUnit">' . $total['paquet'] . '</div>
300 </li>';
301
302 return $info;
303 }
304
305
306 /**
307 * Retourne un texte indiquant un nombre total de paquets
308 *
309 * Calcule le nombre de paquets correspondant à certaines contraintes,
310 * tel que l'appartenance à un certain dépot, une certaine catégorie
311 * ou une certaine branche de SPIP et retourne une phrase traduite
312 * tel que «78 paquets disponibles»
313 *
314 * @uses svp_compter()
315 * @param int $id_depot
316 * Identifiant du dépot
317 * Zéro (par défaut) signifie ici : «dans tous les dépots distants»
318 * (id_dépot>0) et non «dans le dépot local»
319 * @param string $categorie
320 * Type de catégorie (auteur, communication, date...)
321 * @param string $compatible_spip
322 * Numéro de branche de SPIP. (3.0, 2.1, ...)
323 * @return string
324 * Texte indiquant un nombre total de paquets
325 **/
326 function svp_compter_telechargements($id_depot = 0, $categorie = '', $compatible_spip = '') {
327 $total = svp_compter('paquet', $id_depot, $categorie, $compatible_spip);
328 $info = _T('svp:info_paquets_disponibles', array('total_paquets' => $total['paquet']));
329
330 return $info;
331 }
332
333 /**
334 * Retourne un texte indiquant un nombre total de contributions pour un dépot
335 *
336 * Calcule différents totaux pour un dépot donné et retourne un texte
337 * de ces différents totaux. Les totaux correspondent par défaut aux
338 * plugins et paquets, mais l'on peut demander le total des autres contributions
339 * avec le second paramètre.
340 *
341 * @uses svp_compter()
342 * @param int $id_depot
343 * Identifiant du dépot
344 * Zéro (par défaut) signifie ici : «dans tous les dépots distants»
345 * (id_dépot>0) et non «dans le dépot local»
346 * @param string $contrib
347 * Type de total demandé ('plugin' ou autre)
348 * Si 'plugin' : indique le nombre de plugins et de paquets du dépot
349 * Si autre chose : indique le nombre des autres contributions, c'est
350 * à dire des zips qui ne sont pas des plugins, comme certaines libraires ou
351 * certains jeux de squelettes.
352 * @return string
353 * Texte indiquant certains totaux tel que nombre de plugins, nombre de paquets...
354 **/
355 function svp_compter_depots($id_depot, $contrib = 'plugin') {
356 $info = '';
357
358 $total = svp_compter('depot', $id_depot);
359 if (!$id_depot) {
360 $info = _T('svp:info_depots_disponibles', array('total_depots' => $total['depot'])) . ', ' .
361 _T('svp:info_plugins_heberges', array('total_plugins' => $total['plugin'])) . ', ' .
362 _T('svp:info_paquets_disponibles', array('total_paquets' => $total['paquet']));
363 } else {
364 if ($contrib == 'plugin') {
365 $info = _T('svp:info_plugins_heberges', array('total_plugins' => $total['plugin'])) . ', ' .
366 _T('svp:info_paquets_disponibles', array('total_paquets' => $total['paquet'] - $total['autre']));
367 } else {
368 $info = _T('svp:info_contributions_hebergees', array('total_autres' => $total['autre']));
369 }
370 }
371
372 return $info;
373 }
374
375
376 /**
377 * Retourne un texte indiquant un nombre total de plugins
378 *
379 * Calcule le nombre de plugins correspondant à certaines contraintes,
380 * tel que l'appartenance à un certain dépot, une certaine catégorie
381 * ou une certaine branche de SPIP et retourne une phrase traduite
382 * tel que «64 plugins disponibles»
383 *
384 * @uses svp_compter()
385 * @param int $id_depot
386 * Identifiant du dépot
387 * Zéro (par défaut) signifie ici : «dans tous les dépots distants»
388 * (id_dépot>0) et non «dans le dépot local»
389 * @param string $categorie
390 * Type de catégorie (auteur, communication, date...)
391 * @param string $compatible_spip
392 * Numéro de branche de SPIP. (3.0, 2.1, ...)
393 * @return string
394 * Texte indiquant un nombre total de paquets
395 **/
396 function svp_compter_plugins($id_depot = 0, $categorie = '', $compatible_spip = '') {
397 $total = svp_compter('plugin', $id_depot, $categorie, $compatible_spip);
398 $info = _T('svp:info_plugins_disponibles', array('total_plugins' => $total['plugin']));
399
400 return $info;
401 }
402
403
404 /**
405 * Compte le nombre de plugins, paquets ou autres contributions
406 * en fonction de l'entité demandée et de contraintes
407 *
408 * Calcule, pour un type d'entité demandé (depot, plugin, paquet, catégorie)
409 * leur nombre en fonction de certaines contraintes, tel que l'appartenance
410 * à un certain dépot, une certaine catégorie ou une certaine branche de SPIP.
411 *
412 * Lorsque l'entité demandée est un dépot, le tableau des totaux possède,
413 * en plus du nombre de dépots, le nombre de plugins et paquets.
414 *
415 * @note
416 * Attention le critère de compatibilite SPIP pris en compte est uniquement
417 * celui d'une branche SPIP
418 *
419 * @param string $entite
420 * De quoi veut-on obtenir des comptes. Peut être 'depot', 'plugin',
421 * 'paquet' ou 'categorie'
422 * @param int $id_depot
423 * Identifiant du dépot
424 * Zéro (par défaut) signifie ici : «dans tous les dépots distants»
425 * (id_dépot>0) et non «dans le dépot local»
426 * @param string $categorie
427 * Type de catégorie (auteur, communication, date...)
428 * @param string $compatible_spip
429 * Numéro de branche de SPIP. (3.0, 2.1, ...)
430 * @return array
431 * Couples (entite => nombre).
432 **/
433 function svp_compter($entite, $id_depot = 0, $categorie = '', $compatible_spip = '') {
434 $compteurs = array();
435
436 $where = array();
437 if ($id_depot) {
438 $where[] = "t1.id_depot=" . sql_quote($id_depot);
439 } else {
440 $where[] = "t1.id_depot>0";
441 }
442
443 if ($entite == 'plugin') {
444 $from = array('spip_plugins AS t2', 'spip_depots_plugins AS t1');
445 $where[] = "t1.id_plugin=t2.id_plugin";
446 if ($categorie) {
447 $where[] = "t2.categorie=" . sql_quote($categorie);
448 }
449 if ($compatible_spip) {
450 $creer_where = charger_fonction('where_compatible_spip', 'inc');
451 $where[] = $creer_where($compatible_spip, 't2', '>');
452 }
453 $compteurs['plugin'] = sql_count(sql_select('DISTINCT t1.id_plugin', $from, $where));
454 } elseif ($entite == 'paquet') {
455 $from = array('spip_paquets AS t1');
456 if ($categorie) {
457 $ids = sql_allfetsel('id_plugin', 'spip_plugins', 'categorie=' . sql_quote($categorie));
458 $ids = array_column($ids, 'id_plugin');
459 $where[] = sql_in('t1.id_plugin', $ids);
460 }
461 if ($compatible_spip) {
462 $creer_where = charger_fonction('where_compatible_spip', 'inc');
463 $where[] = $creer_where($compatible_spip, 't1', '>');
464 }
465 $compteurs['paquet'] = sql_countsel($from, $where);
466 } elseif ($entite == 'depot') {
467 $from = array('spip_depots AS t1');
468 $select = array(
469 'COUNT(t1.id_depot) AS depot',
470 'SUM(t1.nbr_plugins) AS plugin',
471 'SUM(t1.nbr_paquets) AS paquet',
472 'SUM(t1.nbr_autres) AS autre'
473 );
474 $compteurs = sql_fetsel($select, $from, $where);
475 } elseif ($entite == 'categorie') {
476 $from = array('spip_plugins AS t2', 'spip_depots_plugins AS t1');
477 $where[] = "t1.id_plugin=t2.id_plugin";
478 if ($id_depot) {
479 $ids = sql_allfetsel('id_plugin', 'spip_depots_plugins AS t1', $where);
480 $ids = array_column($ids, 'id_plugin');
481 $where[] = sql_in('t2.id_plugin', $ids);
482 }
483 if ($compatible_spip) {
484 $creer_where = charger_fonction('where_compatible_spip', 'inc');
485 $where[] = $creer_where($compatible_spip, 't2', '>');
486 }
487 if ($categorie) {
488 $where[] = "t2.categorie=" . sql_quote($categorie);
489 $compteurs['categorie'] = sql_count(sql_select('DISTINCT t1.id_plugin', $from, $where));
490 } else {
491 $select = array('t2.categorie', 'count(DISTINCT t1.id_plugin) as nb');
492 $group_by = array('t2.categorie');
493 $plugins = sql_allfetsel($select, $from, $where, $group_by);
494 $compteurs['categorie'] = array_column($plugins, 'nb', 'categorie');
495 }
496 }
497
498 return $compteurs;
499 }
500
501
502 /**
503 * Compile la balise `#SVP_CATEGORIES`
504 *
505 * Cette balise retourne un tableau listant chaque type de catégorie
506 * en index, associé à sa traduction en valeur.
507 *
508 * Accepte 2 paramètres :
509 * 1) le type du tri (ordre_cle ou ordre_alpha)
510 * 2) une catégorie (dans ce cas, limite le tableau à cette seule catégorie si elle existe)
511 *
512 * @example
513 * #SVP_CATEGORIES
514 * #SVP_CATEGORIES{ordre_alpha}
515 * #SVP_CATEGORIES{ordre_cle,auteur}
516 *
517 * @balise
518 * @see calcul_svp_categories()
519 * @param Champ $p
520 * Pile au niveau de la balise
521 * @return Champ
522 * Pile complétée par le code à générer
523 **/
524 function balise_SVP_CATEGORIES($p) {
525 // tri, peut être 'ordre_cle' ou 'ordre_alpha'
526 if (!$tri = interprete_argument_balise(1, $p)) {
527 $tri = "'ordre_cle'";
528 }
529 // catégorie (pour n'en prendre qu'une au lieu de toutes)
530 if (!$categorie = interprete_argument_balise(2, $p)) {
531 $categorie = "''";
532 }
533 $p->code = 'calcul_svp_categories(' . $tri . ',' . $categorie . ')';
534
535 return $p;
536 }
537
538 /**
539 * Retourne un tableau listant chaque type de catégorie
540 * en index, associé à sa traduction en valeur.
541 *
542 * @uses svp_traduire_categorie()
543 *
544 * @param string $tri
545 * Type de tri (ordre_cle ou ordre_alpha)
546 * @param string $categorie
547 * Restreindre le tableau de retour à cette catégorie si elle existe
548 * @return array
549 * Couples (type de catégorie => Texte de la catégorie)
550 **/
551 function calcul_svp_categories($tri = 'ordre_cle', $categorie = '') {
552
553 $retour = array();
554 include_spip('inc/svp_phraser'); // pour $GLOBALS['categories_plugin']
555 $svp_categories = $GLOBALS['categories_plugin'];
556
557 if (is_array($svp_categories)) {
558 if (($categorie) and in_array($categorie, $svp_categories)) {
559 $retour[$categorie] = _T('svp:categorie_' . strtolower($categorie));
560 } else {
561 if ($tri == 'ordre_alpha') {
562 sort($svp_categories);
563 // On positionne l'absence de categorie en fin du tableau
564 $svp_categories[] = array_shift($svp_categories);
565 }
566 foreach ($svp_categories as $_alias) {
567 $retour[$_alias] = svp_traduire_categorie($_alias);
568 }
569 }
570 }
571
572 return $retour;
573 }
574
575
576 /**
577 * Compile la balise `#SVP_BRANCHES_SPIP`
578 *
579 * Cette balise retourne une liste des branches de SPIP
580 *
581 * Avec un paramètre indiquant une branche, la balise retourne
582 * une liste des bornes mini et maxi de cette branche.
583 *
584 * @example
585 * #SVP_BRANCHES_SPIP : array('1.9', '2.0', '2.1', ....)
586 * #SVP_BRANCHES_SPIP{3.0} : array('3.0.0', '3.0.99')
587 *
588 * @balise
589 * @see calcul_svp_branches_spip()
590 *
591 * @param Champ $p
592 * Pile au niveau de la balise
593 * @return Champ
594 * Pile complétée par le code à générer
595 **/
596 function balise_SVP_BRANCHES_SPIP($p) {
597 // nom d'une branche en premier argument
598 if (!$branche = interprete_argument_balise(1, $p)) {
599 $branche = "''";
600 }
601 $p->code = 'calcul_svp_branches_spip(' . $branche . ')';
602
603 return $p;
604 }
605
606 /**
607 * Retourne une liste des branches de SPIP, ou les bornes mini et maxi
608 * d'une branche donnée
609 *
610 * @param string $branche
611 * Branche dont on veut récupérer les bornes mini et maxi
612 * @return array
613 * Liste des branches array('1.9', '2.0', '2.1', ....)
614 * ou liste mini et maxi d'une branche array('3.0.0', '3.0.99')
615 **/
616 function calcul_svp_branches_spip($branche) {
617
618 $retour = array();
619 include_spip('inc/svp_outiller'); // pour $GLOBALS['infos_branches_spip']
620 $svp_branches = $GLOBALS['infos_branches_spip'];
621
622 if (is_array($svp_branches)) {
623 if (($branche) and in_array($branche, $svp_branches)) // On renvoie les bornes inf et sup de la branche specifiee
624 {
625 $retour = $svp_branches[$branche];
626 } else {
627 // On renvoie uniquement les numeros de branches
628 $retour = array_keys($svp_branches);
629 }
630 }
631
632 return $retour;
633 }
634
635 /**
636 * Traduit un type de catégorie de plugin
637 *
638 * @param string $alias
639 * Type de catégorie (auteur, communication, date...)
640 * @return string
641 * Titre complet et traduit de la catégorie
642 **/
643 function svp_traduire_categorie($alias) {
644 $traduction = '';
645 if ($alias) {
646 $traduction = _T('svp:categorie_' . strtolower($alias));
647 }
648
649 return $traduction;
650 }
651
652 /**
653 * Traduit un type de dépot de plugin
654 *
655 * @param string $type
656 * Type de dépot (svn, git, manuel)
657 * @return string
658 * Titre complet et traduit du type de dépot
659 **/
660 function svp_traduire_type_depot($type) {
661
662 $traduction = '';
663 if ($type) {
664 $traduction = _T('svp:info_type_depot_' . $type);
665 }
666
667 return $traduction;
668 }
669
670 /**
671 * Calcule l'url exacte d'un lien de démo en fonction de son écriture
672 *
673 * @param string $url_demo
674 * URL de démonstration telle que saisie dans le paquet.xml
675 * @param boolean $url_absolue
676 * Indique que seules les url absolues doivent être retournées par la fonction.
677 * Tous les autres types d'url renvoient une chaine vide
678 * @return string
679 * URL calculée en fonction de l'URL d'entrée
680 **/
681 function svp_calculer_url_demo($url_demo, $url_absolue = false) {
682
683 $url_calculee = '';
684 $url_demo = trim($url_demo);
685 if (strlen($url_demo) > 0) {
686 $url_elements = @parse_url($url_demo);
687 if (isset($url_elements['scheme']) and $url_elements['scheme']) {
688 // Cas 1 : http://xxxx. C'est donc une url absolue que l'on conserve telle qu'elle.
689 $url_calculee = $url_demo;
690 } else {
691 if (!$url_absolue) {
692 if (isset($url_elements['query']) and $url_elements['query']) {
693 // Cas 2 : ?exec=xxx ou ?page=yyy. C'est donc une url relative que l'on transforme
694 // en url absolue privée ou publique en fonction de la query.
695 $egal = strpos($url_elements['query'], '=');
696 $page = substr($url_elements['query'], $egal + 1, strlen($url_elements['query']) - $egal - 1);
697 if (strpos($url_elements['query'], 'exec=') !== false) {
698 $url_calculee = generer_url_ecrire($page);
699 } else {
700 $url_calculee = generer_url_public($page);
701 }
702 } elseif (isset($url_elements['path']) and $url_elements['path']) {
703 // Cas 3 : xxx/yyy. C'est donc une url relative que l'on transforme
704 $url_calculee = generer_url_public($url_demo);
705 }
706 }
707 }
708 }
709
710 return $url_calculee;
711 }
712
713 /**
714 * Critère de compatibilité avec une version précise ou une branche de SPIP ou une liste de branches séparées par
715 * une virgule.
716 *
717 * Fonctionne sur les tables spip_paquets et spip_plugins.
718 * Si aucune valeur n'est explicité dans le critère on interroge le contexte pour trouver une variable
719 * compatible_spip et sinon tous les objets sont retournés.
720 *
721 * Le ! (NOT) ne fonctionne que sur une branche ou une liste de branches SPIP.
722 *
723 * @critere
724 * @example
725 * {compatible_spip}
726 * {compatible_spip 2.0.8} ou {compatible_spip 1.9}
727 * {compatible_spip #ENV{vers}} ou {compatible_spip #ENV{vers, 1.9.2}}
728 * {compatible_spip #GET{vers}} ou {compatible_spip #GET{vers, 2.1}}
729 * {compatible_spip '2.0,2.1'}
730 * {!compatible_spip 2.0}
731 * {!compatible_spip '2.0,2.1'}
732 * {!compatible_spip #ENV{vers}} ou {!compatible_spip #GET{vers}}
733 *
734 * @param string $idb Identifiant de la boucle
735 * @param array $boucles AST du squelette
736 * @param Critere $crit Paramètres du critère dans cette boucle
737 *
738 * @return void
739 */
740 function critere_compatible_spip_dist($idb, &$boucles, $crit) {
741
742 // Initialisation de la table (spip_plugins ou spip_paquets)
743 $boucle = &$boucles[$idb];
744 $table = $boucle->id_table;
745
746 // Initialisation du numéro de critère pour utiliser plusieurs fois le critère dans la même boucle
747 static $i = 1;
748
749 // La fonction LOCATE retourne soit 0 (pas trouvée) soit une valeur strictement supérieure à 0 (trouvée).
750 // Donc avec le modificateur not l'opérateur est un "=", sinon un ">".
751 // Le NOT s'utilise uniquement avec une branche SPIP (ex 2.0).
752 $op = ($crit->not == '!') ? '=' : '>';
753
754 // On calcule le code des critères.
755 // -- Initialisation avec le chargement de la fonction de calcul du critère.
756 $boucle->hash .= '
757 // COMPATIBILITE SPIP
758 $creer_where = charger_fonction(\'where_compatible_spip\', \'inc\');';
759
760 // On traite le critère suivant que la version ou la branche est explicitement fournie ou pas.
761 if (!empty($crit->param)) {
762 // La ou les versions/branches sont explicites dans l'appel du critere.
763 // - on boucle sur les paramètres sachant qu'il est possible de fournir une liste séparée par une virgule
764 // (ex 3.2,3.1)
765 foreach ($crit->param as $_param) {
766 if (isset($_param[0])) {
767 $version = calculer_liste(array($_param[0]), array(), $boucles, $boucle->id_parent);
768 $boucle->hash .= '
769 $where' . $i . ' = $creer_where(' . $version . ', \'' . $table . '\', \'' . $op . '\');
770 ';
771 $boucle->where[] = '$where' . $i;
772 $i++;
773 }
774 }
775 } else {
776 // Pas de version ou de branche explicite dans l'appel du critere.
777 // - on regarde si elle est dans le contexte
778 $boucle->hash .= '
779 $version = isset($Pile[0][\'compatible_spip\']) ? $Pile[0][\'compatible_spip\'] : \'\';
780 $where' . $i . ' = $creer_where($version, \'' . $table . '\', \'' . $op . '\');
781 ';
782 $boucle->where[] = '$where' . $i;
783 $i++;
784 }
785 }
786
787 /**
788 * Retourne la liste des plugins trouvés par une recherche
789 *
790 * @filtre
791 * @param string $phrase
792 * Texte de la recherche
793 * @param string $categorie
794 * Type de catégorie de plugin (auteur, date...)
795 * @param string $etat
796 * État de plugin (stable, test...)
797 * @param string|int $depot
798 * Identifiant de dépot
799 * @param bool|string $afficher_exclusions
800 * Afficher aussi les paquets déjà installés (true ou 'oui')
801 * ou ceux qui ne le sont pas (false) ?
802 * @param bool|string $afficher_doublons
803 * Afficher toutes les versions de paquet (true ou 'oui')
804 * ou seulement la plus récente (false) ?
805 * @return array
806 * Tableau classé par pertinence de résultat
807 * - 'prefixe' => tableau de description du paquet (si pas de doublons demandé)
808 * - n => tableau de descriptions du paquet (si doublons autorisés)
809 **/
810 function filtre_construire_recherche_plugins(
811 $phrase = '',
812 $categorie = '',
813 $etat = '',
814 $depot = '',
815 $afficher_exclusions = true,
816 $afficher_doublons = false
817 ) {
818
819 // On traite les paramètres d'affichage
820 $afficher_exclusions = ($afficher_exclusions == 'oui') ? true : false;
821 $afficher_doublons = ($afficher_doublons == 'oui') ? true : false;
822
823 $tri = ($phrase) ? 'score' : 'nom';
824 $version_spip = $GLOBALS['spip_version_branche'] . "." . $GLOBALS['spip_version_code'];
825
826 // On recupere la liste des paquets:
827 // - sans doublons, ie on ne garde que la version la plus recente
828 // - correspondant a ces criteres
829 // - compatible avec la version SPIP installee sur le site
830 // - et n'etant pas deja installes (ces paquets peuvent toutefois etre affiches)
831 // tries par nom ou score
832 include_spip('inc/svp_rechercher');
833 $plugins = svp_rechercher_plugins_spip(
834 $phrase, $categorie, $etat, $depot, $version_spip,
835 svp_lister_plugins_installes(), $afficher_exclusions, $afficher_doublons, $tri);
836
837 return $plugins;
838
839 }
840
841 /**
842 * Retourne le nombre d'heures entre chaque actualisation
843 * si le cron est activé.
844 *
845 * @return int
846 * Nombre d'heures (sinon 0)
847 **/
848 function filtre_svp_periode_actualisation_depots() {
849 include_spip('genie/svp_taches_generales_cron');
850
851 return _SVP_CRON_ACTUALISATION_DEPOTS ? _SVP_PERIODE_ACTUALISATION_DEPOTS : 0;
852 }
853
854
855 /**
856 * Retourne 'x.y.z' à partir de '00x.00y.00z'
857 *
858 * Retourne la chaine de la version x.y.z sous sa forme initiale,
859 * sans remplissage à gauche avec des 0.
860 *
861 * @see normaliser_version()
862 * @param string $version_normalisee
863 * Numéro de version normalisée
864 * @return string
865 * Numéro de version dénormalisée
866 **/
867 function denormaliser_version($version_normalisee = '') {
868
869 $version = '';
870 if ($version_normalisee) {
871 $v = explode('.', $version_normalisee);
872 foreach ($v as $_nombre) {
873 $n = ltrim($_nombre, '0');
874 // On traite les cas du type 001.002.000-dev qui doivent etre transformes en 1.2.0-dev.
875 // Etant donne que la denormalisation est toujours effectuee sur une version normalisee on sait
876 // que le suffixe commence toujours pas '-'
877 $vn[] = ((strlen($n) > 0) and substr($n, 0, 1) != '-') ? $n : "0$n";
878 }
879 $version = implode('.', $vn);
880 }
881
882 return $version;
883 }
884
885 /**
886 * Teste l'utilisation du répertoire auto des plugins.
887 *
888 * Ce répertoire permet de télécharger dedans des plugins
889 * lorsqu'il est présent.
890 *
891 * @return bool
892 * Le répertoire de chargement des plugins auto est-il présent
893 * et utilisable ?
894 */
895 function test_plugins_auto() {
896 static $test = null;
897 if (is_null($test)) {
898 include_spip('inc/plugin'); // pour _DIR_PLUGINS_AUTO
899 $test = (defined('_DIR_PLUGINS_AUTO') and _DIR_PLUGINS_AUTO and is_writable(_DIR_PLUGINS_AUTO));
900 }
901
902 return $test;
903 }