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