| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532 | 
							- <?php
 
- /**
 
-  * CodeIgniter
 
-  *
 
-  * An open source application development framework for PHP
 
-  *
 
-  * This content is released under the MIT License (MIT)
 
-  *
 
-  * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
 
-  *
 
-  * Permission is hereby granted, free of charge, to any person obtaining a copy
 
-  * of this software and associated documentation files (the "Software"), to deal
 
-  * in the Software without restriction, including without limitation the rights
 
-  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
-  * copies of the Software, and to permit persons to whom the Software is
 
-  * furnished to do so, subject to the following conditions:
 
-  *
 
-  * The above copyright notice and this permission notice shall be included in
 
-  * all copies or substantial portions of the Software.
 
-  *
 
-  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
-  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
-  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
-  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
-  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
-  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
-  * THE SOFTWARE.
 
-  *
 
-  * @package	CodeIgniter
 
-  * @author	EllisLab Dev Team
 
-  * @copyright	Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
 
-  * @copyright	Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
 
-  * @license	https://opensource.org/licenses/MIT	MIT License
 
-  * @link	https://codeigniter.com
 
-  * @since	Version 1.0.0
 
-  * @filesource
 
-  */
 
- defined('BASEPATH') OR exit('No direct script access allowed');
 
- /**
 
-  * Zip Compression Class
 
-  *
 
-  * This class is based on a library I found at Zend:
 
-  * http://www.zend.com/codex.php?id=696&single=1
 
-  *
 
-  * The original library is a little rough around the edges so I
 
-  * refactored it and added several additional methods -- Rick Ellis
 
-  *
 
-  * @package		CodeIgniter
 
-  * @subpackage	Libraries
 
-  * @category	Encryption
 
-  * @author		EllisLab Dev Team
 
-  * @link		https://codeigniter.com/user_guide/libraries/zip.html
 
-  */
 
