e8d5706f345fde34432d0bd826b8c8f0741807b5
[ptitvelo/web/www.git] / www / ecrire / plugins / installer.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2012 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14
15 /**
16 * Installe ou retire un plugin
17 *
18 * Fonction surchargeable permettant d'installer ou retirer un plugin
19 * en incluant les fichiers associes et en lancant les fonctions specifiques
20 * 1. d'abord sur l'argument 'test',
21 * 2. ensuite sur l'action demandee si le test repond False
22 * 3. enfin sur l'argument 'test' a nouveau.
23 * l'index install_test du tableau resultat est un tableau forme:
24 * - du resultat 3
25 * - des Echo de l'etape 2
26 *
27 * @param string $plug, nom du plugin
28 * @param string $action, nom de l'action (install|uninstall)
29 * @param string $dir_type, repertoire du plugin
30 *
31 * @return array|boolean True si deja installe, le tableau de get_infos sinon
32 *
33 */
34 function plugins_installer_dist($plug, $action, $dir_type='_DIR_PLUGINS')
35 {
36 $get_infos = charger_fonction('get_infos','plugins');
37 $infos = $get_infos($plug, false, constant($dir_type));
38 if (!isset($infos['install']) OR !$infos['install']) return false;
39 // passer en chemin absolu si possible, c'est plus efficace
40 $dir = str_replace('_DIR_','_ROOT_',$dir_type);
41 if (!defined($dir)) $dir = $dir_type;
42 $dir = constant($dir);
43 foreach($infos['install'] as $file) {
44 $file = $dir . $plug . "/" . trim($file);
45 if (file_exists($file)){
46 include_once($file);
47 }
48 }
49 $version = isset($infos['schema'])?$infos['schema']:'';
50 $arg = $infos ;
51 $f = $infos['prefix']."_install";
52 if (!function_exists($f))
53 $f = isset($infos['schema']) ? 'spip_plugin_install' : '';
54 else
55 $arg = $infos['prefix']; // stupide: info deja dans le nom
56
57 if (!$f) {
58 // installation sans operation particuliere
59 $infos['install_test'] = array(true, '');
60 return $infos;
61 }
62 $test = $f('test', $arg, $version);
63 if ($action == 'uninstall') $test = !$test;
64 // Si deja fait, on ne dit rien
65 if ($test) return true;
66 // executer l'installation ou l'inverse
67 // et renvoyer la trace (mais il faudrait passer en AJAX plutot)
68 ob_start();
69 $f($action, $arg, $version);
70 $aff = ob_get_contents();
71 ob_end_clean();
72 // vider le cache des descriptions de tables a chaque (de)installation
73 $trouver_table = charger_fonction('trouver_table', 'base');
74 $trouver_table('');
75 $infos['install_test'] = array($f('test', $arg, $version), $aff);
76 return $infos;
77 }
78
79 // Fonction par defaut pour install/desinstall
80
81 // http://doc.spip.org/@spip_plugin_install
82 function spip_plugin_install($action, $infos, $version_cible){
83 $prefix = $infos['prefix'];
84 if (isset($infos['meta']) AND (($table = $infos['meta']) !== 'meta'))
85 $nom_meta = "base_version";
86 else {
87 $nom_meta = $prefix."_base_version";
88 $table = 'meta';
89 }
90 switch ($action){
91 case 'test':
92 return (isset($GLOBALS[$table])
93 AND isset($GLOBALS[$table][$nom_meta])
94 AND spip_version_compare($GLOBALS[$table][$nom_meta],$version_cible,'>='));
95 break;
96 case 'install':
97 if (function_exists($upgrade = $prefix."_upgrade"))
98 $upgrade($nom_meta, $version_cible, $table);
99 break;
100 case 'uninstall':
101 if (function_exists($vider_tables = $prefix."_vider_tables"))
102 $vider_tables($nom_meta, $table);
103 break;
104 }
105 }
106
107
108 /**
109 * Compare 2 numeros de version entre elles.
110 *
111 * Cette fonction est identique (arguments et retours) a la fonction PHP
112 * version_compare() qu'elle appelle. Cependant, cette fonction reformate
113 * les numeros de versions pour ameliorer certains usages dans SPIP ou bugs
114 * dans PHP. On permet ainsi de comparer 3.0.4 à 3.0.* par exemple.
115 *
116 * @param string $v1
117 * Numero de version servant de base a la comparaison.
118 * Ce numero ne peut pas comporter d'etoile.
119 * @param string $v2
120 * Numero de version a comparer.
121 * Il peut posseder des etoiles tel que 3.0.*
122 * @param string $op
123 * Un operateur eventuel (<, >, <=, >=, =, == ...)
124 * @return int|bool
125 * Sans operateur : int. -1 pour inferieur, 0 pour egal, 1 pour superieur
126 * Avec operateur : bool.
127 **/
128 function spip_version_compare($v1,$v2,$op=null){
129 $v1 = strtolower(preg_replace(',([0-9])[\s-.]?(dev|alpha|a|beta|b|rc|pl|p),i','\\1.\\2',$v1));
130 $v2 = strtolower(preg_replace(',([0-9])[\s-.]?(dev|alpha|a|beta|b|rc|pl|p),i','\\1.\\2',$v2));
131 $v1 = str_replace('rc','RC',$v1); // certaines versions de PHP ne comprennent RC qu'en majuscule
132 $v2 = str_replace('rc','RC',$v2); // certaines versions de PHP ne comprennent RC qu'en majuscule
133
134 $v1 = explode('.',$v1);
135 $v2 = explode('.',$v2);
136 // $v1 est toujours une version, donc sans etoile
137 while (count($v1)<count($v2))
138 $v1[] = '0';
139
140 // $v2 peut etre une borne, donc accepte l'etoile
141 $etoile = false;
142 foreach ($v1 as $k => $v) {
143 if (!isset($v2[$k]))
144 $v2[] = ($etoile AND (is_numeric($v) OR $v=='pl' OR $v=='p')) ? $v : '0';
145 else if ($v2[$k] == '*') {
146 $etoile = true;
147 $v2[$k] = $v;
148 }
149 }
150 $v1 = implode('.',$v1);
151 $v2 = implode('.',$v2);
152
153 return $op?version_compare($v1, $v2,$op):version_compare($v1, $v2);
154 }
155
156 // Cette fonction retourne la meta "plugin" deserialisee
157 // mais en fait une mise a jour qui aurait du intervenir au chgt de version
158 // http://doc.spip.org/@liste_plugin_actifs
159 function liste_plugin_actifs(){
160 $liste = isset($GLOBALS['meta']['plugin'])?$GLOBALS['meta']['plugin']:'';
161 if (!$liste) return array();
162 if (!is_array($liste=unserialize($liste))) {
163 // compatibilite pre 1.9.2, mettre a jour la meta
164 spip_log("MAJ meta plugin vieille version : $liste","plugin");
165 $new = true;
166 list(, $liste) = liste_plugin_valides(explode(",",$liste));
167 } else {
168 $new = false;
169 // compat au moment d'une migration depuis version anterieure
170 // si pas de dir_type, alors c'est _DIR_PLUGINS
171 foreach ($liste as $prefix=>$infos) {
172 if (!isset($infos['dir_type'])) {
173 $liste[$prefix]['dir_type'] = "_DIR_PLUGINS";
174 $new = true;
175 }
176 }
177 }
178 if ($new) ecrire_meta('plugin',serialize($liste));
179 return $liste;
180 }
181
182 ?>