diff --git a/.gitattributes b/.gitattributes
index 440f2f68c6c756fa1c6eacbb8ca6ab689227bc40..2688ac1d2ceb7e0dc156caf91819953c7c3415e0 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -355,6 +355,9 @@ ecrire/inc/cookie.php -text
 ecrire/inc/distant.php -text
 ecrire/inc/forum_insert.php -text
 ecrire/inc/headers.php -text
+ecrire/inc/import_0_0.php -text
+ecrire/inc/import_1_2.php -text
+ecrire/inc/import_1_3.php -text
 ecrire/inc/lang_liste.php -text
 ecrire/inc/message_select.php -text
 ecrire/inc/mini_nav.php -text
diff --git a/ecrire/exec/import_all.php b/ecrire/exec/import_all.php
index 531e2d5f22225188f3f335e5a742090d74b157d1..a601611dee5ffcdd74851a3b13d223c6bdf7bb84 100644
--- a/ecrire/exec/import_all.php
+++ b/ecrire/exec/import_all.php
@@ -1,153 +1,105 @@
-<?php
-
-/***************************************************************************\
- *  SPIP, Systeme de publication pour l'internet                           *
- *                                                                         *
- *  Copyright (c) 2001-2006                                                *
- *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
- *                                                                         *
- *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
- *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
-\***************************************************************************/
-
-if (!defined("_ECRIRE_INC_VERSION")) return;
-
-include_spip('inc/admin');
-include_spip('base/serial');
-include_spip('base/auxiliaires');
-
-// par defaut tout est importe sauf les tables ci-dessous
-// possibiliter de definir cela tables via la meta
-global $IMPORT_tables_noimport;
-if (isset($GLOBALS['meta']['IMPORT_tables_noimport']))
-	$IMPORT_tables_noimport = unserialize($GLOBALS['meta']['IMPORT_tables_noimport']);
-else{
-	include_spip('inc/meta');
-	$IMPORT_tables_noimport[]='spip_ajax_fonc';
-	$IMPORT_tables_noimport[]='spip_caches';
-	$IMPORT_tables_noimport[]='spip_meta';
-	ecrire_meta('IMPORT_tables_noimport',serialize($IMPORT_tables_noimport));
-	ecrire_metas();
-}
-
-// NB: Ce fichier peut ajouter des tables (old-style)
-// donc il faut l'inclure "en globals"
-if ($f = include_spip('mes_fonctions', false)) {
-	global $dossier_squelettes;
-	@include_once ($f); 
-}
-
-function verifier_version_sauvegarde ($archive) {
-	global $spip_version;
-	global $flag_gz;
-
-	$ok = @file_exists(_DIR_SESSIONS . $archive);
-	$gz = $flag_gz;
-	$_fopen = ($gz) ? gzopen : fopen;
-	$_fread = ($gz) ? gzread : fread;
-	$buf_len = 1024; // la version doit etre dans le premier ko
-
-	if ($ok) {
-		$f = $_fopen(_DIR_SESSIONS . $archive, "rb");
-		$buf = $_fread($f, $buf_len);
-
-		if (ereg("<SPIP [^>]* version_base=\"([0-9\.]+)\" ", $buf, $regs)
-			AND $regs[1] == $spip_version)
-			return false; // c'est bon
-		else
-			return _T('avis_erreur_version_archive', array('archive' => $archive));
-	} else
-		return _T('avis_probleme_archive', array('archive' => $archive));
-}
-
-function import_all_check() {
-
-	global $archive;
-
-	// cas de l'appel apres demande de confirmation
-	if ($archive) {
-			$action = _T('info_restauration_sauvegarde', array('archive' => $archive));
-			$commentaire = verifier_version_sauvegarde ($archive);
-		}
-
-	// au tout premier appel, on ne revient pas de cette fonction
-	debut_admin(generer_url_post_ecrire("import_all","archive=$archive"), $action, $commentaire);
-
-	// on est revenu: l'authentification ftp est ok
-	fin_admin($action);
-	// dire qu'on commence
-	ecrire_meta("request_restauration", serialize($_REQUEST));
-	ecrire_meta("debut_restauration", "debut");
-	ecrire_meta("status_restauration", "0");
-	ecrire_metas();
-	// se rappeler pour montrer illico ce qu'on fait 
-	header('Location: ./');
-	exit();
-}
-
-function exec_import_all_dist()
-{
-	// si l'appel est explicite, passer par l'authentification ftp
-	if (!$GLOBALS['meta']["debut_restauration"])
-		import_all_check();
-
-	// construction de la liste des tables pour le dump :
-	// toutes les tables principales
-	// + toutes les tables auxiliaires hors relations
-	// + les tables relations dont les deux tables liees sont dans la liste
-	$tables_for_dump = array();
-	$tables_pointees = array();
-	global $IMPORT_tables_noimport;
-	global $tables_principales;
-	global $tables_auxiliaires;
-	global $table_des_tables;
-	global $tables_jointures;
-
-	// on construit un index des tables de liens
-	// pour les ajouter SI les deux tables qu'ils connectent sont sauvegardees
-	$tables_for_link = array();
-	foreach($tables_jointures as $table=>$liste_relations)
-		if (is_array($liste_relations))
-		{
-			$nom = $table;
-			if (!isset($tables_auxiliaires[$nom])&&!isset($tables_principales[$nom]))
-				$nom = "spip_$table";
-			if (isset($tables_auxiliaires[$nom])||isset($tables_principales[$nom])){
-				foreach($liste_relations as $link_table){
-					if (isset($tables_auxiliaires[$link_table])/*||isset($tables_principales[$link_table])*/){
-						$tables_for_link[$link_table][] = $nom;
-					}
-					else if (isset($tables_auxiliaires["spip_$link_table"])/*||isset($tables_principales["spip_$link_table"])*/){
-						$tables_for_link["spip_$link_table"][] = $nom;
-					}
-				}
-			}
-		}
-	
-	$liste_tables = array_merge(array_keys($tables_principales),array_keys($tables_auxiliaires));
-	foreach($liste_tables as $table){
-		$name = preg_replace("{^spip_}","",$table);
-		if (		!isset($tables_pointees[$table]) 
-				&&	!in_array($table,$IMPORT_tables_noimport)
-				&&	!isset($tables_for_link[$table])){
-			$tables_for_dump[] = $table;
-			$tables_pointees[$table] = 1;
-		}
-	}
-	foreach ($tables_for_link as $link_table =>$liste){
-		$connecte = true;
-		foreach($liste as $connect_table)
-			if (!in_array($connect_table,$tables_for_dump))
-				$connecte = false;
-		if ($connecte)
-			# on ajoute les liaisons en premier
-			# si une restauration est interrompue, cela se verra mieux si il manque des objets
-			# que des liens
-			array_unshift($tables_for_dump,$link_table);
-	}
-	
-	// puis commencer ou continuer
-	include_spip('inc/import');
-	import_all_continue($tables_for_dump);
-}
-?>
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2006                                                *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
+ *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+if (!defined("_ECRIRE_INC_VERSION")) return;
+
+include_spip('inc/admin');
+include_spip('base/serial');
+include_spip('base/auxiliaires');
+
+// par defaut tout est importe sauf les tables ci-dessous
+// possibiliter de definir cela tables via la meta
+global $IMPORT_tables_noimport;
+if (isset($GLOBALS['meta']['IMPORT_tables_noimport']))
+	$IMPORT_tables_noimport = unserialize($GLOBALS['meta']['IMPORT_tables_noimport']);
+else{
+	include_spip('inc/meta');
+	$IMPORT_tables_noimport[]='spip_ajax_fonc';
+	$IMPORT_tables_noimport[]='spip_caches';
+	$IMPORT_tables_noimport[]='spip_meta';
+	ecrire_meta('IMPORT_tables_noimport',serialize($IMPORT_tables_noimport));
+	ecrire_metas();
+}
+
+// NB: Ce fichier peut ajouter des tables (old-style)
+// donc il faut l'inclure "en globals"
+if ($f = include_spip('mes_fonctions', false)) {
+	global $dossier_squelettes;
+	@include_once ($f); 
+}
+
+function verifier_version_sauvegarde ($archive) {
+	global $spip_version;
+	global $flag_gz;
+
+	$_fopen = ($flag_gz) ? gzopen : fopen;
+	$_fread = ($flag_gz) ? gzread : fread;
+	$buf_len = 1024; // la version doit etre dans le premier ko
+
+	if (@file_exists(_DIR_SESSIONS . $archive)) {
+		$f = $_fopen(_DIR_SESSIONS . $archive, "rb");
+		$buf = $_fread($f, $buf_len);
+
+		if (ereg('<SPIP [^>]* version_base="([0-9.]+)".*version_archive="([^"]+)"', $buf, $regs)
+		AND $regs[1] == $spip_version
+		AND import_charge_version($regs[2], 'inc', true))
+			return false; // c'est bon
+		else
+			return _T('avis_erreur_version_archive', array('archive' => $archive));
+	} else
+		return _T('avis_probleme_archive', array('archive' => $archive));
+}
+
+
+function import_charge_version($version_archive)
+{
+	if (preg_match("{^phpmyadmin::}is",$version_archive)){
+	#spip_log("restauration phpmyadmin : version $version_archive tag $tag_archive");
+		$fimport = 'import_1_3'; 
+	} else 	$fimport = 'import_' . str_replace('.','_',$version_archive);
+
+	return  charger_fonction($fimport, 'inc', true);
+}
+
+function exec_import_all_dist()
+{
+	global $archive;
+
+	// si l'appel est explicite, 
+	// passer par l'authentification ftp et attendre d'etre rappele
+	if (!$GLOBALS['meta']["debut_restauration"]) {
+	// cas de l'appel apres demande de confirmation
+		if ($archive) {
+			$action = _T('info_restauration_sauvegarde', array('archive' => $archive));
+			$commentaire = verifier_version_sauvegarde ($archive);
+		}
+
+		// au tout premier appel, on ne revient pas de debut_admin
+		debut_admin(generer_url_post_ecrire("import_all","archive=$archive"), $action, $commentaire);
+
+		// on est revenu: l'authentification ftp est ok
+		fin_admin($action);
+		// dire qu'on commence
+		ecrire_meta("request_restauration", serialize($_REQUEST));
+		ecrire_meta("debut_restauration", "debut");
+		ecrire_meta("status_restauration", "0");
+		ecrire_metas();
+		// se rappeler pour montrer illico ce qu'on fait 
+		header('Location: ./');
+		exit();
+	}
+
+	// au rappel, on commence (voire on continue)
+	include_spip('inc/import');
+	import_all_continue();
+}
+?>
diff --git a/ecrire/inc/import.php b/ecrire/inc/import.php
index 4181dddca17669e3deb7520312ff36881ab7b00b..b7f5c8ae937bb78ed27a6126b7e8545d490740fb 100644
--- a/ecrire/inc/import.php
+++ b/ecrire/inc/import.php
@@ -90,7 +90,6 @@ function import_debut($f, $gz=false) {
 	return false;
 }
 
