From f4e37e3935ab5c9102ba9ee223f08e711e04a987 Mon Sep 17 00:00:00 2001 From: "Committo,Ergo:sum" <esj@rezo.net> Date: Sat, 25 Nov 2006 13:09:29 +0000 Subject: [PATCH] =?UTF-8?q?D=C3=A9but=20de=20la=20t=C3=A2che=20#685.=20Spi?= =?UTF-8?q?p=20propose=20=C3=A0=20pr=C3=A9sent=20de=20fusionner=20la=20bas?= =?UTF-8?q?e=20courante=20avec=20les=20tables=20principales=20d'une=20sauv?= =?UTF-8?q?egarde,=20moins=20la=20tables=20des=20types=20de=20documents=20?= =?UTF-8?q?(qui=20est=20commune=20=C3=A0=20tous=20les=20Spip=20car=20en=20?= =?UTF-8?q?lecture=20seule)=20et=20la=20table=20des=20auteurs=20(pour=20?= =?UTF-8?q?=C3=A9viter=20les=20conflits=20sur=20les=20noms=20de=20login).?= =?UTF-8?q?=20Pour=20une=20base=20contenant=20d=C3=A9j=C3=A0=20N=20rubriqu?= =?UTF-8?q?es,=20les=20secteurs=20(i.e.=20les=20rubriques=20de=20premier?= =?UTF-8?q?=20niveau)=20de=20la=20sauvegarde=20recevront=20un=20num=C3=A9r?= =?UTF-8?q?o=20sup=C3=A9rieur=20=C3=A0=20N,=20ainsi=20que=20leur=20sous-ru?= =?UTF-8?q?briques=20dont=20les=20champs=20id=5Fparent=20et=20id=5Fsecteur?= =?UTF-8?q?=20seront=20eux=20aussi=20modifi=C3=A9s=20pour=20conserver=20l'?= =?UTF-8?q?arborescence.=20Idem=20pour=20les=20champs=20id=5Frubrique=20et?= =?UTF-8?q?=20id=5Fsecteur=20des=20articles,=20br=C3=A8ves,=20forums,=20et?= =?UTF-8?q?=20syndications=20de=20la=20sauvegarde.=20De=20meme,=20le=20cha?= =?UTF-8?q?mp=20id=5Fgroupe=20de=20la=20table=20des=20mots=20de=20la=20sau?= =?UTF-8?q?vegarde=20tiendra=20compte=20de=20la=20renum=C3=A9rotation=20de?= =?UTF-8?q?s=20groupes=20de=20mots=20introduits=20lors=20de=20la=20fusion.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ce qui n'est pas (encore) fait: * l'importation des documents joints, et a fortiori la renumérotation des pseudo balises emb,doc,img dans les champs SQL; * l'importatio des logos; * la fusion des 2 tables d'auteurs, si nom et/ou login identiques * la fusion des 2x2 tables de mots et groupes de mots si meme titre * l'importation des tables auxiliaires (mots/auteurs d'un article...) En l'état actuel des choses, cette option de restauration est surtout intéressante pour qui possède une collection d'articles sur un site Spip (par exemple en local) et veut importer d'un bloc cette collection sur un autre. En jouant sur le statut d'administrateur restreint (on peut en créer une juste pour l'occasion), il est possible de n'importer qu'une partie d'une site d'origine, puisqu'une sauvegarde effectuée par un administrateur restreint est réduite aux rubriques qu'il administre. Egalement dans ce dépot: * la fonction _q() n'entoure plus de guillemets un nombre * en cas de sauvegarde avortée, on arrive à garder la connexion au site. --- ecrire/exec/admin_tech.php | 83 ++++++++-------- ecrire/exec/import_all.php | 148 ++++++++++++---------------- ecrire/inc/import.php | 150 ++++++++++++++++++---------- ecrire/inc/import_0_0.php | 2 +- ecrire/inc/import_1_2.php | 2 +- ecrire/inc/import_1_3.php | 197 ++++++++++++++++++++++++++++--------- ecrire/inc/utils.php | 4 +- 7 files changed, 362 insertions(+), 224 deletions(-) diff --git a/ecrire/exec/admin_tech.php b/ecrire/exec/admin_tech.php index cf20d8884f..3464056b03 100644 --- a/ecrire/exec/admin_tech.php +++ b/ecrire/exec/admin_tech.php @@ -66,8 +66,8 @@ function exec_admin_tech_dist() else $dir_img = _DIR_IMG; - echo "<TABLE BORDER='0' CELLSPACING='0' CELLPADDING='5' WIDTH=\"100%\">", - "<tr><td BGCOLOR='", $couleur_foncee, "' background=''><b>", + echo "<table border='0' cellspacing='0' cellpadding='5' width=\"100%\">", + "<tr><td bgcolor='", $couleur_foncee, "' background=''><b>", "<font face='Verdana,Arial,Sans,sans-serif' size='3' color='#FFFFFF'>", _T('texte_sauvegarde'), "</font></b></td></tr><tr><td class='serif'>", @@ -76,25 +76,25 @@ function exec_admin_tech_dist() http_img_pack('warning.gif', _T('info_avertissement'), "width='48' height='48' align='right'"), _T('texte_admin_tech_01', array('dossier' => '<i>'.$dir_dump.'</i>', 'img'=>'<i>'.$dir_img.'</i>')), - "<p>", - _T('texte_admin_tech_02'); + _T('texte_admin_tech_02'), + "</p>"; if ($flag_gz) { - echo "\n<p align='justify'>"._T('texte_admin_tech_03')."<p>"; - echo "\n<INPUT TYPE='radio' NAME='gz' VALUE='1' id='gz_on' CHECKED><label for='gz_on'> "._T('bouton_radio_sauvegarde_compressee', - array('fichier'=>'<b>'.$zfile.'</b>'))." </label><BR>\n"; - echo "\n<INPUT TYPE='radio' NAME='gz' VALUE='0' id='gz_off'><label for='gz_off'> "._T('bouton_radio_sauvegarde_non_compressee', - array('fichier'=>'<b>'.$file.'</b>'))." </label><BR>\n"; + echo "\n<p align='justify'>"._T('texte_admin_tech_03')."</p>\n<p>"; + echo "\n<input type='radio' name='gz' value='1' id='gz_on' checked='checked' /><label for='gz_on'> "._T('bouton_radio_sauvegarde_compressee', + array('fichier'=>'<b>'.$zfile.'</b>'))." </label><br />\n"; + echo "\n<input type='radio' name='gz' value='0' id='gz_off' /><label for='gz_off'> "._T('bouton_radio_sauvegarde_non_compressee', + array('fichier'=>'<b>'.$file.'</b>'))." </label><br /></p>\n"; } else { echo "\n<p align='justify'>"._T('texte_sauvegarde_compressee', array('fichier'=>'<b>'.$file.'</b>')); - echo "\n<INPUT TYPE='hidden' NAME='gz' VALUE='0' />"; + echo "\n<input type='hidden' name='gz' value='0' />"; } -echo "\n<div align='right'><input class='fondo' type='submit' VALUE='"._T('texte_sauvegarde_base')."'></div></form>"; +echo "\n<div align='right'><input class='fondo' type='submit' value='"._T('texte_sauvegarde_base')."' /></div></form>"; echo "</td></tr>"; -echo "</TABLE>"; +echo "</table>"; // @@ -107,8 +107,8 @@ echo "</TABLE>"; $liste_choix = "<p><ul>"; foreach($liste_dump as $key=>$fichier){ $affiche_fichier = substr($fichier,strlen(_DIR_DUMP)); - $liste_choix.="<li><input type='radio' name='archive' value='$affiche_fichier' id='dump_$key' ". - (($fichier==$selected)?"checked='checked' ":"")."/><label for='dump_$key'>$affiche_fichier</label></li>\n"; + $liste_choix.="\n<li><input type='radio' name='archive' value='$affiche_fichier' id='dump_$key' ". + (($fichier==$selected)?"checked='checked' ":"")."/>\n<label for='dump_$key'>$affiche_fichier</label></li>"; } if ($flag_gz) { @@ -119,22 +119,31 @@ echo "</TABLE>"; $texte_compresse = _T('texte_non_compresse')." "; } - echo "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=8 WIDTH=\"100%\">", - "<TR><TD BGCOLOR='#EEEECC' BACKGROUND=''><B>", - "<FONT FACE='Verdana,Arial,Sans,sans-serif' SIZE=3 COLOR='#000000'>", - _T('texte_restaurer_base')."</FONT></B></TD></TR>", - "<TR><td class='serif'>\n", + echo "\n<table border='0' cellspacing='1' cellpadding='8' width=\"100%\">", + "<tr><td bgcolor='#eeeecc' background=''><b>", + "<font face='Verdana,Arial,Sans,sans-serif' size='3' color='#000000'>", + _T('texte_restaurer_base')."</font></b></td></tr>", + "<tr><td class='serif'>\n", generer_url_post_ecrire("import_all"), "\n<p align='justify'> ", _T('texte_restaurer_sauvegarde', array('dossier' => '<i>'.$dir_dump.'</i>')), - "\n<p>", + '</p>', _T('entree_nom_fichier', array('texte_compresse' => $texte_compresse)), $liste_choix, - "<li><input type='radio' name='archive' value='' />", - "\n<FONT SIZE=3><INPUT TYPE='text' NAME='archive_perso' VALUE='$fichier_defaut' SIZE='30'></FONT></li></ul>", - "\n<p><DIV align='right'><INPUT CLASS='fondo' TYPE='submit' VALUE='"._T('bouton_restaurer_base')."'></DIV></FORM>", - "\n</td></tr>", - "</TABLE>"; + "\n<li><input type='radio' name='archive' value='' />", + "\n<font size='3'><input type='text' name='archive_perso' value='$fichier_defaut' size='30' /></font></li></ul>"; + + debut_cadre_relief(); + echo "<p><input name='insertion' type='radio' /> ", + _L('Fusionner la base actuelle et la sauvegarde'), + '</p>'; + fin_cadre_relief(); + + echo "\n</p><div align='right'><input class='fondo' type='submit' value='", + _T('bouton_restaurer_base'), + "' /></div></form>", + "\n</td></tr>", + "</table>"; } @@ -145,29 +154,25 @@ echo "</TABLE>"; if ($options == "avancees" AND $connect_toutes_rubriques) { $res = spip_mysql_version(); if ($res >= '3.23.14') { - echo "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=8 WIDTH=\"100%\">"; - echo "<TR><TD BGCOLOR='#EEEECC' BACKGROUND=''><B>"; - echo "<FONT FACE='Verdana,Arial,Sans,sans-serif' SIZE=3 COLOR='#000000'>"; + echo "<table border='0' cellspacing='1' cellpadding='8' width=\"100%\">"; + echo "<tr><td bgcolor='#eeeecc' background=''><b>"; + echo "<font face='Verdana,Arial,Sans,sans-serif' size='3' COLOR='#000000'>"; echo _T('texte_recuperer_base'), - "</FONT></B></TD></TR>", - "<TR><TD class='serif'>", + "</font></b></td></tr>", + "<tr><td class='serif'>", generer_url_post_ecrire("admin_repair"), "\n<p align='justify'>"._T('texte_crash_base'), - "\n<p><DIV align='right'><INPUT CLASS='fondo' TYPE='submit' VALUE='", + "\n</p><div align='right'><input class='fondo' type='submit' value='", _T('bouton_tenter_recuperation'), - "'></DIV></FORM>", - "</TD></TR>", - "</TABLE>"; + "' /></div></form>", + "</td></tr>", + "</table>"; } } - fin_cadre_relief(); -echo "<BR>"; - - - +echo "<br />"; echo fin_page(); } diff --git a/ecrire/exec/import_all.php b/ecrire/exec/import_all.php index 868df43706..f01260ed76 100644 --- a/ecrire/exec/import_all.php +++ b/ecrire/exec/import_all.php @@ -98,6 +98,7 @@ function exec_import_all_dist() if (!$GLOBALS['meta']["debut_restauration"]) { // cas de l'appel apres demande de confirmation $archive=_request('archive'); + $insertion=_request('insertion'); if (!strlen($archive)) $archive=_request('archive_perso'); if ($archive) { $action = _T('info_restauration_sauvegarde', array('archive' => $archive)); @@ -105,9 +106,11 @@ function exec_import_all_dist() } // 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 + debut_admin(generer_url_post_ecrire("import_all","archive=$archive&insertion=$insertion"), $action, $commentaire); + + // si on est revenu c'est que l'authentification ftp est ok + // sinon il reste le meta request_restau; a ameliorer. fin_admin($action); // dire qu'on commence ecrire_meta("request_restauration", serialize($_REQUEST)); @@ -120,17 +123,6 @@ function exec_import_all_dist() } // au rappel, on commence (voire on continue) - import_all_continue(); - include_spip('inc/rubriques'); - calculer_rubriques(); -} - - -// http://doc.spip.org/@import_all_continue -function import_all_continue() -{ - global $meta, $flag_gz, $buf, $abs_pos, $my_pos, $connect_toutes_rubriques; - 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'); @@ -138,14 +130,71 @@ function import_all_continue() include_spip('inc/import'); @ignore_user_abort(1); - $request = unserialize($meta['request_restauration']); + $commencer_page = charger_fonction('commencer_page', 'inc'); + echo $commencer_page(_T('titre_page_index'), "accueil", "accueil"); + + debut_gauche(); + + debut_droite(); + $request = unserialize($GLOBALS['meta']['request_restauration']); + spip_log("import_all " . $GLOBALS['meta']['request_restauration']); + $dir = import_queldir(); + $r = import_tables($request, $dir); + + if ($r) { + spip_log("Erreur: $r"); + } + else { + if ($request['insertion']== 'on') { + $request['insertion'] = 'passe2'; + ecrire_meta("request_restauration", serialize($request)); + ecrire_meta("debut_restauration", "debut"); + ecrire_meta("status_restauration", "0"); + ecrire_metas(); + spip_log("import_all passe 2"); + $trans = translate_init($request); + $r = import_tables($request, $dir, $trans); + if ($r) spip_log("Erreur: $r"); + spip_query("DROP TABLE spip_translate"); + } + ecrire_acces(); // Mise a jour du fichier htpasswd + detruit_restaurateur(); + if ($charset = $GLOBALS['meta']['charset_restauration']) { + ecrire_meta('charset', $charset); + ecrire_metas(); + } + import_fin(); + include_spip('inc/rubriques'); + calculer_rubriques(); + } + echo "</body></html>\n"; +} + +function import_fin() { + + effacer_meta("charset_restauration"); + 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(); +} + +// http://doc.spip.org/@import_all_continue +function import_queldir() +{ + global $connect_toutes_rubriques; + if ($connect_toutes_rubriques) { $repertoire = _DIR_DUMP; if(!@file_exists($repertoire)) { $repertoire = preg_replace(','._DIR_TMP.',', '', $repertoire); $repertoire = sous_repertoire(_DIR_TMP, $repertoire); } - $dir = $repertoire; + return $repertoire; } else { $repertoire = _DIR_TRANSFERT; if(!@file_exists($repertoire)) { @@ -155,75 +204,8 @@ function import_all_continue() if(!@file_exists($repertoire.$connect_login)) { $sous_rep = sous_repertoire($repertoire, $connect_login); } - $dir = $sous_rep . '/'; + return $sous_rep . '/'; } - $archive = $dir . $request['archive']; - $affiche_progression_pourcent = @filesize($archive); - $commencer_page = charger_fonction('commencer_page', 'inc'); - echo $commencer_page(_T('titre_page_index'), "accueil", "accueil"); - - 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) || !$affiche_progression_pourcent) { - $texte_boite = _T('info_erreur_restauration'); - echo debut_boite_alerte(); - echo "<font face='Verdana,Arial,Sans,sans-serif' size='4' color='black'><b>$texte_boite</b></font>"; - echo fin_boite_alerte(); - - // 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)) { - $affiche_progression_pourcent = false; - $taille = taille_en_octets($my_pos); - $gz = true; - } else { - $taille = floor(100 * $my_pos / $affiche_progression_pourcent)." %"; - $gz = false; - } - $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>"; - - echo debut_boite_alerte(); - echo "<font FACE='Verdana,Arial,Sans,sans-serif' SIZE=4 color='black'><B>$texte_boite</B></font>"; - echo 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"); - - if ($GLOBALS['flag_ob_flush']) ob_flush(); - flush(); - - $_fopen = ($gz) ? 'gzopen' : 'fopen'; - $f = $_fopen($archive, "rb"); - $buf = ""; - $r = import_tables($f, $gz); - if ($r) { - spip_log("Erreur: $r"); - } - else { - if ($charset = $GLOBALS['meta']['charset_restauration']) - ecrire_meta('charset', $charset); - } - - import_fin(); - echo "</body></html>\n"; } ?> diff --git a/ecrire/inc/import.php b/ecrire/inc/import.php index 6018be3369..32be47c3bf 100644 --- a/ecrire/inc/import.php +++ b/ecrire/inc/import.php @@ -117,20 +117,6 @@ function import_debut($f, $gz=false) { $tables_trans = array( ); -// http://doc.spip.org/@import_fin -function import_fin() { - - effacer_meta("charset_restauration"); - 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(); -} - // http://doc.spip.org/@import_init_tables function import_init_tables() { @@ -145,41 +131,95 @@ function import_init_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("UPDATE spip_auteurs SET id_auteur=0, extra=$connect_id_auteur WHERE id_auteur=$connect_id_auteur"); spip_query("DELETE FROM spip_auteurs WHERE id_auteur!=0"); return $tables; } +// Effacement de la bidouille ci-dessus +// Toutefois si la table des auteurs ne contient plus qu'elle +// c'est que la sauvegarde etait incomplete et on restaure le compte +// pour garder la connection au site (mais il doit pas etre bien beau) + +// http://doc.spip.org/@detruit_restaurateur +function detruit_restaurateur() +{ + $r = spip_fetch_array(spip_query("SELECT COUNT(*) AS n FROM spip_auteurs")); + if ($r['n'] > 1) + spip_query("DELETE FROM spip_auteurs WHERE id_auteur=0"); + else { + spip_query("UPDATE spip_auteurs SET id_auteur=extra WHERE id_auteur=0"); + } +} + // http://doc.spip.org/@import_tables -function import_tables($f, $gz=false) { +function import_tables($request, $dir, $trans=array()) { global $import_ok, $abs_pos, $my_pos; + global $affiche_progression_pourcent; static $time_javascript; + $my_pos = $GLOBALS['meta']["status_restauration"]; + $archive = $dir . ($request['archive'] ? $request['archive'] : $request['archive_perso']); + $size = @filesize($archive); + + // attention : si $request['archive']=="", alors archive='data/' + // le test is_readable n'est donc pas suffisant + if (!@is_readable($archive)||is_dir($archive) || !$size) { + $texte_boite = _T('info_erreur_restauration'); + echo debut_boite_alerte(); + echo "<font face='Verdana,Arial,Sans,sans-serif' size='4' color='black'><b>$texte_boite</b></font>"; + echo fin_boite_alerte(); +// renvoyer True pour effacer les meta sans refaire calculer_rubriques: +// la restauration n'a pas encore commence, on peut eviter de tout casser + return $texte_boite; + } + + if (ereg("\.gz$", $archive)) { + $size = false; + $taille = taille_en_octets($my_pos); + $_fopen = 'gzopen'; + $gz = true; + } else { + $taille = floor(100 * $my_pos / $size)." %"; + $_fopen = 'fopen'; + $gz = false; + } + + import_affiche_javascript($taille); + + if ($GLOBALS['flag_ob_flush']) ob_flush(); + flush(); + list($my_date) = spip_fetch_array(spip_query("SELECT UNIX_TIMESTAMP(maj) AS d FROM spip_meta WHERE nom='debut_restauration'"), SPIP_NUM); if (!$my_date) return false; + if ($request['insertion']=='on') { + $request['init'] = 'insere_1_init'; + $request['boucle'] = 'import_insere'; + } elseif ($request['insertion']=='passe2') { + $request['init'] = 'insere_2_init'; + $request['boucle'] = 'import_translate'; + } else { + $request['init'] = 'import_init'; + $request['boucle'] = 'import_replace'; + } + + $f = $_fopen($archive, "rb"); $my_pos = (!isset($GLOBALS['meta']["status_restauration"])) ? 0 : $GLOBALS['meta']["status_restauration"]; + if ($my_pos==0) { - // par defaut pour les anciens sites - // il est contenu dans le xml d'import et sera reecrit dans import_debut +// par defaut pour les anciens sites +// il est contenu dans le xml d'import et sera reecrit dans import_debut ecrire_meta('charset_restauration', 'iso-8859-1'); - // Debut de l'importation - $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); } - // Normalement c'est controle par import_all auparavant - if (!$fimport) { - return _T('avis_archive_incorrect'); - } - ecrire_meta('version_archive_restauration', $version_archive); ecrire_meta('tag_archive_restauration', $tag_archive); ecrire_metas(); @@ -189,18 +229,24 @@ function import_tables($f, $gz=false) { $_fseek($f, $my_pos); $version_archive = $GLOBALS['meta']['version_archive_restauration']; $tag_archive = $GLOBALS['meta']['tag_archive_restauration']; - $fimport = import_charge_version($version_archive); - $tables = import_table_choix(); + // a completer pour les insertions + $request['init'] = 'import_table_choix'; } - while ($table = $fimport($f, $gz)) { + $fimport = import_charge_version($version_archive); + + // Normalement c'est controle par import_all auparavant + // c'est pour se proteger des reprises avortees + if (!$fimport) return _T('avis_archive_incorrect'); + + while ($table = $fimport($f, $request, $gz, $trans)) { // 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", "$abs_pos"); if (time() - $time_javascript > 3) { // 3 secondes - affiche_progression_javascript($abs_pos,$table); + affiche_progression_javascript($abs_pos,$size,$table); $time_javascript = time(); } @@ -209,51 +255,55 @@ function import_tables($f, $gz=false) { if (!$import_ok) return _T('avis_archive_invalide'); - // Mise a jour du fichier htpasswd - - ecrire_acces(); - - detruit_restaurateur(); - - affiche_progression_javascript('100 %'); + affiche_progression_javascript('100 %', $size); return false; } -// Destruction des entrees non restaurees - -// http://doc.spip.org/@detruit_restaurateur -function detruit_restaurateur() +function import_affiche_javascript($taille) { - spip_query("DELETE FROM spip_auteurs WHERE id_auteur=0"); + $max_time = ini_get('max_execution_time')*1000; + echo debut_boite_alerte(), + "<font face='Verdana,Arial,Sans,sans-serif' size='4' color='black'><b>", + _T('info_base_restauration'), + "</b></font>", + "<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>", + fin_boite_alerte(), + "<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"", + self(), + "\";',", + $max_time, + ");</script>\n"; } + // http://doc.spip.org/@affiche_progression_javascript -function affiche_progression_javascript($abs_pos,$table="") { - global $affiche_progression_pourcent; +function affiche_progression_javascript($abs_pos,$size, $table="") { include_spip('inc/charsets'); if ($GLOBALS['flag_ob_flush']) ob_flush(); flush(); echo "\n<script type='text/javascript'><!--\n"; if ($abs_pos == '100 %') { - $taille = $abs_pos; - if ($GLOBALS['erreur_restauration']) - echo "document.progression.recharge.value='".str_replace("'", "\\'", unicode_to_javascript(_T('avis_erreur')))."';\n"; + + if ($x = $GLOBALS['erreur_restauration']) + echo "document.progression.recharge.value='".str_replace("'", "\\'", unicode_to_javascript(_T('avis_erreur'))).": $x ';\n"; else echo "document.progression.recharge.value='".str_replace("'", "\\'", unicode_to_javascript(_T('info_fini')))."';\n"; - echo "document.progression.taille.value='$taille';\n"; + echo "document.progression.taille.value='$abs_pos';\n"; echo "//--></script>\n"; echo ("<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"".self()."\";',0);</script>\n"); } else { if (trim($table)) echo "document.progression.recharge.value='$table';\n"; - if (! $affiche_progression_pourcent) + if (!$size) $taille = ereg_replace(" ", " ", taille_en_octets($abs_pos)); else - $taille = floor(100 * $abs_pos / $affiche_progression_pourcent)." %"; + $taille = floor(100 * $abs_pos / $size)." %"; echo "document.progression.taille.value='$taille';\n"; echo "//--></script>\n<!--\n"; } diff --git a/ecrire/inc/import_0_0.php b/ecrire/inc/import_0_0.php index 52699d2994..6872ad2885 100644 --- a/ecrire/inc/import_0_0.php +++ b/ecrire/inc/import_0_0.php @@ -15,7 +15,7 @@ if (!defined("_ECRIRE_INC_VERSION")) return; // pour le support des vieux dump // pff ou vous l'avez trouve ce dump ? // http://doc.spip.org/@inc_import_0_0_dist -function inc_import_0_0_dist($f, $gz=false) { +function inc_import_0_0_dist($f, $request, $gz=false, $t='') { global $import_ok, $abs_pos, $my_pos; // detruire les tables a restaurer diff --git a/ecrire/inc/import_1_2.php b/ecrire/inc/import_1_2.php index e6cd8cd9b6..ae8ecc2277 100644 --- a/ecrire/inc/import_1_2.php +++ b/ecrire/inc/import_1_2.php @@ -38,7 +38,7 @@ function description_table($nom){ // pour le support des vieux dump // http://doc.spip.org/@inc_import_1_2_dist -function inc_import_1_2_dist($f, $gz=false) { +function inc_import_1_2_dist($f, $request, $gz=false, $t='') { global $import_ok, $abs_pos, $my_pos; static $field_desc = array (); diff --git a/ecrire/inc/import_1_3.php b/ecrire/inc/import_1_3.php index 1561a1e052..3df4cda5b3 100644 --- a/ecrire/inc/import_1_3.php +++ b/ecrire/inc/import_1_3.php @@ -36,76 +36,177 @@ function description_table($nom){ return array($nom,array()); } +function import_init($request, $my_pos) { + + // au premier appel destruction des tables a restaurer + return (!$my_pos) ? import_init_tables() : import_table_choix(); +} + +function insere_2_init($request, $my_pos) { + + // l'insertion ne porte que sur les tables principales + $t = array_keys($GLOBALS['tables_principales']); + // mais pas cette table car elle n'est pas extensible + // (si on essaye ==> duplication sur la cle secondaire) + unset($t[array_search('spip_types_documents', $t)]); + // ni celle-ci a cause de la duplication des login + unset($t[array_search('spip_auteurs', $t)]); + return $t; +} + +function insere_1_init($request, $my_pos) { + + // preparation de la table des translations + $spip_translate = array( + "type" => "VARCHAR(16) NOT NULL", + "id_old" => "BIGINT (21) DEFAULT '0' NOT NULL", + "id_new" => "BIGINT (21) DEFAULT '0' NOT NULL"); + + $spip_translate_key = array( + "PRIMARY KEY" => "id_old, id_new, type", + "KEY id_old" => "id_old"); + + include_spip('base/create'); + spip_create_table('spip_translate', $spip_translate, $spip_translate_key, true); + // au cas ou la derniere fois ce serait terminee anormalement + spip_query("DELETE FROM spip_translate"); + return insere_2_init($request, $my_pos); +} + +function translate_init($request, $my_pos=0) { + /* + construire le tableau PHP de la table spip_translate + (on l'a mis en table pour pouvoir reprendre apres interruption + mais cette reprise n'est pas encore programmee) + */ + $q = spip_query("SELECT * FROM spip_translate"); + $trans = array(); + while ($r = spip_fetch_array($q)) { + $trans[$r['type']][$r['id_old']] = $r['id_new']; + } + return $trans; +} // http://doc.spip.org/@inc_import_1_3_dist -function inc_import_1_3_dist($f, $gz=false) { - global $import_ok, $abs_pos, $my_pos; +function inc_import_1_3_dist($lecteur, $request, $gz=false, $trans=array()) { + global $import_ok, $abs_pos, $my_pos, $tables_trans; static $tables = ''; + static $phpmyadmin, $fin; static $field_desc = array (); + static $defaut = array('field' => array()); + + // au premier appel, init des invariants de boucle + + if (!$tables OR $trans) { + $init = $request['init']; + $tables = $init($request, $my_pos); + $phpmyadmin = preg_match("{^phpmyadmin::}is", + $GLOBALS['meta']['version_archive_restauration']) + ? array(array('"','>'),array('"','>')) + : false; + $fin = '/' . $GLOBALS['meta']['tag_archive_restauration']; + } - global $tables_trans; - static $primary_table; - static $relation_liste; - global $tables_principales; - global $tables_auxiliaires; + $b = ''; - // au premier appel, detruire les tables a restaurer + if (!($table = xml_fetch_tag($lecteur, $b, $gz))) return false; + if ($table == $fin) return !($import_ok = true); + $new = isset($tables_trans[$table]) ? $tables_trans[$table]: $table; - if (!$tables) - $tables = (!$my_pos) ? import_init_tables() : import_table_choix(); + // indique a la fois la fonction a appliquer + // et les infos qu'il faut lui communiquer + $boucle = $request['boucle']; - $phpmyadmin = preg_match("{^phpmyadmin::}is", $GLOBALS['meta']['version_archive_restauration']); - $tag_fermant = $GLOBALS['meta']['tag_archive_restauration']; - $import_ok = false; + if (!in_array($new,$tables)) + $field_desc[$boucle][$table] = $desc = $defaut; + elseif (isset($field_desc[$boucle][$table])) + $desc = $field_desc[$boucle][$table]; + else { +// recuperer la description de la table pour connaitre ses champs valides + list($nom,$desc) = description_table($table); + if (!isset($desc['field'])) + $desc = $defaut; + else { + if ($request['insertion']=='on') { +// Ne memoriser que la cle primaire pour le premier tour de l'insertion. +// car les autres valeurs rentreraient en conflit avec les presentes + $p = $desc['key']["PRIMARY KEY"]; + $desc['field'] = array($p => $desc['field'][$p]); + } + } + $field_desc[$boucle][$table] = $desc; + } - $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"); + $values = import_lire_champs($lecteur, + $desc['field'], + $gz, + $phpmyadmin, + '/' . $table); + + if ($values === false) return ($import_ok = false); + if ($values) { + if (!$boucle($values, $new, $desc, $trans)) { + $GLOBALS['erreur_restauration'] = spip_sql_error(); + } + } - if (!isset($field_desc[$table])){ - // recuperer la description de la table pour connaitre ses champs valides - list($nom,$desc) = description_table($table); - if (isset($desc['field'])) - $field_desc[$table] = $desc['field']; - else - $field_desc[$table] = NULL; + return $import_ok = $new; +} + +function import_replace($values, $table, $desc, $trans) { + return spip_query("REPLACE $table (" . join(',',array_keys($values)) . ') VALUES (' .join(',',$values) . ')'); +} + +function import_insere($values, $table, $desc, $trans) { + // reserver une place dans les tables principales + $n = spip_abstract_insert($table, '', '()'); + // et memoriser la correspondance dans la table auxilaire + if ($n) { + $type_id = $desc['key']["PRIMARY KEY"]; + $n = spip_abstract_insert('spip_translate', + "(id_old, id_new, type)", + "(". $values[$type_id] .",$n,'$type_id')"); + } + return $n; +} + +function import_translate($values, $table, $desc, $trans) { + $vals = ''; + + foreach ($values as $k => $v) { + + if ($k=='id_parent' OR $k=='id_secteur') $k = 'id_rubrique'; + + if (isset($trans[$k]) AND isset($trans[$k][$v])) { + $v = $trans[$k][$v]; + } + $vals .= ",$v"; } - $fields = $field_desc[$table]; + return spip_query("REPLACE $table (" . join(',',array_keys($values)) . ') VALUES (' .substr($vals,1) . ')'); +} - // Lire les champs de l'objet +function import_lire_champs($f, $fields, $gz, $phpmyadmin, $table) +{ + $values = array(); 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 fermant $col innatendu"); - break; + if ($col[0] == '/') { + if ($col != $table) + // autre tag fermant ici est une erreur de format + spip_log("restauration : table $table tag fermant $col innatendu"); + break; } $value = ''; if (!xml_fetch_tag($f, $value, $gz)) return false; - if ( ($col != 'maj') - && ($fields==NULL or isset($fields[$col])) ) { + if ( ($col != 'maj') AND (isset($fields[$col])) ) { if ($phpmyadmin) - $value = str_replace(array('"','>'),array('"','>'),$value); - $values[$col] = _q($value); + $value = str_replace($phpmyadmin[0],$phpmyadmin[1],$value); + $values[$col]= _q($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(',', array_keys($values)) . ') 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 "; + return $values; } ?> diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php index fba72239bf..d2d0be0157 100644 --- a/ecrire/inc/utils.php +++ b/ecrire/inc/utils.php @@ -225,8 +225,8 @@ function spip_query($query, $serveur='') { // a demenager dans base/abstract_sql a terme // http://doc.spip.org/@_q -function _q($arg_sql) { - return (is_int($arg_sql)) ? $arg_sql : ("'" . addslashes($arg_sql) . "'"); +function _q($a) { + return (is_numeric($a)) ? strval($a) : ("'" . addslashes($a) . "'"); } // Renvoie le _GET ou le _POST emis par l'utilisateur -- GitLab