dump.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. <?php
  2. /***************************************************************************\
  3. * SPIP, Systeme de publication pour l'internet *
  4. * *
  5. * Copyright (c) 2001-2014 *
  6. * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
  7. * *
  8. * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
  9. * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
  10. \***************************************************************************/
  11. if (!defined("_ECRIRE_INC_VERSION")) return;
  12. /**
  13. * Repertoire de sauvegarde
  14. *
  15. * @return string
  16. */
  17. function dump_repertoire() {
  18. $repertoire = _DIR_DUMP;
  19. if (!@file_exists($repertoire)
  20. AND !$repertoire = sous_repertoire(_DIR_DUMP,'',false,true)
  21. ) {
  22. $repertoire = preg_replace(','._DIR_TMP.',', '', _DIR_DUMP);
  23. $repertoire = sous_repertoire(_DIR_TMP, $repertoire);
  24. }
  25. return $repertoire;
  26. }
  27. /**
  28. * Nom du fichier de sauvegarde
  29. * la fourniture de l'extension permet de verifier que le nom n'existe pas deja
  30. *
  31. * @param string $dir
  32. * @param string $extension
  33. * @return string
  34. */
  35. function dump_nom_fichier($dir,$extension='sqlite'){
  36. include_spip('inc/texte');
  37. $site = isset($GLOBALS['meta']['nom_site'])
  38. ? preg_replace(array(",\W,is",",_(?=_),",",_$,"),array("_","",""), couper(translitteration(trim($GLOBALS['meta']['nom_site'])),30,""))
  39. : 'spip';
  40. $site .= '_' . date('Ymd');
  41. $nom = $site;
  42. $cpt=0;
  43. while (file_exists($dir. $nom . ".$extension")) {
  44. $nom = $site . sprintf('_%03d', ++$cpt);
  45. }
  46. return $nom.".$extension";
  47. }
  48. /**
  49. * Determine le type de serveur de sauvegarde
  50. * sqlite2 ou sqlite3
  51. *
  52. * @return string
  53. */
  54. function dump_type_serveur() {
  55. // chercher si sqlite2 ou 3 est disponible
  56. include_spip('req/sqlite3');
  57. if (spip_versions_sqlite3())
  58. return 'sqlite3';
  59. include_spip('req/sqlite2');
  60. if (spip_versions_sqlite2())
  61. return 'sqlite2';
  62. return '';
  63. }
  64. /**
  65. * Conteneur pour les arguments de la connexion
  66. * si on passe $args, les arguments de la connexion sont memorises
  67. * renvoie toujours les derniers arguments memorises
  68. *
  69. * @staticvar array $connect_args
  70. * @param array $connect
  71. * @return array
  72. */
  73. function dump_serveur($args=null) {
  74. static $connect_args = null;
  75. if ($args)
  76. $connect_args = $args;
  77. return $connect_args;
  78. }
  79. function dump_connect_args($archive) {
  80. if (!$type_serveur = dump_type_serveur())
  81. return null;
  82. return array(dirname($archive), '', '', '', basename($archive,".sqlite"), $type_serveur, 'spip');
  83. }
  84. /**
  85. * Initialiser un dump
  86. * @param string $status_file
  87. * @param string $archive
  88. * @param array $tables
  89. * @param array $where
  90. * @return bool/string
  91. */
  92. function dump_init($status_file, $archive, $tables=null, $where=array(),$action='sauvegarde'){
  93. $status_file = _DIR_TMP.basename($status_file).".txt";
  94. if (lire_fichier($status_file, $status)
  95. AND $status = unserialize($status)
  96. AND $status['etape']!=='fini'
  97. AND filemtime($status_file)>=time()-120) // si le fichier status est trop vieux c'est un abandon
  98. return _T("dump:erreur_".$action."_deja_en_cours");
  99. if (!$type_serveur = dump_type_serveur())
  100. return _T('dump:erreur_sqlite_indisponible');
  101. if (!$tables)
  102. list($tables,) = base_liste_table_for_dump(lister_tables_noexport());
  103. $status = array('tables'=>$tables,'where'=>$where,'archive'=>$archive);
  104. $status['connect'] = dump_connect_args($archive);
  105. dump_serveur($status['connect']);
  106. if (!spip_connect('dump'))
  107. return _T('dump:erreur_creation_base_sqlite');
  108. // la constante sert a verifier qu'on utilise bien le connect/dump du plugin,
  109. // et pas une base externe homonyme
  110. if (!defined('_DUMP_SERVEUR_OK'))
  111. return _T('erreur_connect_dump', array('dump' => 'dump'));
  112. $status['etape'] = 'init';
  113. if (!ecrire_fichier($status_file, serialize($status)))
  114. return _T('dump:avis_probleme_ecriture_fichier',array('fichier'=>$status_file));
  115. return true;
  116. }
  117. /**
  118. * Afficher l'avancement de la copie
  119. * @staticvar int $etape
  120. * @param <type> $courant
  121. * @param <type> $total
  122. * @param <type> $table
  123. */
  124. function dump_afficher_progres($courant,$total,$table) {
  125. static $etape = 1;
  126. if (unique($table)) {
  127. if ($total<0 OR !is_numeric($total))
  128. echo "<br /><strong>".$etape. '. '."</strong>$table ";
  129. else
  130. echo "<br /><strong>".$etape. '. '."$table</strong> ".($courant?" <i>($courant)</i> ":"");
  131. $etape++;
  132. }
  133. if (is_numeric($total) AND $total>=0)
  134. echo ". ";
  135. else
  136. echo "(". (-intval($total)).")";
  137. flush();
  138. }
  139. /**
  140. * Ecrire le js pour relancer la procedure de dump
  141. * @param string $redirect
  142. * @return string
  143. */
  144. function dump_relance($redirect){
  145. // si Javascript est dispo, anticiper le Time-out
  146. return "<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"$redirect\";',300);</script>\n";
  147. }
  148. /**
  149. * Marquer la procedure de dump comme finie
  150. * @param string $status_file
  151. * @return <type>
  152. */
  153. function dump_end($status_file, $action=''){
  154. $status_file = _DIR_TMP.basename($status_file).".txt";
  155. if (!lire_fichier($status_file, $status)
  156. OR !$status = unserialize($status))
  157. return;
  158. switch($action) {
  159. case 'restaurer':
  160. // supprimer la structure qui etait stockee dans le dump
  161. sql_delete('spip_meta',"nom='dump_structure_temp'");
  162. break;
  163. case 'sauvegarder':
  164. // stocker dans le dump la structure de la base source
  165. $structure = array();
  166. foreach($status['tables_copiees'] as $t=>$n)
  167. $structure[$t] = sql_showtable($t,true);
  168. dump_serveur($status['connect']);
  169. spip_connect('dump');
  170. sql_delete('spip_meta',"nom='dump_structure_temp'",'dump'); #enlever une vieille structure deja la, au cas ou
  171. sql_insertq('spip_meta',array('nom'=>'dump_structure_temp','valeur'=>serialize($structure),'impt'=>'non'),array(),'dump');
  172. break;
  173. }
  174. $status['etape'] = 'fini';
  175. ecrire_fichier($status_file, serialize($status));
  176. }
  177. /**
  178. * Lister les fichiers de sauvegarde existant dans un repertoire
  179. * trie par nom, date ou taille
  180. *
  181. * @param string $dir
  182. * @param string $tri
  183. * @param string $extension
  184. * @param int $limit
  185. * @return array
  186. */
  187. function dump_lister_sauvegardes($dir,$tri='nom',$extension="sqlite",$limit = 100) {
  188. $liste_dump = preg_files($dir,'\.'.$extension.'$',$limit,false);
  189. $n = strlen($dir);
  190. $tn = $tl = $tt = $td = array();
  191. foreach($liste_dump as $fichier){
  192. $d = filemtime($fichier);
  193. $t = filesize($fichier);
  194. $fichier = substr($fichier, $n);
  195. $tl[]= array('fichier'=>$fichier,'taille'=>$t,'date'=>$d);
  196. $td[] = $d;
  197. $tt[] = $t;
  198. $tn[] = $fichier;
  199. }
  200. if ($tri == 'taille')
  201. array_multisort($tt, SORT_ASC, $tl);
  202. elseif ($tri == 'date')
  203. array_multisort($td, SORT_ASC, $tl);
  204. else
  205. array_multisort($tn, SORT_ASC, $tl);
  206. return $tl;
  207. }
  208. function dump_lire_status($status_file) {
  209. $status_file = _DIR_TMP.basename($status_file).".txt";
  210. if (!lire_fichier($status_file, $status)
  211. OR !$status = unserialize($status))
  212. return '';
  213. return $status;
  214. }
  215. function dump_verifie_sauvegarde_finie($status_file) {
  216. if (!$status=dump_lire_status($status_file)
  217. OR $status['etape']!=='fini')
  218. return '';
  219. return ' ';
  220. }
  221. function dump_nom_sauvegarde($status_file) {
  222. if (!$status=dump_lire_status($status_file)
  223. OR !file_exists($f=$status['archive'].".sqlite"))
  224. return '';
  225. return $f;
  226. }
  227. function dump_taille_sauvegarde($status_file) {
  228. if (!$f=dump_nom_sauvegarde($status_file)
  229. OR !$s = filesize($f))
  230. return '';
  231. return $s;
  232. }
  233. function dump_date_sauvegarde($status_file) {
  234. if (!$f=dump_nom_sauvegarde($status_file)
  235. OR !$d = filemtime($f))
  236. return '';
  237. return date('Y-m-d',$d);
  238. }
  239. ?>