home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 April / CMCD0404.ISO / Software / Freeware / Programare / groupoffice-com-2.01 / classes / zip.class.inc < prev   
Text File  |  2004-03-08  |  8KB  |  208 lines

  1. <?php
  2. class zipfile
  3. {
  4.  
  5.     var $datasec = array(); // array to store compressed data
  6.     var $ctrl_dir = array(); // central directory
  7.     var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record
  8.     var $old_offset = 0;
  9.  
  10.     function add_dir($name)
  11.  
  12.     // adds "directory" to archive - do this before putting any files in directory!
  13.     // $name - name of directory... like this: "path/"
  14.     // ...then you can add files using add_file with names like "path/file.txt"
  15.     {
  16.         $name = str_replace("\\", "/", $name);
  17.  
  18.         $fr = "\x50\x4b\x03\x04";
  19.         $fr .= "\x0a\x00";    // ver needed to extract
  20.         $fr .= "\x00\x00";    // gen purpose bit flag
  21.         $fr .= "\x00\x00";    // compression method
  22.         $fr .= "\x00\x00\x00\x00"; // last mod time and date
  23.  
  24.         $fr .= pack("V",0); // crc32
  25.         $fr .= pack("V",0); //compressed filesize
  26.         $fr .= pack("V",0); //uncompressed filesize
  27.         $fr .= pack("v", strlen($name) ); //length of pathname
  28.         $fr .= pack("v", 0 ); //extra field length
  29.         $fr .= $name;
  30.         // end of "local file header" segment
  31.  
  32.         // no "file data" segment for path
  33.  
  34.         // "data descriptor" segment (optional but necessary if archive is not served as file)
  35.         $crc = 0;
  36.         $c_len = 0;
  37.         $unc_len = 0;
  38.         $fr .= pack("V",$crc); //crc32
  39.         $fr .= pack("V",$c_len); //compressed filesize
  40.         $fr .= pack("V",$unc_len); //uncompressed filesize
  41.  
  42.         // add this entry to array
  43.         $this -> datasec[] = $fr;
  44.  
  45.         $new_offset = strlen(implode("", $this->datasec));
  46.  
  47.         // ext. file attributes mirrors MS-DOS directory attr byte, detailed
  48.  
  49.         // at http://support.microsoft.com/support/kb/articles/Q125/0/19.asp
  50.  
  51.  
  52.         // now add to central record
  53.         $cdrec = "\x50\x4b\x01\x02";
  54.         $cdrec .="\x00\x00";    // version made by
  55.         $cdrec .="\x0a\x00";    // version needed to extract
  56.         $cdrec .="\x00\x00";    // gen purpose bit flag
  57.         $cdrec .="\x00\x00";    // compression method
  58.         $cdrec .="\x00\x00\x00\x00"; // last mod time & date
  59.         $cdrec .= pack("V",0); // crc32
  60.         $cdrec .= pack("V",0); //compressed filesize
  61.         $cdrec .= pack("V",0); //uncompressed filesize
  62.         $cdrec .= pack("v", strlen($name) ); //length of filename
  63.         $cdrec .= pack("v", 0 ); //extra field length
  64.         $cdrec .= pack("v", 0 ); //file comment length
  65.         $cdrec .= pack("v", 0 ); //disk number start
  66.         $cdrec .= pack("v", 0 ); //internal file attributes
  67.         $ext = "\x00\x00\x10\x00";
  68.         $ext = "\xff\xff\xff\xff";
  69.         $cdrec .= pack("V", 16 ); //external file attributes  - 'directory' bit set
  70.  
  71.         $cdrec .= pack("V", $this -> old_offset ); //relative offset of local header
  72.         $this -> old_offset = $new_offset;
  73.  
  74.         $cdrec .= $name;
  75.         // optional extra field, file comment goes here
  76.         // save to array
  77.         $this -> ctrl_dir[] = $cdrec;
  78.  
  79.  
  80.     }
  81.  
  82.  
  83.     function add_file($data, $name)
  84.  
  85.     // adds "file" to archive
  86.     // $data - file contents
  87.     // $name - name of file in archive. Add path if your want
  88.  
  89.     {
  90.         $name = str_replace("\\", "/", $name);
  91.         //$name = str_replace("\\", "\\\\", $name);
  92.  
  93.         $fr = "\x50\x4b\x03\x04";
  94.         $fr .= "\x14\x00";    // ver needed to extract
  95.         $fr .= "\x00\x00";    // gen purpose bit flag
  96.         $fr .= "\x08\x00";    // compression method
  97.         $fr .= "\x00\x00\x00\x00"; // last mod time and date
  98.  
  99.         $unc_len = strlen($data);
  100.         $crc = crc32($data);
  101.         $zdata = gzcompress($data);
  102.         $zdata = substr( substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
  103.         $c_len = strlen($zdata);
  104.         $fr .= pack("V",$crc); // crc32
  105.         $fr .= pack("V",$c_len); //compressed filesize
  106.         $fr .= pack("V",$unc_len); //uncompressed filesize
  107.         $fr .= pack("v", strlen($name) ); //length of filename
  108.         $fr .= pack("v", 0 ); //extra field length
  109.         $fr .= $name;
  110.         // end of "local file header" segment
  111.  
  112.         // "file data" segment
  113.         $fr .= $zdata;
  114.  
  115.         // "data descriptor" segment (optional but necessary if archive is not served as file)
  116.         $fr .= pack("V",$crc); //crc32
  117.         $fr .= pack("V",$c_len); //compressed filesize
  118.         $fr .= pack("V",$unc_len); //uncompressed filesize
  119.  
  120.         // add this entry to array
  121.         $this -> datasec[] = $fr;
  122.  
  123.         $new_offset = strlen(implode("", $this->datasec));
  124.  
  125.         // now add to central directory record
  126.         $cdrec = "\x50\x4b\x01\x02";
  127.         $cdrec .="\x00\x00";    // version made by
  128.         $cdrec .="\x14\x00";    // version needed to extract
  129.         $cdrec .="\x00\x00";    // gen purpose bit flag
  130.         $cdrec .="\x08\x00";    // compression method
  131.         $cdrec .="\x00\x00\x00\x00"; // last mod time & date
  132.         $cdrec .= pack("V",$crc); // crc32
  133.         $cdrec .= pack("V",$c_len); //compressed filesize
  134.         $cdrec .= pack("V",$unc_len); //uncompressed filesize
  135.         $cdrec .= pack("v", strlen($name) ); //length of filename
  136.         $cdrec .= pack("v", 0 ); //extra field length
  137.         $cdrec .= pack("v", 0 ); //file comment length
  138.         $cdrec .= pack("v", 0 ); //disk number start
  139.         $cdrec .= pack("v", 0 ); //internal file attributes
  140.         $cdrec .= pack("V", 32 ); //external file attributes - 'archive' bit set
  141.  
  142.         $cdrec .= pack("V", $this -> old_offset ); //relative offset of local header
  143. //        echo "old offset is ".$this->old_offset.", new offset is $new_offset<br>";
  144.         $this -> old_offset = $new_offset;
  145.  
  146.         $cdrec .= $name;
  147.         // optional extra field, file comment goes here
  148.         // save to central directory
  149.         $this -> ctrl_dir[] = $cdrec;
  150.     }
  151.  
  152.     function file() { // dump out file
  153.         $data = implode("", $this -> datasec);
  154.         $ctrldir = implode("", $this -> ctrl_dir);
  155.  
  156.         return
  157.             $data.
  158.             $ctrldir.
  159.             $this -> eof_ctrl_dir.
  160.             pack("v", sizeof($this -> ctrl_dir)).     // total # of entries "on this disk"
  161.             pack("v", sizeof($this -> ctrl_dir)).     // total # of entries overall
  162.             pack("V", strlen($ctrldir)).             // size of central dir
  163.             pack("V", strlen($data)).                 // offset to start of central dir
  164.             "\x00\x00";                              // .zip file comment length
  165.     }
  166.  
  167.     function add_dir_recursively($path, $remove_path='')
  168.     {
  169.         global $GO_CONFIG;
  170.         require_once($GO_CONFIG->class_path.'filesystem.class.inc');
  171.         $fs = new filesystem(true);
  172.  
  173.         //make sure there are slashes at the end
  174.         $path = dirname($path).'/'.basename($path).'/';
  175.         $remove_path = dirname($remove_path).'/'.basename($remove_path).'/';
  176.  
  177.         //remove $remove_path
  178.         $path_to_add = str_replace($remove_path, '' ,$path);
  179.  
  180.         //add the path to the zipfile
  181.         if($path_to_add != '')
  182.         {
  183.             $this->add_dir($path_to_add);
  184.             //echo $path_to_add.'<br>';
  185.         }
  186.  
  187.         //add folders
  188.         $folders = $fs->get_folders($path);
  189.         while($folder = array_shift($folders))
  190.         {
  191.             $this->add_dir_recursively($folder['path'],$remove_path);
  192.         }
  193.  
  194.         //add files from current folder
  195.         $files = $fs->get_files($path);
  196.         while($file = array_shift($files))
  197.         {
  198.             //get the contents
  199.             $fp = fopen($file['path'], "r");
  200.             $content = fread($fp, $file['size']);
  201.             fclose($fp);
  202.  
  203.             $this->add_file($content, $path_to_add.'/'.$file['name']);
  204.             //echo $path_to_add.$file['name'];
  205.         }
  206.     }
  207. }
  208. ?>