[ Index ]
 

Code source de SPIP 1.9.2c

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/ecrire/inc/ -> import.php (source)

   1  <?php
   2  
   3  /***************************************************************************\
   4   *  SPIP, Systeme de publication pour l'internet                           *
   5   *                                                                         *
   6   *  Copyright (c) 2001-2007                                                *
   7   *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
   8   *                                                                         *
   9   *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
  10   *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
  11  \***************************************************************************/
  12  
  13  if (!defined("_ECRIRE_INC_VERSION")) return;
  14  
  15  include_spip('inc/presentation');
  16  include_spip('inc/acces');
  17  include_spip('inc/indexation'); // pour la fonction primary_index_table 
  18  include_spip('base/abstract_sql');
  19  
  20  // NB: Ce fichier peut ajouter des tables (old-style)
  21  // donc il faut l'inclure "en globals"
  22  if ($f = include_spip('mes_fonctions', false)) {
  23      global $dossier_squelettes;
  24      @include_once ($f); 
  25  }
  26  if (@is_readable(_DIR_TMP."charger_plugins_fonctions.php")){
  27      // chargement optimise precompile
  28      include_once(_DIR_TMP."charger_plugins_fonctions.php");
  29  }
  30  
  31  global $IMPORT_tables_noerase;
  32  $IMPORT_tables_noerase[]='spip_meta';
  33  $GLOBALS['flag_ob_flush'] = function_exists('ob_flush');
  34  
  35  // Retourne la premiere balise XML figurant dans le buffet de la sauvegarde 
  36  // et avance dans ce buffet jusqu'au '>' de cette balise.
  37  // Si le 2e argument (passe par reference) est non vide
  38  // ce qui precede cette balise y est mis.
  39  // Les balises commencant par <! sont ignorees
  40  // $abs_pos est globale pour pouvoir etre reinitialisee a la meta
  41  // status_restauration en cas d'interruption sur TimeOut.
  42  // Evite au maximum les recopies
  43  
  44  // http://doc.spip.org/@xml_fetch_tag
  45  function xml_fetch_tag($f, &$before, $_fread='fread', $skip='!') {
  46      global $abs_pos;
  47      static $buf='';
  48      static $ent = array('&lt;','&amp;');
  49      static $brut = array('<','&');
  50  
  51      while (($b=strpos($buf,'<'))===false) {
  52          if (!($x = $_fread($f, 1024))) return '';
  53          if ($before)
  54              $buf .= $x;
  55          else {
  56              $abs_pos += strlen($buf);
  57              $buf = $x;
  58          }
  59      }
  60      if ($before) $before = str_replace($ent,$brut,substr($buf,0,$b));
  61  #    else { spip_log("position: $abs_pos" . substr($buf,0,12));flush();}
  62  
  63      // $b pour ignorer un > de raccourci Spip avant un < de balise XML
  64  
  65      while (($e=strpos($buf,'>', $b))===false) {
  66          if (!($x = $_fread($f, 1024))) return '';
  67          $buf .= $x;
  68      }
  69  
  70      if ($buf[++$b]!=$skip) {
  71          $tag = substr($buf, $b, $e-$b);
  72          $buf = substr($buf,++$e);
  73          $abs_pos += $e;
  74          return $tag;
  75      }
  76  
  77      $buf = substr($buf,++$e);
  78      $abs_pos += $e;
  79      return xml_fetch_tag($f,$before,$_fread,$skip);
  80  }
  81  
  82  // http://doc.spip.org/@xml_parse_tag
  83  function xml_parse_tag($t) {
  84  
  85      preg_match(',^([\w[?!%.;:-]*),s', $t, $res);
  86      $t = substr($t,strlen($res[0]));
  87      $res[1] = array();
  88  
  89      // pourquoi on ne peut pas mettre \3 entre crochets ?
  90      if (preg_match_all(',\s*(--.*?--)?\s*([^=]*)\s*=\s*([\'"])([^"]*)\3,sS', $t, $m, PREG_SET_ORDER)) {
  91          foreach($m as $r) $res[1][$r[2]] = $r[4];
  92      }
  93      return $res;
  94  }
  95  
  96  // Balise ouvrante:
  97  // 'SPIP' si fait par spip, nom de la base source si fait par  phpmyadmin
  98  
  99  // http://doc.spip.org/@import_debut
 100  function import_debut($f, $gz='fread') {
 101  
 102  //  Pour les anciennes archives, indiquer le charset par defaut:
 103      $charset = 'iso-8859-1'; 
 104  //  les + recentes l'ont en debut de ce fichier 
 105      $flag_phpmyadmin = false;
 106      $b = false;
 107      while ($t = xml_fetch_tag($f, $b, $gz, '')) {
 108          $r = xml_parse_tag($t);
 109          if ($r[0] == '?xml' AND $r[1]['encoding'])
 110              $charset = strtolower($r[1]['encoding']);
 111          elseif ($r[0] == "SPIP") {$r[2] = $charset; return $r;}
 112          if (($r[0] == "!--") && (preg_match(",phpmyadmin\sxml\sdump,is",$r[1]))){
 113              // c'est un dump xml phpmyadmin
 114              // on interprete le commentaire pour recuperer la version de phpmydadmin
 115              $version = preg_replace(",(.*?)version\s*([0-9a-z\.\-]*)\s(.*),is","\\2",$r[1]);
 116              $flag_phpmyadmin = true;
 117          }
 118          if (($r[0] != "!--") && ($flag_phpmyadmin == true)){
 119              $r[1] = array('version_archive'=>"phpmyadmin::$version");
 120              $r[2] = $charset;
 121              return $r;
 122          }
 123      }
 124  }
 125  
 126  // on conserve ce tableau pour faire des translations
 127  // de table eventuelles
 128  $tables_trans = array(
 129  );
 130  
 131  
 132  // http://doc.spip.org/@import_init_tables
 133  function import_init_tables($request)
 134  {
 135    global $IMPORT_tables_noerase, $connect_id_auteur;
 136      // grand menage
 137      // on vide toutes les tables dont la restauration est demandee
 138      $tables = import_table_choix($request);
 139      foreach($tables as $table){
 140          // regarder si il y a au moins un champ impt='non'
 141          if (($table!='spip_auteurs')&&(!in_array($table,$IMPORT_tables_noerase))){
 142              $desc = description_table($table);
 143              if (isset($desc['field']['impt']))
 144                  spip_query("DELETE FROM $table WHERE impt='oui'");
 145              else
 146                  spip_query("DELETE FROM $table");
 147          }
 148      }
 149  
 150      // Bidouille pour garder l'acces admin actuel pendant toute la restauration
 151      spip_query("UPDATE spip_auteurs SET id_auteur=0, extra=$connect_id_auteur WHERE id_auteur=$connect_id_auteur");
 152      spip_query("DELETE FROM spip_auteurs WHERE id_auteur!=0");
 153  
 154      return $tables;
 155  }
 156  
 157  // Effacement de la bidouille ci-dessus
 158  // Toutefois si la table des auteurs ne contient plus qu'elle
 159  // c'est que la sauvegarde etait incomplete et on restaure le compte
 160  // pour garder la connection au site (mais il doit pas etre bien beau)
 161  
 162  // http://doc.spip.org/@detruit_restaurateur
 163  function detruit_restaurateur()
 164  {
 165      $r = spip_fetch_array(spip_query("SELECT COUNT(*) AS n FROM spip_auteurs"));
 166      if ($r['n'] > 1)
 167          spip_query("DELETE FROM spip_auteurs WHERE id_auteur=0");
 168      else {
 169            spip_query("UPDATE spip_auteurs SET id_auteur=extra WHERE id_auteur=0");
 170      }
 171  }
 172  
 173  // http://doc.spip.org/@import_tables
 174  function import_tables($request, $dir) {
 175      global $import_ok, $abs_pos,  $affiche_progression_pourcent;
 176  
 177      $abs_pos = (!isset($GLOBALS['meta']["status_restauration"])) ? 0 :
 178          $GLOBALS['meta']["status_restauration"];
 179  
 180      // au premier appel destruction des tables a restaurer
 181      // ou initialisation de la table des translations,
 182      // mais pas lors d'une reprise.
 183  
 184      if ($request['insertion']=='on') {
 185          include_spip('inc/import_insere');
 186          $request['init'] = (!$abs_pos) ? 'insere_1_init' : 'insere_1bis_init';
 187          $request['boucle'] = 'import_insere';
 188      } elseif ($request['insertion']=='passe2') {
 189          $request['init'] = 'insere_2_init';
 190          $request['boucle'] = 'import_translate';
 191      } else {
 192          $request['init'] = (!$abs_pos) ? 'import_init_tables' : 'import_table_choix';
 193          $request['boucle'] = 'import_replace';
 194      }
 195  
 196      $archive = $dir . ($request['archive'] ? $request['archive'] : $request['archive_perso']);
 197  
 198      if (strncmp(".gz", substr($archive,-3),3)==0) {
 199              $size = false;
 200              $taille = taille_en_octets($abs_pos);
 201              $file = gzopen($archive, 'rb');
 202              $gz = 'gzread';
 203      } else {
 204              $size = @filesize($archive);
 205              $taille = floor(100 * $abs_pos / $size)." %";
 206              $file = fopen($archive, 'rb');
 207              $gz = 'fread';
 208      }
 209  
 210      if ($abs_pos==0) {
 211          list($tag, $atts, $charset) = import_debut($file, $gz);
 212      // improbable: fichier correct avant debut_admin et plus apres
 213          if (!$tag) return !($import_ok = true);
 214          $version_archive = import_init_meta($tag, $atts, $charset, $request);
 215      } else {
 216          $version_archive = $GLOBALS['meta']['version_archive_restauration'];
 217          $atts = unserialize($GLOBALS['meta']['attributs_archive_restauration']);
 218          spip_log("Reprise de l'importation interrompue en $abs_pos");
 219          $_fseek = ($gz=='gzread') ? 'gzseek' : 'fseek';
 220          $_fseek($file, $abs_pos);
 221      }
 222  
 223  
 224      $fimport = import_charge_version($version_archive);
 225  
 226      import_affiche_javascript($taille);
 227  
 228      if ($GLOBALS['flag_ob_flush']) ob_flush();
 229      flush();
 230      $oldtable ='';
 231      $cpt = 0;
 232      $pos = $abs_pos;
 233      while ($table = $fimport($file, $request, $gz, $atts)) {
 234        // memoriser pour pouvoir reprendre en cas d'interrupt,
 235        // mais pas d'ecriture sur fichier, ca ralentit trop
 236          ecrire_meta("status_restauration", "$abs_pos",'non');
 237          if ($oldtable != $table) {
 238              if ($oldtable) spip_log("$cpt entrees");
 239              spip_log("Analyse de $table (commence en $pos)");
 240              affiche_progression_javascript($abs_pos,$size,$table);
 241              $oldtable = $table;
 242              $cpt = 0;
 243              $pos = $abs_pos;
 244          } 
 245          $cpt++;
 246      }
 247      spip_log("$cpt entrees");
 248  
 249      if (!$import_ok) 
 250        $res =  _T('avis_archive_invalide') . ' ' .
 251          _T('taille_octets', array('taille' => $pos)) ;
 252      else {
 253          $res = '';
 254          affiche_progression_javascript('100 %', $size);
 255      }
 256  
 257      return $res ;
 258  }
 259  
 260  // http://doc.spip.org/@import_init_meta
 261  function import_init_meta($tag, $atts, $charset, $request)
 262  {
 263      $version_archive = $atts['version_archive'];
 264      ecrire_meta('attributs_archive_restauration', serialize($atts),'non');
 265      ecrire_meta('version_archive_restauration', $version_archive,'non');
 266      ecrire_meta('tag_archive_restauration', $tag,'non');
 267      if ( $i = $request['insertion'])
 268          ecrire_meta('charset_insertion', $charset,'non');
 269      else    ecrire_meta('charset_restauration', $charset,'non');
 270      ecrire_metas();
 271      spip_log("Debut de l'importation (charset: $charset, format: $version_archive)" . ($i ? " insertion $i" : ''));
 272      return $version_archive;
 273  }
 274  
 275  // http://doc.spip.org/@import_affiche_javascript
 276  function import_affiche_javascript($taille)
 277  {
 278      $max_time = ini_get('max_execution_time')*1000;
 279      echo debut_boite_alerte(),
 280        "<span style='color: black;' class='verdana1 spip_large'><b>",  _T('info_base_restauration'),  "</b></span>",
 281        "<form name='progression'><div style='text-align: center'><input type='text' size='10' name='taille' value='",
 282        $taille,
 283        "'></div><div style='text-align: center'><input type='text' class='forml' name='recharge' value='",
 284        _T('info_recharger_page'),
 285        "'></div></form>",
 286        fin_boite_alerte(),
 287        "<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"",
 288        self(),
 289        "\";',",
 290        $max_time,
 291        ");</script>\n";
 292  }
 293  
 294  
 295  
 296  // http://doc.spip.org/@affiche_progression_javascript
 297  function affiche_progression_javascript($abs_pos,$size, $table="") {
 298      include_spip('inc/charsets');
 299      echo "\n<script type='text/javascript'><!--\n";
 300  
 301      if ($abs_pos == '100 %') {
 302  
 303          if ($x = $GLOBALS['erreur_restauration'])
 304              echo "document.progression.recharge.value='".str_replace("'", "\\'", unicode_to_javascript(html2unicode(_T('avis_erreur')))).": $x ';\n";
 305          else
 306              echo "document.progression.recharge.value='".str_replace("'", "\\'", unicode_to_javascript(html2unicode(_T('info_fini'))))."';\n";
 307          echo "document.progression.taille.value='$abs_pos';\n";
 308          echo "window.setTimeout('location.href=\"".self()."\";',0);";
 309      }
 310      else {
 311          if (trim($table))
 312              echo "document.progression.recharge.value='$table';\n";
 313          if (!$size)
 314              $taille = preg_replace("/&nbsp;/", " ", taille_en_octets($abs_pos));
 315          else
 316              $taille = floor(100 * $abs_pos / $size)." %";
 317          echo "document.progression.taille.value='$taille';\n";
 318      }
 319      echo "\n--></script>\n";
 320      if ($GLOBALS['flag_ob_flush']) ob_flush();
 321      flush();
 322  }
 323  
 324  
 325  // http://doc.spip.org/@import_table_choix
 326  function import_table_choix($request)
 327  {
 328      // construction de la liste des tables pour le dump :
 329      // toutes les tables principales
 330      // + toutes les tables auxiliaires hors relations
 331      // + les tables relations dont les deux tables liees sont dans la liste
 332      $tables_for_dump = array();
 333      $tables_pointees = array();
 334      global $IMPORT_tables_noimport;
 335      global $tables_principales;
 336      global $tables_auxiliaires;
 337      global $table_des_tables;
 338      global $tables_jointures;
 339  
 340      // on construit un index des tables de liens
 341      // pour les ajouter SI les deux tables qu'ils connectent sont sauvegardees
 342      $tables_for_link = array();
 343      foreach($tables_jointures as $table=>$liste_relations)
 344          if (is_array($liste_relations))
 345          {
 346              $nom = $table;
 347              if (!isset($tables_auxiliaires[$nom])&&!isset($tables_principales[$nom]))
 348                  $nom = "spip_$table";
 349              if (isset($tables_auxiliaires[$nom])||isset($tables_principales[$nom])){
 350                  foreach($liste_relations as $link_table){
 351                      if (isset($tables_auxiliaires[$link_table])/*||isset($tables_principales[$link_table])*/){
 352                          $tables_for_link[$link_table][] = $nom;
 353                      }
 354                      else if (isset($tables_auxiliaires["spip_$link_table"])/*||isset($tables_principales["spip_$link_table"])*/){
 355                          $tables_for_link["spip_$link_table"][] = $nom;
 356                      }
 357                  }
 358              }
 359          }
 360      
 361      $liste_tables = array_merge(array_keys($tables_principales),array_keys($tables_auxiliaires));
 362      foreach($liste_tables as $table){
 363          $name = preg_replace("{^spip_}","",$table);
 364          if (        !isset($tables_pointees[$table]) 
 365                  &&    !in_array($table,$IMPORT_tables_noimport)
 366                  &&    !isset($tables_for_link[$table])){
 367              $tables_for_dump[] = $table;
 368              $tables_pointees[$table] = 1;
 369          }
 370      }
 371      foreach ($tables_for_link as $link_table =>$liste){
 372          $connecte = true;
 373          foreach($liste as $connect_table)
 374              if (!in_array($connect_table,$tables_for_dump))
 375                  $connecte = false;
 376          if ($connecte)
 377              # on ajoute les liaisons en premier
 378              # si une restauration est interrompue, cela se verra mieux si il manque des objets
 379              # que des liens
 380              array_unshift($tables_for_dump,$link_table);
 381      }
 382      return $tables_for_dump;
 383  }    
 384  ?>


Généré le : Wed Nov 21 10:20:27 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics