From 0569452f8e6e7ef60d6d2a1747d274fc13ba7977 Mon Sep 17 00:00:00 2001
From: Matthieu Marcillaud <marcimat@rezo.net>
Date: Thu, 27 May 2021 00:57:55 +0200
Subject: [PATCH] =?UTF-8?q?-=20Suppression=20des=20mises=20=C3=A0=20jour?=
 =?UTF-8?q?=20de=20BDD=20<=202.0.0=20-=20D=C3=A9coupage=20des=20mises=20?=
 =?UTF-8?q?=C3=A0=20jour=20par=20version=20de=20SPIP=20(avant=202021).?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ecrire/base/upgrade.php        |  51 +--
 ecrire/maj/legacy/svn10000.php | 751 +--------------------------------
 ecrire/maj/legacy/v019.php     | 555 ------------------------
 ecrire/maj/legacy/v21.php      |  90 ++++
 ecrire/maj/legacy/v30.php      | 347 +++++++++++++++
 ecrire/maj/legacy/v31.php      |  60 +++
 ecrire/maj/legacy/v32.php      |  27 ++
 ecrire/maj/legacy/v40.php      |  81 ++++
 8 files changed, 627 insertions(+), 1335 deletions(-)
 delete mode 100644 ecrire/maj/legacy/v019.php
 create mode 100644 ecrire/maj/legacy/v21.php
 create mode 100644 ecrire/maj/legacy/v30.php
 create mode 100644 ecrire/maj/legacy/v31.php
 create mode 100644 ecrire/maj/legacy/v32.php
 create mode 100644 ecrire/maj/legacy/v40.php

