From 0ef9fa354a3af7e7f808fc931997d3fecbb3e141 Mon Sep 17 00:00:00 2001
From: Cerdic <cedric@yterium.com>
Date: Mon, 8 May 2006 08:57:30 +0000
Subject: [PATCH] =?UTF-8?q?Integration=20de=20super-dump=20dans=20le=20cor?=
 =?UTF-8?q?e.=20L'exercice=20a=20le=20merite=20de=20montrer=20qu'un=20plug?=
 =?UTF-8?q?in=20qui=20surcharge=20c'est=20un=20mini-fork=20de=20fait,=20et?=
 =?UTF-8?q?=20vaut=20mieux=20avoir=20l'esprit=20frais=20pour=20le=20reinte?=
 =?UTF-8?q?grer=20correctement=20...=20J'espere=20ne=20pas=20avoir=20casse?=
 =?UTF-8?q?=20les=20petites=20fonctionalit=C3=A9s=20ajoutees=20dernieremen?=
 =?UTF-8?q?t=20dans=20ce=20coin=20du=20core.=20Il=20y=20a=20des=20chaines?=
 =?UTF-8?q?=20non=20traduites=20dans=20ce=20code=20:-(?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ecrire/exec/export_all.php | 506 ++++++++++++++++++++++---------------
 ecrire/exec/import_all.php | 241 +++++++++++-------
 ecrire/inc/import.php      | 475 ++++++++++++++++++++++------------
 3 files changed, 768 insertions(+), 454 deletions(-)

diff --git a/ecrire/exec/export_all.php b/ecrire/exec/export_all.php
index 6f841a1a80..6c8a1ac819 100644
--- a/ecrire/exec/export_all.php
+++ b/ecrire/exec/export_all.php
@@ -11,250 +11,352 @@
 \***************************************************************************/
 
 if (!defined("_ECRIRE_INC_VERSION")) return;
+ini_set("zlib.output_compression","0"); // pour permettre l'affichage au fur et a mesure
 
-$GLOBALS['version_archive'] = '1.2';
-
-$GLOBALS['sauvegardes'] = array(
-	'rubrique' => _T('info_sauvegarde_rubriques'),
-	'auteur' => _T('info_sauvegarde_auteurs'),
-	'article' => _T('info_sauvegarde_articles'),
-	'type_document' => _T('info_sauvegarde_type_documents'),
-	'document' => _T('info_sauvegarde_documents'),
-	'mot' => _T('info_sauvegarde_mots_cles'),
-	'groupe_mots' => _T('info_sauvegarde_groupe_mots'),
-	'breve' => _T('info_sauvegarde_breves'),
-	'forum' => _T('info_sauvegarde_forums'),
-	'petition' => _T('info_sauvegarde_petitions'),
-	'signature' => _T('info_sauvegarde_signatures'),
-	'syndic' => _T('info_sauvegarde_sites_references'),
-	'syndic_article' => _T('info_sauvegarde_articles_sites_ref')
-	);
+$GLOBALS['version_archive'] = '1.3';
 
+#include_spip('exec/export'); // celui dans le meme repertoire, pas celui de ecrire
 include_spip('inc/admin');
+include_spip('base/serial');
+include_spip('base/auxiliaires');
+include_spip('inc/indexation'); // pour la fonction primary_index_table 
+include_spip('inc/flock');
+
+// 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); 
+}
+
+// par defaut tout est exporte sauf les tables ci-dessous
+// possibiliter de definir cela tables via la meta
+global $EXPORT_tables_noexport;
+if (isset($GLOBALS['meta']['EXPORT_tables_noexport']))
+	$EXPORT_tables_noexport = unserialize($GLOBALS['meta']['EXPORT_tables_noexport']);
+else{
+	include_spip('inc/meta');
+	$EXPORT_tables_noexport[]='spip_ajax_fonc';
+	$EXPORT_tables_noexport[]='spip_caches';
+	$EXPORT_tables_noexport[]='spip_meta';
+	$EXPORT_tables_noexport[]='spip_index';
+	$EXPORT_tables_noexport[]='spip_index_dico';
+	$EXPORT_tables_noexport[]='spip_referers';
+	$EXPORT_tables_noexport[]='spip_referers_articles';
+	$EXPORT_tables_noexport[]='spip_visites';
+	$EXPORT_tables_noexport[]='spip_visites_articles';
+	$EXPORT_tables_noexport[]='spip_ortho_cache';
+	$EXPORT_tables_noexport[]='spip_ortho_dico';
+	ecrire_meta('EXPORT_tables_noexport',serialize($EXPORT_tables_noexport));
+	ecrire_metas();
+}
 
 function exec_export_all_dist()
 {
-  global $archive, $debut_limit, $etape, $gz, $spip_version, $spip_version_affichee, $version_archive, $sauvegardes;
+  global $archive, $debut_limit, $etape, $gz, $spip_version, $spip_version_affichee, $version_archive;
 
-if (!$archive) {
-	if ($gz) $archive = "dump.xml.gz";
-	else $archive = "dump.xml";
-}
+	if (!$archive) {
+		if ($gz) $archive = "dump.xml.gz";
+		else $archive = "dump.xml";
+	}
+	$partfile = $archive.".part";
+	
+	// utiliser une version fraiche des metas (ie pas le cache)
+	include_spip('inc/meta');
+	lire_metas();
 
-$action = _T('info_exportation_base', array('archive' => $archive));
+	$action = _T('info_exportation_base', array('archive' => $archive));
+	if (!isset($GLOBALS['meta']["status_dump"])){
+	  $start = true;
+	}
+	else{
+		$status_dump = explode("::",$GLOBALS['meta']["status_dump"]);
+		if (($status_dump[0]!=$gz)||($status_dump[1]!=$archive))
+			$start = true;
+		else
+			$start = ($status_dump[2]==0)&&($status_dump[3]==0);
+	}
+	if ($start){
+	  // phase admin en debut de dump
+	  // apres, on continue sans verif : 
+		// sur la duree du dump cela genere de demandes recurrentes d'authent
+		debut_admin(generer_url_post_ecrire("export_all","archive=$archive&gz=$gz"), $action);
+		fin_admin($action);
+	}
 
-debut_admin(generer_url_post_ecrire("export_all","archive=$archive&gz=$gz"), $action);
+	install_debut_html(_T('info_sauvegarde'));
+
+	//if (!$etape) echo "<p><blockquote><font size=2>"._T('info_sauvegarde_echouee')." <a href='" . generer_url_ecrire("export_all","reinstall=non&etape=1&gz=$gz") . "'>"._T('info_procedez_par_etape')."</a></font></blockquote><p>";
+
+	$_fputs = ($gz) ? gzputs : fputs;
+
+	if ($start){
+		$status_dump = "$gz::$archive::0::0";
+		ecrire_meta("status_dump", "$status_dump");
+		$status_dump = explode("::",$status_dump);
+		ecrire_metas();
+		// un ramassage preventif au cas ou le dernier dump n'aurait pas ete acheve correctement
+		#ramasse_parties(_DIR_SESSIONS . $archive, $gz, _DIR_SESSIONS . $partfile);
+		// et au cas ou (le rammase_parties s'arrete si un fichier de la serie est absent)
+		// on ratisse large avec un preg_files
+		$liste = preg_files(_DIR_SESSIONS, "$archive\.part\.[0-9]*");
+		foreach($liste as $dummy)
+			@unlink($dummy);
+
+		echo _T("info_sauvegarde")."<br/>";
+		$f = ($gz) ? gzopen(_DIR_SESSIONS . $archive, "wb") : fopen(_DIR_SESSIONS . $archive, "wb");
+		if (!$f) {
+			echo _T('avis_erreur_sauvegarde', array('type'=>'.', 'id_objet'=>'. .'));
+			exit;
+		}
 
- $debut_limit = intval($debut_limit);
+		$_fputs($f, "<"."?xml version=\"1.0\" encoding=\"".$GLOBALS['meta']['charset']."\"?".">\n<SPIP version=\"$spip_version_affichee\" version_base=\"$spip_version\" version_archive=\"$version_archive\">\n\n");
+		if ($gz) gzclose($f);
+		else fclose($f);
+	}
+	else{
+		echo _T("info_sauvegarde")._L(" en cours : Etape ".$status_dump[2]." ligne ".$status_dump[3])."<br/>";
+		$f = ($gz) ? gzopen(_DIR_SESSIONS . $archive, "ab") : fopen(_DIR_SESSIONS . $archive, "ab");
+		if (!$f) {
+			echo _T('avis_erreur_sauvegarde', array('type'=>'.', 'id_objet'=>'. .'));
+			exit;
+		}
+		if ($gz) gzclose($f);
+		else fclose($f);
+	}
 
-install_debut_html(_T('info_sauvegarde'));
+	// 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 $EXPORT_tables_noexport;
+	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,$EXPORT_tables_noexport) 
+	  		&&	!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);
+	}
 
