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("&","&",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('&', '&', str_replace('<', '<', $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('&','<'),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('"','>'),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(" ", " ", 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(" ", " ", 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