PageRenderTime 153ms CodeModel.GetById 17ms RepoModel.GetById 6ms app.codeStats 0ms

/CreateZipFile.inc.php

https://bitbucket.org/cfraunholz/big-red-button
PHP | 220 lines | 156 code | 10 blank | 54 comment | 9 complexity | 865c3104d7abb01f482b91af0bc5597a MD5 | raw file
  1. <?php
  2. /**
  3. * Class to dynamically create a zip file (archive) of file(s) and/or directory
  4. *
  5. * @author Rochak Chauhan www.rochakchauhan.com
  6. * @package CreateZipFile
  7. * @see Distributed under "General Public License"
  8. *
  9. * @version 1.0
  10. */
  11. class CreateZipFile {
  12. public $compressedData = array();
  13. public $centralDirectory = array(); // central directory
  14. public $endOfCentralDirectory = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record
  15. public $oldOffset = 0;
  16. /**
  17. * Function to create the directory where the file(s) will be unzipped
  18. *
  19. * @param string $directoryName
  20. * @access public
  21. * @return void
  22. */
  23. public function addDirectory($directoryName) {
  24. $directoryName = str_replace("\\", "/", $directoryName);
  25. $feedArrayRow = "\x50\x4b\x03\x04";
  26. $feedArrayRow .= "\x0a\x00";
  27. $feedArrayRow .= "\x00\x00";
  28. $feedArrayRow .= "\x00\x00";
  29. $feedArrayRow .= "\x00\x00\x00\x00";
  30. $feedArrayRow .= pack("V",0);
  31. $feedArrayRow .= pack("V",0);
  32. $feedArrayRow .= pack("V",0);
  33. $feedArrayRow .= pack("v", strlen($directoryName) );
  34. $feedArrayRow .= pack("v", 0 );
  35. $feedArrayRow .= $directoryName;
  36. $feedArrayRow .= pack("V",0);
  37. $feedArrayRow .= pack("V",0);
  38. $feedArrayRow .= pack("V",0);
  39. $this->compressedData[] = $feedArrayRow;
  40. $newOffset = strlen(implode("", $this->compressedData));
  41. $addCentralRecord = "\x50\x4b\x01\x02";
  42. $addCentralRecord .="\x00\x00";
  43. $addCentralRecord .="\x0a\x00";
  44. $addCentralRecord .="\x00\x00";
  45. $addCentralRecord .="\x00\x00";
  46. $addCentralRecord .="\x00\x00\x00\x00";
  47. $addCentralRecord .= pack("V",0);
  48. $addCentralRecord .= pack("V",0);
  49. $addCentralRecord .= pack("V",0);
  50. $addCentralRecord .= pack("v", strlen($directoryName) );
  51. $addCentralRecord .= pack("v", 0 );
  52. $addCentralRecord .= pack("v", 0 );
  53. $addCentralRecord .= pack("v", 0 );
  54. $addCentralRecord .= pack("v", 0 );
  55. $addCentralRecord .= pack("V", 16 );
  56. $addCentralRecord .= pack("V", $this->oldOffset );
  57. $this->oldOffset = $newOffset;
  58. $addCentralRecord .= $directoryName;
  59. $this->centralDirectory[] = $addCentralRecord;
  60. }
  61. /**
  62. * Function to add file(s) to the specified directory in the archive
  63. *
  64. * @param string $directoryName
  65. * @param string $data
  66. * @return void
  67. * @access public
  68. */
  69. public function addFile($data, $directoryName) {
  70. $directoryName = str_replace("\\", "/", $directoryName);
  71. $feedArrayRow = "\x50\x4b\x03\x04";
  72. $feedArrayRow .= "\x14\x00";
  73. $feedArrayRow .= "\x00\x00";
  74. $feedArrayRow .= "\x08\x00";
  75. $feedArrayRow .= "\x00\x00\x00\x00";
  76. $uncompressedLength = strlen($data);
  77. $compression = crc32($data);
  78. $gzCompressedData = gzcompress($data);
  79. $gzCompressedData = substr( substr($gzCompressedData, 0, strlen($gzCompressedData) - 4), 2);
  80. $compressedLength = strlen($gzCompressedData);
  81. $feedArrayRow .= pack("V",$compression);
  82. $feedArrayRow .= pack("V",$compressedLength);
  83. $feedArrayRow .= pack("V",$uncompressedLength);
  84. $feedArrayRow .= pack("v", strlen($directoryName) );
  85. $feedArrayRow .= pack("v", 0 );
  86. $feedArrayRow .= $directoryName;
  87. $feedArrayRow .= $gzCompressedData;
  88. $feedArrayRow .= pack("V",$compression);
  89. $feedArrayRow .= pack("V",$compressedLength);
  90. $feedArrayRow .= pack("V",$uncompressedLength);
  91. $this->compressedData[] = $feedArrayRow;
  92. $newOffset = strlen(implode("", $this->compressedData));
  93. $addCentralRecord = "\x50\x4b\x01\x02";
  94. $addCentralRecord .="\x00\x00";
  95. $addCentralRecord .="\x14\x00";
  96. $addCentralRecord .="\x00\x00";
  97. $addCentralRecord .="\x08\x00";
  98. $addCentralRecord .="\x00\x00\x00\x00";
  99. $addCentralRecord .= pack("V",$compression);
  100. $addCentralRecord .= pack("V",$compressedLength);
  101. $addCentralRecord .= pack("V",$uncompressedLength);
  102. $addCentralRecord .= pack("v", strlen($directoryName) );
  103. $addCentralRecord .= pack("v", 0 );
  104. $addCentralRecord .= pack("v", 0 );
  105. $addCentralRecord .= pack("v", 0 );
  106. $addCentralRecord .= pack("v", 0 );
  107. $addCentralRecord .= pack("V", 32 );
  108. $addCentralRecord .= pack("V", $this->oldOffset );
  109. $this->oldOffset = $newOffset;
  110. $addCentralRecord .= $directoryName;
  111. $this->centralDirectory[] = $addCentralRecord;
  112. }
  113. /**
  114. * Function to return the zip file
  115. *
  116. * @return zipfile (archive)
  117. * @access public
  118. * @return void
  119. */
  120. public function getZippedfile() {
  121. $data = implode("", $this->compressedData);
  122. $controlDirectory = implode("", $this->centralDirectory);
  123. return
  124. $data.
  125. $controlDirectory.
  126. $this->endOfCentralDirectory.
  127. pack("v", sizeof($this->centralDirectory)).
  128. pack("v", sizeof($this->centralDirectory)).
  129. pack("V", strlen($controlDirectory)).
  130. pack("V", strlen($data)).
  131. "\x00\x00";
  132. }
  133. /**
  134. *
  135. * Function to force the download of the archive as soon as it is created
  136. *
  137. * @param archiveName string - name of the created archive file
  138. * @access public
  139. * @return ZipFile via Header
  140. */
  141. public function forceDownload($archiveName) {
  142. if(ini_get('zlib.output_compression')) {
  143. ini_set('zlib.output_compression', 'Off');
  144. }
  145. // Security checks
  146. if( $archiveName == "" ) {
  147. echo "<html><title>Public Photo Directory - Download </title><body><BR><B>ERROR:</B> The download file was NOT SPECIFIED.</body></html>";
  148. exit;
  149. }
  150. elseif ( ! file_exists( $archiveName ) ) {
  151. echo "<html><title>Public Photo Directory - Download </title><body><BR><B>ERROR:</B> File not found.</body></html>";
  152. exit;
  153. }
  154. header("Pragma: public");
  155. header("Expires: 0");
  156. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  157. header("Cache-Control: private",false);
  158. header("Content-Type: application/zip");
  159. header("Content-Disposition: attachment; filename=".basename($archiveName).";" );
  160. header("Content-Transfer-Encoding: binary");
  161. header("Content-Length: ".filesize($archiveName));
  162. readfile("$archiveName");
  163. }
  164. /**
  165. * Function to parse a directory to return all its files and sub directories as array
  166. *
  167. * @param string $dir
  168. * @access private
  169. * @return array
  170. */
  171. private function parseDirectory($rootPath, $seperator="/"){
  172. $fileArray=array();
  173. $handle = opendir($rootPath);
  174. while( ($file = @readdir($handle))!==false) {
  175. if($file !='.' && $file !='..'){
  176. if (is_dir($rootPath.$seperator.$file)){
  177. $array=$this->parseDirectory($rootPath.$seperator.$file);
  178. $fileArray=array_merge($array,$fileArray);
  179. }
  180. else {
  181. $fileArray[]=$rootPath.$seperator.$file;
  182. }
  183. }
  184. }
  185. return $fileArray;
  186. }
  187. /**
  188. * Function to Zip entire directory with all its files and subdirectories
  189. *
  190. * @param string $dirName
  191. * @access public
  192. * @return void
  193. */
  194. public function zipDirectory($dirName, $outputDir) {
  195. if (!is_dir($dirName)){
  196. trigger_error("CreateZipFile FATAL ERROR: Could not locate the specified directory $dirName", E_USER_ERROR);
  197. }
  198. $tmp=$this->parseDirectory($dirName);
  199. $count=count($tmp);
  200. $this->addDirectory($outputDir);
  201. for ($i=0;$i<$count;$i++){
  202. $fileToZip=trim($tmp[$i]);
  203. $newOutputDir=substr($fileToZip,0,(strrpos($fileToZip,'/')+1));
  204. $outputDir=$outputDir.$newOutputDir;
  205. $fileContents=file_get_contents($fileToZip);
  206. $this->addFile($fileContents,$fileToZip);
  207. }
  208. }
  209. }
  210. ?>