Wednesday 15 August 2012

Create Zip File for Multiple files to be downloadable in Codeigniter

define('ROOT_DOWNLOAD_FOLDER_PATH', $_SERVER['DOCUMENT_ROOT']."_files/_downloads/");

function CreateZipFile($zip_folder_name)
{
 $directoryToZip = ROOT_DOWNLOAD_FOLDER_PATH; // This will zip all the file(s) in this present working directory
 $outputDir = ROOT_DOWNLOAD_FOLDER_PATH; //Replace "/" with the name of the desired output directory.
 $this->load->library('ZipFile');
  
 //$this->createzipfile->get_files_from_folder($outputDir, $zip_folder_name.'-');
 $this->zipfile->get_files_from_folder($directoryToZip, '');
 
 //Code toZip a directory and all its files/subdirectories
 $this->zipfile->zipDirectory($directoryToZip, $outputDir);
 
 $fileName = $outputDir.$zip_folder_name.'.zip';

 $fd = fopen ($fileName, 'wb');
 $out = fwrite ($fd, $this->zipfile->getZippedfile());
  
 $this->zipfile->forceDownload($fileName);
 
 @unlink($fileName);
 fclose($fd);
 
 /* Empty directory and remove directory. */
 $directoryToZipPath = $directoryToZip.$zip_folder_name;
 unlinkFolderFiles($directoryToZipPath);
 removeDir($directoryToZipPath);

 exit;
}

$timestamp = date('Y.m.d.h.i.s');
$timestamp = '2012.08.15.12.45.46';
$zip_folder_name = 'Flubit.Inv.All.'.$timestamp;
// For the ZipFile.php, save the below ZipFile.php file content into application/libaries/ZipFile.php
/**
 * Class to dynamically create a zip file (archive) of file(s) and/or directory
 *
 * @author Rochak Chauhan  www.rochakchauhan.com
 * @package CreateZipFile
 * @see Distributed under "General Public License"
 * 
 * @version 1.0
 */

class ZipFile {

 public $compressedData = array();
 public $centralDirectory = array(); // central directory
 public $endOfCentralDirectory = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record
 public $oldOffset = 0;
 
 function get_files_from_folder($directory, $put_into) {
  if ($handle = opendir($directory)) {
   while (false !== ($file = readdir($handle))) {
    if (is_file($directory.$file)) {
     $fileContents = file_get_contents($directory.$file);
     $this->addFile($fileContents, $put_into.$file);
    } elseif ($file != '.' and $file != '..' and is_dir($directory.$file)) {
     $this->addDirectory($put_into.$file.'/');
     $this->get_files_from_folder($directory.$file.'/', $put_into.$file.'/');
    }
   }
  }
  closedir($handle);
 }
 
 /**
  * Function to create the directory where the file(s) will be unzipped
  *
  * @param string $directoryName
  * @access public
  * @return void
  */ 
 public function addDirectory($directoryName) {
  $directoryName = str_replace("\\", "/", $directoryName);
  $feedArrayRow = "\x50\x4b\x03\x04";
  $feedArrayRow .= "\x0a\x00";
  $feedArrayRow .= "\x00\x00";
  $feedArrayRow .= "\x00\x00";
  $feedArrayRow .= "\x00\x00\x00\x00";
  $feedArrayRow .= pack("V",0);
  $feedArrayRow .= pack("V",0);
  $feedArrayRow .= pack("V",0);
  $feedArrayRow .= pack("v", strlen($directoryName) );
  $feedArrayRow .= pack("v", 0 );
  $feedArrayRow .= $directoryName;
  $feedArrayRow .= pack("V",0);
  $feedArrayRow .= pack("V",0);
  $feedArrayRow .= pack("V",0);
  $this->compressedData[] = $feedArrayRow;
  $newOffset = strlen(implode("", $this->compressedData));
  $addCentralRecord = "\x50\x4b\x01\x02";
  $addCentralRecord .="\x00\x00";
  $addCentralRecord .="\x0a\x00";
  $addCentralRecord .="\x00\x00";
  $addCentralRecord .="\x00\x00";
  $addCentralRecord .="\x00\x00\x00\x00";
  $addCentralRecord .= pack("V",0);
  $addCentralRecord .= pack("V",0);
  $addCentralRecord .= pack("V",0);
  $addCentralRecord .= pack("v", strlen($directoryName) );
  $addCentralRecord .= pack("v", 0 );
  $addCentralRecord .= pack("v", 0 );
  $addCentralRecord .= pack("v", 0 );
  $addCentralRecord .= pack("v", 0 );
  $addCentralRecord .= pack("V", 16 );
  $addCentralRecord .= pack("V", $this->oldOffset );
  $this->oldOffset = $newOffset;
  $addCentralRecord .= $directoryName;
  $this->centralDirectory[] = $addCentralRecord;
 }

