http_deballe_zip.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. /**
  3. * Gestion du téléporteur HTTP \ Zip.
  4. *
  5. * @plugin SVP pour SPIP
  6. * @license GPL
  7. * @package SPIP\SVP\Teleporteur
  8. */
  9. /**
  10. * Déballer le fichier au format zip dans le répertoire $dest
  11. * en utilisant le dossier temporaire $tmp si besoin
  12. *
  13. * @param string $archive
  14. * Chemin du fichier zip
  15. * @param string $dest
  16. * Répertoire où on veut décompresser
  17. * @param string $tmp
  18. * Répertoire de stockage temporaire
  19. * @return bool|string
  20. * Répertoire où a été décompressé le zip, false sinon.
  21. */
  22. function teleporter_http_deballe_zip_dist($archive, $dest, $tmp){
  23. $status = teleporter_http_charger_zip(
  24. array(
  25. 'archive' => $archive, // normalement l'url source mais on l'a pas ici
  26. 'fichier' => $archive,
  27. 'dest' => $dest,
  28. 'tmp' => $tmp,
  29. 'extract' => true,
  30. 'root_extract' => true, # extraire a la racine de dest
  31. )
  32. );
  33. // le fichier .zip est la et bien forme
  34. if (is_array($status)
  35. AND is_dir($status['target'])) {
  36. return $status['target'];
  37. }
  38. // fichier absent
  39. else if ($status == -1) {
  40. spip_log("dezip de $archive impossible : fichier absent","teleport"._LOG_ERREUR);
  41. return false;
  42. }
  43. // fichier la mais pas bien dezippe
  44. else {
  45. spip_log("probleme lors du dezip de $archive","teleport"._LOG_ERREUR);
  46. return false;
  47. }
  48. }
  49. /**
  50. * Charger un zip à partir d'un tableau d'options descriptives
  51. *
  52. * @param array $quoi
  53. * Tableau d'options
  54. * @return array|bool|int|string
  55. * En cas de réussite, Tableau décrivant le zip, avec les index suivant :
  56. * - files : la liste des fichiers présents dans le zip,
  57. * - size : la taille décompressée
  58. * - compressed_size : la taille compressée
  59. * - dirname : répertoire où les fichiers devront être décompréssés
  60. * - tmpname : répertoire temporaire où les fichiers sont décompressés
  61. * - target : cible sur laquelle décompresser les fichiers...
  62. */
  63. function teleporter_http_charger_zip($quoi = array()){
  64. if (!$quoi)
  65. return false;
  66. foreach (array( 'remove' => 'spip',
  67. 'rename' => array(),
  68. 'edit' => array(),
  69. 'root_extract' => false, # extraire a la racine de dest ?
  70. 'tmp' => sous_repertoire(_DIR_CACHE, 'chargeur')
  71. )
  72. as $opt=>$def) {
  73. isset($quoi[$opt]) || ($quoi[$opt] = $def);
  74. }
  75. if (!@file_exists($fichier = $quoi['fichier']))
  76. return 0;
  77. include_spip('inc/pclzip');
  78. $zip = new PclZip($fichier);
  79. $list = $zip->listContent();
  80. $racine = http_deballe_recherche_racine($list);
  81. $quoi['remove'] = $racine;
  82. // si pas de racine commune, reprendre le nom du fichier zip
  83. // en lui enlevant la racine h+md5 qui le prefixe eventuellement
  84. // cf action/charger_plugin L74
  85. if (!strlen($nom = basename($racine)))
  86. $nom = preg_replace(",^h[0-9a-f]{8}-,i","",basename($fichier, '.zip'));
  87. $dir_export = $quoi['root_extract']
  88. ? $quoi['dest']
  89. : $quoi['dest'] . $nom;
  90. $dir_export = rtrim($dir_export,'/').'/';
  91. $tmpname = $quoi['tmp'].$nom.'/';
  92. // choisir la cible selon si on veut vraiment extraire ou pas
  93. $target = $quoi['extract'] ? $dir_export : $tmpname;
  94. // ici, il faut vider le rep cible si il existe deja, non ?
  95. if (is_dir($target))
  96. supprimer_repertoire($target);
  97. // et enfin on extrait
  98. $ok = $zip->extract(
  99. PCLZIP_OPT_PATH,
  100. $target
  101. ,
  102. PCLZIP_OPT_SET_CHMOD, _SPIP_CHMOD,
  103. PCLZIP_OPT_REPLACE_NEWER,
  104. PCLZIP_OPT_REMOVE_PATH, $quoi['remove']
  105. );
  106. if ($zip->error_code < 0) {
  107. spip_log('charger_decompresser erreur zip ' . $zip->error_code .' pour paquet: ' . $quoi['archive'],"teleport"._LOG_ERREUR);
  108. return //$zip->error_code
  109. $zip->errorName(true);
  110. }
  111. spip_log('charger_decompresser OK pour paquet: ' . $quoi['archive'],"teleport");
  112. $size = $compressed_size = 0;
  113. $removex = ',^'.preg_quote($quoi['remove'], ',').',';
  114. foreach ($list as $a => $f) {
  115. $size += $f['size'];
  116. $compressed_size += $f['compressed_size'];
  117. $list[$a] = preg_replace($removex,'',$f['filename']);
  118. }
  119. // Indiquer par un fichier install.log
  120. // a la racine que c'est chargeur qui a installe ce plugin
  121. ecrire_fichier($target.'install.log',
  122. "installation: charger_plugin\n"
  123. ."date: ".gmdate('Y-m-d\TH:i:s\Z', time())."\n"
  124. ."source: ".$quoi['archive']."\n"
  125. );
  126. return array(
  127. 'files' => $list,
  128. 'size' => $size,
  129. 'compressed_size' => $compressed_size,
  130. 'dirname' => $dir_export,
  131. 'tmpname' => $tmpname,
  132. 'target' => $target,
  133. );
  134. }