-if (!$etape) echo "<p><blockquote><font size=2>"._T('info_sauvegarde_echouee')." <a href='" . generer_url_ecrire("export_all","reinstall=non&etape=1&gz=$gz") . "'>"._T('info_procedez_par_etape')."</a></font></blockquote><p>";
+	ob_flush();flush();
 
-if ($etape < 2)
-	$f = ($gz) ? gzopen(_DIR_SESSIONS . $archive, "wb") : fopen(_DIR_SESSIONS . $archive, "wb");
-else
-	$f = ($gz) ? gzopen(_DIR_SESSIONS . $archive, "ab") : fopen(_DIR_SESSIONS . $archive, "ab");
+	$status_dump = explode("::",$GLOBALS['meta']["status_dump"]);
+	$etape = $status_dump[2];
 
-if (!$f) {
-	echo _T('avis_erreur_sauvegarde', array('type'=>'.', 'id_objet'=>'. .'));
-	exit;
-}
+	if ($etape >= count($tables_for_dump)){
+		foreach($tables_for_dump as $i=>$table){
+			export_objets($table, primary_index_table($table), $tables_for_link[$table],$fpart, false, $i, _T("info_sauvegarde")._L(", table $table"));
+		}
 
-$_fputs = ($gz) ? gzputs : fputs;
+		ob_flush();flush();
+		ramasse_parties(_DIR_SESSIONS . $archive, $gz, _DIR_SESSIONS . $partfile);
 
-if ($etape < 2)
-	$_fputs($f, "<"."?xml version=\"1.0\" encoding=\"".$GLOBALS['meta']['charset']."\"?".">\n<SPIP version=\"$spip_version_affichee\" version_base=\"$spip_version\" version_archive=\"$version_archive\">\n\n");
+		$f = ($gz) ? gzopen(_DIR_SESSIONS . $archive, "ab") : fopen(_DIR_SESSIONS . $archive, "ab");
+		$_fputs ($f, build_end_tag("SPIP")."\n");
+		if ($gz) gzclose($f);
+		else fclose($f);
+		
+		effacer_meta("status_dump");
+		ecrire_metas();
+		echo "<p>"._T('info_sauvegarde_reussi_01')."</b><p>"._T('info_sauvegarde_reussi_02', array('archive' => '<b>'._DIR_SESSIONS.$archive.'</b>'))." <a href='./'>"._T('info_sauvegarde_reussi_03')."</a> "._T('info_sauvegarde_reussi_04')."\n";
+	}
+	else{
+		if (!($timeout = ini_get('max_execution_time')*1000));
+			$timeout = 30000; // parions sur une valeur tellement courante ...
+		if ($start) $timeout = round($timeout/2);
+		// script de rechargement auto sur timeout
+		echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".generer_url_ecrire("export_all","archive=$archive&gz=$gz",true)."\";',$timeout);</script>\n");
+		$cpt = 0;
+		$paquets = 400; // nombre d'enregistrements dans chaque paquet
+		foreach($tables_for_dump as $i=>$table){
+			// par paquets
+			list($string,$status_dump)=export_objets($table, primary_index_table($table), $tables_for_link[$table],0, false, $i, _T("info_sauvegarde")._L(", table $table"),$paquets);
+		  while ($string!=''){
+				if ($cpt == 0)
+					ramasse_parties(_DIR_SESSIONS . $archive, $gz, _DIR_SESSIONS . $partfile);
+
+				// on ecrit dans un fichier generique
+				ecrire_fichier (_DIR_SESSIONS .$partfile, $string);
+				// on le renomme avec un numero -> operation atomique en linux
+				rename(_DIR_SESSIONS .$partfile,_DIR_SESSIONS .$partfile.".$cpt");
+				$cpt ++;
+				ecrire_meta("status_dump", implode("::",$status_dump));
+				#lire_metas();
+				list($string,$status_dump)=export_objets($table, primary_index_table($table), $tables_for_link[$table],0, false, $i, _T("info_sauvegarde")._L(", table $table"),$paquets);
+			}
+			ecrire_meta("status_dump", implode("::",$status_dump));
+			#lire_metas();
+		}
+		// pour recharger la page tout de suite en finir le ramassage
+		echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".str_replace("&amp;","&",generer_url_ecrire("export_all","archive=$archive&gz=$gz"))."\";',0);</script>\n");
+	}
 
