diff --git a/ecrire/exec/admin_tech.php b/ecrire/exec/admin_tech.php index 022fc5822e5ed11184e92a1d626e9a88a025743e..72f8bb4b6b90435dfdfe20d60d55d9b781797b15 100644 --- a/ecrire/exec/admin_tech.php +++ b/ecrire/exec/admin_tech.php @@ -145,6 +145,10 @@ echo "</table>"; echo "<p><input name='insertion' type='radio' /> ", _L('Fusionner la base actuelle et la sauvegarde'), '</p>'; + echo "<p>", + _L("Eventuellement, URL du site d'origine :"), + "<input name='url_site' type='texte' />", + '</p>'; fin_cadre_relief(); echo "\n</p><div align='right'><input class='fondo' type='submit' value='", diff --git a/ecrire/exec/import_all.php b/ecrire/exec/import_all.php index 9fbae317cf140d108f4a49f42f962c74fcd7578a..0a295ffdeef9b501ec1e5d92398b886494e4cc07 100644 --- a/ecrire/exec/import_all.php +++ b/ecrire/exec/import_all.php @@ -116,39 +116,43 @@ function exec_import_all_dist() // precaution inutile I think (esj) 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) { - - global $trans; - if ($request['insertion'] == 'passe2') { - include_spip('inc/import_insere'); - $trans = translate_init($request); - } else $trans = array(); - - $res = import_tables($request, $dir); - } + $res = $my_date ? import_all_milieu($request, $dir) : ''; echo $res, "</body></html>\n"; - if ($request['insertion'] == 'on') { + if ($request['insertion'] == 'on' AND $res) { $request['insertion'] = 'passe2'; + if ($request['url_site'] + AND substr($request['url_site'],-1) != '/') + $request['url_site'] .= '/'; import_all_debut($request); - redirige_par_entete('./'); - } else if ($request['insertion']) - spip_query("DROP TABLE spip_translate"); - + $res = import_all_milieu($request, $dir); + } + if ($charset = $GLOBALS['meta']['charset_restauration']) { ecrire_meta('charset', $charset); ecrire_metas(); } detruit_restaurateur(); - import_all_fin(); + import_all_fin($request); include_spip('inc/rubriques'); calculer_rubriques(); if (!$res) ecrire_acces(); // Mise a jour du fichier htpasswd } +function import_all_milieu($request, $dir) +{ + global $trans; + if ($request['insertion'] == 'passe2') { + include_spip('inc/import_insere'); + $trans = translate_init($request); + } else $trans = array(); + + return import_tables($request, $dir); +} + // http://doc.spip.org/@import_all_debut function import_all_debut($request) { ecrire_meta("request_restauration", serialize($request)); @@ -158,7 +162,7 @@ function import_all_debut($request) { } // http://doc.spip.org/@import_all_fin -function import_all_fin() { +function import_all_fin($request) { effacer_meta("charset_restauration"); effacer_meta("charset_insertion"); @@ -169,6 +173,9 @@ function import_all_fin() { effacer_meta('version_archive_restauration'); effacer_meta('tag_archive_restauration'); ecrire_metas(); + if ($request['insertion'] == 'passe2') + spip_query("DROP TABLE spip_translate"); + } // http://doc.spip.org/@import_queldir diff --git a/ecrire/inc/import.php b/ecrire/inc/import.php index a06e0a97f4e1588556ed6910a8c054eeeff17824..bb0d6056648a55bac3d85dd515f631f9689ecee9 100644 --- a/ecrire/inc/import.php +++ b/ecrire/inc/import.php @@ -121,9 +121,6 @@ function import_debut($f, $gz='fread') { return $r; } } - // improbable: fichier correct avant debut_admin et plus apres - import_all_fin(); - die(_T('info_erreur_restauration')); } // on conserve ce tableau pour faire des translations @@ -180,7 +177,8 @@ function import_tables($request, $dir) { if ($request['insertion']=='on') { include_spip('inc/import_insere'); - $request['init'] = (!$abs_pos) ? 'insere_1_init' : 'insere_2_init'; $request['boucle'] = 'import_insere'; + $request['init'] = (!$abs_pos) ? 'insere_1_init' : 'insere_1bis_init'; + $request['boucle'] = 'import_insere'; } elseif ($request['insertion']=='passe2') { $request['init'] = 'insere_2_init'; $request['boucle'] = 'import_translate'; @@ -205,6 +203,8 @@ function import_tables($request, $dir) { if ($abs_pos==0) { list($tag, $r, $charset) = import_debut($file, $gz); + // improbable: fichier correct avant debut_admin et plus apres + if (!$tag) return !($import_ok = true); // tag ouvrant du Dump: // 'SPIP' si fait par spip, nom de la base source si fait par phpmyadmin $version_archive = $r['version_archive']; @@ -230,18 +230,25 @@ function import_tables($request, $dir) { flush(); $oldtable =''; + $cpt = 0; + $pos = $abs_pos; while ($table = $fimport($file, $request, $gz)) { // memoriser pour pouvoir reprendre en cas d'interrupt, // mais pas d'ecriture sur fichier, ca ralentit trop ecrire_meta("status_restauration", "$abs_pos"); if ($oldtable != $table) { - spip_log("Restauration de $table (commence en $abs_pos)"); + if ($oldtable) spip_log("$cpt entrees"); + spip_log("Analyse de $table (commence en $pos)"); affiche_progression_javascript($abs_pos,$size,$table); $oldtable = $table; - } + $cpt = 0; + $pos = $abs_pos; + } + $cpt++; } + spip_log("$cpt entrees"); - if (!$import_ok) + if (!$import_imok) $res = _T('avis_archive_invalide'); else { $res = ''; diff --git a/ecrire/inc/import_1_3.php b/ecrire/inc/import_1_3.php index b4a559dd6f7f7130ff3072429f2b3e3ad233a1cd..971c49930541c20582800d4968c6f3c0c4a57122 100644 --- a/ecrire/inc/import_1_3.php +++ b/ecrire/inc/import_1_3.php @@ -78,7 +78,7 @@ function inc_import_1_3_dist($lecteur, $request, $gz='fread') { if ($request['insertion']=='on') { // Au premier tour de l'insertion, ne memoriser que le strict necessaire // pour pouvoir identifier avec l'existant. - +// (Faudrait convenir d'une structure de donnees, c'est lourd & inextensible) $b = array(); if (isset($desc['field'][$p='titre'])) $b[$p]= $desc['field'][$p]; @@ -86,6 +86,13 @@ function inc_import_1_3_dist($lecteur, $request, $gz='fread') { $b[$p]= $desc['field'][$p]; if (isset($desc['field'][$p='id_parent'])) $b[$p]= $desc['field'][$p]; + if (isset($desc['field'][$p='id_rubrique'])) + $b[$p]= $desc['field'][$p]; + if (isset($desc['field'][$p='fichier'])) { + $b[$p]= $desc['field'][$p]; + $b['taille']= $desc['field']['taille']; + spip_log("pass1 " . join(',', array_keys($b))); + } $p = $desc['key']["PRIMARY KEY"]; $b[$p] = $desc['field'][$p]; $desc['field'] = $b; diff --git a/ecrire/inc/import_insere.php b/ecrire/inc/import_insere.php index 30ef76ccbe9dc489887b476df3cb974f00997d69..0d01682ceb8529f3f39e52837daecd127fa892e1 100644 --- a/ecrire/inc/import_insere.php +++ b/ecrire/inc/import_insere.php @@ -12,27 +12,6 @@ if (!defined("_ECRIRE_INC_VERSION")) return; -// http://doc.spip.org/@insere_2_init -function insere_2_init($request) { - - // l'insertion porte 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)]); - // et les tables auxiliaires sur les mots car on sait les identifier - $t[]= 'spip_mots_articles'; - $t[]= 'spip_mots_breves'; - $t[]= 'spip_mots_rubriques'; - $t[]= 'spip_mots_syndic'; - $t[]= 'spip_mots_forum'; - $t[]= 'spip_mots_documents'; - - return $t; -} - // http://doc.spip.org/@insere_1_init function insere_1_init($request) { @@ -52,7 +31,38 @@ function insere_1_init($request) { 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); + return insere_1bis_init($request); +} + +// http://doc.spip.org/@insere_2_init +function insere_1bis_init($request) { + + // l'insertion porte 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; +} + +// En passe 2, relire les tables principales et les tables auxiliaires +// sur les mots et les documents car on sait les identifier + +function insere_2_init($request) { + $t = insere_1bis_init($request); + + $t[]= 'spip_mots_articles'; + $t[]= 'spip_mots_breves'; + $t[]= 'spip_mots_rubriques'; + $t[]= 'spip_mots_syndic'; + $t[]= 'spip_mots_forum'; + $t[]= 'spip_mots_documents'; + $t[]= 'spip_documents_articles'; + $t[]= 'spip_documents_rubriques'; + + return $t; } // construire le tableau PHP de la table spip_translate @@ -88,56 +98,93 @@ function import_insere($values, $table, $desc, $request) { } $ajout = 1; } - // et memoriser la correspondance dans la table auxiliaire - // si different et pas de recherche dessus plus tard - if (($n != $values[$type_id]) OR $type_id == 'id_groupe') { - if (is_array($n)) - list($id, $titre) = $n; - else {$id = $n; $titre = "";} - spip_abstract_insert('spip_translate', + + if (is_array($n)) + list($id, $titre) = $n; + else {$id = $n; $titre = "";} + spip_abstract_insert('spip_translate', "(id_old, id_new, titre, type, ajout)", "(". $values[$type_id] .",$id, " . _q($titre) . ", '$type_id', '$ajout')"); - } } // Renumerotation des entites collectees -// Le tableau de correspondance est passe en reference pour que le nouveau -// numero d'une entite soit calcule une seule fois, a sa premiere occurrence. -// Si une allocation est finalement necessaire, la renumerotation -// est repercutee sur la table SQL temporaire pour qu'en cas de reprise -// sur Time-Out il n'y ait pas reallocation. -// Autrement on evite cet acces SQL, quitte a recalculer le nouveau numero -// si une autre occurrence est rencontree a la reprise. Pas dramatique. +// Appelle la fonction specifique a la table, ou a defaut la std. +// Le tableau de correspondance est global, et permet qu'un numero +// d'une entite soit calcule une seule fois, a sa premiere occurrence. +// (Mais des requetes avec jointures eviteraient sa construction. A voir) // http://doc.spip.org/@import_translate function import_translate($values, $table, $desc, $request) { + + if (!function_exists($f = 'import_translate_' . $table)) + $f = 'import_translate_std'; + $f($values, $table, $desc, $request); +} + +// La fonction d'insertion apres renumerotation. +// Afin qu'inserer une 2e fois la meme sauvegarde ne change pas la base, +// chaque entree de la sauvegarde est ignoree s'il existe une entree +// de meme titre avec le meme contexte (parent etc) dans la base installee. +// Une synchronisation plus fine serait preferable, cf [8002] + +function import_inserer_translate($values, $table, $desc, $request, $vals) { global $trans; + $p = $desc['key']["PRIMARY KEY"]; + $v = $values[$p]; + if (!isset($trans[$p]) OR !isset($trans[$p][$v]) OR $trans[$p][$v][2]) + spip_query("REPLACE $table (" . join(',',array_keys($values)) . ') VALUES (' .substr($vals,1) . ')'); +} + +// Insertion avec renumerotation, y compris des raccourcis. +function import_translate_std($values, $table, $desc, $request) { + $vals = ''; foreach ($values as $k => $v) { - if ($k=='id_parent' OR $k=='id_secteur') $k = 'id_rubrique'; + if (($k=='chapo') AND preg_match(',^=(\d+)(.*)$,', $v, $m)) + $v = '=' . importe_translate_maj('id_article',$m[1]).$m[2]; + else { + if ($k=='id_parent' OR $k=='id_secteur') + $k = 'id_rubrique'; + $v = importe_raccourci($k,importe_translate_maj($k, $v)); + } + $vals .= "," . _q($v); + } + import_inserer_translate($values, $table, $desc, $request, $vals); +} - $v = importe_translate_maj($k, $v); +function import_translate_spip_documents($values, $table, $desc, $request) { - if (preg_match_all(_RACCOURCI_LIEN, $v, $m, PREG_SET_ORDER)) { - foreach ($m as $regs) { - $v = importe_raccourci($regs, $k, $v); - } - } - $vals .= "," . _q($v); + if (isset($request['url_site'])) { + $distancer = ($values['distant'] == 'non'); + $url = $request['url_site']; + } else $distancer = false; + + $values['distant']= 'oui'; + + $vals = ''; + foreach ($values as $k => $v) { + if ($distancer AND $k=='fichier') + $v = $url .$v; + else $v = importe_raccourci($k,importe_translate_maj($k, $v)); + $vals .= "," . _q($v); } - // pas la peine d'ecraser avec les memes valeurs si rien de neuf - $p = $desc['key']["PRIMARY KEY"]; - $v = $values[$p]; - if (!isset($trans[$p]) OR !isset($trans[$p][$v]) OR $trans[$p][$v][2]) - spip_query($q = "REPLACE $table (" . join(',',array_keys($values)) . ') VALUES (' .substr($vals,1) . ')'); + import_inserer_translate($values, $table, $desc, $request, $vals); } +// Fonction de renumerotation, par delegation aux fonction specialisees +// Si une allocation est finalement necessaire, celles-ci doivent repercuter +// la renumerotation sur la table SQL temporaire pour qu'en cas de reprise +// sur Time-Out il n'y ait pas reallocation. +// En l'absence d'allocation, cet acces SQL peut etre omis, quitte a +// recalculer le nouveau numero si une autre occurrence est rencontree +// a la reprise. Pas dramatique. + // http://doc.spip.org/@importe_translate_maj function importe_translate_maj($k, $v) { - global $trans; + global $trans; if (!(isset($trans[$k]) AND isset($trans[$k][$v]))) return $v; list($g, $titre, $ajout) = $trans[$k][$v]; @@ -154,27 +201,41 @@ function importe_translate_maj($k, $v) } // http://doc.spip.org/@importe_raccourci -function importe_raccourci($regs, $k, $v) +function importe_raccourci($k, $v) { - $lien = vider_url($regs[3]); # supprimer 'http://' ou 'mailto:' - - if (!$match = typer_raccourci($lien)) return $v; - - list($f,$objet,$id,$params,$ancre) = $match; - - $k = 'id_' . $f; - $g = importe_translate_maj($k, $id); - - if ($g == $id) return $v; + if (preg_match_all(_RACCOURCI_LIEN, $v, $m, PREG_SET_ORDER)) { + foreach ($m as $regs) { + // supprimer 'http://' ou 'mailto:' + $lien = vider_url($regs[3]); + if ($match = typer_raccourci($lien)) { + list($f,$objet,$id,$params,$ancre) = $match; + $k = 'id_' . $f; + $g = importe_translate_maj($k, $id); + if ($g != $id) { + + $rac = '[' . $regs[1] . '->' . $reg[2] . $objet . $g . $params . $ancre .']'; + $v = str_replace($regs[0], $rac, $v); + } + } + } + } + return $v; +} - $rac = '[' . $regs[1] . '->' . $reg[2] . $objet . $g . $params . $ancre .']'; - return str_replace($regs[0], $rac, $v); +// un document importe est considere comme identique a un document present +// s'ils ont meme taille et meme nom +function import_identifie_id_document($values, $table, $desc, $request) { + $t = $values['taille']; + $f = $values['fichier']; + $h = $request['url_site'] . $f; + $r = spip_fetch_array(spip_query($q="SELECT id_document, fichier FROM spip_documents WHERE taille=" . _q($t) . " AND (fichier=" . _q($f) . " OR fichier= " . _q($h) . ')'), SPIP_NUM); + return $r; } // deux groupes de mots ne peuvent avoir le meme titre ==> identification // http://doc.spip.org/@import_identifie_id_groupe function import_identifie_id_groupe($values, $table, $desc, $request) { - $r = spip_fetch_array(spip_query($q = "SELECT id_groupe, titre FROM spip_groupes_mots WHERE titre=" . _q($values['titre'])), SPIP_NUM); + $r = spip_fetch_array(spip_query("SELECT id_groupe, titre FROM spip_groupes_mots WHERE titre=" . _q($values['titre'])), SPIP_NUM); return $r; } @@ -185,11 +246,11 @@ function import_identifie_id_mot($values, $table, $desc, $request) { return array((0 - $values['id_groupe']), $values['titre']); } -// mot de meme titre et de meme groupe ==> identification +// Passe 2: mot de meme titre et de meme groupe ==> identification // http://doc.spip.org/@import_identifie_parent_id_mot function import_identifie_parent_id_mot($id_groupe, $titre, $v) { - global $trans; + global $trans; $titre = _q($titre); $id_groupe = 0-$id_groupe; if (isset($trans['id_groupe']) @@ -201,9 +262,30 @@ function import_identifie_parent_id_mot($id_groupe, $titre, $v) $r = spip_abstract_insert('spip_mots', '', '()'); spip_query("REPLACE spip_translate (id_old, id_new, titre, type, ajout) VALUES ($v,$r,$titre,'id_mot',1)"); return $r; +} + +// idem pour les articles +function import_identifie_id_article($values, $table, $desc, $request) { + return array((0 - $values['id_rubrique']), $values['titre']); +} + +// Passe 2 des articles comme pour les mots + +function import_identifie_parent_id_article($id_parent, $titre, $v) +{ + $id_parent = importe_translate_maj('id_rubrique', (0 - $id_parent)); + $titre = _q($titre); + $r = spip_fetch_array(spip_query("SELECT id_article FROM spip_articles WHERE titre=$titre AND id_rubrique=$id_parent" )); + + if ($r) return (0 - $r['id_article']); + + $r = spip_abstract_insert('spip_articles', '', '()'); + spip_query("REPLACE spip_translate (id_old, id_new, titre, type, ajout) VALUES ($v,$r,$titre,'id_article',1)"); + return $r; } + // pour une rubrique le titre est insuffisant, il faut l'identite du parent // Memoriser ces 2 infos et le signaler a import_translate grace a 1 negatif // http://doc.spip.org/@import_identifie_id_rubrique @@ -211,7 +293,7 @@ function import_identifie_id_rubrique($values, $table, $desc, $request) { return array((0 - $values['id_parent']), $values['titre']); } -// renumerotation en cascade. +// Passe 2 des rubriques, renumerotation en cascade. // rubrique de meme titre et de meme parent ==> identification // http://doc.spip.org/@import_identifie_parent_id_rubrique function import_identifie_parent_id_rubrique($id_parent, $titre, $v) @@ -256,5 +338,4 @@ function import_alloue_id_rubrique($id_parent, $titre, $v) { spip_query("REPLACE spip_translate (id_old, id_new, titre, type, ajout) VALUES ($v,$r,$titre,'id_rubrique',1)"); return $r; } - ?>