 /**
  * Function to add file(s) to the specified directory in the archive 
  *
  * @param string $directoryName
  * @param string $data
  * @return void
  * @access public
  */ 
 public function addFile($data, $directoryName)   {
  $directoryName = str_replace("\\", "/", $directoryName);
  $feedArrayRow = "\x50\x4b\x03\x04";
  $feedArrayRow .= "\x14\x00";
  $feedArrayRow .= "\x00\x00";
  $feedArrayRow .= "\x08\x00";
  $feedArrayRow .= "\x00\x00\x00\x00";
  $uncompressedLength = strlen($data);
  $compression = crc32($data);
  $gzCompressedData = gzcompress($data);
  $gzCompressedData = substr( substr($gzCompressedData, 0, strlen($gzCompressedData) - 4), 2);
  $compressedLength = strlen($gzCompressedData);
  $feedArrayRow .= pack("V",$compression);
  $feedArrayRow .= pack("V",$compressedLength);
  $feedArrayRow .= pack("V",$uncompressedLength);
  $feedArrayRow .= pack("v", strlen($directoryName) );
  $feedArrayRow .= pack("v", 0 );
  $feedArrayRow .= $directoryName;
  $feedArrayRow .= $gzCompressedData;
  $feedArrayRow .= pack("V",$compression);
  $feedArrayRow .= pack("V",$compressedLength);
  $feedArrayRow .= pack("V",$uncompressedLength);
  $this->compressedData[] = $feedArrayRow;
  $newOffset = strlen(implode("", $this->compressedData));
  $addCentralRecord = "\x50\x4b\x01\x02";
  $addCentralRecord .="\x00\x00";
  $addCentralRecord .="\x14\x00";
  $addCentralRecord .="\x00\x00";
  $addCentralRecord .="\x08\x00";
  $addCentralRecord .="\x00\x00\x00\x00";
  $addCentralRecord .= pack("V",$compression);
  $addCentralRecord .= pack("V",$compressedLength);
  $addCentralRecord .= pack("V",$uncompressedLength);
  $addCentralRecord .= pack("v", strlen($directoryName) );
  $addCentralRecord .= pack("v", 0 );
  $addCentralRecord .= pack("v", 0 );
  $addCentralRecord .= pack("v", 0 );
  $addCentralRecord .= pack("v", 0 );
  $addCentralRecord .= pack("V", 32 );
  $addCentralRecord .= pack("V", $this->oldOffset );
  $this->oldOffset = $newOffset;
  $addCentralRecord .= $directoryName;
  $this->centralDirectory[] = $addCentralRecord;
 }

 /**
  * Function to return the zip file
  *
  * @return zipfile (archive)
  * @access public
  * @return void
  */
 public function getZippedfile() {
  $data = implode("", $this->compressedData);
  $controlDirectory = implode("", $this->centralDirectory);
  return
  $data.
  $controlDirectory.
  $this->endOfCentralDirectory.
  pack("v", sizeof($this->centralDirectory)).
  pack("v", sizeof($this->centralDirectory)).
  pack("V", strlen($controlDirectory)).
  pack("V", strlen($data)).
  "\x00\x00";
 }

 /**
  *
  * Function to force the download of the archive as soon as it is created
  *
  * @param archiveName string - name of the created archive file
  * @access public
  * @return ZipFile via Header
  */
 public function forceDownload($archiveName) {
  if(ini_get('zlib.output_compression')) {
   ini_set('zlib.output_compression', 'Off');
  }

  // Security checks
  if( $archiveName == "" ) {
   echo "Public Photo Directory - Download 
ERROR: The download file was NOT SPECIFIED."; exit; } elseif ( ! file_exists( $archiveName ) ) { echo "Public Photo Directory - Download
ERROR: File not found."; exit; } header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private",false); header("Content-Type: application/zip"); header("Content-Disposition: attachment; filename=".basename($archiveName).";" ); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize($archiveName)); readfile("$archiveName"); } /** * Function to parse a directory to return all its files and sub directories as array * * @param string $dir * @access protected * @return array */ protected function parseDirectory($rootPath, $seperator="/"){ $fileArray=array(); $handle = opendir($rootPath); while( ($file = @readdir($handle))!==false) { if($file !='.' && $file !='..'){ if (is_dir($rootPath.$seperator.$file)){ $array=$this->parseDirectory($rootPath.$seperator.$file); $fileArray=array_merge($array,$fileArray); } else { $fileArray[]=$rootPath.$seperator.$file; } } } return $fileArray; } /** * Function to Zip entire directory with all its files and subdirectories * * @param string $dirName * @access public * @return void */ public function zipDirectory($dirName, $outputDir) { if (!is_dir($dirName)){ trigger_error("CreateZipFile FATAL ERROR: Could not locate the specified directory $dirName", E_USER_ERROR); } $tmp=$this->parseDirectory($dirName); $count=count($tmp); $this->addDirectory($outputDir); for ($i=0;$i<$count;$i++){ $fileToZip=trim($tmp[$i]); $newOutputDir=substr($fileToZip,0,(strrpos($fileToZip,'/')+1)); $outputDir=$outputDir.$newOutputDir; $fileContents=file_get_contents($fileToZip); $this->addFile($fileContents,$fileToZip); } } }
// The below are the basic File and Directory Related functions.
function createFile($filePath='')
{
 try {
  if (!empty($filePath))
  { 
   $ourFileHandle = fopen($filePath, 'w');
   fclose($ourFileHandle);
  }
  return true;
 }
 Catch(Exception $e){ return false; }
}

function unlinkFolderFiles($dir)
{
 $files = getFolderFiles($dir);

 foreach ($files as $file)
 {
  if(file_exists($dir.'/'.$file)) @unlink($dir.'/'.$file);
 }

 return true;
}

function getFolderFiles($dir)
{
 $files = '';
 $ffs = scandir($dir);

 foreach($ffs as $ff)
 {
  if($ff != '.' && $ff != '..')
  {
   $files[] = $ff;
  }
 }

 return $files;
}

function createDir($dir)
{
 if (!is_dir($dir)) {
  mkdir($dir);
 }

 return true;
}

function removeDir($dir)
{
 if (is_dir($dir)) {
  rmdir($dir);
 }
 
 return true;
}

No comments:

Post a Comment

Please post any queries and comments here.