You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

810 lines
26 KiB

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