PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/spip/ecrire/inc/plugin.php

https://github.com/eyeswebcrea/espace-couture-sittler.fr
PHP | 782 lines | 569 code | 73 blank | 140 comment | 105 complexity | 8f33e39e4c96c26b44ec901d020127fd MD5 | raw file
Possible License(s): LGPL-2.1, GPL-3.0
  1. <?php
  2. /***************************************************************************\
  3. * SPIP, Systeme de publication pour l'internet *
  4. * *
  5. * Copyright (c) 2001-2011 *
  6. * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
  7. * *
  8. * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
  9. * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
  10. \***************************************************************************/
  11. if (!defined('_ECRIRE_INC_VERSION')) return;
  12. // librairie pour parametrage plugin
  13. //
  14. define('_FILE_PLUGIN_CONFIG', "plugin.xml");
  15. # l'adresse du repertoire de telechargement et de decompactage des plugins
  16. define('_DIR_PLUGINS_AUTO', _DIR_PLUGINS.'auto/');
  17. // besoin de inc_meta
  18. include_spip('inc/texte');
  19. function spip_version_compare($v1,$v2,$op){
  20. $v1 = strtolower(preg_replace(',([0-9])[\s-.]?(dev|alpha|a|beta|b|rc|pl|p),i','\\1.\\2',$v1));
  21. $v2 = strtolower(preg_replace(',([0-9])[\s-.]?(dev|alpha|a|beta|b|rc|pl|p),i','\\1.\\2',$v2));
  22. $v1 = str_replace('rc','RC',$v1); // certaines versions de PHP ne comprennent RC qu'en majuscule
  23. $v2 = str_replace('rc','RC',$v2); // certaines versions de PHP ne comprennent RC qu'en majuscule
  24. $v1 = explode('.',$v1);
  25. $v2 = explode('.',$v2);
  26. while (count($v1)<count($v2))
  27. $v1[] = '0';
  28. while (count($v2)<count($v1))
  29. $v2[] = '0';
  30. $v1 = implode('.',$v1);
  31. $v2 = implode('.',$v2);
  32. return version_compare($v1, $v2,$op);
  33. }
  34. // lecture des sous repertoire plugin existants
  35. // $dir_plugins pour forcer un repertoire (ex: _DIR_EXTENSIONS)
  36. // _DIR_PLUGINS_SUPPL pour aller en chercher ailleurs (separes par des ":")
  37. // http://doc.spip.org/@liste_plugin_files
  38. function liste_plugin_files($dir_plugins = null){
  39. static $plugin_files=array();
  40. if (is_null($dir_plugins)) {
  41. $dir_plugins = _DIR_PLUGINS;
  42. if (defined('_DIR_PLUGINS_SUPPL'))
  43. $dir_plugins_suppl = array_filter(explode(':',_DIR_PLUGINS_SUPPL));
  44. }
  45. if (!isset($plugin_files[$dir_plugins])
  46. OR count($plugin_files[$dir_plugins]) == 0){
  47. $plugin_files[$dir_plugins] = array();
  48. foreach (preg_files($dir_plugins, '/plugin[.]xml$') as $plugin) {
  49. $plugin_files[$dir_plugins][] = substr(dirname($plugin),strlen($dir_plugins));
  50. }
  51. sort($plugin_files[$dir_plugins]);
  52. // hack affreux pour avoir le bon chemin pour les repertoires
  53. // supplementaires ; chemin calcule par rapport a _DIR_PLUGINS.
  54. if (isset($dir_plugins_suppl)) {
  55. foreach($dir_plugins_suppl as $suppl) {
  56. foreach (preg_files(_DIR_RACINE.$suppl, 'plugin[.]xml$') as $plugin) {
  57. $plugin_files[$dir_plugins][] = (_DIR_RACINE? '':'../').dirname($plugin);
  58. }
  59. }
  60. }
  61. }
  62. return $plugin_files[$dir_plugins];
  63. }
  64. // http://doc.spip.org/@plugin_version_compatible
  65. function plugin_version_compatible($intervalle,$version){
  66. if (!strlen($intervalle)) return true;
  67. if (!preg_match(',^[\[\(]([0-9.a-zRC\s\-]*)[;]([0-9.a-zRC\s\-]*)[\]\)]$,',$intervalle,$regs)) return false;
  68. #var_dump("$version::$intervalle");
  69. $minimum = $regs[1];
  70. $maximum = $regs[2];
  71. $minimum_inc = $intervalle{0}=="[";
  72. $maximum_inc = substr($intervalle,-1)=="]";
  73. #var_dump("$version::$minimum_inc::$minimum::$maximum::$maximum_inc");
  74. #var_dump(spip_version_compare($version,$minimum,'<'));
  75. if (strlen($minimum)){
  76. if ($minimum_inc AND spip_version_compare($version,$minimum,'<')) return false;
  77. if (!$minimum_inc AND spip_version_compare($version,$minimum,'<=')) return false;
  78. }
  79. if (strlen($maximum)){
  80. if ($maximum_inc AND spip_version_compare($version,$maximum,'>')) return false;
  81. if (!$maximum_inc AND spip_version_compare($version,$maximum,'>=')) return false;
  82. }
  83. return true;
  84. }
  85. /**
  86. * Faire la liste des librairies disponibles
  87. * retourne un array ( nom de la lib => repertoire , ... )
  88. *
  89. * @return array
  90. */
  91. // http://doc.spip.org/@liste_librairies
  92. function plugins_liste_librairies() {
  93. $libs = array();
  94. foreach (array_reverse(creer_chemin()) as $d) {
  95. if (is_dir($dir = $d.'lib/')
  96. AND $t = @opendir($dir)) {
  97. while (($f = readdir($t)) !== false) {
  98. if ($f[0] != '.'
  99. AND is_dir("$dir/$f"))
  100. $libs[$f] = $dir;
  101. }
  102. }
  103. }
  104. return $libs;
  105. }
  106. // Prend comme argument le tableau des <necessite> et retourne un tableau vide
  107. // si tout est bon, et un tableau avec une entree par erreur sinon
  108. // http://doc.spip.org/@erreur_necessite
  109. function erreur_necessite($n, $liste) {
  110. if (!is_array($n) OR !count($n)) {
  111. return array();
  112. }
  113. $msg = array();
  114. foreach($n as $need){
  115. $id = strtoupper($need['id']);
  116. // Necessite SPIP version x ?
  117. if ($id=='SPIP') {
  118. if (!plugin_version_compatible($need['version'],
  119. $GLOBALS['spip_version_branche'])) {
  120. $msg[] = _T('plugin_necessite_spip', array(
  121. 'version' => $need['version']
  122. ));
  123. }
  124. }
  125. // Necessite une librairie ?
  126. else if (preg_match(',^(lib):(.*),i', $need['id'], $r)) {
  127. $lib = trim($r[2]);
  128. if (!find_in_path('lib/'.$lib)) {
  129. $lien_download = '';
  130. if (isset($need['src'])) {
  131. $url = $need['src'];
  132. include_spip('inc/charger_plugin');
  133. $lien_download = '<br />'
  134. .bouton_telechargement_plugin($url, strtolower($r[1]));
  135. }
  136. $msg[] = _T('plugin_necessite_lib', array('lib'=>$lib)) . $lien_download;
  137. }
  138. }
  139. // Necessite un autre plugin version x ?
  140. else if (!isset($liste[$id])
  141. OR !plugin_version_compatible($need['version'],$liste[$id]['version'])
  142. ) {
  143. $msg[] = _T('plugin_necessite_plugin', array(
  144. 'plugin' => $id,
  145. 'version' => $need['version']));
  146. }
  147. }
  148. return $msg;
  149. }
  150. // http://doc.spip.org/@liste_plugin_valides
  151. function liste_plugin_valides($liste_plug, $force = false){
  152. $liste = array();
  153. $ordre = array();
  154. $infos = array();
  155. // lister les extensions qui sont automatiquement actives
  156. $liste_extensions = liste_plugin_files(_DIR_EXTENSIONS);
  157. $listes = array(
  158. '_DIR_EXTENSIONS'=>$liste_extensions,
  159. '_DIR_PLUGINS'=>$liste_plug
  160. );
  161. // creer une premiere liste non ordonnee mais qui ne retient
  162. // que les plugins valides, et dans leur derniere version en cas de doublon
  163. $liste_non_classee = array();
  164. $get_infos = charger_fonction('get_infos','plugins');
  165. foreach($listes as $dir_type=>$l){
  166. foreach($l as $k=>$plug) {
  167. // renseigner ce plugin
  168. $infos[$dir_type][$plug] = $get_infos($plug,$force,constant($dir_type));
  169. // si il n'y a pas d'erreur
  170. if ($infos[$dir_type][$plug] AND !isset($infos[$dir_type][$plug]['erreur'])) {
  171. // regarder si on a pas deja selectionne le meme plugin dans une autre version
  172. $version = isset($infos[$dir_type][$plug]['version'])?$infos[$dir_type][$plug]['version']:NULL;
  173. if (isset($liste_non_classee[$p=strtoupper($infos[$dir_type][$plug]['prefix'])])){
  174. // prendre le plus recent
  175. if (spip_version_compare($version,$liste_non_classee[$p]['version'],'>'))
  176. unset($liste_non_classee[$p]);
  177. else{
  178. continue;
  179. }
  180. }
  181. // ok, le memoriser
  182. $liste_non_classee[$p] = array(
  183. 'nom' => $infos[$dir_type][$plug]['nom'],
  184. 'etat' => $infos[$dir_type][$plug]['etat'],
  185. 'dir_type' => $dir_type, // extensions ou plugins
  186. 'dir'=>$plug,
  187. 'version'=>isset($infos[$dir_type][$plug]['version'])?$infos[$dir_type][$plug]['version']:NULL
  188. );
  189. }
  190. }
  191. }
  192. // il y a des plugins a trier
  193. if (is_array($liste_non_classee)){
  194. // pour tester utilise, il faut connaitre tous les plugins
  195. // qui seront forcement pas la a la fin,
  196. // car absent de la liste des plugins actifs
  197. $toute_la_liste = $liste_non_classee;
  198. // construire une liste ordonnee des plugins
  199. $count = 0;
  200. while ($c=count($liste_non_classee) AND $c!=$count){ // tant qu'il reste des plugins a classer, et qu'on ne stagne pas
  201. #echo "tour::";var_dump($liste_non_classee);
  202. $count = $c;
  203. foreach($liste_non_classee as $p=>$resume) {
  204. $plug = $resume['dir'];
  205. $dir_type = $resume['dir_type'];
  206. // si des plugins sont necessaire, on ne peut inserer qu'apres eux
  207. $necessite_ok = !erreur_necessite($infos[$dir_type][$plug]['necessite'], $liste);
  208. // si des plugins sont utiles, on ne peut inserer qu'apres eux,
  209. // sauf si ils sont de toute facon absents de la liste
  210. $utilise_ok = true;
  211. // tous les plugins "utilise" absents
  212. $nb_utilise_absents_toleres = count(erreur_necessite($infos[$dir_type][$plug]['utilise'], $toute_la_liste));
  213. // tous les plugins "utilise" absents de la liste deja trie
  214. $nb_utilise_absents_tries = count(erreur_necessite($infos[$dir_type][$plug]['utilise'], $liste));
  215. if (abs($nb_utilise_absents_tries - $nb_utilise_absents_toleres) > 0) {
  216. $utilise_ok = false;
  217. }
  218. if ($necessite_ok AND $utilise_ok){
  219. $liste[$p] = $liste_non_classee[$p];
  220. $ordre[] = $p;
  221. unset($liste_non_classee[$p]);
  222. }
  223. }
  224. }
  225. if (count($liste_non_classee)) {
  226. include_spip('inc/lang');
  227. utiliser_langue_visiteur();
  228. $erreurs = "";
  229. foreach($liste_non_classee as $p=>$resume){
  230. $plug = $resume['dir'];
  231. $dir_type = $resume['dir_type'];
  232. if ($n = erreur_necessite($infos[$dir_type][$plug]['necessite'], $liste)){
  233. $erreurs .= "<li>" . _T('plugin_impossible_activer',
  234. array('plugin' => constant($dir_type). $plug)
  235. ) . "<ul><li>" . implode("</li><li>", $n) . "</li></ul></li>";
  236. }
  237. else {
  238. // dependance circulaire, ou utilise qu'on peut ignorer ?
  239. // dans le doute on fait une erreur quand meme
  240. // plutot que d'inserer silencieusement et de risquer un bug sournois latent
  241. $necessite = erreur_necessite($infos[$dir_type][$plug]['utilise'], $liste);
  242. $erreurs .= "<li>" . _T('plugin_impossible_activer',
  243. array('plugin' => constant($dir_type). $plug)
  244. ) . "<ul><li>" . implode("</li><li>", $necessite) . "</li></ul></li>";
  245. }
  246. }
  247. ecrire_meta('plugin_erreur_activation',
  248. "<ul>$erreurs</ul>");
  249. }
  250. }
  251. return array($liste,$ordre,$infos);
  252. }
  253. // A utiliser pour initialiser ma variable globale $plugin
  254. // http://doc.spip.org/@liste_plugin_actifs
  255. function liste_plugin_actifs(){
  256. $meta_plugin = isset($GLOBALS['meta']['plugin'])?$GLOBALS['meta']['plugin']:'';
  257. if (strlen($meta_plugin)>0){
  258. if (is_array($t=unserialize($meta_plugin)))
  259. return $t;
  260. else{ // compatibilite pre 1.9.2, mettre a jour la meta
  261. spip_log("MAJ meta plugin vieille version : $meta_plugin","plugin");
  262. $t = explode(",",$meta_plugin);
  263. list($liste,,) = liste_plugin_valides($t);
  264. include_spip('inc/meta');
  265. ecrire_meta('plugin',serialize($liste));
  266. return $liste;
  267. }
  268. }
  269. else
  270. return array();
  271. }
  272. /**
  273. * Lister les chemins vers les plugins actifs d'un dossier plugins/
  274. *
  275. * @return unknown
  276. */
  277. // http://doc.spip.org/@liste_chemin_plugin_actifs
  278. function liste_chemin_plugin_actifs($dir_plugins=_DIR_PLUGINS){
  279. $liste = liste_plugin_actifs();
  280. foreach ($liste as $prefix=>$infos) {
  281. // compat au moment d'une migration depuis version anterieure
  282. // si pas de dir_type, alors c'est _DIR_PLUGINS
  283. if (!isset($infos['dir_type']))
  284. $infos['dir_type'] = "_DIR_PLUGINS";
  285. if (defined($infos['dir_type'])
  286. AND constant($infos['dir_type'])==$dir_plugins)
  287. $liste[$prefix] = $infos['dir'];
  288. else
  289. unset($liste[$prefix]);
  290. }
  291. return $liste;
  292. }
  293. // http://doc.spip.org/@ecrire_plugin_actifs
  294. function ecrire_plugin_actifs($plugin,$pipe_recherche=false,$operation='raz') {
  295. static $liste_pipe_manquants=array();
  296. // creer le repertoire cache/ si necessaire ! (installation notamment)
  297. sous_repertoire(_DIR_CACHE, '', false,true);
  298. $liste_fichier_verif = array();
  299. if (($pipe_recherche)&&(!in_array($pipe_recherche,$liste_pipe_manquants)))
  300. $liste_pipe_manquants[]=$pipe_recherche;
  301. if ($operation!='raz'){
  302. $plugin_actifs = liste_chemin_plugin_actifs();
  303. $plugin_liste = liste_plugin_files();
  304. $plugin_valides = array_intersect($plugin_actifs,$plugin_liste);
  305. if ($operation=='ajoute')
  306. $plugin = array_merge($plugin_valides,$plugin);
  307. if ($operation=='enleve')
  308. $plugin = array_diff($plugin_valides,$plugin);
  309. }
  310. // recharger le xml des plugins a activer
  311. list($plugin_valides,$ordre,$infos) = liste_plugin_valides($plugin,true);
  312. ecrire_meta('plugin',serialize($plugin_valides));
  313. effacer_meta('message_crash_plugins'); // baisser ce flag !
  314. $plugin_header_info = array();
  315. foreach($plugin_valides as $p=>$resume){
  316. $plugin_header_info[]= $p.($resume['version']?"(".$resume['version'].")":"");
  317. }
  318. ecrire_meta('plugin_header',substr(strtolower(implode(",",$plugin_header_info)),0,900));
  319. $start_file = "<"."?php\nif (defined('_ECRIRE_INC_VERSION')) {\n";
  320. $end_file = "}\n?".">";
  321. if (is_array($infos)){
  322. // construire tableaux de boutons et onglets
  323. $liste_boutons = array();
  324. $liste_onglets = array();
  325. foreach($ordre as $p){
  326. $dir_type = $plugin_valides[$p]['dir_type'];
  327. $plug = $plugin_valides[$p]['dir'];
  328. $info = $infos[$dir_type][$plug];
  329. if (isset($info['bouton'])){
  330. $liste_boutons = array_merge($liste_boutons,$info['bouton']);
  331. }
  332. if (isset($info['onglet'])){
  333. $liste_onglets = array_merge($liste_onglets,$info['onglet']);
  334. }
  335. }
  336. }
  337. // generer les fichier
  338. // charger_plugins_options.php
  339. // charger_plugins_fonctions.php
  340. if (defined('_DIR_PLUGINS_SUPPL'))
  341. $dir_plugins_suppl = implode(array_filter(explode(':',_DIR_PLUGINS_SUPPL)),'|');
  342. foreach(array('chemins'=>_CACHE_PLUGINS_PATH,'options'=>_CACHE_PLUGINS_OPT,'fonctions'=>_CACHE_PLUGINS_FCT) as $charge=>$fileconf){
  343. $s = "";
  344. $splugs = "";
  345. $chemins = array();
  346. if (is_array($infos)){
  347. foreach($ordre as $p){
  348. $dir_type = $plugin_valides[$p]['dir_type'];
  349. $plug = $plugin_valides[$p]['dir'];
  350. $info = $infos[$dir_type][$plug];
  351. if($dir_plugins_suppl && preg_match(',('.$dir_plugins_suppl.'),',$plugin_valides[$p]['dir'])){
  352. //$plugin_valides[$p]['dir_type'] = '_DIR_RACINE';
  353. $dir_type = '_DIR_RACINE';
  354. //if(!test_espace_prive())
  355. $plug = str_replace('../','',$plug);
  356. }
  357. $root_dir_type = str_replace('_DIR_','_ROOT_',$dir_type);
  358. $dir = $dir_type.".'" . $plug ."/'";
  359. // definir le plugin, donc le path avant l'include du fichier options
  360. // permet de faire des include_spip pour attraper un inc_ du plugin
  361. if ($charge=='chemins'){
  362. $prefix = strtoupper(preg_replace(',\W,','_',$info['prefix']));
  363. $splugs .= "define('_DIR_PLUGIN_$prefix',$dir);\n";
  364. foreach($info['path'] as $chemin){
  365. if (!isset($chemin['version']) OR plugin_version_compatible($chemin['version'],$GLOBALS['spip_version_branche'])){
  366. $dir = $chemin['dir'];
  367. if (strlen($dir) AND $dir{0}=="/") $dir = substr($dir,1);
  368. if (!isset($chemin['type']) OR $chemin['type']=='public')
  369. $chemins['public'][]="_DIR_PLUGIN_$prefix".(strlen($dir)?".'$dir'":"");
  370. if (!isset($chemin['type']) OR $chemin['type']=='prive')
  371. $chemins['prive'][]="_DIR_PLUGIN_$prefix".(strlen($dir)?".'$dir'":"");
  372. #$splugs .= "if (".(($chemin['type']=='public')?"":"!")."_DIR_RESTREINT) ";
  373. #$splugs .= "_chemin(_DIR_PLUGIN_$prefix".(strlen($dir)?".'$dir'":"").");\n";
  374. }
  375. }
  376. }
  377. // concerne uniquement options et fonctions
  378. if (isset($info[$charge])){
  379. foreach($info[$charge] as $file){
  380. // on genere un if file_exists devant chaque include pour pouvoir garder le meme niveau d'erreur general
  381. $file = trim($file);
  382. if (strlen(constant($dir_type)) && (strpos($plug, constant($dir_type)) === 0)) {
  383. $dir = str_replace("'".constant($dir_type), $root_dir_type.".'", "'$plug/'");
  384. }
  385. if($root_dir_type == '_ROOT_RACINE'){
  386. $plug = str_replace('../','',$plug);
  387. }
  388. else
  389. $dir = $root_dir_type.".'$plug/'";
  390. $s .= "if (file_exists(\$f=$dir.'".trim($file)."')){ include_once \$f;}\n";
  391. $liste_fichier_verif[] = "$root_dir_type:$plug/".trim($file);
  392. }
  393. }
  394. }
  395. }
  396. if ($charge=='chemins'){
  397. if (count($chemins)){
  398. $splugs .= "if (_DIR_RESTREINT) _chemin(implode(':',array(".implode(',',array_reverse($chemins['public'])).")));\n";
  399. $splugs .= "else _chemin(implode(':',array(".implode(',',array_reverse($chemins['prive'])).")));\n";
  400. }
  401. }
  402. if ($charge=='options'){
  403. $s .= "if (!function_exists('boutons_plugins')){function boutons_plugins(){return unserialize('".str_replace("'","\'",serialize($liste_boutons))."');}}\n";
  404. $s .= "if (!function_exists('onglets_plugins')){function onglets_plugins(){return unserialize('".str_replace("'","\'",serialize($liste_onglets))."');}}\n";
  405. }
  406. ecrire_fichier($fileconf, $start_file . $splugs . $s . $end_file);
  407. }
  408. if (is_array($infos)){
  409. // construire tableaux de pipelines et matrices et boutons
  410. // $GLOBALS['spip_pipeline']
  411. // $GLOBALS['spip_matrice']
  412. $liste_boutons = array();
  413. foreach($ordre as $p){
  414. $dir_type = $plugin_valides[$p]['dir_type'];
  415. $root_dir_type = str_replace('_DIR_','_ROOT_',$dir_type);
  416. $plug = $plugin_valides[$p]['dir'];
  417. $info = $infos[$dir_type][$plug];
  418. $prefix = "";
  419. $prefix = $info['prefix']."_";
  420. if (isset($info['pipeline']) AND is_array($info['pipeline'])){
  421. foreach($info['pipeline'] as $pipe){
  422. $nom = $pipe['nom'];
  423. if (isset($pipe['action']))
  424. $action = $pipe['action'];
  425. else
  426. $action = $nom;
  427. $nomlower = strtolower($nom);
  428. if ($nomlower!=$nom
  429. AND isset($GLOBALS['spip_pipeline'][$nom])
  430. AND !isset($GLOBALS['spip_pipeline'][$nomlower])){
  431. $GLOBALS['spip_pipeline'][$nomlower] = $GLOBALS['spip_pipeline'][$nom];
  432. unset($GLOBALS['spip_pipeline'][$nom]);
  433. }
  434. $nom = $nomlower;
  435. if (!isset($GLOBALS['spip_pipeline'][$nom])) // creer le pipeline eventuel
  436. $GLOBALS['spip_pipeline'][$nom]="";
  437. if (strpos($GLOBALS['spip_pipeline'][$nom],"|$prefix$action")===FALSE)
  438. $GLOBALS['spip_pipeline'][$nom] = preg_replace(",(\|\||$),","|$prefix$action\\1",$GLOBALS['spip_pipeline'][$nom],1);
  439. if (isset($pipe['inclure'])){
  440. $GLOBALS['spip_matrice']["$prefix$action"] =
  441. "$root_dir_type:$plug/".$pipe['inclure'];
  442. }
  443. }
  444. }
  445. }
  446. }
  447. // on charge les fichiers d'options qui peuvent completer
  448. // la globale spip_pipeline egalement
  449. if (@is_readable(_CACHE_PLUGINS_PATH))
  450. include_once(_CACHE_PLUGINS_PATH); // securite : a priori n'a pu etre fait plus tot
  451. if (@is_readable(_CACHE_PLUGINS_OPT)) {
  452. include_once(_CACHE_PLUGINS_OPT);
  453. } else {
  454. spip_log("pipelines desactives: impossible de produire " . _CACHE_PLUGINS_OPT);
  455. }
  456. // on ajoute les pipe qui ont ete recenses manquants
  457. foreach($liste_pipe_manquants as $add_pipe)
  458. if (!isset($GLOBALS['spip_pipeline'][$add_pipe]))
  459. $GLOBALS['spip_pipeline'][$add_pipe]= '';
  460. $liste_fichier_verif2 = pipeline_precompile();
  461. $liste_fichier_verif = array_merge($liste_fichier_verif,$liste_fichier_verif2);
  462. // on note dans tmp la liste des fichiers qui doivent etre presents,
  463. // pour les verifier "souvent"
  464. // ils ne sont verifies que depuis l'espace prive, mais peuvent etre reconstruit depuis l'espace public
  465. // dans le cas d'un plugin non declare, spip etant mis devant le fait accompli
  466. // hackons donc avec un "../" en dur dans ce cas, qui ne manquera pas de nous embeter un jour...
  467. foreach ($liste_fichier_verif as $k => $f){
  468. // si un _DIR_XXX: est dans la chaine, on extrait la constante
  469. if (preg_match(",(_(DIR|ROOT)_[A-Z_]+):,Ums",$f,$regs))
  470. $f = str_replace($regs[0],$regs[2]=="ROOT"?constant($regs[1]):(_DIR_RACINE?"":"../").constant($regs[1]),$f);
  471. $liste_fichier_verif[$k] = $f;
  472. }
  473. ecrire_fichier(_CACHE_PLUGINS_VERIF,
  474. serialize($liste_fichier_verif));
  475. clear_path_cache();
  476. }
  477. // precompilation des pipelines
  478. // http://doc.spip.org/@pipeline_precompile
  479. function pipeline_precompile(){
  480. global $spip_pipeline, $spip_matrice;
  481. $liste_fichier_verif = array();
  482. $start_file = "<"."?php\nif (defined('_ECRIRE_INC_VERSION')) {\n";
  483. $end_file = "}\n?".">";
  484. $content = "";
  485. foreach($spip_pipeline as $action=>$pipeline){
  486. $s_inc = "";
  487. $s_call = "";
  488. $pipe = array_filter(explode('|',$pipeline));
  489. // Eclater le pipeline en filtres et appliquer chaque filtre
  490. foreach ($pipe as $fonc) {
  491. $fonc = trim($fonc);
  492. $s_call .= '$val = minipipe(\''.$fonc.'\', $val);'."\n";
  493. if (isset($spip_matrice[$fonc])){
  494. $file = $spip_matrice[$fonc];
  495. $liste_fichier_verif[] = $file;
  496. $s_inc .= 'if (file_exists($f=';
  497. $file = "'$file'";
  498. // si un _DIR_XXX: est dans la chaine, on extrait la constante
  499. if (preg_match(",(_(DIR|ROOT)_[A-Z_]+):,Ums",$file,$regs)){
  500. $dir = $regs[1];
  501. $root_dir = str_replace('_DIR_','_ROOT_',$dir);
  502. if (defined($root_dir))
  503. $dir = $root_dir;
  504. $file = str_replace($regs[0],"'.".$dir.".'",$file);
  505. $file = str_replace("''.","",$file);
  506. $file = str_replace(constant($dir), '', $file);
  507. }
  508. $s_inc .= $file . ')){include_once($f);}'."\n";
  509. }
  510. }
  511. $content .= "// Pipeline $action \n";
  512. $content .= "function execute_pipeline_$action(&\$val){\n";
  513. $content .= $s_inc;
  514. $content .= $s_call;
  515. $content .= "return \$val;\n}\n\n";
  516. }
  517. ecrire_fichier(_CACHE_PIPELINES, $start_file . $content . $end_file);
  518. return $liste_fichier_verif;
  519. }
  520. // pas sur que ca serve...
  521. // http://doc.spip.org/@liste_plugin_inactifs
  522. function liste_plugin_inactifs(){
  523. return array_diff (liste_plugin_files(),liste_chemin_plugin_actifs());
  524. }
  525. // mise a jour du meta en fonction de l'etat du repertoire
  526. // Les ecrire_meta() doivent en principe aussi initialiser la valeur a vide
  527. // si elle n'existe pas
  528. // risque de pb en php5 a cause du typage ou de null (verifier dans la doc php)
  529. function actualise_plugins_actifs($pipe_recherche = false){
  530. if (!spip_connect()) return false;
  531. $plugin_actifs = liste_chemin_plugin_actifs();
  532. $plugin_liste = liste_plugin_files();
  533. $plugin_new = array_intersect($plugin_actifs,$plugin_liste);
  534. $actifs_avant = $GLOBALS['meta']['plugin'];
  535. ecrire_plugin_actifs($plugin_new,$pipe_recherche);
  536. // retourner -1 si la liste des plugins actifs a change
  537. return (strcmp($GLOBALS['meta']['plugin'],$actifs_avant)==0) ? 1 : -1;
  538. }
  539. // http://doc.spip.org/@spip_plugin_install
  540. function spip_plugin_install($action, $infos){
  541. $prefix = $infos['prefix'];
  542. $version_cible = $infos['version_base'];
  543. if (isset($infos['meta']) AND (($table = $infos['meta']) !== 'meta'))
  544. $nom_meta = "base_version";
  545. else {
  546. $nom_meta = $prefix."_base_version";
  547. $table = 'meta';
  548. }
  549. switch ($action){
  550. case 'test':
  551. return (isset($GLOBALS[$table])
  552. AND isset($GLOBALS[$table][$nom_meta])
  553. AND spip_version_compare($GLOBALS[$table][$nom_meta],$version_cible,'>='));
  554. break;
  555. case 'install':
  556. if (function_exists($upgrade = $prefix."_upgrade"))
  557. $upgrade($nom_meta, $version_cible, $table);
  558. break;
  559. case 'uninstall':
  560. if (function_exists($vider_tables = $prefix."_vider_tables"))
  561. $vider_tables($nom_meta, $table);
  562. break;
  563. }
  564. }
  565. // http://doc.spip.org/@desinstalle_un_plugin
  566. function desinstalle_un_plugin($plug,$infos){
  567. // faire les include qui vont bien
  568. charge_instal_plugin($plug, $infos);
  569. $version_cible = isset($infos['version_base'])?$infos['version_base']:'';
  570. $prefix_install = $infos['prefix']."_install";
  571. if (function_exists($prefix_install)){
  572. $prefix_install('uninstall',$infos['prefix'],$version_cible);
  573. $ok = $prefix_install('test',$infos['prefix'],$version_cible);
  574. return $ok;
  575. }
  576. if (isset($infos['version_base'])){
  577. spip_plugin_install('uninstall',$infos);
  578. $ok = spip_plugin_install('test',$infos);
  579. return $ok;
  580. }
  581. return false;
  582. }
  583. function charge_instal_plugin($plug,$infos,$dir_plugins = '_DIR_PLUGINS'){
  584. // passer en chemin absolu si possible
  585. $dir = str_replace('_DIR_','_ROOT_',$dir_plugins);
  586. if (!defined($dir))
  587. $dir = $dir_plugins;
  588. // faire les include qui vont bien
  589. foreach($infos['install'] as $file){
  590. $file = trim($file);
  591. if (file_exists($f=constant($dir)."$plug/$file")){
  592. include_once($f);
  593. }
  594. }
  595. }
  596. function installe_un_plugin($plug,$infos,$dir_plugins = '_DIR_PLUGINS'){
  597. charge_instal_plugin($plug, $infos, $dir_plugins);
  598. $version_cible = isset($infos['version_base'])?$infos['version_base']:'';
  599. $prefix_install = $infos['prefix']."_install";
  600. // cas de la fonction install fournie par le plugin
  601. if (function_exists($prefix_install)){
  602. // voir si on a besoin de faire l'install
  603. $ok = $prefix_install('test',$infos['prefix'],$version_cible);
  604. if (!$ok) {
  605. echo "<div class='install-plugins'>";
  606. echo _T('plugin_titre_installation',array('plugin'=>typo($infos['nom'])))."<br />";
  607. $prefix_install('install',$infos['prefix'],$version_cible);
  608. $ok = $prefix_install('test',$infos['prefix'],$version_cible);
  609. // vider le cache des definitions des tables
  610. $trouver_table = charger_fonction('trouver_table','base');
  611. $trouver_table(false);
  612. echo "<span class='".($ok?'ok':'erreur')."'>".($ok ? _L("OK"):_L("Echec"))."</span>";
  613. echo "</div>";
  614. }
  615. return $ok; // le plugin est deja installe et ok
  616. }
  617. // pas de fonction instal fournie, mais une version_base dans le plugin
  618. // on utilise la fonction par defaut
  619. if (isset($infos['version_base'])){
  620. $ok = spip_plugin_install('test',$infos);
  621. if (!$ok) {
  622. echo "<div class='install-plugins'>";
  623. echo _T('plugin_titre_installation',array('plugin'=>typo($infos['nom'])))."<br />";
  624. spip_plugin_install('install',$infos);
  625. $ok = spip_plugin_install('test',$infos);
  626. // vider le cache des definitions des tables
  627. $trouver_table = charger_fonction('trouver_table','base');
  628. $trouver_table(false);
  629. echo "<span class='".($ok?'ok':'erreur')."'>".($ok ? _L("OK"):_L("Echec"))."</span>";
  630. echo "</div>";
  631. }
  632. return $ok; // le plugin est deja installe et ok
  633. }
  634. return false;
  635. }
  636. // http://doc.spip.org/@installe_plugins
  637. function installe_plugins($test = false){
  638. $meta_plug_installes = array();
  639. // vider le cache des descriptions de tables avant installation
  640. $trouver_table = charger_fonction('trouver_table', 'base');
  641. $trouver_table('');
  642. $liste = liste_plugin_actifs();
  643. $get_infos = charger_fonction('get_infos','plugins');
  644. foreach ($liste as $prefix=>$resume) {
  645. $plug = $resume['dir'];
  646. $dir_type = $resume['dir_type'];
  647. $infos = $get_infos($plug,false,constant($dir_type));
  648. if ($infos AND isset($infos['install'])){
  649. if ($test) return true; // il y a des installations a faire
  650. $ok = installe_un_plugin($plug,$infos,$dir_type);
  651. // on peut enregistrer le chemin ici car il est mis a jour juste avant l'affichage
  652. // du panneau -> cela suivra si le plugin demenage
  653. if ($ok)
  654. $meta_plug_installes[] = $plug;
  655. // vider le cache des descriptions de tables apres chaque installation
  656. $trouver_table('');
  657. }
  658. }
  659. ecrire_meta('plugin_installes',serialize($meta_plug_installes),'non');
  660. if ($test) return false; // il n'y a pas d'installations a faire
  661. return true; // succes
  662. }
  663. // http://doc.spip.org/@plugin_est_installe
  664. function plugin_est_installe($plug_path){
  665. $plugin_installes = isset($GLOBALS['meta']['plugin_installes'])?unserialize($GLOBALS['meta']['plugin_installes']):array();
  666. if (!$plugin_installes) return false;
  667. return in_array($plug_path,$plugin_installes);
  668. }
  669. // http://doc.spip.org/@verifie_include_plugins
  670. function verifie_include_plugins() {
  671. include_spip('inc/meta');
  672. ecrire_meta('message_crash_plugins', 1);
  673. /* if (_request('exec')!="admin_plugin"
  674. AND $_SERVER['X-Requested-With'] != 'XMLHttpRequest'){
  675. if (@is_readable(_DIR_PLUGINS)) {
  676. include_spip('inc/headers');
  677. redirige_url_ecrire("admin_plugin");
  678. }
  679. // plus de repertoire plugin existant, le menu n'existe plus
  680. // on fait une mise a jour silencieuse
  681. // generer les fichiers php precompiles
  682. // de chargement des plugins et des pipelines
  683. actualise_plugins_actifs();
  684. spip_log("desactivation des plugins suite a suppression du repertoire");
  685. }
  686. */
  687. }
  688. // http://doc.spip.org/@message_crash_plugins
  689. function message_crash_plugins() {
  690. if (autoriser('configurer')
  691. AND lire_fichier(_CACHE_PLUGINS_VERIF,$l)
  692. AND $l = @unserialize($l)) {
  693. $err = array();
  694. foreach ($l as $fichier) {
  695. if (!@is_readable($fichier)) {
  696. spip_log("Verification plugin: echec sur $fichier !");
  697. $err[] = $fichier;
  698. }
  699. }
  700. if ($err) {
  701. $err = array_map('joli_repertoire', array_unique($err));
  702. return "<a href='".generer_url_ecrire('admin_plugin')."'>"
  703. ._T('plugins_erreur',
  704. array('plugins' => join(', ', $err)))
  705. .'</a>';
  706. }
  707. }
  708. }
  709. ?>