zip.class.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. /**
  19. * Zip wrapper class
  20. */
  21. class Zip
  22. {
  23. protected static $pool = array();
  24. public static function pool($hash = '')
  25. {
  26. if (empty($hash)) {
  27. return self::$pool;
  28. } else {
  29. return self::$pool[$hash];
  30. }
  31. }
  32. /**
  33. *
  34. * @param string $path
  35. * @return Zip
  36. */
  37. public static function create($path)
  38. {
  39. return new self($path);
  40. }
  41. protected $path = '';
  42. protected $archive = null;
  43. protected $entries = array();
  44. public function __construct($path = '')
  45. {
  46. $this->path = $path;
  47. self::$pool[$this->get_hash()] = $this;
  48. }
  49. public function get_path()
  50. {
  51. return $this->path;
  52. }
  53. public function get_hash()
  54. {
  55. return md5($this->path);
  56. }
  57. public function add($file_path, $archive_path = '', $comment = '')
  58. {
  59. /**
  60. * Remove c: when working on windows.
  61. */
  62. if (substr($file_path, 1, 1) == ':') {
  63. $file_path = substr($file_path, 2);
  64. }
  65. $entry = array(
  66. 'file_path' => $file_path,
  67. 'archive_path' => $archive_path,
  68. 'comment' => $comment
  69. );
  70. $this->entries[$file_path] = $entry;
  71. $callback_name = 'zipcallback_' . $this->get_hash();
  72. if (!function_exists($callback_name)) {
  73. $callback = '';
  74. $callback .= 'function ' . $callback_name . '($event, &$header){';
  75. $callback .= '$parts = explode(\'_\', __FUNCTION__);';
  76. $callback .= '$hash = end($parts);';
  77. $callback .= 'return Zip::pool($hash)->callback($event, $header);';
  78. $callback .= '};';
  79. eval($callback);
  80. }
  81. $archive = $this->archive();
  82. $archive->add($file_path, PCLZIP_CB_PRE_ADD, $callback_name);
  83. }
  84. /**
  85. *
  86. * @return PclZip
  87. */
  88. protected function archive()
  89. {
  90. if ($this->archive) {
  91. return $this->archive;
  92. }
  93. if (empty($this->path)) {
  94. return null;
  95. }
  96. return $this->archive = new PclZip($this->path);
  97. }
  98. public function callback($event, &$header)
  99. {
  100. if ($event != PCLZIP_CB_PRE_ADD) {
  101. return 0;
  102. }
  103. $path = $header['filename'];
  104. if (!isset($this->entries[$path])) {
  105. return 1;
  106. }
  107. $entry = $this->entries[$path];
  108. $archive_path = $entry['archive_path'];
  109. if (!empty($archive_path)) {
  110. $header['stored_filename'] = $archive_path;
  111. }
  112. return 1;
  113. }
  114. }