-$i = 0;
-foreach ($sauvegardes as $nom => $info) {
-	$i++;
-	$table = table_objet($nom);
-	$table = $table ? "spip_$table" : $nom;
-	$n = export_objets($table, $nom, $f, $gz, $etape, $i, $info);
-	spip_log("sauvegarde de $table: $n");
- }
+	install_fin_html();
 
-if (!$etape OR $etape == 13){
-	$_fputs ($f, build_end_tag("SPIP")."\n");
-	echo "<p>"._T('info_sauvegarde_reussi_01')."</b><p>"._T('info_sauvegarde_reussi_02', array('archive' => '<b>'._DIR_SESSIONS.$archive.'</b>'))." <a href='./'>"._T('info_sauvegarde_reussi_03')."</a> "._T('info_sauvegarde_reussi_04')."\n";
-}
-else {
-	$etape_suivante = $etape + 1;
-	if ($debut_limit > 1) echo "<p align='right'> <a href='" . generer_url_ecrire("export_all","reinstall=non&etape=$etape&debut_limit=$debut_limit&gz=$gz") . "'>>>>> "._T('info_etape_suivante')."</a>";
-	else echo "<p align='right'> <a href='" . generer_url_ecrire("export_all","reinstall=non&etape=$etape_suivante&gz=$gz") . "'>>>>> "._T('info_etape_suivante')."</a>";
 }
-install_fin_html();
 
-if ($gz) gzclose($f);
-else fclose($f);
-
-if (!$etape OR $etape == 14) fin_admin($action);
+function ramasse_parties($archive, $gz, $partfile){
+	// a ameliorer par un preg_file
+	// si le rammassage est interrompu par un timeout, on perd des morceaux
+	$cpt=0;
+	while(file_exists($f = $partfile.".$cpt")){
+		$contenu = "";
+		if (lire_fichier ($f, $contenu))
+			if (!ecrire_fichier($archive,$contenu,false,false))
+			{
+				echo _T('avis_erreur_sauvegarde', array('type'=>'.', 'id_objet'=>'. .'));
+				exit;
+			}
+		unlink($f);
+		$cpt++;
+	}
 }
 
-
 //
 // Exportation generique d'objets (fichier ou retour de fonction)
 //
