zip.class.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. /**
  3. * Wrapper around pclzip. Makes a bit easier to use compression.
  4. *
  5. * Usage:
  6. *
  7. * $zip = Zip::create('...');
  8. * $zip->add($file_path, $local_path);
  9. *
  10. * Note
  11. *
  12. * Pclzip do not accept method callbacks. It only accepts pure function callbacks.
  13. * As a result the implementation is a bit more complicated than it should be.
  14. *
  15. * @license see /license.txt
  16. * @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
  17. */
  18. class Zip
  19. {
  20. protected static $pool = array();
  21. public static function pool($hash = '')
  22. {
  23. if (empty($hash)) {
  24. return self::$pool;
  25. } else {
  26. return self::$pool[$hash];
  27. }
  28. }
  29. /**
  30. *
  31. * @param string $path
  32. * @return Zip
  33. */
  34. public static function create($path)
  35. {
  36. return new self($path);
  37. }
  38. protected $path = '';
  39. protected $archive = null;
  40. protected $entries = array();
  41. public function __construct($path = '')
  42. {
  43. $this->path = $path;
  44. self::$pool[$this->get_hash()] = $this;
  45. }
  46. public function get_path()
  47. {
  48. return $this->path;
  49. }
  50. public function get_hash()
  51. {
  52. return md5($this->path);
  53. }
  54. public function add($file_path, $archive_path = '', $comment = '')
  55. {
  56. /**
  57. * Remove c: when working on windows.
  58. */
  59. if (substr($file_path, 1, 1) == ':') {
  60. $file_path = substr($file_path, 2);
  61. }
  62. $entry = array(
  63. 'file_path' => $file_path,
  64. 'archive_path' => $archive_path,
  65. 'comment' => $comment
  66. );
  67. $this->entries[$file_path] = $entry;
  68. $callback_name = 'zipcallback_' . $this->get_hash();
  69. if (!function_exists($callback_name)) {
  70. $callback = '';
  71. $callback .= 'function ' . $callback_name . '($event, &$header){';
  72. $callback .= '$parts = explode(\'_\', __FUNCTION__);';
  73. $callback .= '$hash = end($parts);';
  74. $callback .= 'return Zip::pool($hash)->callback($event, $header);';
  75. $callback .= '};';
  76. eval($callback);
  77. }
  78. $archive = $this->archive();
  79. $archive->add($file_path, PCLZIP_CB_PRE_ADD, $callback_name);
  80. }
  81. /**
  82. *
  83. * @return PclZip
  84. */
  85. protected function archive()
  86. {
  87. if ($this->archive) {
  88. return $this->archive;
  89. }
  90. if (empty($this->path)) {
  91. return null;
  92. }
  93. return $this->archive = new PclZip($this->path);
  94. }
  95. public function callback($event, &$header)
  96. {
  97. if ($event != PCLZIP_CB_PRE_ADD) {
  98. return 0;
  99. }
  100. $path = $header['filename'];
  101. if (!isset($this->entries[$path])) {
  102. return 1;
  103. }
  104. $entry = $this->entries[$path];
  105. $archive_path = $entry['archive_path'];
  106. if (!empty($archive_path)) {
  107. $header['stored_filename'] = $archive_path;
  108. }
  109. return 1;
  110. }
  111. }