diff --git a/ecrire/base/upgrade.php b/ecrire/base/upgrade.php
index dcfc243080..e1ba77a756 100644
--- a/ecrire/base/upgrade.php
+++ b/ecrire/base/upgrade.php
@@ -94,6 +94,16 @@ function base_upgrade_dist($titre = '', $reprise = '') {
  * schéma actuel de la base de données.
  *
  * Les fonctions de mises à jour se trouvent dans `ecrire/maj/`
+ * 
+ * @note
+ *     Si version nulle ou inexistante, c'est une nouvelle installation,
+ *     on ne passe pas par le processus de mise à jour.
+ * 
+ *     De même en cas de version supérieure: ca devait être un test,
+ *     il y a eu le message d'avertissement il doit savoir ce qu'il fait
+ * 
+ *     version_installee = YYYYMMDDNN; quand on a besoin de forcer une MAJ
+ *     tel que 2021021800 où 00 est un incrément.
  *
  * @uses upgrade_test()
  * @uses maj_while()
@@ -104,14 +114,7 @@ function base_upgrade_dist($titre = '', $reprise = '') {
  */
 function maj_base($version_cible = 0, $redirect = '', $debut_page = true) {
 
-	$version_installee = @$GLOBALS['meta']['version_installee'];
-	//
-	// Si version nulle ou inexistante, c'est une nouvelle installation
-	//   => ne pas passer par le processus de mise a jour.
-	// De meme en cas de version superieure: ca devait etre un test,
-	// il y a eu le message d'avertissement il doit savoir ce qu'il fait
-	//
-	// version_installee = 1.702; quand on a besoin de forcer une MAJ
+	$version_installee = $GLOBALS['meta']['version_installee'] ?? null;
 
 	spip_log(
 		"Version anterieure: $version_installee. Courante: " . $GLOBALS['spip_version_base'],
@@ -134,34 +137,12 @@ function maj_base($version_cible = 0, $redirect = '', $debut_page = true) {
 
 	$cible = ($version_cible ? $version_cible : $GLOBALS['spip_version_base']);
 
-	if ($version_installee <= 1.926) {
-		$n = floor($version_installee * 10);
-		while ($n < 19) {
-			$nom = sprintf('v%03d', $n);
-			$f = charger_fonction($nom, 'maj/legacy', true);
-			if ($f) {
-				spip_log("$f repercute les modifications de la version " . ($n / 10), 'maj.' . _LOG_INFO_IMPORTANTE);
-				$f($version_installee, $GLOBALS['spip_version_base']);
-			} else {
-				spip_log("pas de fonction pour la maj $n $nom", 'maj.' . _LOG_INFO_IMPORTANTE);
-			}
-			$n++;
-		}
-		include_spip('maj/legacy/v019_pre193');
-		maj_legacy_v019_pre193($version_installee, $version_cible);
-	}
-	if ($version_installee < 2000) {
-		if ($version_installee < 2) {
-			$version_installee = $version_installee * 1000;
-		}
-		include_spip('maj/legacy/v019');
-	}
-	if ($cible < 2) {
-		$cible = $cible * 1000;
-	}
-
 	if ($version_installee < 2021010100) {
-		include_spip('maj/legacy/svn10000');
+		include_spip('maj/legacy/v21');
+		include_spip('maj/legacy/v30');
+		include_spip('maj/legacy/v31');
+		include_spip('maj/legacy/v32');
+		include_spip('maj/legacy/v40');
 	}
 
 	include_spip('maj/2021');
diff --git a/ecrire/maj/legacy/svn10000.php b/ecrire/maj/legacy/svn10000.php
index 1a2c924729..4907b295d5 100644
--- a/ecrire/maj/legacy/svn10000.php
+++ b/ecrire/maj/legacy/svn10000.php
@@ -11,753 +11,14 @@
 \***************************************************************************/
 
 /**
- * Gestion des mises à jour de SPIP, version >= 10000
- *
- * Gestion des mises à jour du cœur de SPIP par un tableau global `maj`
- * indexé par le numero SVN du changement
- *
+ * Certains plugins appelaient ce fichier pour acceder a maj_lien(),
+ * qui sert à la migration des tables vers SPIP 3.0
+ * 
  * @package SPIP\Core\SQL\Upgrade
- **/
-if (!defined('_ECRIRE_INC_VERSION')) {
-	return;
-}
-
-
-// Type cls et sty pour LaTeX
-$GLOBALS['maj'][10990] = array(array('upgrade_types_documents'));
-
-// Type 3gp: http://www.faqs.org/rfcs/rfc3839.html
-// Aller plus vite pour les vieilles versions en redeclarant une seule les doc
-unset($GLOBALS['maj'][10990]);
-$GLOBALS['maj'][11042] = array(array('upgrade_types_documents'));
-
-
-// Un bug permettait au champ 'upload' d'etre vide, provoquant
-// l'impossibilite de telecharger une image
-// https://core.spip.net/issues/1238
-$GLOBALS['maj'][11171] = array(
-	array('sql_query', "UPDATE spip_types_documents SET upload='oui' WHERE upload IS NULL OR upload!='non'")
-);
-
-/**
- * Mise à jour 11268 : renommer spip_recherches la mal nommée en spip_resultats
- **/
-function maj_11268() {
-	global $tables_auxiliaires;
-	include_spip('base/auxiliaires');
-	$v = $tables_auxiliaires[$k = 'spip_resultats'];
-	sql_create($k, $v['field'], $v['key'], false, false);
-}
-
-$GLOBALS['maj'][11268] = array(array('maj_11268'));
-
-/**
- * Mise à jour 11276 : réparer les éventuelles tables spip_documents
- * en se fondant sur l'extension de la colonne fichier
- *
- * @uses maj_1_938()
- **/
-function maj_11276() {
-	include_spip('maj/v019');
-	maj_1_938();
-}
-
-$GLOBALS['maj'][11276] = array(array('maj_11276'));
-
-/**
- * Mise à jour 11388 : réparer les referers d'article, qui sont vides depuis r10572
- */
-function maj_11388() {
-	$s = sql_select('referer_md5', 'spip_referers_articles', "referer='' OR referer IS NULL");
-	while ($t = sql_fetch($s)) {
-		$k = sql_fetsel('referer', 'spip_referers', 'referer_md5=' . sql_quote($t['referer_md5']));
-		if ($k['referer']) {
-			sql_query('UPDATE spip_referers_articles
-			SET referer=' . sql_quote($k['referer']) . '
-			WHERE referer_md5=' . sql_quote($t['referer_md5'])
-				. " AND (referer='' OR referer IS NULL)"
-			);
-		}
-	}
-}
-
-$GLOBALS['maj'][11388] = array(array('maj_11388'));
-
-/**
- * Mise à jour 11431 : réparer spip_mots.type = titre du groupe
- */
-function maj_11431() {
-	// mysql only
-	// sql_query("UPDATE spip_mots AS a LEFT JOIN spip_groupes_mots AS b ON (a.id_groupe = b.id_groupe) SET a.type=b.titre");
-
-	// selection des mots cles dont le type est different du groupe
-	$res = sql_select(
-		array("a.id_mot AS id_mot", "b.titre AS type"),
-		array("spip_mots AS a LEFT JOIN spip_groupes_mots AS b ON (a.id_groupe = b.id_groupe)"),
-		array("a.type != b.titre"));
-	// mise a jour de ces mots la
-	if ($res) {
-		while ($r = sql_fetch($res)) {
-			sql_updateq('spip_mots', array('type' => $r['type']), 'id_mot=' . sql_quote($r['id_mot']));
-		}
-	}
-}
-
-$GLOBALS['maj'][11431] = array(array('maj_11431'));
-
-/**
- * Mise à jour 11778 : réparer spip_types_documents.id_type qui est parfois encore présent
- */
-function maj_11778() {
-	// si presence id_type
-	$s = sql_showtable('spip_types_documents');
-	if (isset($s['field']['id_type'])) {
-		sql_alter('TABLE spip_types_documents CHANGE id_type id_type BIGINT(21) NOT NULL');
-		sql_alter('TABLE spip_types_documents DROP id_type');
-		sql_alter('TABLE spip_types_documents ADD PRIMARY KEY (extension)');
-	}
-}
-
-$GLOBALS['maj'][11778] = array(array('maj_11778'));
-
-/**
- * Mise à jour 11790 : Optimisation des forums
  */
-function maj_11790() {
-#	sql_alter('TABLE spip_forum DROP INDEX id_message id_message');
-	sql_alter('TABLE spip_forum ADD INDEX id_parent (id_parent)');
-	sql_alter('TABLE spip_forum ADD INDEX id_auteur (id_auteur)');
-	sql_alter('TABLE spip_forum ADD INDEX id_thread (id_thread)');
-}
-
-$GLOBALS['maj'][11790] = array(array('maj_11790'));
-
-$GLOBALS['maj'][11794] = array(); // ajout de spip_documents_forum
-
-
-$GLOBALS['maj'][11961] = array(
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `tables` tables_liees text DEFAULT '' NOT NULL AFTER obligatoire"),
-	// si tables a ete cree on le renomme
-	array('sql_alter', "TABLE spip_groupes_mots ADD tables_liees text DEFAULT '' NOT NULL AFTER obligatoire"),
-	// sinon on l'ajoute
-	array('sql_update', 'spip_groupes_mots', array('tables_liees' => "''"), "articles REGEXP '.*'"),
-	// si le champ articles est encore la, on reinit la conversion
-	array(
-		'sql_update',
-		'spip_groupes_mots',
-		array('tables_liees' => "concat(tables_liees,'articles,')"),
-		"articles='oui'"
-	),
-	// sinon ces 4 requetes ne feront rien
-	array('sql_update', 'spip_groupes_mots', array('tables_liees' => "concat(tables_liees,'breves,')"), "breves='oui'"),
-	array(
-		'sql_update',
-		'spip_groupes_mots',
-		array('tables_liees' => "concat(tables_liees,'rubriques,')"),
-		"rubriques='oui'"
-	),
-	array('sql_update', 'spip_groupes_mots', array('tables_liees' => "concat(tables_liees,'syndic,')"), "syndic='oui'"),
-);
-
-
-/**
- * Mise à jour 12008 : Réunir en une seule table les liens de documents
- * spip_documents_articles et spip_documents_forum
- */
-function maj_12008() {
-	// Creer spip_documents_liens
-	global $tables_auxiliaires;
-	include_spip('base/auxiliaires');
-	$v = $tables_auxiliaires[$k = 'spip_documents_liens'];
-	sql_create($k, $v['field'], $v['key'], false, false);
-
-	// Recopier les donnees
-	foreach (array('article', 'breve', 'rubrique', 'auteur', 'forum') as $l) {
-		if ($s = sql_select('*', 'spip_documents_' . $l . 's')
-			or $s = sql_select('*', 'spip_documents_' . $l)
-		) {
-			$tampon = array();
-			while ($t = sql_fetch($s)) {
-				// transformer id_xx=N en (id_objet=N, objet=xx)
-				$t['id_objet'] = $t["id_$l"];
-				$t['objet'] = $l;
-				unset($t["id_$l"]);
-				unset($t['maj']);
-				$tampon[] = $t;
-				if (count($tampon) > 10000) {
-					sql_insertq_multi('spip_documents_liens', $tampon);
-					$tampon = array();
-				}
-			}
-			if (count($tampon)) {
-				sql_insertq_multi('spip_documents_liens', $tampon);
-			}
-		}
-	}
-}
-
-$GLOBALS['maj'][12008] = array(
-//array('sql_drop_table',"spip_documents_liens"), // tant pis pour ceux qui ont joue a 11974
-	array('sql_alter', "TABLE spip_documents_liens DROP PRIMARY KEY"),
-	array('sql_alter', "TABLE spip_documents_liens ADD id_objet bigint(21) DEFAULT '0' NOT NULL AFTER id_document"),
-	array('sql_alter', "TABLE spip_documents_liens ADD objet VARCHAR (25) DEFAULT '' NOT NULL AFTER id_objet"),
-	array(
-		'sql_update',
-		'spip_documents_liens',
-		array('id_objet' => "id_article", 'objet' => "'article'"),
-		"id_article IS NOT NULL AND id_article>0"
-	),
-	array(
-		'sql_update',
-		'spip_documents_liens',
-		array('id_objet' => "id_rubrique", 'objet' => "'rubrique'"),
-		"id_rubrique IS NOT NULL AND id_rubrique>0"
-	),
-	array(
-		'sql_update',
-		'spip_documents_liens',
-		array('id_objet' => "id_breve", 'objet' => "'breve'"),
-		"id_breve IS NOT NULL AND id_breve>0"
-	),
-	array(
-		'sql_update',
-		'spip_documents_liens',
-		array('id_objet' => "id_auteur", 'objet' => "'auteur'"),
-		"id_auteur IS NOT NULL AND id_auteur>0"
-	),
-	array(
-		'sql_update',
-		'spip_documents_liens',
-		array('id_objet' => "id_forum", 'objet' => "'forum'"),
-		"id_forum IS NOT NULL AND id_forum>0"
-	),
-	array('sql_alter', "TABLE spip_documents_liens ADD PRIMARY KEY  (id_document,id_objet,objet)"),
-	array('sql_alter', "TABLE spip_documents_liens DROP id_article"),
-	array('sql_alter', "TABLE spip_documents_liens DROP id_rubrique"),
-	array('sql_alter', "TABLE spip_documents_liens DROP id_breve"),
-	array('sql_alter', "TABLE spip_documents_liens DROP id_auteur"),
-	array('sql_alter', "TABLE spip_documents_liens DROP id_forum"),
-	array('maj_12008'),
-);
-
-
-// destruction des tables spip_documents_articles etc, cf. 12008
-$GLOBALS['maj'][12009] = array(
-	array('sql_drop_table', "spip_documents_articles"),
-	array('sql_drop_table', "spip_documents_breves"),
-	array('sql_drop_table', "spip_documents_rubriques"),
-	array('sql_drop_table', "spip_documents_auteurs"), # plugin #FORMULAIRE_UPLOAD
-	array('sql_drop_table', "spip_documents_syndic") # plugin podcast_client
-);
-
-// destruction des champs articles breves rubriques et syndic, cf. 11961
-$GLOBALS['maj'][12010] = array(
-	array('sql_alter', "TABLE spip_groupes_mots DROP articles"),
-	array('sql_alter', "TABLE spip_groupes_mots DROP breves"),
-	array('sql_alter', "TABLE spip_groupes_mots DROP rubriques"),
-	array('sql_alter', "TABLE spip_groupes_mots DROP syndic"),
-);
-
-/**
- * Mise à jour 13135 : réparer le calcul des rubriques ayant des articles postdatés
- */
-function maj_13135() {
-	include_spip('inc/rubriques');
-	calculer_prochain_postdate();
-
-	// supprimer les eventuels vieux cache plugin qui n'utilisaient pas _chemin
-	@spip_unlink(_CACHE_PLUGINS_OPT);
-	@spip_unlink(_CACHE_PLUGINS_FCT);
-}
-
-$GLOBALS['maj'][13135] = array(array('maj_13135'));
-
-// Type flac: http://flac.sourceforge.net
-$GLOBALS['maj'][13333] = array(array('upgrade_types_documents'));
-
-// http://archives.rezo.net/archives/spip-zone.mbox/C6RZKNBUNJYN42IOEOC4QKVCA233AMLI/
-
-$GLOBALS['maj'][13833] = array(
-	array('sql_alter', "TABLE spip_documents_liens ADD INDEX objet(id_objet,objet)")
-);
-
-// Fin upgrade commun branche 2.0
-
-$GLOBALS['maj'][13904] = array(
-	array('sql_alter', "TABLE spip_auteurs ADD webmestre varchar(3)  DEFAULT 'non' NOT NULL"),
-	array(
-		'sql_update',
-		'spip_auteurs',
-		array('webmestre' => "'oui'"),
-		sql_in("id_auteur", defined('_ID_WEBMESTRES') ? explode(':',
-			_ID_WEBMESTRES) : (autoriser('configurer') ? array($GLOBALS['visiteur_session']['id_auteur']) : array(0)))
-	) // le webmestre est celui qui fait l'upgrade si rien de defini
-);
-
-// sites plantes en mode "'su" au lieu de "sus"
-$GLOBALS['maj'][13929] = array(
-	array('sql_update', "spip_syndic", array('syndication' => "'sus'"), "syndication LIKE '\\'%'")
-);
-
-// Types de fichiers m4a/m4b/m4p/m4u/m4v/dv
-// Types de fichiers Open XML (cro$oft)
-$GLOBALS['maj'][14558] = array(array('upgrade_types_documents'));
-
-// refaire les upgrade dont les numeros sont inferieurs a ceux de la branche 2.0
-// etre sur qu'ils sont bien unipotents(?)...
-$GLOBALS['maj'][14559] = $GLOBALS['maj'][13904] + $GLOBALS['maj'][13929] + $GLOBALS['maj'][14558];
-
-// La version 14588 etait une mauvaise piste:
-// Retour en arriere pour ceux qui l'ont subi, ne rien faire sinon
-if (@$GLOBALS['meta']['version_installee'] >= 14588) {
-
-	// "mode" est un mot-cle d'Oracle
-	$GLOBALS['maj'][14588] = array(
-		array('sql_alter', "TABLE spip_documents  DROP INDEX mode"),
-		array(
-			'sql_alter',
-			"TABLE spip_documents  CHANGE mode genre ENUM('vignette', 'image', 'document') DEFAULT 'document' NOT NULL"
-		),
-		array('sql_alter', "TABLE spip_documents  ADD INDEX genre(genre)")
-	);
-	// solution moins intrusive au pb de mot-cle d'Oracle, retour avant 14588
-	$GLOBALS['maj'][14598] = array(
-		array('sql_alter', "TABLE spip_documents  DROP INDEX genre"),
-		array(
-			'sql_alter',
-			"TABLE spip_documents  CHANGE genre mode ENUM('vignette', 'image', 'document') DEFAULT 'document' NOT NULL"
-		),
-		array('sql_alter', "TABLE spip_documents  ADD INDEX mode(mode)")
-	);
-}
 
-// Restauration correcte des types mime des fichiers Ogg
-// https://core.spip.net/issues/1941
-// + Types de fichiers : f4a/f4b/f4p/f4v/mpc http://en.wikipedia.org/wiki/Flv#File_formats
-// + Report du commit oublié : https://git.spip.net/spip/spip/commit/a6468fa5e3e34483b98b24b0102c4356f2f369a3
-$GLOBALS['maj'][15676] = array(array('upgrade_types_documents'));
-
-// Type de fichiers : webm http://en.wikipedia.org/wiki/Flv#File_formats
-$GLOBALS['maj'][15827] = array(array('upgrade_types_documents'));
-
-$GLOBALS['maj'][16428] = array(
-	array('maj_liens', 'auteur'), // creer la table liens
-	array('maj_liens', 'auteur', 'article'),
-	array('sql_drop_table', "spip_auteurs_articles"),
-	array('maj_liens', 'auteur', 'rubrique'),
-	array('sql_drop_table', "spip_auteurs_rubriques"),
-	array('maj_liens', 'auteur', 'message'),
-	array('sql_drop_table', "spip_auteurs_messages"),
-);
-
-/**
- * Mise à jour des tables de liens
- *
- * Crée la table de lien au nouveau format (spip_xx_liens) ou insère
- * les données d'ancien format dans la nouveau format.
- *
- * Par exemple pour réunir en une seule table les liens de documents,
- * spip_documents_articles et spip_documents_forum
- *
- * Supprime la table au vieux format une fois les données transférées.
- *
- * @uses creer_ou_upgrader_table()
- * @uses maj_liens_insertq_multi_check()
- *
- * @param string $pivot
- *     Nom de la table pivot, tel que `auteur`
- * @param string $l
- *     Vide : crée la table de lien pivot.
- *     Sinon, nom de la table à lier, tel que `article`, et dans ce cas là,
- *     remplit spip_auteurs_liens à partir de spip_auteurs_articles.
- */
-function maj_liens($pivot, $l = '') {
-
-	@define('_LOG_FILTRE_GRAVITE', 8);
-
-	$exceptions_pluriel = array('forum' => 'forum', 'syndic' => 'syndic');
-
-	$pivot = preg_replace(',[^\w],', '', $pivot); // securite
-	$pivots = (isset($exceptions_pluriel[$pivot]) ? $exceptions_pluriel[$pivot] : $pivot . "s");
-	$liens = "spip_" . $pivots . "_liens";
-	$id_pivot = "id_" . $pivot;
-	// Creer spip_auteurs_liens
-	global $tables_auxiliaires;
-	if (!$l) {
-		include_spip('base/auxiliaires');
-		include_spip('base/create');
-		creer_ou_upgrader_table($liens, $tables_auxiliaires[$liens], false);
-	} else {
-		// Preparer
-		$l = preg_replace(',[^\w],', '', $l); // securite
-		$primary = "id_$l";
-		$objet = ($l == 'syndic' ? 'site' : $l);
-		$ls = (isset($exceptions_pluriel[$l]) ? $exceptions_pluriel[$l] : $l . "s");
-		$ancienne_table = 'spip_' . $pivots . '_' . $ls;
-		$pool = 400;
-
-		$trouver_table = charger_fonction('trouver_table', 'base');
-		if (!$desc = $trouver_table($ancienne_table)) {
-			return;
-		}
-
-		// securite pour ne pas perdre de donnees
-		if (!$trouver_table($liens)) {
-			return;
-		}
-
-		$champs = $desc['field'];
-		if (isset($champs['maj'])) {
-			unset($champs['maj']);
-		}
-		if (isset($champs[$primary])) {
-			unset($champs[$primary]);
-		}
-
-		$champs = array_keys($champs);
-		// ne garder que les champs qui existent sur la table destination
-		if ($desc_cible = $trouver_table($liens)) {
-			$champs = array_intersect($champs, array_keys($desc_cible['field']));
-		}
-
-		$champs[] = "$primary as id_objet";
-		$champs[] = "'$objet' as objet";
-		$champs = implode(', ', $champs);
-
-		// Recopier les donnees
-		$sub_pool = 100;
-		while ($ids = array_map('reset', sql_allfetsel("$primary", $ancienne_table, '', '', '', "0,$sub_pool"))) {
-			$insert = array();
-			foreach ($ids as $id) {
-				$n = sql_countsel($liens, "objet='$objet' AND id_objet=" . intval($id));
-				while ($t = sql_allfetsel($champs, $ancienne_table, "$primary=" . intval($id), '', $id_pivot, "$n,$pool")) {
-					$n += count($t);
-					// empiler en s'assurant a minima de l'unicite
-					while ($r = array_shift($t)) {
-						$insert[$r[$id_pivot] . ':' . $r['id_objet']] = $r;
-					}
-					if (count($insert) >= $sub_pool) {
-						maj_liens_insertq_multi_check($liens, $insert, $tables_auxiliaires[$liens]);
-						$insert = array();
-					}
-					// si timeout, sortir, la relance nous ramenera dans cette fonction
-					// et on verifiera/repartira de la
-					if (time() >= _TIME_OUT) {
-						return;
-					}
-				}
-				if (time() >= _TIME_OUT) {
-					return;
-				}
-			}
-			if (count($insert)) {
-				maj_liens_insertq_multi_check($liens, $insert, $tables_auxiliaires[$liens]);
-			}
-			sql_delete($ancienne_table, sql_in($primary, $ids));
-		}
-	}
-}
-
-/**
- * Insère des données dans une table de liaison de façon un peu sécurisée
- *
- * Si une insertion multiple échoue, on réinsère ligne par ligne.
- *
- * @param string $table Table de liaison
- * @param array $couples Tableau de couples de données à insérer
- * @param array $desc Description de la table de liaison
- * @return void
- **/
-function maj_liens_insertq_multi_check($table, $couples, $desc = array()) {
-	$n_before = sql_countsel($table);
-	sql_insertq_multi($table, $couples, $desc);
-	$n_after = sql_countsel($table);
-	if (($n_after - $n_before) == count($couples)) {
-		return;
-	}
-	// si ecart, on recommence l'insertion ligne par ligne...
-	// moins rapide mais secure : seul le couple en doublon echouera, et non toute la serie
-	foreach ($couples as $c) {
-		sql_insertq($table, $c, $desc);
-	}
-}
-
-$GLOBALS['maj'][17311] = array(
-	array(
-		'ecrire_meta',
-		"multi_objets",
-		implode(',',
-			array_diff(
-				array(
-					(isset($GLOBALS['meta']['multi_rubriques']) and $GLOBALS['meta']['multi_rubriques'] == 'oui')
-						? 'spip_rubriques' : '',
-					(isset($GLOBALS['meta']['multi_articles']) and $GLOBALS['meta']['multi_articles'] == 'oui')
-						? 'spip_articles' : ''
-				),
-				array('')
-			))
-	),
-	array(
-		'ecrire_meta',
-		"gerer_trad_objets",
-		implode(',',
-			array_diff(
-				array(
-					(isset($GLOBALS['meta']['gerer_trad']) and $GLOBALS['meta']['gerer_trad'] == 'oui')
-						? 'spip_articles' : ''
-				),
-				array('')
-			))
-	),
-);
-$GLOBALS['maj'][17555] = array(
-	array('sql_alter', "TABLE spip_resultats ADD table_objet varchar(30) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_resultats ADD serveur char(16) DEFAULT '' NOT NULL"),
-);
-
-$GLOBALS['maj'][17563] = array(
-	array('sql_alter', "TABLE spip_articles ADD virtuel VARCHAR(255) DEFAULT '' NOT NULL"),
-	array('sql_update', 'spip_articles', array('virtuel' => 'SUBSTRING(chapo,2)', 'chapo' => "''"), "chapo LIKE '=_%'"),
-);
-
-$GLOBALS['maj'][17577] = array(
-	array('maj_tables', array('spip_jobs', 'spip_jobs_liens')),
-);
-
-$GLOBALS['maj'][17743] = array(
-	array('sql_update', 'spip_auteurs', array('prefs' => 'bio', 'bio' => "''"), "statut='nouveau' AND bio<>''"),
-);
-
-$GLOBALS['maj'][18219] = array(
-	array('sql_alter', "TABLE spip_rubriques DROP id_import"),
-	array('sql_alter', "TABLE spip_rubriques DROP export"),
-);
-
-$GLOBALS['maj'][18310] = array(
-	array('sql_alter', "TABLE spip_auteurs_liens CHANGE vu vu VARCHAR(6) DEFAULT 'non' NOT NULL"),
-);
-
-$GLOBALS['maj'][18597] = array(
-	array('sql_alter', "TABLE spip_rubriques ADD profondeur smallint(5) DEFAULT '0' NOT NULL"),
-	array('maj_propager_les_secteurs'),
-);
-
-$GLOBALS['maj'][18955] = array(
-	array('sql_alter', "TABLE spip_auteurs_liens ADD INDEX id_objet (id_objet)"),
-	array('sql_alter', "TABLE spip_auteurs_liens ADD INDEX objet (objet)"),
-);
-
-/**
- * Mise à jour pour recalculer les secteurs des rubriques
- *
- * @uses propager_les_secteurs()
- **/
-function maj_propager_les_secteurs() {
-	include_spip('inc/rubriques');
-	propager_les_secteurs();
-}
-
-/**
- * Mise à jour des bdd SQLite pour réparer les collation des champs texte
- * pour les passer en NOCASE
- *
- * @uses base_lister_toutes_tables()
- * @uses _sqlite_remplacements_definitions_table()
- **/
-function maj_collation_sqlite() {
-
-
-	include_spip('base/dump');
-	$tables = base_lister_toutes_tables();
-
-	// rien a faire si base non sqlite
-	if (strncmp($GLOBALS['connexions'][0]['type'], 'sqlite', 6) !== 0) {
-		return;
-	}
-
-	$trouver_table = charger_fonction('trouver_table', 'base');
-	// forcer le vidage de cache
-	$trouver_table('');
-
-	// cas particulier spip_auteurs : retablir le collate binary sur le login
-	$desc = $trouver_table("spip_auteurs");
-	spip_log("spip_auteurs : " . var_export($desc['field'], true), "maj." . _LOG_INFO_IMPORTANTE);
-	if (stripos($desc['field']['login'], "BINARY") === false) {
-		spip_log("Retablir champ login BINARY sur table spip_auteurs", "maj");
-		sql_alter("table spip_auteurs change login login VARCHAR(255) BINARY");
-		$trouver_table('');
-		$new_desc = $trouver_table("spip_auteurs");
-		spip_log("Apres conversion spip_auteurs : " . var_export($new_desc['field'], true), "maj." . _LOG_INFO_IMPORTANTE);
-	}
-
-	foreach ($tables as $table) {
-		if (time() >= _TIME_OUT) {
-			return;
-		}
-		if ($desc = $trouver_table($table)) {
-			$desc_collate = _sqlite_remplacements_definitions_table($desc['field']);
-			if ($d = array_diff($desc['field'], $desc_collate)) {
-				spip_log("Table $table COLLATE incorrects", "maj");
-
-				// cas particulier spip_urls :
-				// supprimer les doublons avant conversion sinon echec (on garde les urls les plus recentes)
-				if ($table == 'spip_urls') {
-					// par date DESC pour conserver les urls les plus recentes
-					$data = sql_allfetsel("*", "spip_urls", '', '', 'date DESC');
-					$urls = array();
-					foreach ($data as $d) {
-						$key = $d['id_parent'] . "::" . strtolower($d['url']);
-						if (!isset($urls[$key])) {
-							$urls[$key] = true;
-						} else {
-							spip_log("Suppression doublon dans spip_urls avant conversion : " . serialize($d),
-								"maj." . _LOG_INFO_IMPORTANTE);
-							sql_delete("spip_urls", "id_parent=" . sql_quote($d['id_parent']) . " AND url=" . sql_quote($d['url']));
-						}
-					}
-				}
-				foreach ($desc['field'] as $field => $type) {
-					if ($desc['field'][$field] !== $desc_collate[$field]) {
-						spip_log("Conversion COLLATE table $table", "maj." . _LOG_INFO_IMPORTANTE);
-						sql_alter("table $table change $field $field " . $desc_collate[$field]);
-						$trouver_table('');
-						$new_desc = $trouver_table($table);
-						spip_log("Apres conversion $table : " . var_export($new_desc['field'], true),
-							"maj." . _LOG_INFO_IMPORTANTE);
-						continue 2; // inutile de continuer pour cette table : un seul alter remet tout a jour en sqlite
-					}
-				}
-			}
-		}
-	}
-
-	// forcer le vidage de cache
-	$trouver_table('');
-
-}
-
-
-$GLOBALS['maj'][19236] = array(
-	array('sql_updateq', 'spip_meta', array('impt' => 'oui'), "nom='version_installee'"), // version base principale
-	array('sql_updateq', 'spip_meta', array('impt' => 'oui'), "nom LIKE '%_base_version'"),  // version base plugins
-	array('maj_collation_sqlite'),
-);
-
-$GLOBALS['maj'][19268] = array(
-	array('supprimer_toutes_sessions'),
-);
-
-/**
- * Supprime toutes les sessions des auteurs
- *
- * Obligera tous les auteurs à se reconnecter !
- **/
-function supprimer_toutes_sessions() {
-	spip_log("supprimer sessions auteur");
-	if ($dir = opendir(_DIR_SESSIONS)) {
-		while (($f = readdir($dir)) !== false) {
-			spip_unlink(_DIR_SESSIONS . $f);
-			if (time() >= _TIME_OUT) {
-				return;
-			}
-		}
-	}
-}
-
-$GLOBALS['maj'][21676] = array(
-	array('ranger_cache_gd2'),
-);
-
-/**
- * Ranger les images de local/cache-gd2 dans des sous-rep
- *
- * https://core.spip.net/issues/3277
- */
-function ranger_cache_gd2() {
-	spip_log("ranger_cache_gd2");
-	$base = _DIR_VAR . "cache-gd2/";
-	if (is_dir($base) and is_readable($base)) {
-		if ($dir = opendir($base)) {
-			while (($f = readdir($dir)) !== false) {
-				if (!is_dir($base . $f) and strncmp($f, ".", 1) !== 0
-					and preg_match(",[0-9a-f]{32}\.\w+,", $f)
-				) {
-					$sub = substr($f, 0, 2);
-					$sub = sous_repertoire($base, $sub);
-					@rename($base . $f, $sub . substr($f, 2));
-					@unlink($base . $f); // au cas ou le rename a foire (collision)
-				}
-				if (time() >= _TIME_OUT) {
-					return;
-				}
-			}
-		}
-	}
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
 }
 
-
-$GLOBALS['maj'][21742] = array(
-	array('sql_alter', "TABLE spip_articles CHANGE url_site url_site text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE virtuel virtuel text DEFAULT '' NOT NULL"),
-);
-
-$GLOBALS['maj'][23375] = array(
-	array('sql_alter', "TABLE spip_auteurs CHANGE prefs prefs text"),
-);
-
-
-// adaptation des timestamp mysql
-$GLOBALS['maj'][24379] = [['maj_timestamp_mysql']];
-
-/**
- * Mise à jour des bdd Mysql pour réparer les timestamp auto-update absents
- *
- * @uses base_lister_toutes_tables()
- * @uses _mysql_remplacements_definitions_table()
- **/
-function maj_timestamp_mysql($tables = null) {
-
-	include_spip('base/dump');
-	if (is_null($tables)) {
-		$tables = base_lister_toutes_tables();
-	} elseif (is_string($tables)) {
-		$tables = [$tables];
-	} elseif (!is_array($tables)) {
-		return;
-	}
-
-	// rien a faire si base non mysql
-	if (strncmp($GLOBALS['connexions'][0]['type'], 'mysql', 5) !== 0) {
-		return;
-	}
-
-	$trouver_table = charger_fonction('trouver_table', 'base');
-	// forcer le vidage de cache
-	$trouver_table('');
-
-	foreach ($tables as $table) {
-		if (time() >= _TIME_OUT) {
-			return;
-		}
-		if ($desc = $trouver_table($table)) {
-			$fields_corrected = _mysql_remplacements_definitions_table($desc['field']);
-			$d = array_diff($desc['field'], $fields_corrected);
-			if ($d) {
-				spip_log("Table $table TIMESTAMP incorrect", "maj");
-				foreach ($desc['field'] as $field => $type) {
-					if ($desc['field'][$field] !== $fields_corrected[$field]) {
-						spip_log("Adaptation TIMESTAMP table $table", "maj." . _LOG_INFO_IMPORTANTE);
-						sql_alter("table $table change $field $field " . $fields_corrected[$field]);
-						$trouver_table('');
-						$new_desc = $trouver_table($table);
-						spip_log("Apres conversion $table : " . var_export($new_desc['field'], true),
-							"maj." . _LOG_INFO_IMPORTANTE);
-					}
-				}
-			}
-		}
-	}
-
-	// forcer le vidage de cache
-	$trouver_table('');
-}
+include_spip('maj/legacy/v30');
\ No newline at end of file
diff --git a/ecrire/maj/legacy/v019.php b/ecrire/maj/legacy/v019.php
deleted file mode 100644
index d782fc192d..0000000000
--- a/ecrire/maj/legacy/v019.php
+++ /dev/null
@@ -1,555 +0,0 @@
-<?php
-
-/***************************************************************************\
- *  SPIP, Système de publication pour l'internet                           *
- *                                                                         *
- *  Copyright © avec tendresse depuis 2001                                 *
- *  Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James  *
- *                                                                         *
- *  Ce programme est un logiciel libre distribué sous licence GNU/GPL.     *
- *  Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne.   *
-\***************************************************************************/
-
-/**
- * Gestion des mises à jour de SPIP, versions >= 1.9.3-dev
- *
- * Cette version de SPIP introduit une nouvelle gestion des
- * mises à jour par tableau
- *
- * On la fait coincider rétroactivement avec l'état de la 1.9.2
- * L'index numérique entier est multiplié par 1000 (resultat < SVN c'est ok)
- *
- * @package SPIP\Core\SQL\Upgrade
- **/
-if (!defined('_ECRIRE_INC_VERSION')) {
-	return;
-}
-
-
-// FLV est incrustable, la MAJ precedente l'avait oublie
-$GLOBALS['maj'][1931] = array(
-	array('sql_query', "UPDATE spip_types_documents SET `inclus`='embed' WHERE `extension`='flv'")
-);
-
-// Ajout de spip_forum.date_thread, et on essaie de le remplir
-// a coup de table temporaire (est-ce autorise partout... sinon
-// tant pis, ca ne marchera que pour les forums recemment modifies)
-$GLOBALS['maj'][1932] = array(
-	array('sql_alter', "TABLE spip_forum ADD `date_thread` datetime DEFAULT '0000-00-00 00:00:00' NOT NULL"),
-	array('sql_alter', "TABLE spip_forum ADD INDEX `date_thread` (`date_thread`)"),
-
-	array('sql_query', "DROP TABLE IF EXISTS spip_tmp"),
-	array(
-		'sql_query',
-		"CREATE TABLE spip_tmp SELECT `id_thread`,MAX(`date_heure`) AS dt FROM spip_forum GROUP BY `id_thread`"
-	),
-	array('sql_alter', "TABLE spip_tmp ADD INDEX `p` (`id_thread`)"),
-	array('sql_query', "UPDATE spip_forum AS F JOIN spip_tmp AS T ON F.id_thread=T.id_thread SET F.date_thread=T.dt"),
-	array('sql_query', "DROP TABLE spip_tmp"),
-);
-
-/**
- * Mise à jour 1_934 : Retrait de `_DIR_IMG` dans le champ fichier de la table des doc
- **/
-function maj_1_934() {
-	// attention, en cas de mutualisation _DIR_IMG contient quelque chose comme sites/urldusite/IMG/
-	// essayons en ne prenant que le dernier segment
-	$dir_img = basename(_DIR_IMG) . '/';
-	$res = sql_query("SELECT fichier FROM spip_documents WHERE fichier LIKE " . sql_quote($dir_img . '%') . " LIMIT 0,1");
-	if (!$row = sql_fetch($res)) {
-		// sinon on essaye avec le chemin complet
-		// il faut donc verifier qu'on a bien le bon nom de repertoire
-		$dir_img = substr(_DIR_IMG, strlen(_DIR_RACINE));
-	}
-	$n = strlen($dir_img) + 1;
-	sql_query("UPDATE spip_documents SET `fichier`=substring(fichier,$n) WHERE `fichier` LIKE " . sql_quote($dir_img . '%'));
-}
-
-$GLOBALS['maj'][1934] = array(array('maj_1_934'));
-
-/**
- * Mise à jour 1_935 : calcul du nouveau champ 'vu' sur les associations documents_xx
- **/
-function maj_1_935() {
-	include_spip('inc/texte');
-	foreach (array(
-		         'article' => 'id_article',
-		         'rubrique' => 'id_rubrique',
-		         'breve' => 'id_breve'
-	         ) as $type => $id_table_objet) {
-		$table_objet = "$type" . "s";
-		$chapo = $type == 'article' ? ",a.chapo" : "";
-		$res = sql_query("SELECT a.$id_table_objet,a.texte $chapo FROM spip_documents_$table_objet AS d JOIN spip_$table_objet AS a ON a.$id_table_objet=d.$id_table_objet GROUP BY $id_table_objet");
-		while ($row = sql_fetch($res)) {
-			$GLOBALS['doublons_documents_inclus'] = array();
-			traiter_modeles(($chapo ? $row['chapo'] : "") . $row['texte'], true); // detecter les doublons
-			if (count($GLOBALS['doublons_documents_inclus'])) {
-				$id = $row[$id_table_objet];
-				$liste = "(" . implode(",$id,'oui'),(", $GLOBALS['doublons_documents_inclus']) . ",$id,'oui')";
-				sql_query("REPLACE INTO spip_documents_$table_objet (`id_document`,`$id_table_objet`,`vu`) VALUES $liste");
-			}
-		}
-	}
-}
-
-$GLOBALS['maj'][1935] = array(
-	array('sql_alter', "TABLE spip_documents_articles ADD `vu` ENUM('non', 'oui') DEFAULT 'non' NOT NULL"),
-	array('sql_alter', "TABLE spip_documents_rubriques ADD `vu` ENUM('non', 'oui') DEFAULT 'non' NOT NULL"),
-	array('sql_alter', "TABLE spip_documents_breves ADD `vu` ENUM('non', 'oui') DEFAULT 'non' NOT NULL"),
-	array('maj_1_935')
-);
-
-
-/**
- * Convertit un champ de type `blob` en champ de type `text`
- *
- * @param string $table Nom de la table
- * @param string $champ Nom du champ dans la table
- * @param string $type Type de champ de destination, par exemple `LONGTEXT`
- **/
-function convertir_un_champ_blob_en_text($table, $champ, $type) {
-	// precaution : definir le charset par defaut de la table, car c'est lui qui prevaut
-	// et il faut qu'il corresponde au charset de la connexion qui est celui
-	// dans lequel on a ecrit le champ en blob
-	if ($charset = sql_getfetsel('@@character_set_connection')) {
-		sql_alter("TABLE $table DEFAULT CHARACTER SET " . $charset);
-	}
-	$res = sql_query("SHOW FULL COLUMNS FROM $table LIKE '$champ'");
-	if ($row = sql_fetch($res)) {
-		if (strtolower($row['Type']) != strtolower($type)) {
-			$default = $row['Default'] ? (" DEFAULT " . sql_quote($row['Default'])) : "";
-			$notnull = ($row['Null'] == 'YES') ? "" : " NOT NULL";
-			sql_alter("TABLE $table CHANGE $champ $champ $type $default $notnull");
-		}
-	}
-}
-
-$GLOBALS['maj'][1937] = array(
-	// convertir les champs blob des tables spip en champs texte
-	array('convertir_un_champ_blob_en_text', "spip_articles", "texte", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_articles", "extra", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_auteurs", "extra", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_breves", "texte", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_breves", "extra", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_messages", "texte", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_mots", "texte", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_mots", "extra", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_groupes_mots", "texte", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_rubriques", "texte", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_rubriques", "extra", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_syndic", "nom_site", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_syndic", "descriptif", "TEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_syndic", "extra", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_syndic_articles", "descriptif", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_petitions", "texte", "LONGTEXT"),
-	array('convertir_un_champ_blob_en_text', "spip_ortho_cache", "suggest", "TEXT"),
-);
-
-/**
- * Mise à jour 1_938 : suppression des id_type de documents, remplacés par extension
- **/
-function maj_1_938() {
-	$res = sql_select('extension', 'spip_documents', "extension='' OR extension is NULL");
-	if ($n = sql_count($res)) {
-		$repli = false;
-		// verifier que la colonne id_type est toujours la (update post 1.938)
-		$desc = sql_showtable('spip_documents');
-		if (!$desc or !isset($desc['field']['id_type'])) {
-			$repli = true;
-		}
-
-		$s = sql_select('extension' . ($repli ? '' : ',id_type'), 'spip_types_documents');
-		while ($t = sql_fetch($s)) {
-			if (isset($t['id_type'])) {
-				sql_query("UPDATE spip_documents	SET `extension`=" . sql_quote($t['extension']) . " WHERE `id_type`=" . sql_quote($t['id_type']));
-			} else {
-				sql_query("UPDATE spip_documents	SET `extension`=" . sql_quote($t['extension']) . " WHERE fichier LIKE " . sql_quote("%." . $t['extension']));
-			}
-		}
-		$res = sql_select('extension', 'spip_documents', "extension='' OR extension is NULL");
-		if ($n = sql_count($res)) {
-			spip_log("Table spip_documents : Colonne extension incomplete : $n lignes vides");
-		}
-	}
-}
-
-$GLOBALS['maj'][1938] = array(
-	// Des champs NULL a l'installation
-	// Ajouter un champ extension aux spip_documents, et le
-	// remplir avec les valeurs ad hoc
-	array('sql_alter', "TABLE spip_documents ADD `extension` VARCHAR(10) DEFAULT ''  NOT NULL "),
-	array('sql_alter', "TABLE spip_documents ADD INDEX `extension` (`extension`)"),
-	array('maj_1_938'),
-
-	array('sql_alter', "TABLE spip_documents DROP INDEX `id_type`, DROP `id_type`"),
-	## supprimer l'autoincrement avant de supprimer la PRIMARY KEY
-	array('sql_alter', "TABLE spip_types_documents CHANGE `id_type` `id_type` BIGINT( 21 ) NOT NULL "),
-	array('sql_alter', "TABLE spip_types_documents DROP PRIMARY KEY"),
-	array('sql_alter', "TABLE spip_types_documents DROP `id_type`"),
-	array('sql_alter', "TABLE spip_types_documents DROP INDEX `extension`"),
-
-	## recreer la PRIMARY KEY sur spip_types_documents.extension
-	array('sql_alter', "TABLE spip_types_documents ADD PRIMARY KEY (`extension`)"),
-);
-
-$GLOBALS['maj'][1939] = array(
-	array('sql_alter', "TABLE spip_visites CHANGE `visites` `visites` INT UNSIGNED DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_visites_articles CHANGE `visites` `visites` INT UNSIGNED DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_referers CHANGE `visites` `visites` INT UNSIGNED DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_referers CHANGE `visites_jour` `visites_jour` INT UNSIGNED DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_referers CHANGE `visites_veille` `visites_veille` INT UNSIGNED DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_referers_articles CHANGE `visites` `visites` INT UNSIGNED DEFAULT '0' NOT NULL")
-);
-
-$GLOBALS['maj'][1940] = array(
-	array('sql_query', "DROP TABLE spip_caches"),
-);
-
-
-$GLOBALS['maj'][1941] = array(
-	array('sql_query', "UPDATE spip_meta SET `valeur` = '' WHERE `nom`='preview' AND `valeur`='non' "),
-	array(
-		'sql_query',
-		"UPDATE spip_meta SET `valeur` = ',0minirezo,1comite,' WHERE `nom`='preview' AND `valeur`='1comite' "
-	),
-	array('sql_query', "UPDATE spip_meta SET `valeur` = ',0minirezo,' WHERE `nom`='preview' AND `valeur`='oui' "),
-);
-
-$GLOBALS['maj'][1942] = array(
-	array('sql_alter', "TABLE spip_auteurs CHANGE `statut` `statut` varchar(255)  DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_breves CHANGE `statut` `statut` varchar(6)  DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_messages CHANGE `statut` `statut` varchar(6)  DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_rubriques CHANGE `statut` `statut` varchar(10) DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_rubriques CHANGE `statut_tmp` `statut_tmp` varchar(10) DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic CHANGE `statut` `statut` varchar(10) DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic_articles CHANGE `statut` `statut` varchar(10) DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_forum CHANGE `statut` `statut` varchar(8) DEFAULT '0' NOT NULL"),
-	array('sql_alter', "TABLE spip_signatures CHANGE `statut` `statut` varchar(10) DEFAULT '0' NOT NULL")
-);
-
-
-// suppression de l'indexation dans la version standard
-$GLOBALS['maj'][1943] = array(
-	array('sql_alter', "TABLE spip_articles DROP KEY `idx`"),
-	array('sql_alter', "TABLE spip_articles DROP `idx`"),
-	array('sql_alter', "TABLE spip_auteurs DROP KEY `idx`"),
-	array('sql_alter', "TABLE spip_auteurs DROP `idx`"),
-	array('sql_alter', "TABLE spip_breves DROP KEY `idx`"),
-	array('sql_alter', "TABLE spip_breves DROP `idx`"),
-	array('sql_alter', "TABLE spip_mots DROP KEY `idx`"),
-	array('sql_alter', "TABLE spip_mots DROP `idx`"),
-	array('sql_alter', "TABLE spip_rubriques DROP KEY `idx`"),
-	array('sql_alter', "TABLE spip_rubriques DROP `idx`"),
-#	array('sql_alter', "TABLE spip_documents DROP KEY `idx`"),
-	array('sql_alter', "TABLE spip_documents DROP `idx`"),
-	array('sql_alter', "TABLE spip_syndic DROP KEY `idx`"),
-	array('sql_alter', "TABLE spip_syndic DROP `idx`"),
-	array('sql_alter', "TABLE spip_forum DROP KEY `idx`"),
-	array('sql_alter', "TABLE spip_forum DROP `idx`"),
-	array('sql_alter', "TABLE spip_signatures DROP KEY `idx`"),
-	array('sql_alter', "TABLE spip_signatures DROP `idx`"),
-
-	array('sql_query', "DROP TABLE spip_index"),
-	array('sql_query', "DROP TABLE spip_index_dico"),
-);
-
-$GLOBALS['maj'][1944] = array(
-	array('sql_alter', "TABLE spip_documents CHANGE `taille` `taille` integer"),
-	array('sql_alter', "TABLE spip_documents CHANGE `largeur` `largeur` integer"),
-	array('sql_alter', "TABLE spip_documents CHANGE `hauteur` `hauteur` integer")
-);
-
-$GLOBALS['maj'][1945] = array(
-	array('sql_alter', "TABLE spip_petitions CHANGE `email_unique` `email_unique` CHAR (3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_petitions CHANGE `site_obli` `site_obli` CHAR (3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_petitions CHANGE `site_unique` `site_unique` CHAR (3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_petitions CHANGE `message` `message` CHAR (3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_petitions CHANGE `texte` `texte` LONGTEXT DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE `surtitre` `surtitre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE `titre` `titre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE `soustitre` `soustitre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE `descriptif` `descriptif` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE `chapo` `chapo` mediumtext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE `texte` `texte` longtext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE `ps` `ps` mediumtext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE `accepter_forum` `accepter_forum` CHAR(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE `nom_site` `nom_site` tinytext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE `url_site` `url_site` VARCHAR(255) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_articles CHANGE `url_propre` `url_propre` VARCHAR(255) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_auteurs CHANGE `nom` `nom` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_auteurs CHANGE `bio` `bio` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_auteurs CHANGE `email` `email` tinytext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_auteurs CHANGE `nom_site` `nom_site` tinytext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_auteurs CHANGE `url_site` `url_site` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_auteurs CHANGE `pass` `pass` tinytext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_auteurs CHANGE `low_sec` `low_sec` tinytext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_auteurs CHANGE `pgp` `pgp` TEXT DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_auteurs CHANGE `htpass` `htpass` tinytext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_breves CHANGE `titre` `titre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_breves CHANGE `texte` `texte` longtext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_breves CHANGE `lien_titre` `lien_titre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_breves CHANGE `lien_url` `lien_url` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_messages CHANGE `titre` `titre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_messages CHANGE `texte` `texte` longtext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_messages CHANGE `type` `type` varchar(6) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_messages CHANGE `rv` `rv` varchar(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_mots CHANGE `titre` `titre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_mots CHANGE `descriptif` `descriptif` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_mots CHANGE `texte` `texte` longtext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_mots CHANGE `type` `type` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_mots CHANGE `url_propre` `url_propre` VARCHAR(255) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `titre` `titre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `descriptif` `descriptif` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `texte` `texte` longtext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `unseul` `unseul` varchar(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `obligatoire` `obligatoire` varchar(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `articles` `articles` varchar(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `breves` `breves` varchar(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `rubriques` `rubriques` varchar(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `syndic` `syndic` varchar(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `minirezo` `minirezo` varchar(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `comite` `comite` varchar(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_groupes_mots CHANGE `forum` `forum` varchar(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_rubriques CHANGE `titre` `titre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_rubriques CHANGE `descriptif` `descriptif` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_rubriques CHANGE `texte` `texte` longtext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_rubriques CHANGE `url_propre` `url_propre` VARCHAR(255) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_documents CHANGE `extension` `extension` VARCHAR(10) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_documents CHANGE `titre` `titre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_documents CHANGE `date` `date` datetime DEFAULT '0000-00-00 00:00:00' NOT NULL"),
-	array('sql_alter', "TABLE spip_documents CHANGE `descriptif` `descriptif` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_documents CHANGE `fichier` `fichier` varchar(255) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_types_documents CHANGE `extension` `extension` varchar(10) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_types_documents CHANGE `titre` `titre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_types_documents CHANGE `descriptif` `descriptif` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_types_documents CHANGE `mime_type` `mime_type` varchar(100) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic CHANGE `nom_site` `nom_site` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic CHANGE `url_site` `url_site` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic CHANGE `url_syndic` `url_syndic` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic CHANGE `descriptif` `descriptif` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic CHANGE `url_propre` `url_propre` VARCHAR(255) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic CHANGE `syndication` `syndication` VARCHAR(3) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic_articles CHANGE `titre` `titre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic_articles CHANGE `url` `url` VARCHAR(255) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic_articles CHANGE `lesauteurs` `lesauteurs` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_syndic_articles CHANGE `descriptif` `descriptif` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_forum CHANGE `titre` `titre` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_forum CHANGE `texte` `texte` mediumtext DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_forum CHANGE `auteur` `auteur` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_forum CHANGE `email_auteur` `email_auteur` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_forum CHANGE `nom_site` `nom_site` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_forum CHANGE `url_site` `url_site` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_forum CHANGE `ip` `ip` varchar(16) DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_signatures CHANGE `nom_email` `nom_email` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_signatures CHANGE `ad_email` `ad_email` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_signatures CHANGE `nom_site` `nom_site` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_signatures CHANGE `url_site` `url_site` text DEFAULT '' NOT NULL"),
-	array('sql_alter', "TABLE spip_signatures CHANGE `message` `message` mediumtext DEFAULT '' NOT NULL")
-);
-
-
-$GLOBALS['maj'][1946] = array(
-	array('sql_alter', "TABLE spip_forum DROP INDEX `id_parent`"),
-	array('sql_alter', "TABLE spip_forum DROP INDEX `id_article`"),
-	array('sql_alter', "TABLE spip_forum DROP INDEX `id_breve`"),
-	array('sql_alter', "TABLE spip_forum DROP INDEX `id_syndic`"),
-	array('sql_alter', "TABLE spip_forum DROP INDEX `id_rubrique`"),
-	array('sql_alter', "TABLE spip_forum DROP INDEX `date_thread`"),
-	array('sql_alter', "TABLE spip_forum DROP INDEX `statut`"),
-	array(
-		'sql_alter',
-		"TABLE spip_forum ADD INDEX `optimal` (`statut`,`id_parent`,`id_article`,`date_heure`,`id_breve`,`id_syndic`,`id_rubrique`)"
-	)
-);
-
-
-$GLOBALS['maj'][1947] = array(
-
-	array('sql_alter', "TABLE spip_articles DROP INDEX `url_site`"),
-	array('sql_alter', "TABLE spip_articles DROP INDEX `date_modif`"),
-	array('sql_alter', "TABLE spip_auteurs  DROP INDEX `lang`")
-);
-
-// mauvaise manip
-$GLOBALS['maj'][1949] = array(
-
-	array('sql_alter', "TABLE spip_versions DROP INDEX `date`"),
-	array('sql_alter', "TABLE spip_versions DROP INDEX `id_auteur`")
-);
-
-/**
- * Mise à jour 1_950 : Gestion du prefixe pour la table des urls
- *
- * @param float $installee Numéro de version actuellement installée
- **/
-function maj_1_950($installee) {
-	// oubli de gerer le prefixe lors l'introduction de l'abstraction
-	// => Relancer les MAJ concernees si la version dont on part les avait fait
-	if ($installee >= 1.946) {
-		serie_alter('950a', $GLOBALS['maj'][1946]);
-	}
-	if ($installee >= 1.947) {
-		serie_alter('950b', $GLOBALS['maj'][1947]);
-	}
-	if ($installee >= 1.949) {
-		@serie_alter('950c', $GLOBALS['maj'][1949]);
-	}
-	global $tables_auxiliaires;
-	include_spip('base/auxiliaires');
-	$v = $tables_auxiliaires[$k = 'spip_urls'];
-	sql_create($k, $v['field'], $v['key'], false, false);
-
-
-	foreach (array(
-		         'article' => 'id_article',
-		         'rubrique' => 'id_rubrique',
-		         'breve' => 'id_breve',
-		         'auteur' => 'id_auteur',
-		         'mot' => 'id_mot',
-		         'syndic' => 'id_syndic'
-	         ) as $type => $id_objet) {
-		$table = ($type == 'syndic') ? $type : ($type . "s");
-		$date = ($type == 'breve') ? 'date_heure' :
-			(($type == 'auteur') ? 'maj' :
-				(($type == 'mot') ? 'maj' : 'date'));
-		$q = @sql_select("url_propre AS url, $id_objet AS id_objet, '$type' AS type, $date as date", "spip_$table",
-			"url_propre<>''");
-		if (!$q) {
-			return;
-		} // anormal, mais ne pas boucler en erreur
-		while ($r = sql_fetch($q)) {
-			sql_replace('spip_urls', $r);
-		}
-		spip_log("table $table : " . sql_count($q) . " urls propres copiees");
-		sql_alter("TABLE spip_$table DROP INDEX `url_propre`");
-		sql_alter("TABLE spip_$table DROP `url_propre`");
-	}
-}
-
-// Donner a la fonction ci-dessus le numero de version installee
-// AVANT que la mise a jour ait commencee
-$GLOBALS['maj'][1950] = array(array('maj_1_950', $GLOBALS['meta']['version_installee']));
-
-// Erreur dans maj_1_948():
-// // https://git.spip.net/spip/spip/commit/619a9e5b10bfbe287aec1e11d66b720ec9da4494
-// // Gestion du verrou SQL par PHP
-
-$GLOBALS['maj'][1951] = array(
-
-	array('sql_alter', "TABLE spip_versions CHANGE `id_version` `id_version` bigint(21) DEFAULT 0 NOT NULL")
-);
-
-
-/**
- * Mise à jour 1_952 : Transformation des documents
- *
- * - image => mode=image
- * - vignette => mode=vignette
- **/
-function maj_1_952() {
-
-	$ok = sql_alter("TABLE spip_documents CHANGE `mode` `mode` enum('vignette','image','document') DEFAULT NULL");
-
-	if ($ok) {
-
-		$s = sql_select("v.id_document as id_document",
-			"spip_documents as d join spip_documents as v ON d.id_vignette=v.id_document");
-
-		$vignettes = array();
-		while ($t = sql_fetch($s)) {
-			$vignettes[] = intval($t['id_document']);
-		}
-
-		$ok &= sql_query("UPDATE spip_documents SET `mode`='image' WHERE `mode`='vignette'");
-		$ok &= sql_query("UPDATE spip_documents SET `mode`='vignette' WHERE `mode`='image' AND " . sql_in('id_document',
-				$vignettes));
-	}
-	if (!$ok) {
-		die('echec sur maj_1_952()');
-	}
-}
-
-$GLOBALS['maj'][1952] = array(array('maj_1_952'));
-
-$GLOBALS['maj'][1953] = array(array('upgrade_types_documents'));
-
-$GLOBALS['maj'][1954] = array(
-
-	//pas de psd en <img>
-	array('sql_query', "UPDATE spip_types_documents SET `inclus`='non' WHERE `extension`='psd'"),
-	//ajout csv
-	array('sql_query', "INSERT IGNORE INTO spip_types_documents (`extension`, `titre`) VALUES ('csv', 'CSV')"),
-	array('sql_query', "UPDATE spip_types_documents SET `mime_type`='text/csv' WHERE `extension`='csv'"),
-	//ajout mkv
-	array(
-		'sql_query',
-		"INSERT IGNORE INTO spip_types_documents (`extension`, `titre`, `inclus`) VALUES ('mkv', 'Matroska Video', 'embed')"
-	),
-	array('sql_query', "UPDATE spip_types_documents SET `mime_type`='video/x-mkv' WHERE `extension`='mkv'"),
-	//ajout mka
-	array(
-		'sql_query',
-		"INSERT IGNORE INTO spip_types_documents (`extension`, `titre`, `inclus`) VALUES ('mka', 'Matroska Audio', 'embed')"
-	),
-	array('sql_query', "UPDATE spip_types_documents SET `mime_type`='audio/x-mka' WHERE `extension`='mka'"),
-	//ajout kml
-	array(
-		'sql_query',
-		"INSERT IGNORE INTO spip_types_documents (`extension`, `titre`) VALUES ('kml', 'Keyhole Markup Language')"
-	),
-	array(
-		'sql_query',
-		"UPDATE spip_types_documents SET `mime_type`='application/vnd.google-earth.kml+xml' WHERE `extension`='kml'"
-	),
-	//ajout kmz
-	array(
-		'sql_query',
-		"INSERT IGNORE INTO spip_types_documents (`extension`, `titre`) VALUES ('kmz', 'Google Earth Placemark File')"
-	),
-	array(
-		'sql_query',
-		"UPDATE spip_types_documents SET `mime_type`='application/vnd.google-earth.kmz' WHERE `extension`='kmz'"
-	)
-);
-
-if ($GLOBALS['meta']['version_installee'] > 1.950) // 1.950 lisait un bug dans auxiliaires.php corrige a present
-{
-	$GLOBALS['maj'][1955] = array(
-		array('sql_alter', "TABLE spip_urls CHANGE `maj` date DATETIME DEFAULT '0000-00-00 00:00:00' NOT NULL")
-	);
-}
-
-// la mise a jour vers 1.938 contient une erreur
-// il faut supprimer l'autoincrement avant de supprimer la PRIMARY KEY
-
-$GLOBALS['maj'][1938] = array(
-
-# creer un champ plus informatif, et son index
-	array('sql_alter', "TABLE spip_documents ADD `extension` VARCHAR(10) DEFAULT ''  NOT NULL "),
-# recopier l'ancien champ dans le nouveau
-	array('maj_1_938'),
-# supprimer l'ancien champ et son index
-	array('sql_alter', "TABLE spip_documents DROP INDEX `id_type`, DROP `id_type`"),
-	## supprimer l'autoincrement avant de supprimer la PRIMARY KEY
-	array('sql_alter', "TABLE spip_types_documents CHANGE `id_type` `id_type` BIGINT( 21 ) NOT NULL "),
-# le champ id_type devient superflu
-	array('sql_alter', "TABLE spip_types_documents DROP `id_type`"),
-	array('sql_alter', "TABLE spip_types_documents ADD PRIMARY KEY (`extension`)")
-);
-
-
-// PG veut une valeur par defaut a l'insertion
-// https://git.spip.net/spip/spip/commit/5a981d1fbec021a42593a91482a6b17da060c2c5
-
-$GLOBALS['maj'][1957] = array(
-	array('sql_alter', "TABLE spip_mots CHANGE `id_groupe` `id_groupe` bigint(21) DEFAULT 0 NOT NULL"),
-	array(
-		'sql_alter',
-		"TABLE spip_documents CHANGE `mode` `mode` ENUM('vignette', 'image', 'document') DEFAULT 'document' NOT NULL"
-	)
-);
-
-// Ce champ est inutile et provoque une erreur a l'insertion qui l'oublie
-$GLOBALS['maj'][1958] = array(
-	array('sql_alter', "TABLE spip_referers_articles DROP date")
-);
diff --git a/ecrire/maj/legacy/v21.php b/ecrire/maj/legacy/v21.php
new file mode 100644
index 0000000000..505192dfb0
--- /dev/null
+++ b/ecrire/maj/legacy/v21.php
@@ -0,0 +1,90 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Système de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright © avec tendresse depuis 2001                                 *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribué sous licence GNU/GPL.     *
+ *  Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+/**
+ * Gestion des mises à jour de bdd de SPIP
+ * 
+ * Mises à jour en 2.1 (et 2.0.0+)
+ *
+ * @package SPIP\Core\SQL\Upgrade
+ **/
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+// 2.0.0+
+
+// http://archives.rezo.net/archives/spip-zone.mbox/C6RZKNBUNJYN42IOEOC4QKVCA233AMLI/
+$GLOBALS['maj'][13833] = array(
+	array('sql_alter', "TABLE spip_documents_liens ADD INDEX objet(id_objet,objet)")
+);
+
+// 2.1
+
+$GLOBALS['maj'][13904] = array(
+	array('sql_alter', "TABLE spip_auteurs ADD webmestre varchar(3)  DEFAULT 'non' NOT NULL"),
+	array(
+		'sql_update',
+		'spip_auteurs',
+		array('webmestre' => "'oui'"),
+		sql_in("id_auteur", defined('_ID_WEBMESTRES') ? explode(':',
+			_ID_WEBMESTRES) : (autoriser('configurer') ? array($GLOBALS['visiteur_session']['id_auteur']) : array(0)))
+	) // le webmestre est celui qui fait l'upgrade si rien de defini
+);
+
+// sites plantes en mode "'su" au lieu de "sus"
+$GLOBALS['maj'][13929] = array(
+	array('sql_update', "spip_syndic", array('syndication' => "'sus'"), "syndication LIKE '\\'%'")
+);
+
+// Types de fichiers m4a/m4b/m4p/m4u/m4v/dv
+// Types de fichiers Open XML (cro$oft)
+$GLOBALS['maj'][14558] = array(array('upgrade_types_documents'));
+
+
+
+// refaire les upgrade dont les numeros sont inferieurs a ceux de la branche 2.0
+// etre sur qu'ils sont bien unipotents(?)...
+$GLOBALS['maj'][14559] = $GLOBALS['maj'][13904] + $GLOBALS['maj'][13929] + $GLOBALS['maj'][14558];
+
+// La version 14588 etait une mauvaise piste:
+// Retour en arriere pour ceux qui l'ont subi, ne rien faire sinon
+if (@$GLOBALS['meta']['version_installee'] >= 14588) {
+
+	// "mode" est un mot-cle d'Oracle
+	$GLOBALS['maj'][14588] = array(
+		array('sql_alter', "TABLE spip_documents  DROP INDEX mode"),
+		array(
+			'sql_alter',
+			"TABLE spip_documents  CHANGE mode genre ENUM('vignette', 'image', 'document') DEFAULT 'document' NOT NULL"
+		),
+		array('sql_alter', "TABLE spip_documents  ADD INDEX genre(genre)")
+	);
+	// solution moins intrusive au pb de mot-cle d'Oracle, retour avant 14588
+	$GLOBALS['maj'][14598] = array(
+		array('sql_alter', "TABLE spip_documents  DROP INDEX genre"),
+		array(
+			'sql_alter',
+			"TABLE spip_documents  CHANGE genre mode ENUM('vignette', 'image', 'document') DEFAULT 'document' NOT NULL"
+		),
+		array('sql_alter', "TABLE spip_documents  ADD INDEX mode(mode)")
+	);
+}
+
+// Restauration correcte des types mime des fichiers Ogg
+// https://core.spip.net/issues/1941
+// + Types de fichiers : f4a/f4b/f4p/f4v/mpc http://en.wikipedia.org/wiki/Flv#File_formats
+// + Report du commit oublié : https://git.spip.net/spip/spip/commit/a6468fa5e3e34483b98b24b0102c4356f2f369a3
+$GLOBALS['maj'][15676] = array(array('upgrade_types_documents'));
+
+// Type de fichiers : webm http://en.wikipedia.org/wiki/Flv#File_formats
+$GLOBALS['maj'][15827] = array(array('upgrade_types_documents'));
diff --git a/ecrire/maj/legacy/v30.php b/ecrire/maj/legacy/v30.php
new file mode 100644
index 0000000000..adca72eef5
--- /dev/null
+++ b/ecrire/maj/legacy/v30.php
@@ -0,0 +1,347 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Système de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright © avec tendresse depuis 2001                                 *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribué sous licence GNU/GPL.     *
+ *  Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+/**
+ * Gestion des mises à jour de bdd de SPIP
+ * 
+ * Mises à jour en 3.0
+ *
+ * @package SPIP\Core\SQL\Upgrade
+ **/
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+
+$GLOBALS['maj'][16428] = array(
+	array('maj_liens', 'auteur'), // creer la table liens
+	array('maj_liens', 'auteur', 'article'),
+	array('sql_drop_table', "spip_auteurs_articles"),
+	array('maj_liens', 'auteur', 'rubrique'),
+	array('sql_drop_table', "spip_auteurs_rubriques"),
+	array('maj_liens', 'auteur', 'message'),
+	array('sql_drop_table', "spip_auteurs_messages"),
+);
+
+/**
+ * Mise à jour des tables de liens
+ *
+ * Crée la table de lien au nouveau format (spip_xx_liens) ou insère
+ * les données d'ancien format dans la nouveau format.
+ *
+ * Par exemple pour réunir en une seule table les liens de documents,
+ * spip_documents_articles et spip_documents_forum
+ *
+ * Supprime la table au vieux format une fois les données transférées.
+ *
+ * @uses creer_ou_upgrader_table()
+ * @uses maj_liens_insertq_multi_check()
+ *
+ * @param string $pivot
+ *     Nom de la table pivot, tel que `auteur`
+ * @param string $l
+ *     Vide : crée la table de lien pivot.
+ *     Sinon, nom de la table à lier, tel que `article`, et dans ce cas là,
+ *     remplit spip_auteurs_liens à partir de spip_auteurs_articles.
+ */
+function maj_liens($pivot, $l = '') {
+
+	@define('_LOG_FILTRE_GRAVITE', 8);
+
+	$exceptions_pluriel = array('forum' => 'forum', 'syndic' => 'syndic');
+
+	$pivot = preg_replace(',[^\w],', '', $pivot); // securite
+	$pivots = (isset($exceptions_pluriel[$pivot]) ? $exceptions_pluriel[$pivot] : $pivot . "s");
+	$liens = "spip_" . $pivots . "_liens";
+	$id_pivot = "id_" . $pivot;
+	// Creer spip_auteurs_liens
+	global $tables_auxiliaires;
+	if (!$l) {
+		include_spip('base/auxiliaires');
+		include_spip('base/create');
+		creer_ou_upgrader_table($liens, $tables_auxiliaires[$liens], false);
+	} else {
+		// Preparer
+		$l = preg_replace(',[^\w],', '', $l); // securite
+		$primary = "id_$l";
+		$objet = ($l == 'syndic' ? 'site' : $l);
+		$ls = (isset($exceptions_pluriel[$l]) ? $exceptions_pluriel[$l] : $l . "s");
+		$ancienne_table = 'spip_' . $pivots . '_' . $ls;
+		$pool = 400;
+
+		$trouver_table = charger_fonction('trouver_table', 'base');
+		if (!$desc = $trouver_table($ancienne_table)) {
+			return;
+		}
+
+		// securite pour ne pas perdre de donnees
+		if (!$trouver_table($liens)) {
+			return;
+		}
+
+		$champs = $desc['field'];
+		if (isset($champs['maj'])) {
+			unset($champs['maj']);
+		}
+		if (isset($champs[$primary])) {
+			unset($champs[$primary]);
+		}
+
+		$champs = array_keys($champs);
+		// ne garder que les champs qui existent sur la table destination
+		if ($desc_cible = $trouver_table($liens)) {
+			$champs = array_intersect($champs, array_keys($desc_cible['field']));
+		}
+
+		$champs[] = "$primary as id_objet";
+		$champs[] = "'$objet' as objet";
+		$champs = implode(', ', $champs);
+
+		// Recopier les donnees
+		$sub_pool = 100;
+		while ($ids = array_map('reset', sql_allfetsel("$primary", $ancienne_table, '', '', '', "0,$sub_pool"))) {
+			$insert = array();
+			foreach ($ids as $id) {
+				$n = sql_countsel($liens, "objet='$objet' AND id_objet=" . intval($id));
+				while ($t = sql_allfetsel($champs, $ancienne_table, "$primary=" . intval($id), '', $id_pivot, "$n,$pool")) {
+					$n += count($t);
+					// empiler en s'assurant a minima de l'unicite
+					while ($r = array_shift($t)) {
+						$insert[$r[$id_pivot] . ':' . $r['id_objet']] = $r;
+					}
+					if (count($insert) >= $sub_pool) {
+						maj_liens_insertq_multi_check($liens, $insert, $tables_auxiliaires[$liens]);
+						$insert = array();
+					}
+					// si timeout, sortir, la relance nous ramenera dans cette fonction
+					// et on verifiera/repartira de la
+					if (time() >= _TIME_OUT) {
+						return;
+					}
+				}
+				if (time() >= _TIME_OUT) {
+					return;
+				}
+			}
+			if (count($insert)) {
+				maj_liens_insertq_multi_check($liens, $insert, $tables_auxiliaires[$liens]);
+			}
+			sql_delete($ancienne_table, sql_in($primary, $ids));
+		}
+	}
+}
+
+/**
+ * Insère des données dans une table de liaison de façon un peu sécurisée
+ *
+ * Si une insertion multiple échoue, on réinsère ligne par ligne.
+ *
+ * @param string $table Table de liaison
+ * @param array $couples Tableau de couples de données à insérer
+ * @param array $desc Description de la table de liaison
+ * @return void
+ **/
+function maj_liens_insertq_multi_check($table, $couples, $desc = array()) {
+	$n_before = sql_countsel($table);
+	sql_insertq_multi($table, $couples, $desc);
+	$n_after = sql_countsel($table);
+	if (($n_after - $n_before) == count($couples)) {
+		return;
+	}
+	// si ecart, on recommence l'insertion ligne par ligne...
+	// moins rapide mais secure : seul le couple en doublon echouera, et non toute la serie
+	foreach ($couples as $c) {
+		sql_insertq($table, $c, $desc);
+	}
+}
+
+$GLOBALS['maj'][17311] = array(
+	array(
+		'ecrire_meta',
+		"multi_objets",
+		implode(',',
+			array_diff(
+				array(
+					(isset($GLOBALS['meta']['multi_rubriques']) and $GLOBALS['meta']['multi_rubriques'] == 'oui')
+						? 'spip_rubriques' : '',
+					(isset($GLOBALS['meta']['multi_articles']) and $GLOBALS['meta']['multi_articles'] == 'oui')
+						? 'spip_articles' : ''
+				),
+				array('')
+			))
+	),
+	array(
+		'ecrire_meta',
+		"gerer_trad_objets",
+		implode(',',
+			array_diff(
+				array(
+					(isset($GLOBALS['meta']['gerer_trad']) and $GLOBALS['meta']['gerer_trad'] == 'oui')
+						? 'spip_articles' : ''
+				),
+				array('')
+			))
+	),
+);
+$GLOBALS['maj'][17555] = array(
+	array('sql_alter', "TABLE spip_resultats ADD table_objet varchar(30) DEFAULT '' NOT NULL"),
+	array('sql_alter', "TABLE spip_resultats ADD serveur char(16) DEFAULT '' NOT NULL"),
+);
+
+$GLOBALS['maj'][17563] = array(
+	array('sql_alter', "TABLE spip_articles ADD virtuel VARCHAR(255) DEFAULT '' NOT NULL"),
+	array('sql_update', 'spip_articles', array('virtuel' => 'SUBSTRING(chapo,2)', 'chapo' => "''"), "chapo LIKE '=_%'"),
+);
+
+$GLOBALS['maj'][17577] = array(
+	array('maj_tables', array('spip_jobs', 'spip_jobs_liens')),
+);
+
+$GLOBALS['maj'][17743] = array(
+	array('sql_update', 'spip_auteurs', array('prefs' => 'bio', 'bio' => "''"), "statut='nouveau' AND bio<>''"),
+);
+
+$GLOBALS['maj'][18219] = array(
+	array('sql_alter', "TABLE spip_rubriques DROP id_import"),
+	array('sql_alter', "TABLE spip_rubriques DROP export"),
+);
+
+$GLOBALS['maj'][18310] = array(
+	array('sql_alter', "TABLE spip_auteurs_liens CHANGE vu vu VARCHAR(6) DEFAULT 'non' NOT NULL"),
+);
+
+$GLOBALS['maj'][18597] = array(
+	array('sql_alter', "TABLE spip_rubriques ADD profondeur smallint(5) DEFAULT '0' NOT NULL"),
+	array('maj_propager_les_secteurs'),
+);
+
+$GLOBALS['maj'][18955] = array(
+	array('sql_alter', "TABLE spip_auteurs_liens ADD INDEX id_objet (id_objet)"),
+	array('sql_alter', "TABLE spip_auteurs_liens ADD INDEX objet (objet)"),
+);
+
+/**
+ * Mise à jour pour recalculer les secteurs des rubriques
+ *
+ * @uses propager_les_secteurs()
+ **/
+function maj_propager_les_secteurs() {
+	include_spip('inc/rubriques');
+	propager_les_secteurs();
+}
+
+/**
+ * Mise à jour des bdd SQLite pour réparer les collation des champs texte
+ * pour les passer en NOCASE
+ *
+ * @uses base_lister_toutes_tables()
+ * @uses _sqlite_remplacements_definitions_table()
+ **/
+function maj_collation_sqlite() {
+
+
+	include_spip('base/dump');
+	$tables = base_lister_toutes_tables();
+
+	// rien a faire si base non sqlite
+	if (strncmp($GLOBALS['connexions'][0]['type'], 'sqlite', 6) !== 0) {
+		return;
+	}
+
+	$trouver_table = charger_fonction('trouver_table', 'base');
+	// forcer le vidage de cache
+	$trouver_table('');
+
+	// cas particulier spip_auteurs : retablir le collate binary sur le login
+	$desc = $trouver_table("spip_auteurs");
+	spip_log("spip_auteurs : " . var_export($desc['field'], true), "maj." . _LOG_INFO_IMPORTANTE);
+	if (stripos($desc['field']['login'], "BINARY") === false) {
+		spip_log("Retablir champ login BINARY sur table spip_auteurs", "maj");
+		sql_alter("table spip_auteurs change login login VARCHAR(255) BINARY");
+		$trouver_table('');
+		$new_desc = $trouver_table("spip_auteurs");
+		spip_log("Apres conversion spip_auteurs : " . var_export($new_desc['field'], true), "maj." . _LOG_INFO_IMPORTANTE);
+	}
+
+	foreach ($tables as $table) {
+		if (time() >= _TIME_OUT) {
+			return;
+		}
+		if ($desc = $trouver_table($table)) {
+			$desc_collate = _sqlite_remplacements_definitions_table($desc['field']);
+			if ($d = array_diff($desc['field'], $desc_collate)) {
+				spip_log("Table $table COLLATE incorrects", "maj");
+
+				// cas particulier spip_urls :
+				// supprimer les doublons avant conversion sinon echec (on garde les urls les plus recentes)
+				if ($table == 'spip_urls') {
+					// par date DESC pour conserver les urls les plus recentes
+					$data = sql_allfetsel("*", "spip_urls", '', '', 'date DESC');
+					$urls = array();
+					foreach ($data as $d) {
+						$key = $d['id_parent'] . "::" . strtolower($d['url']);
+						if (!isset($urls[$key])) {
+							$urls[$key] = true;
+						} else {
+							spip_log("Suppression doublon dans spip_urls avant conversion : " . serialize($d),
+								"maj." . _LOG_INFO_IMPORTANTE);
+							sql_delete("spip_urls", "id_parent=" . sql_quote($d['id_parent']) . " AND url=" . sql_quote($d['url']));
+						}
+					}
+				}
+				foreach ($desc['field'] as $field => $type) {
+					if ($desc['field'][$field] !== $desc_collate[$field]) {
+						spip_log("Conversion COLLATE table $table", "maj." . _LOG_INFO_IMPORTANTE);
+						sql_alter("table $table change $field $field " . $desc_collate[$field]);
+						$trouver_table('');
+						$new_desc = $trouver_table($table);
+						spip_log("Apres conversion $table : " . var_export($new_desc['field'], true),
+							"maj." . _LOG_INFO_IMPORTANTE);
+						continue 2; // inutile de continuer pour cette table : un seul alter remet tout a jour en sqlite
+					}
+				}
+			}
+		}
+	}
+
+	// forcer le vidage de cache
+	$trouver_table('');
+
+}
+
+
+$GLOBALS['maj'][19236] = array(
+	array('sql_updateq', 'spip_meta', array('impt' => 'oui'), "nom='version_installee'"), // version base principale
+	array('sql_updateq', 'spip_meta', array('impt' => 'oui'), "nom LIKE '%_base_version'"),  // version base plugins
+	array('maj_collation_sqlite'),
+);
+
+$GLOBALS['maj'][19268] = array(
+	array('supprimer_toutes_sessions'),
+);
+
+/**
+ * Supprime toutes les sessions des auteurs
+ *
+ * Obligera tous les auteurs à se reconnecter !
+ **/
+function supprimer_toutes_sessions() {
+	spip_log("supprimer sessions auteur");
+	if ($dir = opendir(_DIR_SESSIONS)) {
+		while (($f = readdir($dir)) !== false) {
+			spip_unlink(_DIR_SESSIONS . $f);
+			if (time() >= _TIME_OUT) {
+				return;
+			}
+		}
+	}
+}
diff --git a/ecrire/maj/legacy/v31.php b/ecrire/maj/legacy/v31.php
new file mode 100644
index 0000000000..52487249c2
--- /dev/null
+++ b/ecrire/maj/legacy/v31.php
@@ -0,0 +1,60 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Système de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright © avec tendresse depuis 2001                                 *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribué sous licence GNU/GPL.     *
+ *  Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+/**
+ * Gestion des mises à jour de bdd de SPIP
+ * 
+ * Mises à jour en 3.1
+ *
+ * @package SPIP\Core\SQL\Upgrade
+ **/
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+
+$GLOBALS['maj'][21676] = array(
+	array('ranger_cache_gd2'),
+);
+
+/**
+ * Ranger les images de local/cache-gd2 dans des sous-rep
+ *
+ * https://core.spip.net/issues/3277
+ */
+function ranger_cache_gd2() {
+	spip_log("ranger_cache_gd2");
+	$base = _DIR_VAR . "cache-gd2/";
+	if (is_dir($base) and is_readable($base)) {
+		if ($dir = opendir($base)) {
+			while (($f = readdir($dir)) !== false) {
+				if (!is_dir($base . $f) and strncmp($f, ".", 1) !== 0
+					and preg_match(",[0-9a-f]{32}\.\w+,", $f)
+				) {
+					$sub = substr($f, 0, 2);
+					$sub = sous_repertoire($base, $sub);
+					@rename($base . $f, $sub . substr($f, 2));
+					@unlink($base . $f); // au cas ou le rename a foire (collision)
+				}
+				if (time() >= _TIME_OUT) {
+					return;
+				}
+			}
+		}
+	}
+}
+
+
+$GLOBALS['maj'][21742] = array(
+	array('sql_alter', "TABLE spip_articles CHANGE url_site url_site text DEFAULT '' NOT NULL"),
+	array('sql_alter', "TABLE spip_articles CHANGE virtuel virtuel text DEFAULT '' NOT NULL"),
+);
diff --git a/ecrire/maj/legacy/v32.php b/ecrire/maj/legacy/v32.php
new file mode 100644
index 0000000000..95585b182c
--- /dev/null
+++ b/ecrire/maj/legacy/v32.php
@@ -0,0 +1,27 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Système de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright © avec tendresse depuis 2001                                 *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribué sous licence GNU/GPL.     *
+ *  Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+/**
+ * Gestion des mises à jour de bdd de SPIP
+ * 
+ * Mises à jour en 3.2
+ *
+ * @package SPIP\Core\SQL\Upgrade
+ **/
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+
+$GLOBALS['maj'][23375] = array(
+	array('sql_alter', "TABLE spip_auteurs CHANGE prefs prefs text"),
+);
diff --git a/ecrire/maj/legacy/v40.php b/ecrire/maj/legacy/v40.php
new file mode 100644
index 0000000000..a27d8679aa
--- /dev/null
+++ b/ecrire/maj/legacy/v40.php
@@ -0,0 +1,81 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Système de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright © avec tendresse depuis 2001                                 *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribué sous licence GNU/GPL.     *
+ *  Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+/**
+ * Gestion des mises à jour de bdd de SPIP
+ * 
+ * Mises à jour en 4.0 (avant 2021)
+ * 
+ * À partir de 2021, les numéros d'upgrade sont de la forme YYYYMMDD00 où 00 est un incrément.
+ *
+ * @package SPIP\Core\SQL\Upgrade
+ **/
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+
+// adaptation des timestamp mysql
+$GLOBALS['maj'][24379] = [['maj_timestamp_mysql']];
+
+/**
+ * Mise à jour des bdd Mysql pour réparer les timestamp auto-update absents
+ *
+ * @uses base_lister_toutes_tables()
+ * @uses _mysql_remplacements_definitions_table()
+ **/
+function maj_timestamp_mysql($tables = null) {
+
+	include_spip('base/dump');
+	if (is_null($tables)) {
+		$tables = base_lister_toutes_tables();
+	} elseif (is_string($tables)) {
+		$tables = [$tables];
+	} elseif (!is_array($tables)) {
+		return;
+	}
+
+	// rien a faire si base non mysql
+	if (strncmp($GLOBALS['connexions'][0]['type'], 'mysql', 5) !== 0) {
+		return;
+	}
+
+	$trouver_table = charger_fonction('trouver_table', 'base');
+	// forcer le vidage de cache
+	$trouver_table('');
+
+	foreach ($tables as $table) {
+		if (time() >= _TIME_OUT) {
+			return;
+		}
+		if ($desc = $trouver_table($table)) {
+			$fields_corrected = _mysql_remplacements_definitions_table($desc['field']);
+			$d = array_diff($desc['field'], $fields_corrected);
+			if ($d) {
+				spip_log("Table $table TIMESTAMP incorrect", "maj");
+				foreach ($desc['field'] as $field => $type) {
+					if ($desc['field'][$field] !== $fields_corrected[$field]) {
+						spip_log("Adaptation TIMESTAMP table $table", "maj." . _LOG_INFO_IMPORTANTE);
+						sql_alter("table $table change $field $field " . $fields_corrected[$field]);
+						$trouver_table('');
+						$new_desc = $trouver_table($table);
+						spip_log("Apres conversion $table : " . var_export($new_desc['field'], true),
+							"maj." . _LOG_INFO_IMPORTANTE);
+					}
+				}
+			}
+		}
+	}
+
+	// forcer le vidage de cache
+	$trouver_table('');
+}
-- 
GitLab