-function export_objets($table, $type, $file = 0, $gz = false, $etape_en_cours="", $etape_actuelle="", $nom_etape="") {
-	global $debut_limit;
+function export_objets($table, $primary, $liens, $file = 0, $gz = false, $etape_actuelle="", $nom_etape="",$limit=0) {
+	static $etape_affichee=array();
+	static $table_fields=array();
+	$string='';
+
+	$status_dump = explode("::",$GLOBALS['meta']["status_dump"]);
+	$etape_en_cours = $status_dump[2];
+	$pos_in_table = $status_dump[3];
+	
 	if ($etape_en_cours < 1 OR $etape_en_cours == $etape_actuelle){
-		if ($etape_en_cours > 0) {
-			echo "<li><b>$nom_etape</b>";
+
+		$result = spip_query("SELECT COUNT(*) FROM $table");
+		$row = spip_fetch_array($result,SPIP_NUM);
+		$total = $row[0];
+		$debut = $pos_in_table;
+		if (!isset($etape_affichee[$etape_actuelle])){
+			echo "<li><strong>$etape_actuelle-$nom_etape</strong>";
+			echo " : $total";
+			$etape_affichee[$etape_actuelle] = 1;
+			if ($limit<$total) echo "<br/>";
 		}
-	
-		$result = spip_query("SELECT * FROM $table");
-		$total = spip_num_rows($result);
-		if ($etape_en_cours > 0){
-			if ($type == "forum"){
-				if ($total > 5000){
-					$result = spip_query("SELECT * FROM $table LIMIT  $debut_limit, 5000");
-#" LIMIT  5000 OFFSET $debut_limit" # PG
-
-					$debut_limit = $debut_limit + 5000;
-					if ($debut_limit > $total) {
-						$debut_limit = 0;
-						echo " "._T('info_tous_resultats_enregistres');
-					}
-					else {
-						echo " "._T('info_premier_resultat', array('debut_limit' => $debut_limit, 'total' => $total));
-					}
-				} 
-				else {
-					$debut_limit = 0;
-				}
-			}
-			if ($type == "article"){
-				if ($total > 500){
-					$result = spip_query("SELECT * FROM $table  LIMIT  $debut_limit, 500");
-#" LIMIT  500 OFFSET $debut_limit" # PG
-
-					$debut_limit = $debut_limit + 500;
-					if ($debut_limit > $total) {
-						$debut_limit = 0;
-						echo " "._T('info_tous_resultats_enregistres');
-					}
-					else {
-						echo " "._T('info_premier_resultat_sur', array('debut_limit' => $debut_limit, 'total' => $total));
-					}
-				} 
-				else {
-					$debut_limit = 0;
-				}
-			}
+		if ($pos_in_table!=0)
+			echo "| $pos_in_table ";
+		ob_flush();flush();
+
+		if ($limit == 0) $limit=$total;
+		$result = spip_query("SELECT * FROM $table LIMIT $debut,$limit");
+#" LIMIT  $limit OFFSET $debut" # PG
+
+		if (!isset($table_fields[$table])){
+			$nfields = mysql_num_fields($result);
+			// Recuperer les noms des champs
+			for ($i = 0; $i < $nfields; ++$i) $table_fields[$table][$i] = mysql_field_name($result, $i);
 		}
-		
-		$_fputs = ($gz) ? gzputs : fputs;
-		$nfields = mysql_num_fields($result);
-		// Recuperer les noms des champs
-		for ($i = 0; $i < $nfields; ++$i) $fields[$i] = mysql_field_name($result, $i);
-		while ($row = spip_fetch_array($result)) {
-			$string .= build_begin_tag($type) . "\n";
-			// Exporter les champs de la table
-			for ($i = 0; $i < $nfields; ++$i) {
-				$string .= '<'.$fields[$i].'>' . text_to_xml($row[$i]) . '</'.$fields[$i].'>' . "\n";
-			}
-			// Exporter les relations
-			if ($type == 'article') {
-				$res2 = spip_query("SELECT id_auteur FROM spip_auteurs_articles WHERE id_article=".$row['id_article']);
-
-				while($row2 = spip_fetch_array($res2)) {
-					$string .= '<lien:auteur>' . $row2['id_auteur'] . '</lien:auteur>' . "\n";
-				}
-				spip_free_result($res2);
-				$res2 = spip_query("SELECT id_document FROM spip_documents_articles WHERE id_article=".$row['id_article']);
-
-				while($row2 = spip_fetch_array($res2)) {
-					$string .= '<lien:document>' . $row2['id_document'] . '</lien:document>' . "\n";
-				}
-				spip_free_result($res2);
-			}
-			else if ($type == 'message') {
-				$res2 = spip_query("SELECT id_auteur FROM spip_auteurs_messages WHERE id_message=".$row['id_message']);
-
-				while($row2 = spip_fetch_array($res2)) {
-					$string .= '<lien:auteur>' . $row2['id_auteur'] . '</lien:auteur>' . "\n";
-				}
-				spip_free_result($res2);
-			}
-			else if ($type == 'breve') {
-				$res2 = spip_query("SELECT id_document FROM spip_documents_breves WHERE id_breve=".$row['id_breve']);
-
-				while($row2 = spip_fetch_array($res2)) {
-					$string .= '<lien:document>' . $row2['id_document'] . '</lien:document>' . "\n";
+		else
+			$nfields = count($table_fields[$table]);
+
+		if (!$file) {
+			while ($row = spip_fetch_array($result,SPIP_ASSOC)) {
+				$string .= build_begin_tag($table) . "\n";
+				// Exporter les champs de la table
+				for ($i = 0; $i < $nfields; ++$i) {
+					$string .= '<'.$table_fields[$table][$i].'>' . text_to_xml($row[$table_fields[$table][$i]]) . '</'.$table_fields[$table][$i].'>' . "\n";
 				}
-				spip_free_result($res2);
+					
+				$string .= build_end_tag($table) . "\n\n";
+				$status_dump[3] = $pos_in_table = $pos_in_table +1;
 			}
-			else if ($type == 'rubrique') {
-				$res2 = spip_query("SELECT id_document FROM spip_documents_rubriques WHERE id_rubrique=".$row['id_rubrique']);
-
-				while($row2 = spip_fetch_array($res2)) {
-					$string .= '<lien:document>' . $row2['id_document'] . '</lien:document>' . "\n";
-				}
-				spip_free_result($res2);
-				$res2 = spip_query("SELECT id_auteur FROM spip_auteurs_rubriques WHERE id_rubrique=".$row['id_rubrique']);
-
-				while($row2 = spip_fetch_array($res2)) {
-					$string .= '<lien:auteur>' . $row2['id_auteur'] . '</lien:auteur>' . "\n";
-				}
-				spip_free_result($res2);
-			}
-			else if ($type == 'auteur') {
-				$res2 = spip_query("SELECT id_rubrique FROM spip_auteurs_rubriques WHERE id_auteur=".$row['id_auteur']);
-				while($row2 = spip_fetch_array($res2)) {
-					$string .= '<lien:rubrique>' . $row2['id_rubrique'] . '</lien:rubrique>' . "\n";
-				}
-				spip_free_result($res2);
-			}
-			else if ($type == 'mot') {
-				$res2 = spip_query("SELECT id_article FROM spip_mots_articles WHERE id_mot=".$row['id_mot']);
-
-				while($row2 = spip_fetch_array($res2)) {
-					$string .= '<lien:article>' . $row2['id_article'] . '</lien:article>' . "\n";
-				}
-				spip_free_result($res2);
-				$res2 = spip_query("SELECT id_breve FROM spip_mots_breves WHERE id_mot=".$row['id_mot']);
-
-				while($row2 = spip_fetch_array($res2)) {
-					$string .= '<lien:breve>' . $row2['id_breve'] . '</lien:breve>' . "\n";
-				}
-				spip_free_result($res2);
-				$res3 = spip_query("SELECT id_forum FROM spip_mots_forum WHERE id_mot=".$row['id_mot']);
-
-				while($row3 = spip_fetch_array($res3)) {
-					$string .= '<lien:forum>' . $row3['id_forum'] . '</lien:forum>' . "\n";
-				}
-				spip_free_result($res3);
-				$res4 = spip_query("SELECT id_rubrique FROM spip_mots_rubriques WHERE id_mot=".$row['id_mot']);
-
-				while($row4 = spip_fetch_array($res4)) {
-					$string .= '<lien:rubrique>' . $row4['id_rubrique'] . '</lien:rubrique>' . "\n";
-				}
-				spip_free_result($res4);
-				$res4 = spip_query("SELECT id_syndic FROM spip_mots_syndic WHERE id_mot=".$row['id_mot']);
-
-				while($row4 = spip_fetch_array($res4)) {
-					$string .= '<lien:syndic>' . $row4['id_syndic'] . '</lien:syndic>' . "\n";
+		}
+		else {
+			$_fputs = ($gz) ? gzputs : fputs;
+			while ($row = spip_fetch_array($result,SPIP_ASSOC)) {
+				$string .= build_begin_tag($table) . "\n";
+				// Exporter les champs de la table
+				for ($i = 0; $i < $nfields; ++$i) {
+					$string .= '<'.$fields[$i].'>' . text_to_xml($row[$fields[$i]]) . '</'.$fields[$i].'>' . "\n";
 				}
-				spip_free_result($res4);
-			}
-			$string .= build_end_tag($type) . "\n\n";
-			if ($file) {
+					
+				$string .= build_end_tag($table) . "\n\n";
+				$status_dump[3] = $pos_in_table = $pos_in_table +1;
+	
 				$_fputs($file, $string);
+				fflush($file);
+				// on se contente d'une ecriture en base pour aller plus vite
+				// a la relecture on en profitera pour mettre le cache a jour
+				ecrire_meta("status_dump", implode("::",$status_dump));
+				#lire_metas();
+				#ecrire_metas(); 
 				$string = '';
 			}
 		}
+		if ($pos_in_table>=$total){
+			// etape suivante : 
+			echo " ok";
+			$status_dump[2] = $status_dump[2]+1;
+			$status_dump[3] = 0;
+		}
+		if ($file) {
+			// on se contente d'une ecriture en base pour aller plus vite
+			// a la relecture on en profitera pour mettre le cache a jour
+			ecrire_meta("status_dump", implode("::",$status_dump));
+			#lire_metas();
+			#ecrire_metas();
+		}
 		spip_free_result($result);
-		if (!$file) return $string;
+		return array($string,$status_dump);
 	}
 	else if ($etape_actuelle < $etape_en_cours) {
-		echo "<li> $nom_etape";
+		if (!isset($etape_affichee[$etape_actuelle]))
+			echo "<li> $etape_actuelle-$nom_etape";
+		ob_flush();flush();
 	} else {
-		echo "<li> <font color='#999999'>$nom_etape</font>";
+		if (!isset($etape_affichee[$etape_actuelle]))
+			echo "<li> <font color='#999999'>$etape_actuelle-$nom_etape</font>";
+		ob_flush();flush();
 	}
-	return $total;
+	return array($string,$status_dump);
 }
 
+
 function build_begin_tag($tag) {
 	return "<$tag>";
 }
diff --git a/ecrire/exec/import_all.php b/ecrire/exec/import_all.php
index 3871a75b8b..10d082a886 100644
--- a/ecrire/exec/import_all.php
+++ b/ecrire/exec/import_all.php
@@ -1,87 +1,154 @@
-<?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');
-
-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();
-
-	// sinon commencer ou continuer
-	include_spip('inc/import');
-	import_all_continue(array(
-'spip_auteurs',
-'spip_articles',
-'spip_breves',
-'spip_documents',
-'spip_forum',
-'spip_mots',
-'spip_groupes_mots',
-'spip_petitions',
-'spip_rubriques',
-'spip_signatures',
-'spip_types_documents',
-'spip_visites'));		
-}
-?>
+<?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);
+}
+?>
diff --git a/ecrire/inc/import.php b/ecrire/inc/import.php
index 706c0cf1a0..42c79664b0 100644
--- a/ecrire/inc/import.php
+++ b/ecrire/inc/import.php
@@ -12,53 +12,56 @@
 
 if (!defined("_ECRIRE_INC_VERSION")) return;
 
-include_spip('inc/acces');
-include_spip('inc/filtres');
-include_spip('base/abstract_sql');
+include_spip('inc/presentation');
+include_spip ("inc/acces");
+include_spip('inc/indexation'); // pour la fonction primary_index_table 
+include_spip('inc/serialbase');
+include_spip('inc/auxbase');
 
-function xml_fetch_tag($f, &$before, $gz=false) {
+global $IMPORT_tables_noerase;
+$IMPORT_tables_noerase[]='spip_ajax_fonc';
+$IMPORT_tables_noerase[]='spip_meta';
+
+function xml_fetch_tag($f, &$before, $gz=false, $skip_comment=true) {
 	global $buf, $pos, $abs_pos;
-	static $buf_len = 1000;
-	$_fread = ($gz) ? gzread : fread;
-	$_feof = ($gz) ? gzeof : feof;
-	$_ftell = ($gz) ? gztell : ftell;
-	$p = $pos;
-
-	$q = @strpos($buf, '<', $p);
-	while (!$q AND substr($buf, $p, 1) != '<') {
-		if ($_feof($f)) return false;
-		$before .= substr($buf, $p);
-		$buf = $_fread($f, $buf_len);
-		$p = 0;
-		$q = strpos($buf, '<');
-	}
-	$before .= substr($buf, $p, $q - $p);
-	$tag = '';
-	$p = ++$q;
-	$q = @strpos($buf, '>', $p);
-	while (!$q AND substr($buf, $p, 1) != '>') {
-		if ($_feof($f)) return false;
-		$tag .= substr($buf, $p);
-		$buf = $_fread($f, $buf_len);
-		$p = 0;
-		$q = strpos($buf, '>');
+	static $buf_len = 500;
+	static $_fread,$_feof,$_ftell;
+	if (!$_fread){
+		$_fread = ($gz) ? gzread : fread;
+		$_feof = ($gz) ? gzeof : feof;
+		$_ftell = ($gz) ? gztell : ftell;
 	}
-	$pos = $q + 1;
-	$tag .= substr($buf, $p, $q - $p);
-	$before = str_replace('&amp;', '&', str_replace('&lt;', '<', $before));
+	
+	while (preg_match("{<([^>]*?)>}s",$buf)==FALSE)
+		$buf .= $_fread($f, $buf_len);
+	$chars = preg_split("{<([^>]*?)>}s",$buf,2,PREG_SPLIT_OFFSET_CAPTURE|PREG_SPLIT_DELIM_CAPTURE);
+
+	$before .= str_replace(array('&amp;','&lt;'),array('&','<'),$chars[0][0]);
+	$tag = $chars[1][0];
+	$buf = $chars[2][0];
+
 	$abs_pos = $_ftell($f) - strlen($buf);
-	return $tag;
-}
 
+	if (($skip_comment==true)&&(substr($tag,0,3)=='!--')){
+	  return xml_fetch_tag($f,$before,$gz,$skip_comment);
+	}
+	else
+		return $tag;
+}
 
 function xml_parse_tag($texte) {
 	list($tag, $atts) = split('[[:space:]]+', $texte, 2);
 	$result[0] = $tag;
 	$result[1] = '';
 	if (!$atts) return $result;
-	while (ereg('^([^[:space:]]+)[[:space:]]*=[[:space:]]*"([^"]*)"([[:space:]]+(.*))?', $atts, $regs)) {
-		$result[1][$regs[1]] = $regs[2];
-		$atts = $regs[4];
+	if ($tag=='!--'){
+	  $result[1]=preg_replace(",(.*?)--$,s",'\\1',$atts);
+	}
+	else {
+		while (ereg('^([^[:space:]]+)[[:space:]]*=[[:space:]]*"([^"]*)"([[:space:]]+(.*))?', $atts, $regs)) {
+			$result[1][$regs[1]] = $regs[2];
+			$atts = $regs[4];
+		}
 	}
 	return $result;
 }
@@ -66,11 +69,22 @@ function xml_parse_tag($texte) {
 
 function import_debut($f, $gz=false) {
 	$b = "";
-	while ($t = xml_fetch_tag($f, $b, $gz)) {
+	$flag_phpmyadmin = false;
+	while ($t = xml_fetch_tag($f, $b, $gz, false)) {
 		$r = xml_parse_tag($t);
 		if ($r[0] == '?xml' AND $r[1]['encoding'])
 			ecrire_meta('charset_restauration', strtolower($r[1]['encoding']));
 		if ($r[0] == "SPIP") return $r;
+		if (($r[0] == "!--") && (preg_match(",phpmyadmin\sxml\sdump,is",$r[1]))){
+			// c'est un dump xml phpmyadmin
+			// on interprete le commentaire pour recuperer la version de phpmydadmin
+			$version = preg_replace(",(.*?)version\s*([0-9a-z\.\-]*)\s(.*),is","\\2",$r[1]);
+			$flag_phpmyadmin = true;
+		}
+		if (($r[0] != "!--") && ($flag_phpmyadmin == true)){
+		  $r[1] = array('version_archive'=>"phpmyadmin::$version");
+			return $r;
+		}
 		$b = "";
 	}
 	return false;
@@ -84,10 +98,84 @@ function import_debut($f, $gz=false) {
 // importe un objet depuis le fichier, retourne true si ok, false si erreur ou fin de fichier
 //
 
+// on conserve ce tableau pour faire des translations
+// de table eventuelles
+$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[] = "'".addslashes($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 $pos, $abs_pos;
-	static $prev_type, $total= array();
-	global $import_ok;
+	global $import_ok, $pos, $abs_pos;
 	static $time_javascript;
 
 	if (time() - $time_javascript > 3) {	// 3 secondes
@@ -95,27 +183,39 @@ function import_objet_1_2($f, $gz=false) {
 		$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 ($import_ok = false);
+	if (!($type = xml_fetch_tag($f, $b, $gz))) return false;
+	if ($type == '/SPIP') return !($import_ok = true);
 	$id = "id_$type";
 	$id_objet = 0;
-	$liens = array();
-	if ($prev_type != $type) {
-		if ($prev_type)
-			spip_log("Importation $prev_type : " . $total[$prev_type]);
-		$prev_type = $type;
-	}
-	if ($type == '/SPIP') {$import_ok = true; return false;}
-	$total[$type]++;
+
 	// Lire les champs de l'objet
 	for (;;) {
-		if (!($col = xml_fetch_tag($f, $value, $gz)))
-		  return $import_ok = false;
+		$b = '';
+		if (!($col = xml_fetch_tag($f, $b, $gz))) return false;
 		if ($col == '/'.$type) break;
 		$value = '';
-		if (!xml_fetch_tag($f, $value, $gz))
-		  return $import_ok = false;
+		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.')';
@@ -129,7 +229,7 @@ function import_objet_1_2($f, $gz=false) {
 					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;
+					$GLOBALS['erreur_restauration'] = true;
 				}
 			}
 			else {
@@ -139,40 +239,13 @@ function import_objet_1_2($f, $gz=false) {
 			}
 		}
 	}
-	$table = table_objet($type);
-	if ($table) 
-		$table = "spip_$table";
-	else {
-		// Table non Spip, on accepte.
-		// Si c'est vraiment n'importe quoi le test suivant le dira
-		$table = $type;
-	}
-	$n = spip_query("REPLACE " . $table . "(" . join(',', $cols) . ') VALUES (' . join(',', $values) . ')');
-	if(!$n) {
+
+	$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;
 	}
 
-	supprime_anciens_liens($type, $id_objet);
-	$sens = ($type == 'auteur' OR $type == 'mot' OR $type == 'document');
-	$type .= 's';
-	foreach($liens as $type_lien => $t) {
-		if (!$sens)
-			$table_lien = $type_lien.'s_'.$type;
-		else
-			$table_lien = $type.'_'.$type_lien .
-			  (($type_lien == 'syndic' OR $type_lien == 'forum') ? '' : 's');
-		spip_abstract_insert('spip_' . $table_lien, "($id, id_$type_lien)", join(',', $t));
-	}
-	
-	ecrire_meta("status_restauration", strval($pos + $abs_pos));
-
-	$import_ok = true;
-	return true;
-}
-
-function supprime_anciens_liens($type, $id_objet)
-{
 	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");
@@ -197,8 +270,27 @@ function supprime_anciens_liens($type, $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;
 
@@ -262,36 +354,36 @@ function import_objet_0_0($f, $gz=false) {
 		if ($articles) {
 			reset ($articles);
 			while (list(, $article) = each($articles)) {
-				
-			  spip_abstract_insert("spip_mots_articles", "(id_mot, id_article)", "($id_mot, $article)");
+
+				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)");
+
+				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)");
+
+				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)");
+
+				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)");
+
+				spip_abstract_insert("spip_mots_syndic", "(id_mot, id_syndic)", "($id_mot, $syndic)");
 			}
 		}
 	}
@@ -316,6 +408,10 @@ function import_fin() {
 	effacer_meta("status_restauration");
 	effacer_meta("debut_restauration");
 	effacer_meta("date_optimisation");
+	effacer_meta('request_restauration');
+	effacer_meta('fichier_restauration');
+	effacer_meta('version_archive_restauration');
+	effacer_meta('tag_archive_restauration');
 	ecrire_meta('calculer_rubriques', 'oui');
 	ecrire_metas();
 }
@@ -327,64 +423,84 @@ function import_abandon() {
 	effacer_meta("status_restauration");
 	effacer_meta("debut_restauration");
 	effacer_meta("date_optimisation");
+	effacer_meta('request_restauration');
+	effacer_meta('fichier_restauration');
+	effacer_meta('version_archive_restauration');
+	effacer_meta('tag_archive_restauration');
 	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;
 
-	// utiliser une version fraiche des metas (ie pas le cache)
-	include_spip('inc/meta');
-	lire_metas();
+	$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;
 
-	$s = spip_fetch_array(spip_query("SELECT UNIX_TIMESTAMP(maj) AS d FROM spip_meta WHERE nom='debut_restauration'"));
-	$my_date = $s['d'];
+	$my_pos = 0;
+	if (isset($GLOBALS['meta']["status_restauration"]))
+		$my_pos = $GLOBALS['meta']["status_restauration"];
 
-	if (!$my_date) {
-		spip_log("importation: debut_restauration absent");
-		return false;
-	}
-
-	$my_pos = $GLOBALS['meta']["status_restauration"];
-
-	if (!$my_pos) {
+	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'));
-			spip_log("importation: avis_archive_incorrect");
 			return false;
 		}
-		else {
-			// Bidouille pour garder l'acces admin actuel pendant toute la restauration
-			if (in_array('spip_auteurs', $tables))
-				spip_query("UPDATE spip_auteurs SET id_auteur=0 WHERE id_auteur=$connect_id_auteur");
 
-			$version_archive = $r[1]['version_archive'];
-			ecrire_meta('version_archive_restauration', $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");
+			}
+		}
+
+		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('version_archive_restauration', $version_archive);
+		ecrire_meta('tag_archive_restauration', $tag_archive);
+		#ecrire_metas();
+
 	}
 	else {
 		// Reprise de l'importation
 		$_fseek($f, $my_pos);
 		$version_archive = $GLOBALS['meta']['version_archive_restauration'];
+		$tag_archive = $GLOBALS['meta']['tag_archive_restauration'];
 	}
 
 	// Restauration des entrees du fichier
-
-	switch ($version_archive) {
-	case '1.2':
-		while (import_objet_1_2($f, $gz));
-		break;
-	default:
-		while (import_objet_0_0($f, $gz));
-		break;
+	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;
+		}
 	}
-
 	if (!$import_ok) {
 		ecrire_meta("erreur", _T('avis_archive_invalide'));
 		return false;
@@ -396,7 +512,7 @@ function import_tables($f, $tables, $gz=false) {
 
 	// Destruction des entrees non restaurees
 
-	detruit_non_restaurees($my_date, $tables);
+	detruit_non_restaurees($mydate, $tables);
 
 	import_fin();
 
@@ -405,23 +521,21 @@ function import_tables($f, $tables, $gz=false) {
 	return true;
 }
 
-
 // Destruction des entrees non restaurees
 
-function detruit_non_restaurees($my_date, $tables)
+function detruit_non_restaurees($mydate, $tables)
 {
-	
-	foreach ($tables as $v) 
-	  spip_query("DELETE FROM $v WHERE UNIX_TIMESTAMP(maj) < $my_date");
+	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");
 }
 
 
-function affiche_progression_javascript($abs_pos) {
+function affiche_progression_javascript($abs_pos,$table="") {
 	global $affiche_progression_pourcent;
-	include_spip('inc/charsets');
-
-	flush();
-	echo "<script type='text/javascript'><!--\n";
+	include_ecrire('inc_charsets');
+	ob_flush();flush();
+	echo " -->\n<script type='text/javascript'><!--\n";
 
 	if ($abs_pos == '100 %') {
 		$taille = $abs_pos;
@@ -429,36 +543,65 @@ function affiche_progression_javascript($abs_pos) {
 			echo "document.progression.recharge.value='".str_replace("'", "\\'", unicode_to_javascript(_T('avis_erreur')))."';\n";
 		else
 			echo "document.progression.recharge.value='".str_replace("'", "\\'", unicode_to_javascript(_T('info_fini')))."';\n";
+		echo "document.progression.taille.value='$taille';\n";
+		echo "//--></script>\n";
+		echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".self()."\";',0);</script>\n");
+	}
+	else {
+		if ($table!="")
+			echo "document.progression.recharge.value='$table';\n";
+		if (! $affiche_progression_pourcent)
+			$taille = ereg_replace("&nbsp;", " ", taille_en_octets($abs_pos));
+		else
+			$taille = floor(100 * $abs_pos / $affiche_progression_pourcent)." %";
+		echo "document.progression.taille.value='$taille';\n";
+		echo "//--></script>\n<!--\n";
 	}
-	else if (! $affiche_progression_pourcent)
-		$taille = ereg_replace("&nbsp;", " ", taille_en_octets($abs_pos));
-	else
-		$taille = floor(100 * $abs_pos / $affiche_progression_pourcent)." %";
 
-	echo "document.progression.taille.value='$taille';\n";
-	echo "//--></script>\n";
-	flush();
+	ob_flush();flush();
 }
 
 function import_all_continue($tables)
 {
 	global $meta, $flag_gz, $buf, $pos, $abs_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');
+	lire_metas();
 
 	@ignore_user_abort(1);
 
 	$request = unserialize($meta['request_restauration']);
-
 	$archive = _DIR_SESSIONS . $request['archive'];
 
-	if (!@is_readable($archive)) {
-		import_abandon();
-		minipres(_T('info_base_restauration'),
-			 _T('info_erreur_restauration') .
-			 "<br /><br /><a href='./'>"._T('info_sauvegarde_reussi_03').
-			 "</a> "._T('info_sauvegarde_reussi_04'));
+	debut_page(_T('titre_page_index'), "asuivre", "asuivre");
+
+	debut_gauche();
+
+	debut_droite();
+
+	// attention : si $request['archive']=="", alors archive='data/' 
+	// le test is_readable n'est donc pas suffisant
+	if (!@is_readable($archive)||is_dir($archive)) {
+		$texte_boite = _T('info_erreur_restauration');
+		debut_boite_alerte();
+		echo "<font FACE='Verdana,Arial,Sans,sans-serif' SIZE=4 color='black'><B>$texte_boite</B></font>";
+		fin_boite_alerte();
+		fin_html();
+		// faut faire quelque chose, sinon le site est mort :-)
+		// a priori on reset les meta de restauration car rien n'a encore commence
+		effacer_meta('request_restauration');
+		effacer_meta('fichier_restauration');
+		effacer_meta('version_archive_restauration');
+		effacer_meta('tag_archive_restauration');
+		effacer_meta('status_restauration');
+		effacer_meta('debut_restauration');
+		effacer_meta('charset_restauration');
+		ecrire_metas();
+		exit;
 	}
 
-
 	$my_pos = $meta["status_restauration"];
 
 	if (ereg("\.gz$", $archive)) {
@@ -467,30 +610,32 @@ function import_all_continue($tables)
 			$gz = true;
 	} else {
 			$affiche_progression_pourcent = filesize($archive);
+			#echo $affiche_progression_pourcent;
 			$taille = floor(100 * $my_pos / $affiche_progression_pourcent)." %";
 			$gz = false;
 		}
-	install_debut_html(_T('info_base_restauration'));
-        echo "<p><table cellpadding='6' border='0'><tr><td width='100%' bgcolor='red'>";
-        echo "<table width='100%' cellpadding='12' border='0'><tr><td width='100%' bgcolor
-='white'>";
-	echo "<form name='progression'><center><input type='text' size=10 style='text-align:center;' name='taille' value='$taille'><br>
-		<input type='text' class='forml' size='80' name='recharge' value='"._T('info_recharger_page')."'></center></form>";
-        echo "</td></tr></table>";
-        echo "</td></tr></table><br /><br >";
+	$texte_boite = _T('info_base_restauration')."<p>
+		<form name='progression'><center><input type='text' size=10 style='text-align:center;' name='taille' value='$taille'><br>
+		<input type='text' class='forml' name='recharge' value='"._T('info_recharger_page')."'></center></form>";
+
+	debut_boite_alerte();
+	echo "<font FACE='Verdana,Arial,Sans,sans-serif' SIZE=4 color='black'><B>$texte_boite</B></font>";
+	fin_boite_alerte();
+	$max_time = ini_get('max_execution_time')*1000;
+	echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".self()."\";',$max_time);</script>\n");
+
+	fin_page();
+	ob_flush();flush();
+
+	echo "<font color='white'>\n<!--";
 
 	$_fopen = ($gz) ? gzopen : fopen;
 	$f = $_fopen($archive, "rb");
 	$pos = 0;
 	$buf = "";
-	$res = import_tables($f, $tables, $gz);
-	spip_log("Restauration: " . ($res ? "finie" : "echec"));
-	if ($res)
+	if (!import_tables($f, $tables, $gz))
 		import_abandon();
 	else	import_fin();
-	echo " <a href='./'>",_T('info_sauvegarde_reussi_03'),"</a> ",_T('info_sauvegarde_reussi_04');
-	install_fin_html();
-	flush();
 }
 
-?>
+?>
\ No newline at end of file
-- 
GitLab