- class CI_Zip {
 
- 	/**
 
- 	 * Zip data in string form
 
- 	 *
 
- 	 * @var string
 
- 	 */
 
- 	public $zipdata = '';
 
- 	/**
 
- 	 * Zip data for a directory in string form
 
- 	 *
 
- 	 * @var string
 
- 	 */
 
- 	public $directory = '';
 
- 	/**
 
- 	 * Number of files/folder in zip file
 
- 	 *
 
- 	 * @var int
 
- 	 */
 
- 	public $entries = 0;
 
- 	/**
 
- 	 * Number of files in zip
 
- 	 *
 
- 	 * @var int
 
- 	 */
 
- 	public $file_num = 0;
 
- 	/**
 
- 	 * relative offset of local header
 
- 	 *
 
- 	 * @var int
 
- 	 */
 
- 	public $offset = 0;
 
- 	/**
 
- 	 * Reference to time at init
 
- 	 *
 
- 	 * @var int
 
- 	 */
 
- 	public $now;
 
- 	/**
 
- 	 * The level of compression
 
- 	 *
 
- 	 * Ranges from 0 to 9, with 9 being the highest level.
 
- 	 *
 
- 	 * @var	int
 
- 	 */
 
- 	public $compression_level = 2;
 
- 	/**
 
- 	 * mbstring.func_overload flag
 
- 	 *
 
- 	 * @var	bool
 
- 	 */
 
- 	protected static $func_overload;
 
- 	/**
 
- 	 * Initialize zip compression class
 
- 	 *
 
- 	 * @return	void
 
- 	 */
 
- 	public function __construct()
 
- 	{
 
- 		isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload'));
 
- 		$this->now = time();
 
- 		log_message('info', 'Zip Compression Class Initialized');
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Add Directory
 
- 	 *
 
- 	 * Lets you add a virtual directory into which you can place files.
 
- 	 *
 
- 	 * @param	mixed	$directory	the directory name. Can be string or array
 
- 	 * @return	void
 
- 	 */
 
- 	public function add_dir($directory)
 
- 	{
 
- 		foreach ((array) $directory as $dir)
 
- 		{
 
- 			if ( ! preg_match('|.+/$|', $dir))
 
- 			{
 
- 				$dir .= '/';
 
- 			}
 
- 			$dir_time = $this->_get_mod_time($dir);
 
- 			$this->_add_dir($dir, $dir_time['file_mtime'], $dir_time['file_mdate']);
 
- 		}
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Get file/directory modification time
 
- 	 *
 
- 	 * If this is a newly created file/dir, we will set the time to 'now'
 
- 	 *
 
- 	 * @param	string	$dir	path to file
 
- 	 * @return	array	filemtime/filemdate
 
- 	 */
 
- 	protected function _get_mod_time($dir)
 
- 	{
 
- 		// filemtime() may return false, but raises an error for non-existing files
 
- 		$date = file_exists($dir) ? getdate(filemtime($dir)) : getdate($this->now);
 
- 		return array(
 
- 			'file_mtime' => ($date['hours'] << 11) + ($date['minutes'] << 5) + $date['seconds'] / 2,
 
- 			'file_mdate' => (($date['year'] - 1980) << 9) + ($date['mon'] << 5) + $date['mday']
 
- 		);
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Add Directory
 
- 	 *
 
- 	 * @param	string	$dir	the directory name
 
- 	 * @param	int	$file_mtime
 
- 	 * @param	int	$file_mdate
 
- 	 * @return	void
 
- 	 */
 
- 	protected function _add_dir($dir, $file_mtime, $file_mdate)
 
- 	{
 
- 		$dir = str_replace('\\', '/', $dir);
 
- 		$this->zipdata .=
 
- 			"\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00"
 
- 			.pack('v', $file_mtime)
 
- 			.pack('v', $file_mdate)
 
- 			.pack('V', 0) // crc32
 
- 			.pack('V', 0) // compressed filesize
 
- 			.pack('V', 0) // uncompressed filesize
 
- 			.pack('v', self::strlen($dir)) // length of pathname
 
- 			.pack('v', 0) // extra field length
 
- 			.$dir
 
- 			// below is "data descriptor" segment
 
- 			.pack('V', 0) // crc32
 
- 			.pack('V', 0) // compressed filesize
 
- 			.pack('V', 0); // uncompressed filesize
 
- 		$this->directory .=
 
- 			"\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00"
 
- 			.pack('v', $file_mtime)
 
- 			.pack('v', $file_mdate)
 
- 			.pack('V',0) // crc32
 
- 			.pack('V',0) // compressed filesize
 
- 			.pack('V',0) // uncompressed filesize
 
- 			.pack('v', self::strlen($dir)) // length of pathname
 
- 			.pack('v', 0) // extra field length
 
- 			.pack('v', 0) // file comment length
 
- 			.pack('v', 0) // disk number start
 
- 			.pack('v', 0) // internal file attributes
 
- 			.pack('V', 16) // external file attributes - 'directory' bit set
 
- 			.pack('V', $this->offset) // relative offset of local header
 
- 			.$dir;
 
- 		$this->offset = self::strlen($this->zipdata);
 
- 		$this->entries++;
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Add Data to Zip
 
- 	 *
 
- 	 * Lets you add files to the archive. If the path is included
 
- 	 * in the filename it will be placed within a directory. Make
 
- 	 * sure you use add_dir() first to create the folder.
 
- 	 *
 
- 	 * @param	mixed	$filepath	A single filepath or an array of file => data pairs
 
- 	 * @param	string	$data		Single file contents
 
- 	 * @return	void
 
- 	 */
 
- 	public function add_data($filepath, $data = NULL)
 
- 	{
 
- 		if (is_array($filepath))
 
- 		{
 
- 			foreach ($filepath as $path => $data)
 
- 			{
 
- 				$file_data = $this->_get_mod_time($path);
 
- 				$this->_add_data($path, $data, $file_data['file_mtime'], $file_data['file_mdate']);
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			$file_data = $this->_get_mod_time($filepath);
 
- 			$this->_add_data($filepath, $data, $file_data['file_mtime'], $file_data['file_mdate']);
 
- 		}
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Add Data to Zip
 
- 	 *
 
- 	 * @param	string	$filepath	the file name/path
 
- 	 * @param	string	$data	the data to be encoded
 
- 	 * @param	int	$file_mtime
 
- 	 * @param	int	$file_mdate
 
- 	 * @return	void
 
- 	 */
 
- 	protected function _add_data($filepath, $data, $file_mtime, $file_mdate)
 
- 	{
 
- 		$filepath = str_replace('\\', '/', $filepath);
 
- 		$uncompressed_size = self::strlen($data);
 
- 		$crc32  = crc32($data);
 
- 		$gzdata = self::substr(gzcompress($data, $this->compression_level), 2, -4);
 
- 		$compressed_size = self::strlen($gzdata);
 
- 		$this->zipdata .=
 
- 			"\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00"
 
- 			.pack('v', $file_mtime)
 
- 			.pack('v', $file_mdate)
 
- 			.pack('V', $crc32)
 
- 			.pack('V', $compressed_size)
 
- 			.pack('V', $uncompressed_size)
 
- 			.pack('v', self::strlen($filepath)) // length of filename
 
- 			.pack('v', 0) // extra field length
 
- 			.$filepath
 
- 			.$gzdata; // "file data" segment
 
- 		$this->directory .=
 
- 			"\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00"
 
- 			.pack('v', $file_mtime)
 
- 			.pack('v', $file_mdate)
 
- 			.pack('V', $crc32)
 
- 			.pack('V', $compressed_size)
 
- 			.pack('V', $uncompressed_size)
 
- 			.pack('v', self::strlen($filepath)) // length of filename
 
- 			.pack('v', 0) // extra field length
 
- 			.pack('v', 0) // file comment length
 
- 			.pack('v', 0) // disk number start
 
- 			.pack('v', 0) // internal file attributes
 
- 			.pack('V', 32) // external file attributes - 'archive' bit set
 
- 			.pack('V', $this->offset) // relative offset of local header
 
- 			.$filepath;
 
- 		$this->offset = self::strlen($this->zipdata);
 
- 		$this->entries++;
 
- 		$this->file_num++;
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Read the contents of a file and add it to the zip
 
- 	 *
 
- 	 * @param	string	$path
 
- 	 * @param	bool	$archive_filepath
 
- 	 * @return	bool
 
- 	 */
 
- 	public function read_file($path, $archive_filepath = FALSE)
 
- 	{
 
- 		if (file_exists($path) && FALSE !== ($data = file_get_contents($path)))
 
- 		{
 
- 			if (is_string($archive_filepath))
 
- 			{
 
- 				$name = str_replace('\\', '/', $archive_filepath);
 
- 			}
 
- 			else
 
- 			{
 
- 				$name = str_replace('\\', '/', $path);
 
- 				if ($archive_filepath === FALSE)
 
- 				{
 
- 					$name = preg_replace('|.*/(.+)|', '\\1', $name);
 
- 				}
 
- 			}
 
- 			$this->add_data($name, $data);
 
- 			return TRUE;
 
- 		}
 
- 		return FALSE;
 
- 	}
 
- 	// ------------------------------------------------------------------------
 
- 	/**
 
- 	 * Read a directory and add it to the zip.
 
- 	 *
 
- 	 * This function recursively reads a folder and everything it contains (including
 
- 	 * sub-folders) and creates a zip based on it. Whatever directory structure
 
- 	 * is in the original file path will be recreated in the zip file.
 
- 	 *
 
- 	 * @param	string	$path	path to source directory
 
- 	 * @param	bool	$preserve_filepath
 
- 	 * @param	string	$root_path
 
- 	 * @return	bool
 
- 	 */
 
- 	public function read_dir($path, $preserve_filepath = TRUE, $root_path = NULL)
 
- 	{
 
- 		$path = rtrim($path, '/\\').DIRECTORY_SEPARATOR;
 
- 		if ( ! $fp = @opendir($path))
 
- 		{
 
- 			return FALSE;
 
- 		}
 
- 		// Set the original directory root for child dir's to use as relative
 
- 		if ($root_path === NULL)
 
- 		{
 
- 			$root_path = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, dirname($path)).DIRECTORY_SEPARATOR;
 
- 		}
 
- 		while (FALSE !== ($file = readdir($fp)))
 
- 		{
 
- 			if ($file[0] === '.')
 
- 			{
 
- 				continue;
 
- 			}
 
- 			if (is_dir($path.$file))
 
- 			{
 
- 				$this->read_dir($path.$file.DIRECTORY_SEPARATOR, $preserve_filepath, $root_path);
 
- 			}
 
- 			elseif (FALSE !== ($data = file_get_contents($path.$file)))
 
- 			{
 
- 				$name = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $path);
 
- 				if ($preserve_filepath === FALSE)
 
- 				{
 
- 					$name = str_replace($root_path, '', $name);
 
- 				}
 
- 				$this->add_data($name.$file, $data);
 
- 			}
 
- 		}
 
- 		closedir($fp);
 
- 		return TRUE;
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Get the Zip file
 
- 	 *
 
- 	 * @return	string	(binary encoded)
 
- 	 */
 
- 	public function get_zip()
 
- 	{
 
- 		// Is there any data to return?
 
- 		if ($this->entries === 0)
 
- 		{
 
- 			return FALSE;
 
- 		}
 
- 		return $this->zipdata
 
- 			.$this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00"
 
- 			.pack('v', $this->entries) // total # of entries "on this disk"
 
- 			.pack('v', $this->entries) // total # of entries overall
 
- 			.pack('V', self::strlen($this->directory)) // size of central dir
 
- 			.pack('V', self::strlen($this->zipdata)) // offset to start of central dir
 
- 			."\x00\x00"; // .zip file comment length
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Write File to the specified directory
 
- 	 *
 
- 	 * Lets you write a file
 
- 	 *
 
- 	 * @param	string	$filepath	the file name
 
- 	 * @return	bool
 
- 	 */
 
- 	public function archive($filepath)
 
- 	{
 
- 		if ( ! ($fp = @fopen($filepath, 'w+b')))
 
- 		{
 
- 			return FALSE;
 
- 		}
 
- 		flock($fp, LOCK_EX);
 
- 		for ($result = $written = 0, $data = $this->get_zip(), $length = self::strlen($data); $written < $length; $written += $result)
 
- 		{
 
- 			if (($result = fwrite($fp, self::substr($data, $written))) === FALSE)
 
- 			{
 
- 				break;
 
- 			}
 
- 		}
 
- 		flock($fp, LOCK_UN);
 
- 		fclose($fp);
 
- 		return is_int($result);
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Download
 
- 	 *
 
- 	 * @param	string	$filename	the file name
 
- 	 * @return	void
 
- 	 */
 
- 	public function download($filename = 'backup.zip')
 
- 	{
 
- 		if ( ! preg_match('|.+?\.zip$|', $filename))
 
- 		{
 
- 			$filename .= '.zip';
 
- 		}
 
- 		get_instance()->load->helper('download');
 
- 		$get_zip = $this->get_zip();
 
- 		$zip_content =& $get_zip;
 
- 		force_download($filename, $zip_content);
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Initialize Data
 
- 	 *
 
- 	 * Lets you clear current zip data. Useful if you need to create
 
- 	 * multiple zips with different data.
 
- 	 *
 
- 	 * @return	CI_Zip
 
- 	 */
 
- 	public function clear_data()
 
- 	{
 
- 		$this->zipdata = '';
 
- 		$this->directory = '';
 
- 		$this->entries = 0;
 
- 		$this->file_num = 0;
 
- 		$this->offset = 0;
 
- 		return $this;
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Byte-safe strlen()
 
- 	 *
 
- 	 * @param	string	$str
 
- 	 * @return	int
 
- 	 */
 
- 	protected static function strlen($str)
 
- 	{
 
- 		return (self::$func_overload)
 
- 			? mb_strlen($str, '8bit')
 
- 			: strlen($str);
 
- 	}
 
- 	// --------------------------------------------------------------------
 
- 	/**
 
- 	 * Byte-safe substr()
 
- 	 *
 
- 	 * @param	string	$str
 
- 	 * @param	int	$start
 
- 	 * @param	int	$length
 
- 	 * @return	string
 
- 	 */
 
- 	protected static function substr($str, $start, $length = NULL)
 
- 	{
 
- 		if (self::$func_overload)
 
- 		{
 
- 			// mb_substr($str, $start, null, '8bit') returns an empty
 
- 			// string on PHP 5.3
 
- 			isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start);
 
- 			return mb_substr($str, $start, $length, '8bit');
 
- 		}
 
- 		return isset($length)
 
- 			? substr($str, $start, $length)
 
- 			: substr($str, $start);
 
- 	}
 
- }
 
 
  |