[SPIP] ~2.1.12 -->2.1.25
[velocampus/web/www.git] / www / ecrire / base / upgrade.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2014 *
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 // Programme de mise a jour des tables SQL lors d'un chgt de version.
16 // Marche aussi pour les plugins en appelant directement la fonction maj_while.
17 // Pour que ceux-ci profitent aussi de la reprise sur interruption,
18 // ils doivent indiquer leur numero de version installee dans une meta.
19 // Le nom de cette meta doit aussi etre un tableau global
20 // dont l'index "maj" est le sous-tableau des mises a jours
21 // et l'index "cible" la version a atteindre
22 // A tester.
23
24 // http://doc.spip.org/@base_upgrade_dist
25 function base_upgrade_dist($titre='', $reprise='')
26 {
27 if (!$titre) return; // anti-testeur automatique
28 if ($GLOBALS['spip_version']!=$GLOBALS['meta']['version_installee']) {
29 if (!is_numeric(_request('reinstall'))) {
30 include_spip('base/create');
31 spip_log("recree les tables eventuellement disparues");
32 creer_base();
33 }
34 $meta = _request('meta');
35 if (!$meta)
36 $res = maj_base();
37 // reprise sur demande de mise a jour interrompue pour plugin
38 else $res= maj_while($GLOBALS['meta'][$meta],
39 $GLOBALS[$meta]['cible'],
40 $GLOBALS[$meta]['maj'],
41 $meta,
42 _request('table'));
43 if ($res) {
44 if (!is_array($res))
45 spip_log("Pb d'acces SQL a la mise a jour");
46 else {
47 include_spip('inc/minipres');
48 echo minipres(_T('avis_operation_echec') . ' ' . join(' ', $res));
49 exit;
50 }
51 }
52 }
53 spip_log("Fin de mise a jour SQL. Debut m-a-j acces et config");
54
55 // supprimer quelques fichiers temporaires qui peuvent se retrouver invalides
56 spip_unlink(_DIR_TMP.'plugin_xml.cache');
57 spip_unlink(_DIR_SESSIONS.'ajax_fonctions.txt');
58 spip_unlink(_CACHE_PIPELINES);
59 spip_unlink(_CACHE_RUBRIQUES);
60 spip_unlink(_CACHE_PLUGINS_OPT);
61 spip_unlink(_CACHE_PLUGINS_FCT);
62 spip_unlink(_CACHE_PLUGINS_VERIF);
63
64 include_spip('inc/acces');
65 ecrire_acces();
66 $config = charger_fonction('config', 'inc');
67 $config();
68 }
69
70 // http://doc.spip.org/@maj_base
71 function maj_base($version_cible = 0) {
72 global $spip_version_base;
73
74 $version_installee = @$GLOBALS['meta']['version_installee'];
75 //
76 // Si version nulle ou inexistante, c'est une nouvelle installation
77 // => ne pas passer par le processus de mise a jour.
78 // De meme en cas de version superieure: ca devait etre un test,
79 // il y a eu le message d'avertissement il doit savoir ce qu'il fait
80 //
81 // version_installee = 1.702; quand on a besoin de forcer une MAJ
82
83 spip_log("Version anterieure: $version_installee. Courante: $spip_version_base");
84 if (!$version_installee OR ($spip_version_base < $version_installee)) {
85 sql_replace('spip_meta',
86 array('nom' => 'version_installee',
87 'valeur' => $spip_version_base,
88 'impt' => 'non'));
89 return false;
90 }
91 if (!upgrade_test()) return true;
92
93 $cible = ($version_cible ? $version_cible : $spip_version_base);
94
95 if ($version_installee <= 1.926) {
96 $n = floor($version_installee * 10);
97 while ($n < 19) {
98 $nom = sprintf("v%03d",$n);
99 $f = charger_fonction($nom, 'maj', true);
100 if ($f) {
101 spip_log("$f repercute les modifications de la version " . ($n/10));
102 $f($version_installee, $spip_version_base);
103 } else spip_log("pas de fonction pour la maj $n $nom");
104 $n++;
105 }
106 include_spip('maj/v019_pre193');
107 v019_pre193($version_installee, $version_cible);
108 }
109 if ($version_installee < 2000) {
110 if ($version_installee < 2)
111 $version_installee = $version_installee*1000;
112 include_spip('maj/v019');
113 }
114 if ($cible < 2)
115 $cible = $cible*1000;
116
117 include_spip('maj/svn10000');
118 return maj_while($version_installee, $cible, $GLOBALS['maj'], 'version_installee');
119 }
120
121 // A partir des > 1.926 (i.e SPIP > 1.9.2), cette fonction gere les MAJ.
122 // Se relancer soi-meme pour eviter l'interruption pendant une operation SQL
123 // (qu'on espere pas trop longue chacune)
124 // evidemment en ecrivant dans la meta a quel numero on en est.
125 // Cette fonction peut servir aux plugins qui doivent donner comme arguments:
126 // 1. le numero de version courant (nombre entier; ex: numero de commit)
127 // 2. le numero de version a atteindre (idem)
128 // 3. le tableau des instructions de mise a jour a executer
129 // Pour profiter du mecanisme de reprise sur interruption il faut de plus
130 // 4. le nom de la meta permettant de retrouver tout ca
131 // 5. la table des meta ou elle se trouve ($table_prefix . '_meta' par defaut)
132 // (cf debut de fichier)
133 // en cas d'echec, cette fonction retourne un tableau (etape,sous-etape)
134 // sinon elle retourne un tableau vide
135
136 define('_UPGRADE_TIME_OUT', 20);
137
138 // http://doc.spip.org/@maj_while
139 function maj_while($installee, $cible, $maj, $meta='', $table='meta')
140 {
141 $n = 0;
142 $time = time();
143
144 while ($installee < $cible) {
145 $installee++;
146 if (isset($maj[$installee])) {
147 $etape = serie_alter($installee, $maj[$installee], $meta, $table);
148
149 if ($etape) return array($installee, $etape);
150 $n = time() - $time;
151 spip_log("$table $meta: $installee en $n secondes",'maj');
152 if ($meta) ecrire_meta($meta, $installee,'non', $table);
153 } // rien pour SQL
154 if ($n >= _UPGRADE_TIME_OUT) {
155 redirige_url_ecrire('upgrade', "reinstall=$installee&meta=$meta&table=$table");
156 }
157 }
158 // indispensable pour les chgt de versions qui n'ecrivent pas en base
159 // tant pis pour la redondance eventuelle avec ci-dessus
160 if ($meta) ecrire_meta($meta, $installee,'non');
161 spip_log("MAJ terminee. $meta: $installee",'maj');
162 return array();
163 }
164
165 // Appliquer une serie de chgt qui risquent de partir en timeout
166 // (Alter cree une copie temporaire d'une table, c'est lourd)
167
168 // http://doc.spip.org/@serie_alter
169 function serie_alter($serie, $q = array(), $meta='', $table='meta') {
170 $meta .= '_maj_' . $serie;
171 $etape = intval(@$GLOBALS[$table][$meta]);
172 foreach ($q as $i => $r) {
173 if ($i >= $etape) {
174 $msg = "maj $table $meta etape $i";
175 if (is_array($r)
176 AND function_exists($f = array_shift($r))) {
177 spip_log("$msg: $f " . join(',',$r),'maj');
178 ecrire_meta($meta, $i+1, 'non', $table); // attention on enregistre le meta avant de lancer la fonction, de maniere a eviter de boucler sur timeout
179 call_user_func_array($f, $r);
180 spip_log("$meta: ok", 'maj');
181 } else return $i+1;
182 }
183 }
184 effacer_meta($meta, $table);
185 return 0;
186 }
187
188
189
190 // La fonction a appeler dans le tableau global $maj
191 // quand on rajoute des types MIME. cf par exemple la 1.953
192
193 // http://doc.spip.org/@upgrade_types_documents
194 function upgrade_types_documents() {
195 include_spip('base/create');
196 creer_base_types_doc();
197 }
198
199 // http://doc.spip.org/@upgrade_test
200 function upgrade_test() {
201 sql_drop_table("spip_test", true);
202 sql_create("spip_test", array('a' => 'int'));
203 sql_alter("TABLE spip_test ADD b INT");
204 sql_insertq('spip_test', array('b' => 1), array('field'=>array('b' => 'int')));
205 $result = sql_select('b', "spip_test");
206 // ne pas garder le resultat de la requete sinon sqlite3
207 // ne peut pas supprimer la table spip_test lors du sql_alter qui suit
208 // car cette table serait alors 'verouillee'
209 $result = $result?true:false;
210 sql_alter("TABLE spip_test DROP b");
211 return $result;
212 }
213
214 // pour versions <= 1.926
215 // http://doc.spip.org/@maj_version
216 function maj_version ($version, $test = true) {
217 if ($test) {
218 if ($version>=1.922)
219 ecrire_meta('version_installee', $version, 'non');
220 else {
221 // on le fait manuellement, car ecrire_meta utilise le champs impt qui est absent sur les vieilles versions
222 $GLOBALS['meta']['version_installee'] = $version;
223 sql_updateq('spip_meta', array('valeur' => $version), "nom=" . sql_quote('version_installee') );
224 }
225 spip_log("mise a jour de la base en $version");
226 } else {
227 echo _T('alerte_maj_impossible', array('version' => $version));
228 exit;
229 }
230 }
231
232 // pour versions <= 1.926
233 // http://doc.spip.org/@upgrade_vers
234 function upgrade_vers($version, $version_installee, $version_cible = 0){
235 return ($version_installee<$version
236 AND (($version_cible>=$version) OR ($version_cible==0))
237 );
238 }
239 ?>