X-Git-Url: https://git.cyclocoop.org/%242?a=blobdiff_plain;f=www%2Fecrire%2Finc%2Fexport.php;fp=www%2Fecrire%2Finc%2Fexport.php;h=0637d8602403ca685eba11be8b5b362fe6779411;hb=e99f0878011913365e49b30d90e496c24c301393;hp=25afae2549f7fc6423b372e613ff60af978c68f9;hpb=80b4d3e85f78d402ed2e73f8f5d1bf4c19962eed;p=velocampus%2Fweb%2Fwww.git
diff --git a/www/ecrire/inc/export.php b/www/ecrire/inc/export.php
index 25afae2..0637d86 100644
--- a/www/ecrire/inc/export.php
+++ b/www/ecrire/inc/export.php
@@ -3,7 +3,7 @@
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
- * Copyright (c) 2001-2011 *
+ * Copyright (c) 2001-2014 *
* Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
* *
* Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
@@ -15,118 +15,132 @@ if (!defined('_ECRIRE_INC_VERSION')) return;
define('_EXPORT_TRANCHES_LIMITE', 200);
define('_EXTENSION_PARTIES', '.gz');
-// http://doc.spip.org/@exec_export_all_args
function inc_export_dist($meta)
{
if (!isset($GLOBALS['meta'][$meta])) {
include_spip('inc/minipres');
echo minipres();
+ } else {
+ while (true) {
+ $val = unserialize($GLOBALS['meta'][$meta]);
+ if ($dir = export_repertoire($meta, $val))
+ export_trace($val, $dir, $meta);
+ else break;
+ }
+ list($gz, $archive, $rub,,,,$serveur,$save) = $val;
+ // retour a exec_export_all qui renverra sur action_export_all
+ return "end,$gz,$archive,$rub,$serveur,$save";
}
- else {
- $start = false;
- list($gz, $archive, $rub, $tables_for_dump, $etape_actuelle, $sous_etape) =
- unserialize($GLOBALS['meta'][$meta]);
-
- // determine upload va aussi initialiser l'index "restreint"
- $maindir = determine_upload();
- if (!$GLOBALS['visiteur_session']['restreint'])
- $maindir = _DIR_DUMP;
- $dir = sous_repertoire($maindir, $meta);
- $file = $dir . $archive;
- $metatable = $meta . '_tables';
+}
- // Reperer une situation anormale (echec reprise sur interruption)
- if (!$etape_actuelle AND !$sous_etape) {
- $l = preg_files($file . ".part_[0-9]+_[0-9]+");
- if ($l) {
- spip_log("menage d'une sauvegarde inachevee: " . join(',', $l));
- foreach($l as $dummy) spip_unlink($dummy);
- }
- $start = true; // utilise pour faire un premier hit moitie moins long
- $tables_sauvegardees = array();
- } else $tables_sauvegardees = isset($GLOBALS['meta'][$metatable])?unserialize($GLOBALS['meta'][$metatable]):array();
-
- // concatenation des fichiers crees a l'appel precedent
- ramasse_parties($dir, $archive);
- $all = count($tables_for_dump);
- if ($etape_actuelle > $all OR !$all){
- return "end,$gz,$archive,$rub"; // c'est fini !
- }
+// calcule le repertoire de la sauvegarde
+// et le nettoie au premier appel.
+// Aux suivants, retourne le nom du repertoire ou rien si c'est fini.
- include_spip('inc/minipres');
- @ini_set("zlib.output_compression","0"); // pour permettre l'affichage au fur et a mesure
+function export_repertoire($meta, $val_meta)
+{
+ list(, $archive, , $tables, $etape, $sous_etape, , $save) = $val_meta;
+ if (!function_exists('inc_export_' . ($save ? $save : 'xml'))) {
+ spip_log("fonction inc_export_$save indisponible");
+ return false;
+ }
+ $dir = base_dump_dir($meta);
- echo ( install_debut_html(_T('info_sauvegarde') . " ($all)"));
+ // Reperer une situation anormale (echec reprise sur interruption)
+ if (($etape == 1) AND !$sous_etape) {
+ $file = $dir . $archive;
+ $l = preg_files($file . ".part_[0-9]+_[0-9]+");
+ if ($l) {
+ spip_log("menage d'une sauvegarde inachevee: " . join(',', $l));
+ foreach($l as $dummy) spip_unlink($dummy);
+ }
+ }
+ $all = count($tables);
+ return ($etape > $all OR !$all) ? false : $dir;
+}
+
+function export_trace($val_meta, $dir, $meta)
+{
+ list($gz, $archive, $rub, $tables_for_dump, $etape_actuelle, $sous_etape, $serveur, $save) = $val_meta;
+ include_spip('inc/minipres');
+ // pour permettre l'affichage au fur et a mesure
+ @ini_set("zlib.output_compression","0");
- if (!($timeout = ini_get('max_execution_time')*1000));
- $timeout = 30000; // parions sur une valeur tellement courante ...
+ if (!($timeout = ini_get('max_execution_time')*1000));
+ $timeout = 30000; // parions sur une valeur tellement courante ...
// le premier hit est moitie moins long car seulement une phase d'ecriture de morceaux
// sans ramassage
// sinon grosse ecriture au 1er hit, puis gros rammassage au deuxieme avec petite ecriture,... ca oscille
- if ($start) $timeout = round($timeout/2);
+ if (!$etape_actuelle AND !$sous_etape) {
+ $timeout = round($timeout/2);
+ $tables_sauvegardees = array();
+ } else {
+ $metatable = $meta . '_tables';
+ $tables_sauvegardees = isset($GLOBALS['meta'][$metatable])?unserialize($GLOBALS['meta'][$metatable]):array();
+ }
// Les sauvegardes partielles prennent le temps d'indiquer les logos
// Instancier une fois pour toutes, car on va boucler un max.
// On complete jusqu'au secteur pour resituer dans l'arborescence)
- if ($rub) {
- $GLOBALS['chercher_logo'] = charger_fonction('chercher_logo', 'inc',true);
- $les_rubriques = complete_fils(array($rub));
- $les_meres = complete_secteurs(array($rub));
- } else {
- $GLOBALS['chercher_logo'] = false;
- $les_rubriques = $les_meres = '';
- }
+ if ($rub) {
+ $GLOBALS['chercher_logo'] = charger_fonction('chercher_logo', 'inc',true);
+ $les_rubriques = complete_fils(array($rub), $serveur);
+ $les_meres = complete_secteurs(array($rub), $serveur);
+ } else {
+ $GLOBALS['chercher_logo'] = false;
+ $les_rubriques = $les_meres = '';
+ }
// script de rechargement auto sur timeout
- $redirect = generer_url_ecrire("export_all");
- echo http_script("window.setTimeout('location.href=\"".$redirect."\";',$timeout)");
-
- echo "
\n";
- $etape = 1;
- foreach($tables_for_dump as $table){
- if ($etape_actuelle > $etape) {
- // sauter les deja faits, mais rappeler qu'ils sont fait
- echo ( "\n
".$etape. '. '."". $tables_sauvegardees[$table]);
- }
+ $redirect = generer_url_ecrire("export_all");
+ $all = count($tables_for_dump);
+ echo ( install_debut_html(_T('info_sauvegarde') . " ($all)"));
+ echo http_script("window.setTimeout('location.href=\"".$redirect."\";',$timeout)");
+
+ echo "
\n";
+ $etape = 1;
+ foreach($tables_for_dump as $table){
+ if ($etape_actuelle > $etape) {
+ // sauter les deja faits, mais rappeler qu'ils sont fait
+ echo ( "\n
".$etape. '. '."". $tables_sauvegardees[$table]);
+ }
+ else {
+ echo ( "\n
".$etape. '. '. $table." ");
+ $r = sql_countsel($table, array(), array(), array(), $serveur);
+ flush();
+ if (!$r) $r = ( _T('texte_vide'));
else {
- echo ( "\n
".$etape. '. '. $table." ");
- $r = sql_countsel($table);
- flush();
- if (!$r) $r = ( _T('texte_vide'));
- else {
$f = $dir . $archive . '.part_' . sprintf('%03d',$etape);
$r = export_objets($table, $sous_etape, $r, $f, $les_rubriques, $les_meres, $meta);
$r += $sous_etape*_EXPORT_TRANCHES_LIMITE;
// info pas fiable si interruption+partiel
if ($rub AND $etape_actuelle > 1) $r = ">= $r";
- }
- echo " $r";
- flush();
- $sous_etape = 0;
- // on utilise l'index comme ca c'est pas grave si on ecrit plusieurs fois la meme
- $tables_sauvegardees[$table] = "$table ($r)";
- ecrire_meta($metatable, serialize($tables_sauvegardees),'non');
}
- $etape++;
- $v = serialize(array($gz, $archive, $rub, $tables_for_dump, $etape,$sous_etape));
- ecrire_meta($meta, $v,'non');
+ echo " $r";
+ flush();
+ $sous_etape = 0;
+ // on utilise l'index comme ca c'est pas grave si on ecrit plusieurs fois la meme
+ $tables_sauvegardees[$table] = "$table ($r)";
+ ecrire_meta($meta . '_tables', serialize($tables_sauvegardees),'non');
}
- echo ( "
\n");
- // si Javascript est dispo, anticiper le Time-out
- echo ("\n");
- echo (install_fin_html());
- flush();
+ $etape++;
+ $v = serialize(array($gz, $archive, $rub, $tables_for_dump, $etape,$sous_etape, $serveur, $save));
+ ecrire_meta($meta, $v,'non');
}
+ echo ( "
\n");
+ // si Javascript est dispo, anticiper le Time-out
+ echo ("\n");
+ echo (install_fin_html());
+ flush();
}
-
// http://doc.spip.org/@complete_secteurs
-function complete_secteurs($les_rubriques)
+function complete_secteurs($les_rubriques, $serveur='')
{
$res = array();
foreach($les_rubriques as $r) {
do {
- $r = sql_getfetsel("id_parent", "spip_rubriques", "id_rubrique=$r");
+ $r = sql_getfetsel("id_parent", "spip_rubriques", "id_rubrique=$r", array(), array(), '', array(), $serveur);
if ($r) {
if ((isset($les_rubriques[$r])) OR isset($res[$r]))
$r = false;
@@ -138,13 +152,13 @@ function complete_secteurs($les_rubriques)
}
// http://doc.spip.org/@complete_fils
-function complete_fils($rubriques)
+function complete_fils($rubriques, $serveur='')
{
$r = $rubriques;
do {
- $q = sql_select("id_rubrique", "spip_rubriques", "id_parent IN (".join(',',$r).")");
+ $q = sql_select("id_rubrique", "spip_rubriques", "id_parent IN (".join(',',$r).")", array(), array(), '', array(), $serveur);
$r = array();
- while ($row = sql_fetch($q)) {
+ while ($row = sql_fetch($q, $serveur)) {
$r[]= $rubriques[] = $row['id_rubrique'];
}
} while ($r);
@@ -153,31 +167,6 @@ function complete_fils($rubriques)
return $rubriques;
}
-// Concatenation des tranches
-// Il faudrait ouvrir une seule fois le fichier, et d'abord sous un autre nom
-// et sans detruire les tranches: au final renommage+destruction massive pour
-// prevenir autant que possible un Time-out.
-
-// http://doc.spip.org/@ramasse_parties
-function ramasse_parties($dir, $archive)
-{
- $files = preg_files($dir . $archive . ".part_[0-9]+_[0-9]+[.gz]?");
-
- $ok = true;
- $files_o = array();
- $but = $dir . $archive;
- foreach($files as $f) {
- $contenu = "";
- if (lire_fichier ($f, $contenu)) {
- if (!ecrire_fichier($but,$contenu,false,false))
- { $ok = false; break;}
- }
- spip_unlink($f);
- $files_o[]=$f;
- }
- return $ok ? $files_o : false;
-}
-
//
// Exportation de table SQL au format xml
// La constante ci-dessus determine la taille des tranches,
@@ -203,33 +192,36 @@ function export_objets($table, $cpt, $total, $filetable, $les_rubriques, $les_me
$debut = $cpt * _EXPORT_TRANCHES_LIMITE;
$effectifs = 0;
+ $v = unserialize($GLOBALS['meta'][$meta]);
while (1){ // on ne connait pas le nb de paquets d'avance
$cpt++;
- $tranche = build_while($debut, $table, $prim, $les_rubriques, $les_meres);
+ $tranche = build_while($debut, $table, $prim, $les_rubriques, $les_meres, $v[7], $v[6]);
// attention: vide ne suffit pas a sortir
// car les sauvegardes partielles peuvent parcourir
// une table dont la portion qui les concerne sera vide..
if ($tranche) {
// on ecrit dans un fichier generique
// puis on le renomme pour avoir une operation atomique
- ecrire_fichier ($temp, join('', $tranche));
- $f = $filetable . sprintf('_%04d',$cpt) . _EXTENSION_PARTIES;
- // le fichier destination peut deja exister
- // si on sort d'un timeout entre le rename et le ecrire_meta
- if (file_exists($f)) spip_unlink($f);
- rename($temp, $f);
- $effectifs += count($tranche);
+ if (is_array($tranche)) {
+ ecrire_fichier ($temp, join('', $tranche));
+ $f = $filetable . sprintf('_%04d',$cpt) . _EXTENSION_PARTIES;
+ // le fichier destination peut deja exister
+ // si on sort d'un timeout entre le rename et le ecrire_meta
+ if (file_exists($f)) spip_unlink($f);
+ rename($temp, $f);
+ $tranche = count($tranche);
+ }
+ $effectifs += $tranche;
}
// incrementer le numero de sous-etape
// au cas ou une interruption interviendrait
- $v = unserialize($GLOBALS['meta'][$meta]);
$v[5]++;
ecrire_meta($meta, serialize($v));
$debut += _EXPORT_TRANCHES_LIMITE;
if ($debut >= $total) {break;}
/* pour tester la robustesse de la reprise sur interruption
- decommenter ce qui suit.
+ decommenter ce qui suit.
if ($cpt && 1) {
spip_log("force interrup $s");
include_spip('inc/headers');
@@ -238,50 +230,53 @@ function export_objets($table, $cpt, $total, $filetable, $les_rubriques, $les_me
echo(". ");
flush();
}
-
return $effectifs;
}
-
-// Construit la version xml des champs d'une table
-
+// sauvegarde d'une table par ordre croissant de la cle primaire simple
+// sinon les sequences PG seront pertubees a la restauration
+// (a ameliorer)
+// Retourne un tableau de chaines, d'autant d'element que de Row
+// ou leur nombre, selon la fonction utilisee
// http://doc.spip.org/@build_while
-function build_while($debut, $table, $prim, $les_rubriques, $les_meres) {
- global $chercher_logo ;
+function build_while($debut, $table, $prim, $les_rubriques, $les_meres, $save='', $serveur='') {
- // sauver par ordre croissant les tables avec cles primaires simples
- // sinon les sequences PG seront pertubees a la restauration
- // (a ameliorer)
- $result = sql_select('*', $table, '', '', $prim, "$debut," . _EXPORT_TRANCHES_LIMITE);
+ $result = sql_select('*', $table, '', '', $prim, "$debut," . _EXPORT_TRANCHES_LIMITE, array(), $serveur);
+ $i = 0;
$res = array();
- while ($row = sql_fetch($result)) {
- if (export_select($row, $les_rubriques, $les_meres)) {
- $attributs = "";
- if ($chercher_logo) {
- if ($logo = $chercher_logo($row[$prim], $prim, 'on'))
- $attributs .= ' on="' . $logo[3] . '"';
- if ($logo = $chercher_logo($row[$prim], $prim, 'off'))
- $attributs .= ' off="' . $logo[3] . '"';
- }
-
- $string = "<$table$attributs>\n";
- foreach ($row as $k => $v) {
- $string .= "<$k>" . text_to_xml($v) . "$k>\n";
- }
- $string .= "$table>\n\n";
- $res[]= $string;
+ $save = 'inc_export_' . ($save ? $save : 'xml');
+ while ($r = sql_fetch($result, $serveur)) {
+ if (export_select($r, $les_rubriques, $les_meres)) {
+ if ($s = $save($r, $table, $prim, $serveur)) $res[]=$s; else $i++;
}
}
- sql_free($result);
- return $res;
+ sql_free($result, $serveur);
+ return $res ? $res : $i;
+}
+
+// Construit la version xml des champs d'une table
+function inc_export_xml($row, $table, $prim, $serveur) {
+ global $chercher_logo ;
+ if ($chercher_logo) {
+ $on = $chercher_logo($row[$prim], $prim, 'on');
+ $off = $chercher_logo($row[$prim], $prim, 'off');
+ } else $on = $off = "";
+ foreach ($row as $k => $v) {
+ $row[$k] = "<$k>" . text_to_xml($v) . "$k>";
+ }
+ return "<$table"
+ . ($on ? " on='$on[3]'" : '')
+ . ($off ? " off='$off[3]'" : '')
+ . ">\n"
+ . join("\n", $row)
+ . "\n$table>\n\n";
}
// dit si Row est exportable,
// en particulier quand on se restreint a certaines rubriques
-// Attention, la table articles doit etre au debut
-// et la table document_articles avant la table documents
-// (faudrait blinder, c'est un bug potentiel)
+// La table des documents doit etre apres celle des liens de doc
+// elle-meme apres celle des objets auxquels elle lie ces documents.
// http://doc.spip.org/@export_select
function export_select($row, $les_rubriques, $les_meres) {
@@ -291,7 +286,7 @@ function export_select($row, $les_rubriques, $les_meres) {
if (isset($row['impt']) AND $row['impt'] !='oui') return false;
if (!$les_rubriques) return true;
- // numero de rubrique non determinant pour les forums (0 � 99%)
+ // numero de rubrique non determinant pour les forums (0 a 99%)
if (isset($row['id_rubrique']) AND $row['id_rubrique']) {
if (in_array($row['id_rubrique'], $les_rubriques)) {
if (isset($row['id_article']))
@@ -346,7 +341,9 @@ function export_select($row, $les_rubriques, $les_meres) {
// Conversion texte -> xml (ajout d'entites)
// http://doc.spip.org/@text_to_xml
function text_to_xml($string) {
- return str_replace(array('&','<','>'), array('&','<','>'), $string);
+ static $old = array('&','<','>');
+ static $new = array('&','<','>');
+ return str_replace($old, $new, $string);
}
?>