-
 //
 // $f = handle fichier
 // $gz = flag utilisation zlib
@@ -103,301 +102,6 @@ function import_debut($f, $gz=false) {
 $tables_trans = array(
 );
 
-function import_objet_1_3($f, $gz=false, $tag_fermant='SPIP', $tables, $phpmyadmin=false) {
-	global $import_ok, $pos, $abs_pos;
-	static $time_javascript;
-
-	global $tables_trans;
-	static $primary_table;
-	static $relation_liste;
-	global $tables_principales;
-	global $tables_auxiliaires;
-
-	$import_ok = false;
-	$b = '';
-	// Lire le type d'objet
-	if (!($table = xml_fetch_tag($f, $b, $gz))) return false;
-	if ($table == ('/'.$tag_fermant)) return !($import_ok = true);
-	#spip_log("import_objet_1_3 : table $table");
-	if (!isset($primary_table[$table]))
-		$primary_table[$table]=primary_index_table($table);
-
-	$primary = $primary_table[$table];
-	$id_objet = 0;
-	$liens = array();
-
-	// Lire les champs de l'objet
-	for (;;) {
-		$b = '';
-		if (!($col = xml_fetch_tag($f, $b, $gz))) return false;
-		if ($col == '/'.$table) break;
-		if (substr($col,0,1) == '/')
-		{ // tag fermant ici : probleme erreur de format
-			spip_log('restauration : table $table tag fermanr $col innatendu');
-		  break;
-		}
-		$value = '';
-		if (!xml_fetch_tag($f, $value, $gz)) return false;
-
-		if ($col != 'maj') {
-			if ($phpmyadmin)
-				$value = str_replace(array('&quot;','&gt;'),array('"','>'),$value);
-			$cols[] = $col;
-			$values[] = spip_abstract_quote($value);
-			if ($col == $primary) $id_objet = $value;
-		}
-	}
-	
-	if (isset($tables_trans[$table])) $table = $tables_trans[$table];
-	if (in_array($table,$tables)){
-
-		#spip_log("import_objet_1_3 : query $query");
-		if (!spip_query("REPLACE $table (" . join(',', $cols) . ') VALUES (' . join(',', $values) . ')')) {
-			echo "--><br><font color='red'><b>"._T('avis_erreur_mysql')."</b></font>\n<font color='black'><tt>".spip_sql_error()."</tt></font>\n<!--";
-			$GLOBALS['erreur_restauration'] = true;
-		}
-	}
-
-	$p = $pos + $abs_pos;
-	// on se contente d'une ecriture en bdd car sinon le temps de backup
-	// est double. Il faut juste faire attention a bien lire_metas()
-	// au debut de la restauration
-	ecrire_meta("status_restauration", "$p");
-	#ecrire_metas(); 
-
-	if (time() - $time_javascript > 3) {	// 3 secondes
-		affiche_progression_javascript($abs_pos,$table);
-		$time_javascript = time();
-	}
-
-	return $import_ok = true;
-}
-
-// pour le support des vieux dump
-function import_objet_1_2($f, $gz=false) {
-	global $import_ok, $pos, $abs_pos;
-	static $time_javascript;
-
-	if (time() - $time_javascript > 3) {	// 3 secondes
-		affiche_progression_javascript($abs_pos);
-		$time_javascript = time();
-	}
-
-	static $tables;
-	if (!$tables) $tables = array(
-		'article' => 'spip_articles',
-		'auteur' => 'spip_auteurs',
-		'breve' => 'spip_breves',
-		'document' => 'spip_documents',
-		'forum' => 'spip_forum',
-		'groupe_mots' => 'spip_groupes_mots',
-		'message' => 'spip_messages',
-		'mot' => 'spip_mots',
-		'petition' => 'spip_petitions',
-		'rubrique' => 'spip_rubriques',
-		'signature' => 'spip_signatures',
-		'syndic' => 'spip_syndic',
-		'syndic_article' => 'spip_syndic_articles',
-		'type_document' => 'spip_types_documents'
-	);
-
-	$import_ok = false;
-	$b = '';
-	// Lire le type d'objet
-	if (!($type = xml_fetch_tag($f, $b, $gz))) return false;
-	if ($type == '/SPIP') return !($import_ok = true);
-	$id = "id_$type";
-	$id_objet = 0;
-
-	// Lire les champs de l'objet
-	for (;;) {
-		$b = '';
-		if (!($col = xml_fetch_tag($f, $b, $gz))) return false;
-		if ($col == '/'.$type) break;
-		$value = '';
-		if (!xml_fetch_tag($f, $value, $gz)) return false;
-		if (substr($col, 0, 5) == 'lien:') {
-			$type_lien = substr($col, 5);
-			$liens[$type_lien][] = '('.$id_objet.','.$value.')';
-		}
-		else if ($col != 'maj') {
-			// tentative de restauration d'une base sauvegardee avec le champ 'images' ; d'experience, ca arrive...
-			// mieux vaut accepter que canner silencieusement...
-			if (($type == 'article') && ($col == 'images'))
-			{
-				if ($value) {		// ne pas afficher de message si on a un champ suppl mais vide
-					echo "--><br><font color='red'><b>"._T('avis_erreur_sauvegarde', array('type' => $type, 'id_objet' => $id_objet))."</b></font>\n<font color='black'>"._T('avis_colonne_inexistante', array('col' => $col));
-					if ($col == 'images') echo _T('info_verifier_image');
-					echo "</font>\n<!--";
-					$GLOBALS['erreur_restauration'] = true;
-				}
-			}
-			else {
-				$cols[] = $col;
-				$values[] = spip_abstract_quote($value);
-				if ($col == $id) $id_objet = $value;
-			}
-		}
-	}
-
-	$table = $tables[$type];
-	if (!spip_query("REPLACE $table (" . join(',', $cols) . ') VALUES (' . join(',', $values) . ')')) {
-		echo "--><br><font color='red'><b>"._T('avis_erreur_mysql')."</b></font>\n<font color='black'><tt>".spip_sql_error()."</tt></font>\n<!--";
-		$GLOBALS['erreur_restauration'] = true;
-	}
-
-	if ($type == 'article') {
-		spip_query("DELETE FROM spip_auteurs_articles WHERE id_article=$id_objet");
-		spip_query("DELETE FROM spip_documents_articles WHERE id_article=$id_objet");
-	}
-	else if ($type == 'rubrique') {
-		spip_query("DELETE FROM spip_auteurs_rubriques WHERE id_rubrique=$id_objet");
-		spip_query("DELETE FROM spip_documents_rubriques WHERE id_rubrique=$id_objet");
-	}
-	else if ($type == 'breve') {
-		spip_query("DELETE FROM spip_documents_breves WHERE id_breve=$id_objet");
-	}
-	else if ($type == 'mot') {
-		spip_query("DELETE FROM spip_mots_articles WHERE id_mot=$id_objet");
-		spip_query("DELETE FROM spip_mots_breves WHERE id_mot=$id_objet");
-		spip_query("DELETE FROM spip_mots_forum WHERE id_mot=$id_objet");
-		spip_query("DELETE FROM spip_mots_rubriques WHERE id_mot=$id_objet");
-		spip_query("DELETE FROM spip_mots_syndic WHERE id_mot=$id_objet");
-	}
-	else if ($type == 'auteur') {
-		spip_query("DELETE FROM spip_auteurs_rubriques WHERE id_auteur=$id_objet");
-	}
-	else if ($type == 'message') {
-		spip_query("DELETE FROM spip_auteurs_messages WHERE id_message=$id_objet");
-	}
-	if ($liens) {
-		reset($liens);
-		while (list($type_lien, $t) = each($liens)) {
-			if ($type == 'auteur' OR $type == 'mot' OR $type == 'document')
-				if ($type_lien == 'syndic' OR $type_lien == 'forum') $table_lien = 'spip_'.$type.'s_'.$type_lien;
-				else $table_lien = 'spip_'.$type.'s_'.$type_lien.'s';
-			else
-				$table_lien = 'spip_'.$type_lien.'s_'.$type.'s';
-			spip_abstract_insert($table_lien, "($id, id_$type_lien)", join(',', $t));
-		}
-	}
-
-	$p = $pos + $abs_pos;
-	ecrire_meta("status_restauration", "$p");
-
-	return $import_ok = true;
-}
-
-
-// pour le support des vieux dump
-// pff ou vous l'avez trouve ce dump ?
-function import_objet_0_0($f, $gz=false) {
-	global $import_ok, $pos, $abs_pos;
-
-	$import_ok = false;
-	$b = '';
-	if (!($type = xml_fetch_tag($f, $b, $gz))) return false;
-	if ($type == '/SPIP') return !($import_ok = true);
-	$is_art = ($type == 'article');
-	$is_mot = ($type == 'mot');
-	for (;;) {
-		$b = '';
-		if (!($col = xml_fetch_tag($f, $b, $gz))) return false;
-		if ($col == ("/$type")) break;
-		$value = '';
-		if (!xml_fetch_tag($f, $value, $gz)) return false;
-		if ($is_art AND $col == 'id_auteur') {
-			$auteurs[] = $value;
-		}
-		else if ($is_mot AND $col == 'id_article') {
-			$articles[] = $value;
-		}
-		else if ($is_mot AND $col == 'id_breve') {
-			$breves[] = $value;
-		}
-		else if ($is_mot AND $col == 'id_forum') {
-			$forums[] = $value;
-		}
-		else if ($is_mot AND $col == 'id_rubrique') {
-			$rubriques[] = $value;
-		}
-		else if ($is_mot AND $col == 'id_syndic') {
-			$syndics[] = $value;
-		}
-		else if ($col != 'maj') {
-			$cols[] = $col;
-			$values[] = spip_abstract_quote($value);
-			if ($is_art && ($col == 'id_article')) $id_article = $value;
-			if ($is_mot && ($col == 'id_mot')) $id_mot = $value;
-		}
-	}
-
-	$table = "spip_$type";
-	if ($type != 'forum' AND $type != 'syndic') $table .= 's';
-	spip_query("REPLACE $table (" . join(",", $cols) . ") VALUES (" . join(",", $values) . ")");
-
-	if ($is_art && $id_article) {
-		spip_query("DELETE FROM spip_auteurs_articles WHERE id_article=$id_article");
-		if ($auteurs) {
-			reset ($auteurs);
-			while (list(, $auteur) = each($auteurs)) {
-			  spip_abstract_insert("spip_auteurs_articles", "(id_auteur, id_article)", "($auteur, $id_article)");
-			}
-		}
-	}
-	if ($is_mot && $id_mot) {
-		spip_query("DELETE FROM spip_mots_articles WHERE id_mot=$id_mot");
-		spip_query("DELETE FROM spip_mots_breves WHERE id_mot=$id_mot");
-		spip_query("DELETE FROM spip_mots_forum WHERE id_mot=$id_mot");
-		spip_query("DELETE FROM spip_mots_rubriques WHERE id_mot=$id_mot");
-		spip_query("DELETE FROM spip_mots_syndic WHERE id_mot=$id_mot");
-		if ($articles) {
-			reset ($articles);
-			while (list(, $article) = each($articles)) {
-
-				spip_abstract_insert("spip_mots_articles", "(id_mot, id_article)", "($id_mot, $article)");
-			}
-		}
-		if ($breves) {
-			reset ($breves);
-			while (list(, $breve) = each($breves)) {
-
-				spip_abstract_insert("spip_mots_breves", "(id_mot, id_breve)", "($id_mot, $breve)");
-			}
-		}
-		if ($forums) {
-			reset ($forums);
-			while (list(, $forum) = each($forums)) {
-
-				spip_abstract_insert("spip_mots_forum", "(id_mot, id_forum)", "($id_mot, $forum)");
-			}
-		}
-		if ($rubriques) {
-			reset ($rubriques);
-			while (list(, $rubrique) = each($rubriques)) {
-
-				spip_abstract_insert("spip_mots_rubriques", "(id_mot, id_rubrique)", "($id_mot, $id_rubrique)");
-			}
-		}
-		if ($syndics) {
-			reset ($syndics);
-			while (list(, $syndic) = each($syndics)) {
-
-				spip_abstract_insert("spip_mots_syndic", "(id_mot, id_syndic)", "($id_mot, $syndic)");
-			}
-		}
-	}
-
-	$p = $pos + $abs_pos;
-	ecrire_meta("status_restauration", "$p");
-
-	return $import_ok = true;
-}
-
-function import_objet($f, $gz = false) {
-	return import_objet_1_2($f, $gz);
-}
-
 function import_fin() {
 	// Effacer l'ancien acces admin
 	spip_query("DELETE FROM spip_auteurs WHERE id_auteur=0");
@@ -430,104 +134,99 @@ function import_abandon() {
 	ecrire_metas();
 }
 
-function import_tables($f, $tables, $gz=false) {
-	global $IMPORT_tables_noerase;
-	global $import_ok;
-	global $auth_htaccess;
-	global $connect_id_auteur;
-	$_fseek = ($gz) ? gzseek : fseek;
+function import_init_tables()
+{
+  global $IMPORT_tables_noerase, $connect_id_auteur;
+	// grand menage
+	// on vide toutes les tables dont la restauration est demandee
+	$tables = import_table_choix();
+	foreach($tables as $table){
+
+		if (($table!='spip_auteurs')&&(!in_array($table,$IMPORT_tables_noerase)))
+			spip_query("DELETE FROM $table");
+	}
 
-	$s = spip_query("SELECT UNIX_TIMESTAMP(maj) AS d FROM spip_meta WHERE nom='debut_restauration'");
-	list($my_date) = spip_fetch_array($s);
-	if (!$my_date) return false;
+	// Bidouille pour garder l'acces admin actuel pendant toute la restauration
+	spip_query("UPDATE spip_auteurs SET id_auteur=0 WHERE id_auteur=$connect_id_auteur");
+	spip_query("DELETE FROM spip_auteurs WHERE id_auteur!=0");
 
-	$my_pos = 0;
-	if (isset($GLOBALS['meta']["status_restauration"]))
-		$my_pos = $GLOBALS['meta']["status_restauration"];
+	return $tables;
+}
 
+function import_tables($f, $gz=false) {
+	global $import_ok, $my_pos;
+	static $time_javascript;
+
+	list($my_date) = spip_fetch_array(spip_query("SELECT UNIX_TIMESTAMP(maj) AS d FROM spip_meta WHERE nom='debut_restauration'"));
+
+	if (!$my_date) return false;
+
+	$my_pos = (!isset($GLOBALS['meta']["status_restauration"])) ? 0 :
+		$GLOBALS['meta']["status_restauration"];
 	if ($my_pos==0) {
 		// Debut de l'importation
-		ecrire_meta('charset_restauration', 'iso-8859-1');
-		if (!($r = import_debut($f, $gz))) {
-			ecrire_meta("erreur", _T('avis_archive_incorrect'));
-			return false;
+		$fimport = false;
+		if ($r = import_debut($f, $gz)) {
+// tag ouvrant :
+// 'SPIP' pour un dump xml spip, nom de la base source pour un dump phpmyadmin
+			$tag_archive = $r[0];
+			$version_archive = $r[1]['version_archive'];
+			$fimport = import_charge_version($version_archive);
 		}
-
-		// grand menage
-		// on vide toutes les tables dont la restauration est demandee
-		foreach($tables as $table){
-			$name = preg_replace("{^spip_}","",$table);
-			if (($table!='spip_auteurs')&&(!in_array($table,$IMPORT_tables_noerase))){
-				spip_query("DELETE FROM $table");
-			}
+		// Normalement c'est controle par import_all auparavant
+		if (!$fimport) {
+			return _T('avis_archive_incorrect');
 		}
 
-		if (in_array("spip_auteurs",$tables)){
-			// Bidouille pour garder l'acces admin actuel pendant toute la restauration
-			spip_query("UPDATE spip_auteurs SET id_auteur=0 WHERE id_auteur=$connect_id_auteur");
-			spip_query("DELETE FROM spip_auteurs WHERE id_auteur!=0");
-		}
-		// tag ouvrant :
-		// 'SPIP' pour un dump xml spip, nom de la base source pour un dump phpmyadmin
-		$tag_archive = $r[0];
-		$version_archive = $r[1]['version_archive'];
+		ecrire_meta('charset_restauration', 'iso-8859-1');
 		ecrire_meta('version_archive_restauration', $version_archive);
 		ecrire_meta('tag_archive_restauration', $tag_archive);
-		#ecrire_metas();
-
-	}
-	else {
+		ecrire_metas();
+	} else {
 		// Reprise de l'importation
+		$_fseek = ($gz) ? gzseek : fseek;
 		$_fseek($f, $my_pos);
 		$version_archive = $GLOBALS['meta']['version_archive_restauration'];
 		$tag_archive = $GLOBALS['meta']['tag_archive_restauration'];
+		$fimport = import_charge_version($version_archivee);
+		$tables = import_table_choix();
 	}
 
-	// Restauration des entrees du fichier
-	if (preg_match("{^phpmyadmin::}is",$version_archive)){
-		#spip_log("restauration phpmyadmin : version $version_archive tag $tag_archive");
-		while (import_objet_1_3($f, $gz, $tag_archive, $tables, true));
-	}
-	else{
-		switch ($version_archive) {
-			case '1.3':
-				while (import_objet_1_3($f, $gz, $tag_archive, $tables));
-				break;
-			case '1.2':
-				while (import_objet_1_2($f, $gz));
-				break;
-			default:
-				while (import_objet_0_0($f, $gz));
-				break;
+	while ($table = $fimport($f, $gz)) {
+		$p = $pos + $abs_pos;
+	// Pas d'ecriture SQL car sinon le temps double.
+	// Il faut juste faire attention a bien lire_metas()
+	// au debut de la restauration
+		ecrire_meta("status_restauration", "$p");
+
+		if (time() - $time_javascript > 3) {	// 3 secondes
+			affiche_progression_javascript($abs_pos,$table);
+			$time_javascript = time();
 		}
-	}
-	if (!$import_ok) {
-		ecrire_meta("erreur", _T('avis_archive_invalide'));
-		return false;
+
+		$my_pos = true;
 	}
 
+	if (!$import_ok) return  _T('avis_archive_invalide');
+
 	// Mise a jour du fichier htpasswd
 
 	ecrire_acces();
 
-	// Destruction des entrees non restaurees
-
-	detruit_non_restaurees($mydate, $tables);
+	detruit_restaurateur();
 
 	import_fin();
 
 	affiche_progression_javascript('100 %');
 
-	return true;
+	return false;
 }
 
 // Destruction des entrees non restaurees
 
-function detruit_non_restaurees($mydate, $tables)
+function detruit_restaurateur()
 {
 	spip_query("DELETE FROM spip_auteurs WHERE id_auteur=0");
-	//foreach ($tables as $v) 
-	//  spip_query("DELETE FROM $v WHERE UNIX_TIMESTAMP(maj) < $my_date");
 }
 
 
@@ -548,7 +247,7 @@ function affiche_progression_javascript($abs_pos,$table="") {
 		echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".self()."\";',0);</script>\n");
 	}
 	else {
-		if ($table!="")
+		if (trim($table))
 			echo "document.progression.recharge.value='$table';\n";
 		if (! $affiche_progression_pourcent)
 			$taille = ereg_replace("&nbsp;", " ", taille_en_octets($abs_pos));
@@ -561,10 +260,71 @@ function affiche_progression_javascript($abs_pos,$table="") {
 	ob_flush();flush();
 }
 
-function import_all_continue($tables)
+
+function import_table_choix()
 {
-	global $meta, $flag_gz, $buf, $pos, $abs_pos;
-  global $affiche_progression_pourcent;
+	// construction de la liste des tables pour le dump :
+	// toutes les tables principales
+	// + toutes les tables auxiliaires hors relations
+	// + les tables relations dont les deux tables liees sont dans la liste
+	$tables_for_dump = array();
+	$tables_pointees = array();
+	global $IMPORT_tables_noimport;
+	global $tables_principales;
+	global $tables_auxiliaires;
+	global $table_des_tables;
+	global $tables_jointures;
+
+	// on construit un index des tables de liens
+	// pour les ajouter SI les deux tables qu'ils connectent sont sauvegardees
+	$tables_for_link = array();
+	foreach($tables_jointures as $table=>$liste_relations)
+		if (is_array($liste_relations))
+		{
+			$nom = $table;
+			if (!isset($tables_auxiliaires[$nom])&&!isset($tables_principales[$nom]))
+				$nom = "spip_$table";
+			if (isset($tables_auxiliaires[$nom])||isset($tables_principales[$nom])){
+				foreach($liste_relations as $link_table){
+					if (isset($tables_auxiliaires[$link_table])/*||isset($tables_principales[$link_table])*/){
+						$tables_for_link[$link_table][] = $nom;
+					}
+					else if (isset($tables_auxiliaires["spip_$link_table"])/*||isset($tables_principales["spip_$link_table"])*/){
+						$tables_for_link["spip_$link_table"][] = $nom;
+					}
+				}
+			}
+		}
+	
+	$liste_tables = array_merge(array_keys($tables_principales),array_keys($tables_auxiliaires));
+	foreach($liste_tables as $table){
+		$name = preg_replace("{^spip_}","",$table);
+		if (		!isset($tables_pointees[$table]) 
+				&&	!in_array($table,$IMPORT_tables_noimport)
+				&&	!isset($tables_for_link[$table])){
+			$tables_for_dump[] = $table;
+			$tables_pointees[$table] = 1;
+		}
+	}
+	foreach ($tables_for_link as $link_table =>$liste){
+		$connecte = true;
+		foreach($liste as $connect_table)
+			if (!in_array($connect_table,$tables_for_dump))
+				$connecte = false;
+		if ($connecte)
+			# on ajoute les liaisons en premier
+			# si une restauration est interrompue, cela se verra mieux si il manque des objets
+			# que des liens
+			array_unshift($tables_for_dump,$link_table);
+	}
+	return $tables_for_dump;
+}	
+
+
+function import_all_continue()
+{
+  global $meta, $flag_gz, $buf, $pos, $abs_pos, $my_pos;
+	global $affiche_progression_pourcent;
 	ini_set("zlib.output_compression","0"); // pour permettre l'affichage au fur et a mesure
 	// utiliser une version fraiche des metas (ie pas le cache)
 	include_spip('inc/meta');
@@ -633,8 +393,11 @@ function import_all_continue($tables)
 	$f = $_fopen($archive, "rb");
 	$pos = 0;
 	$buf = "";
-	if (!import_tables($f, $tables, $gz))
+	$r = import_tables($f, $gz);
+	if ($r) {
+		spip_log("Erreur: $r");
 		import_abandon();
+	}
 	else	import_fin();
 }
 
diff --git a/ecrire/inc/import_0_0.php b/ecrire/inc/import_0_0.php
new file mode 100644
index 0000000000000000000000000000000000000000..152ecf68bf1a093b83e26133b5ae383e0695e78a
--- /dev/null
+++ b/ecrire/inc/import_0_0.php
@@ -0,0 +1,119 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2006                                                *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
+ *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+if (!defined("_ECRIRE_INC_VERSION")) return;
+
+// pour le support des vieux dump
+// pff ou vous l'avez trouve ce dump ?
+function inc_import_0_0_dist($f, $gz=false) {
+	global $import_ok, $pos, $abs_pos, $my_pos;
+
+	// detruire les tables a restaurer
+	$tables = (!$my_pos) ? import_init_tables() : import_table_choix();
+
+	$import_ok = false;
+	$b = '';
+	if (!($type = xml_fetch_tag($f, $b, $gz))) return false;
+	if ($type == '/SPIP') return !($import_ok = true);
+	$is_art = ($type == 'article');
+	$is_mot = ($type == 'mot');
+	for (;;) {
+		$b = '';
+		if (!($col = xml_fetch_tag($f, $b, $gz))) return false;
+		if ($col == ("/$type")) break;
+		$value = '';
+		if (!xml_fetch_tag($f, $value, $gz)) return false;
+		if ($is_art AND $col == 'id_auteur') {
+			$auteurs[] = $value;
+		}
+		else if ($is_mot AND $col == 'id_article') {
+			$articles[] = $value;
+		}
+		else if ($is_mot AND $col == 'id_breve') {
+			$breves[] = $value;
+		}
+		else if ($is_mot AND $col == 'id_forum') {
+			$forums[] = $value;
+		}
+		else if ($is_mot AND $col == 'id_rubrique') {
+			$rubriques[] = $value;
+		}
+		else if ($is_mot AND $col == 'id_syndic') {
+			$syndics[] = $value;
+		}
+		else if ($col != 'maj') {
+			$cols[] = $col;
+			$values[] = spip_abstract_quote($value);
+			if ($is_art && ($col == 'id_article')) $id_article = $value;
+			if ($is_mot && ($col == 'id_mot')) $id_mot = $value;
+		}
+	}
+
+	$table = "spip_$type";
+	if ($type != 'forum' AND $type != 'syndic') $table .= 's';
+	spip_query("REPLACE $table (" . join(",", $cols) . ") VALUES (" . join(",", $values) . ")");
+
+	if ($is_art && $id_article) {
+		spip_query("DELETE FROM spip_auteurs_articles WHERE id_article=$id_article");
+		if ($auteurs) {
+			reset ($auteurs);
+			while (list(, $auteur) = each($auteurs)) {
+			  spip_abstract_insert("spip_auteurs_articles", "(id_auteur, id_article)", "($auteur, $id_article)");
+			}
+		}
+	}
+	if ($is_mot && $id_mot) {
+		spip_query("DELETE FROM spip_mots_articles WHERE id_mot=$id_mot");
+		spip_query("DELETE FROM spip_mots_breves WHERE id_mot=$id_mot");
+		spip_query("DELETE FROM spip_mots_forum WHERE id_mot=$id_mot");
+		spip_query("DELETE FROM spip_mots_rubriques WHERE id_mot=$id_mot");
+		spip_query("DELETE FROM spip_mots_syndic WHERE id_mot=$id_mot");
+		if ($articles) {
+			reset ($articles);
+			while (list(, $article) = each($articles)) {
+
+				spip_abstract_insert("spip_mots_articles", "(id_mot, id_article)", "($id_mot, $article)");
+			}
+		}
+		if ($breves) {
+			reset ($breves);
+			while (list(, $breve) = each($breves)) {
+
+				spip_abstract_insert("spip_mots_breves", "(id_mot, id_breve)", "($id_mot, $breve)");
+			}
+		}
+		if ($forums) {
+			reset ($forums);
+			while (list(, $forum) = each($forums)) {
+
+				spip_abstract_insert("spip_mots_forum", "(id_mot, id_forum)", "($id_mot, $forum)");
+			}
+		}
+		if ($rubriques) {
+			reset ($rubriques);
+			while (list(, $rubrique) = each($rubriques)) {
+
+				spip_abstract_insert("spip_mots_rubriques", "(id_mot, id_rubrique)", "($id_mot, $id_rubrique)");
+			}
+		}
+		if ($syndics) {
+			reset ($syndics);
+			while (list(, $syndic) = each($syndics)) {
+
+				spip_abstract_insert("spip_mots_syndic", "(id_mot, id_syndic)", "($id_mot, $syndic)");
+			}
+		}
+	}
+
+	return $import_ok = "      ";
+}
+?>
diff --git a/ecrire/inc/import_1_2.php b/ecrire/inc/import_1_2.php
new file mode 100644
index 0000000000000000000000000000000000000000..378c4cae31e45cf9a082c09717f3e4fbe72b1e59
--- /dev/null
+++ b/ecrire/inc/import_1_2.php
@@ -0,0 +1,126 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2006                                                *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
+ *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+if (!defined("_ECRIRE_INC_VERSION")) return;
+
+
+// pour le support des vieux dump
+function inc_import_1_2_dist($f, $gz=false) {
+	global $import_ok, $pos, $abs_pos;
+
+	// detruire les tables a restaurer
+	if (!$abs_pos) import_init_tables();
+
+	static $tables;
+	if (!$tables) $tables = array(
+		'article' => 'spip_articles',
+		'auteur' => 'spip_auteurs',
+		'breve' => 'spip_breves',
+		'document' => 'spip_documents',
+		'forum' => 'spip_forum',
+		'groupe_mots' => 'spip_groupes_mots',
+		'message' => 'spip_messages',
+		'mot' => 'spip_mots',
+		'petition' => 'spip_petitions',
+		'rubrique' => 'spip_rubriques',
+		'signature' => 'spip_signatures',
+		'syndic' => 'spip_syndic',
+		'syndic_article' => 'spip_syndic_articles',
+		'type_document' => 'spip_types_documents'
+	);
+
+	$import_ok = false;
+	$b = '';
+	// Lire le type d'objet
+	if (!($type = xml_fetch_tag($f, $b, $gz))) return false;
+	if ($type == '/SPIP') return !($import_ok = true);
+	$id = "id_$type";
+	$id_objet = 0;
+
+	// Lire les champs de l'objet
+	for (;;) {
+		$b = '';
+		if (!($col = xml_fetch_tag($f, $b, $gz))) return false;
+		if ($col == '/'.$type) break;
+		$value = '';
+		if (!xml_fetch_tag($f, $value, $gz)) return false;
+		if (substr($col, 0, 5) == 'lien:') {
+			$type_lien = substr($col, 5);
+			$liens[$type_lien][] = '('.$id_objet.','.$value.')';
+		}
+		else if ($col != 'maj') {
+			// tentative de restauration d'une base sauvegardee avec le champ 'images' ; d'experience, ca arrive...
+			// mieux vaut accepter que canner silencieusement...
+			if (($type == 'article') && ($col == 'images'))
+			{
+				if ($value) {		// ne pas afficher de message si on a un champ suppl mais vide
+					echo "--><br><font color='red'><b>"._T('avis_erreur_sauvegarde', array('type' => $type, 'id_objet' => $id_objet))."</b></font>\n<font color='black'>"._T('avis_colonne_inexistante', array('col' => $col));
+					if ($col == 'images') echo _T('info_verifier_image');
+					echo "</font>\n<!--";
+					$GLOBALS['erreur_restauration'] = true;
+				}
+			}
+			else {
+				$cols[] = $col;
+				$values[] = spip_abstract_quote($value);
+				if ($col == $id) $id_objet = $value;
+			}
+		}
+	}
+
+	$table = isset($tables[$type]) ? $tables[$type] : $type;
+	
+	if (!spip_query("REPLACE $table (" . join(',', $cols) . ') VALUES (' . join(',', $values) . ')')) {
+		echo "--><br><font color='red'><b>"._T('avis_erreur_mysql')."</b></font>\n<font color='black'><tt>".spip_sql_error()."</tt></font>\n<!--";
+		$GLOBALS['erreur_restauration'] = true;
+	}
+
+	if ($type == 'article') {
+		spip_query("DELETE FROM spip_auteurs_articles WHERE id_article=$id_objet");
+		spip_query("DELETE FROM spip_documents_articles WHERE id_article=$id_objet");
+	}
+	else if ($type == 'rubrique') {
+		spip_query("DELETE FROM spip_auteurs_rubriques WHERE id_rubrique=$id_objet");
+		spip_query("DELETE FROM spip_documents_rubriques WHERE id_rubrique=$id_objet");
+	}
+	else if ($type == 'breve') {
+		spip_query("DELETE FROM spip_documents_breves WHERE id_breve=$id_objet");
+	}
+	else if ($type == 'mot') {
+		spip_query("DELETE FROM spip_mots_articles WHERE id_mot=$id_objet");
+		spip_query("DELETE FROM spip_mots_breves WHERE id_mot=$id_objet");
+		spip_query("DELETE FROM spip_mots_forum WHERE id_mot=$id_objet");
+		spip_query("DELETE FROM spip_mots_rubriques WHERE id_mot=$id_objet");
+		spip_query("DELETE FROM spip_mots_syndic WHERE id_mot=$id_objet");
+	}
+	else if ($type == 'auteur') {
+		spip_query("DELETE FROM spip_auteurs_rubriques WHERE id_auteur=$id_objet");
+	}
+	else if ($type == 'message') {
+		spip_query("DELETE FROM spip_auteurs_messages WHERE id_message=$id_objet");
+	}
+	if ($liens) {
+		reset($liens);
+		while (list($type_lien, $t) = each($liens)) {
+			if ($type == 'auteur' OR $type == 'mot' OR $type == 'document')
+				if ($type_lien == 'syndic' OR $type_lien == 'forum') $table_lien = 'spip_'.$type.'s_'.$type_lien;
+				else $table_lien = 'spip_'.$type.'s_'.$type_lien.'s';
+			else
+				$table_lien = 'spip_'.$type_lien.'s_'.$type.'s';
+			spip_abstract_insert($table_lien, "($id, id_$type_lien)", join(',', $t));
+		}
+	}
+
+	return $import_ok = "    ";
+}
+
+?>
diff --git a/ecrire/inc/import_1_3.php b/ecrire/inc/import_1_3.php
new file mode 100644
index 0000000000000000000000000000000000000000..ea2b7aef603e7406050ee0f649cb3d39fa2ae46a
--- /dev/null
+++ b/ecrire/inc/import_1_3.php
@@ -0,0 +1,82 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2006                                                *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
+ *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+if (!defined("_ECRIRE_INC_VERSION")) return;
+
+function inc_import_1_3_dist($f, $gz=false) {
+  global $import_ok, $pos, $abs_pos, $my_pos;
+	static $tables = '';
+
+	global $tables_trans;
+	static $primary_table;
+	static $relation_liste;
+	global $tables_principales;
+	global $tables_auxiliaires;
+
+	// au premier appel, detruire les tables a restaurer
+
+	if (!$tables)
+		$tables = (!$my_pos) ? import_init_tables() : import_table_choix();
+
+	$phpmyadmin = preg_match("{^phpmyadmin::}is", $GLOBALS['meta']['version_archive_restauration']);
+	$tag_fermant = $GLOBALS['meta']['tag_archive_restauration'];
+	$import_ok = false;
+
+	$b = '';
+	// Lire le type d'objet
+	if (!($table = xml_fetch_tag($f, $b, $gz))) return false;
+	if ($table == ('/'.$tag_fermant)) return !($import_ok = true);
+	#spip_log("import_objet_1_3 : table $table");
+	if (!isset($primary_table[$table]))
+		$primary_table[$table]=primary_index_table($table);
+
+	$primary = $primary_table[$table];
+	$id_objet = 0;
+	$liens = array();
+
+	// Lire les champs de l'objet
+	for (;;) {
+		$b = '';
+		if (!($col = xml_fetch_tag($f, $b, $gz))) return false;
+		if ($col == '/'.$table) break;
+		if (substr($col,0,1) == '/')
+		{ // tag fermant ici : probleme erreur de format
+			spip_log('restauration : table $table tag fermanr $col innatendu');
+		  break;
+		}
+		$value = '';
+		if (!xml_fetch_tag($f, $value, $gz)) return false;
+
+		if ($col != 'maj') {
+			if ($phpmyadmin)
+				$value = str_replace(array('&quot;','&gt;'),array('"','>'),$value);
+			$cols[] = $col;
+			$values[] = spip_abstract_quote($value);
+			if ($col == $primary) $id_objet = $value;
+		}
+	}
+	
+	if (isset($tables_trans[$table])) $table = $tables_trans[$table];
+#	spip_log("import_objet_1_3 : $table " . in_array($table,$tables));
+	if (in_array($table,$tables)){
+
+
+		if (!spip_query("REPLACE $table (" . join(',', $cols) . ') VALUES (' . join(',', $values) . ')')) {
+			echo "--><br><font color='red'><b>"._T('avis_erreur_mysql')."</b></font>\n<font color='black'><tt>".spip_sql_error()."</tt></font>\n<!--";
+			$GLOBALS['erreur_restauration'] = true;
+		}
+	}
+
+
+	return $import_ok = " $table ";
+}
+?>
diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php
index 468431df38d62547397c67db4b0e8ca27c315484..b2f137471880b51e8a7f7b010770f9cddcbb7585 100644
--- a/ecrire/inc_version.php
+++ b/ecrire/inc_version.php
@@ -204,6 +204,7 @@ $table_des_tables = array();
 $tables_auxiliaires = array();
 $table_primary = array();
 $table_date = array();
+$tables_jointures = array();
 $tables_des_serveurs_sql['localhost'] =  &$tables_principales;