Dépôt officiel du core SPIP * Anciennement présent sur svn://trac.rezo.net/spip * Les plugins-dist faisant partie de la distribution SPIP sont présents dans https://git.spip.net/SPIP/[nom du plugin dist] https://www.spip.net
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.

1481 lines
47 KiB

5 years ago
  1. <?php
  2. /***************************************************************************\
  3. * SPIP, Système de publication pour l'internet *
  4. * *
  5. * Copyright © avec tendresse depuis 2001 *
  6. * Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James *
  7. * *
  8. * Ce programme est un logiciel libre distribué sous licence GNU/GPL. *
  9. * Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne. *
  10. \***************************************************************************/
  11. /**
  12. * Gestion de l'activation des plugins
  13. *
  14. * @package SPIP\Core\Plugins
  15. **/
  16. if (!defined('_ECRIRE_INC_VERSION')) {
  17. return;
  18. }
  19. /** l'adresse du repertoire de telechargement et de decompactage des plugins */
  20. if (!defined('_DIR_PLUGINS_AUTO')) {
  21. define('_DIR_PLUGINS_AUTO', _DIR_PLUGINS . 'auto/');
  22. }
  23. #include_spip('inc/texte'); // ????? Appelle public/parametrer trop tot avant la reconstruction du chemin des plugins.
  24. include_spip('plugins/installer');
  25. /**
  26. * Retourne la description de chaque plugin présent dans un répertoire
  27. *
  28. * Lecture des sous repertoire plugin existants
  29. *
  30. * @example
  31. * - `liste_plugin_files()`
  32. * - `liste_plugin_files(_DIR_PLUGINS_DIST)`
  33. * - `liste_plugin_files(_DIR_PLUGINS_SUPPL)`
  34. *
  35. * @uses fast_find_plugin_dirs()
  36. * @uses plugins_get_infos_dist()
  37. *
  38. * @param string|null $dir_plugins
  39. * - string : Chemin (relatif à la racine du site) du répertoire à analyser.
  40. * - null : utilise le chemin `_DIR_PLUGINS`.
  41. * @return array
  42. **/
  43. function liste_plugin_files($dir_plugins = null) {
  44. static $plugin_files = [];
  45. if (is_null($dir_plugins)) {
  46. $dir_plugins = _DIR_PLUGINS;
  47. }
  48. if (
  49. !isset($plugin_files[$dir_plugins])
  50. or count($plugin_files[$dir_plugins]) == 0
  51. ) {
  52. $plugin_files[$dir_plugins] = [];
  53. foreach (fast_find_plugin_dirs($dir_plugins) as $plugin) {
  54. $plugin_files[$dir_plugins][] = substr($plugin, strlen($dir_plugins));
  55. }
  56. sort($plugin_files[$dir_plugins]);
  57. // et on lit le XML de tous les plugins pour le mettre en cache
  58. // et en profiter pour nettoyer ceux qui n'existent plus du cache
  59. $get_infos = charger_fonction('get_infos', 'plugins');
  60. $get_infos($plugin_files[$dir_plugins], false, $dir_plugins, true);
  61. }
  62. return $plugin_files[$dir_plugins];
  63. }
  64. /**
  65. * Recherche rapide des répertoires de plugins contenus dans un répertoire
  66. *
  67. * @uses is_plugin_dir()
  68. *
  69. * @param string $dir
  70. * Chemin du répertoire dont on souhaite retourner les sous répertoires
  71. * @param int $max_prof
  72. * Profondeur maximale des sous répertoires
  73. * @return array
  74. * Liste complète des répeertoires
  75. **/
  76. function fast_find_plugin_dirs($dir, $max_prof = 100) {
  77. $fichiers = [];
  78. // revenir au repertoire racine si on a recu dossier/truc
  79. // pour regarder dossier/truc/ ne pas oublier le / final
  80. $dir = preg_replace(',/[^/]*$,', '', $dir);
  81. if ($dir == '') {
  82. $dir = '.';
  83. }
  84. if (!is_dir($dir)) {
  85. return $fichiers;
  86. }
  87. if (is_plugin_dir($dir, '')) {
  88. $fichiers[] = $dir;
  89. return $fichiers;
  90. }
  91. if ($max_prof <= 0) {
  92. return $fichiers;
  93. }
  94. $subdirs = [];
  95. if (@is_dir($dir) and is_readable($dir) and $d = opendir($dir)) {
  96. while (($f = readdir($d)) !== false) {
  97. if (
  98. $f[0] != '.' # ignorer . .. .svn etc
  99. and $f != 'CVS'
  100. and is_dir($f = "$dir/$f")
  101. ) {
  102. $subdirs[] = $f;
  103. }
  104. }
  105. closedir($d);
  106. }
  107. foreach ($subdirs as $d) {
  108. $fichiers = array_merge($fichiers, fast_find_plugin_dirs("$d/", $max_prof - 1));
  109. }
  110. return $fichiers;
  111. }
  112. /**
  113. * Indique si un répertoire (ou plusieurs) est la racine d'un plugin SPIP
  114. *
  115. * Vérifie le ou les chemins relatifs transmis pour vérifier qu'ils contiennent
  116. * un `paquet.xml`. Les chemins valides sont retournés.
  117. *
  118. * @param string|string[] $dir
  119. * Chemin (relatif à `$dir_plugins`), ou liste de chemins à tester
  120. * @param string|null $dir_plugins
  121. * - string : Chemin de répertoire (relatif à la `_DIR_RACINE`), départ des chemin(s) à tester
  122. * - null (par défaut) : utilise le chemin `_DIR_PLUGINS`
  123. * @return string|string[]
  124. * - string : Le chemin accepté (c'était un plugin)
  125. * - '' : ce n'était pas un chemin valide
  126. * - array : Ensemble des chemins acceptés (si `$dir` était array)
  127. **/
  128. function is_plugin_dir($dir, $dir_plugins = null) {
  129. if (is_array($dir)) {
  130. foreach ($dir as $k => $d) {
  131. if (!is_plugin_dir($d, $dir_plugins)) {
  132. unset($dir[$k]);
  133. }
  134. }
  135. return $dir;
  136. }
  137. if (is_null($dir_plugins)) {
  138. $dir_plugins = _DIR_PLUGINS;
  139. }
  140. $search = ["$dir_plugins$dir/paquet.xml"];
  141. foreach ($search as $s) {
  142. if (file_exists($s)) {
  143. return $dir;
  144. }
  145. }
  146. return '';
  147. }
  148. /** Regexp d'extraction des informations d'un intervalle de compatibilité */
  149. define('_EXTRAIRE_INTERVALLE', ',^[\[\(\]]([0-9.a-zRC\s\-]*)[;]([0-9.a-zRC\s\-\*]*)[\]\)\[]$,');
  150. /**
  151. * Teste si le numéro de version d'un plugin est dans un intervalle donné.
  152. *
  153. * Cette fonction peut être volontairement trompée (phase de développement) :
  154. * voir commentaire infra sur l'utilisation de la constante _DEV_VERSION_SPIP_COMPAT
  155. *
  156. * @uses spip_version_compare()
  157. *
  158. * @param string $intervalle
  159. * Un intervalle entre 2 versions. ex: [2.0.0-dev;2.1.*]
  160. * @param string $version
  161. * Un numéro de version. ex: 3.1.99]
  162. * @param string $avec_quoi
  163. * Ce avec quoi est testée la compatibilité. par défaut ('')
  164. * avec un plugin (cas des 'necessite'), parfois ('spip')
  165. * avec SPIP.
  166. * @return bool
  167. * True si dans l'intervalle, false sinon.
  168. **/
  169. function plugin_version_compatible($intervalle, $version, $avec_quoi = '') {
  170. if (!strlen($intervalle)) {
  171. return true;
  172. }
  173. if (!preg_match(_EXTRAIRE_INTERVALLE, $intervalle, $regs)) {
  174. return false;
  175. }
  176. // Extraction des bornes et traitement de * pour la borne sup :
  177. // -- on autorise uniquement les ecritures 3.0.*, 3.*
  178. $minimum = $regs[1];
  179. $maximum = $regs[2];
  180. // si une version SPIP de compatibilité a été définie (dans
  181. // mes_options.php, sous la forme : define('_DEV_VERSION_SPIP_COMPAT', '3.1.0');
  182. // on l'utilise (phase de dev, de test...) mais *que* en cas de comparaison