/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk
20.1.1 by galaxyAbstractor
* Added an simple admin panel to the codeviewer-cmssy stuff
1
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP 5.1.6 or newer
6
 *
7
 * @package		CodeIgniter
8
 * @author		ExpressionEngine Dev Team
9
 * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
10
 * @license		http://codeigniter.com/user_guide/license.html
11
 * @link		http://codeigniter.com
12
 * @since		Version 1.0
13
 * @filesource
14
 */
15
16
// ------------------------------------------------------------------------
17
18
/**
19
 * Zip Compression Class
20
 *
21
 * This class is based on a library I found at Zend:
22
 * http://www.zend.com/codex.php?id=696&single=1
23
 *
24
 * The original library is a little rough around the edges so I
25
 * refactored it and added several additional methods -- Rick Ellis
26
 *
27
 * @package		CodeIgniter
28
 * @subpackage	Libraries
29
 * @category	Encryption
30
 * @author		ExpressionEngine Dev Team
31
 * @link		http://codeigniter.com/user_guide/libraries/zip.html
32
 */
33
class CI_Zip  {
34
35
	var $zipdata	= '';
36
	var $directory	= '';
37
	var $entries	= 0;
38
	var $file_num	= 0;
39
	var $offset		= 0;
40
	var $now;
41
42
	/**
43
	 * Constructor
44
	 */
45
	public function __construct()
46
	{
47
		log_message('debug', "Zip Compression Class Initialized");
48
49
		$this->now = time();
50
	}
51
52
	// --------------------------------------------------------------------
53
54
	/**
55
	 * Add Directory
56
	 *
57
	 * Lets you add a virtual directory into which you can place files.
58
	 *
59
	 * @access	public
60
	 * @param	mixed	the directory name. Can be string or array
61
	 * @return	void
62
	 */
63
	function add_dir($directory)
64
	{
65
		foreach ((array)$directory as $dir)
66
		{
67
			if ( ! preg_match("|.+/$|", $dir))
68
			{
69
				$dir .= '/';
70
			}
71
72
			$dir_time = $this->_get_mod_time($dir);
73
74
			$this->_add_dir($dir, $dir_time['file_mtime'], $dir_time['file_mdate']);
75
		}
76
	}
77
78
	// --------------------------------------------------------------------
79
80
	/**
81
	 *	Get file/directory modification time
82
	 *
83
	 *	If this is a newly created file/dir, we will set the time to 'now'
84
	 *
85
	 *	@param string	path to file
86
	 *	@return array	filemtime/filemdate
87
	 */
88
	function _get_mod_time($dir)
89
	{
90
		// filemtime() will return false, but it does raise an error.
91
		$date = (@filemtime($dir)) ? filemtime($dir) : getdate($this->now);
92
93
		$time['file_mtime'] = ($date['hours'] << 11) + ($date['minutes'] << 5) + $date['seconds'] / 2;
94
		$time['file_mdate'] = (($date['year'] - 1980) << 9) + ($date['mon'] << 5) + $date['mday'];
95
96
		return $time;
97
	}
98
99
	// --------------------------------------------------------------------
100
101
	/**
102
	 * Add Directory
103
	 *
104
	 * @access	private
105
	 * @param	string	the directory name
106
	 * @return	void
107
	 */
108
	function _add_dir($dir, $file_mtime, $file_mdate)
109
	{
110
		$dir = str_replace("\\", "/", $dir);
111
112
		$this->zipdata .=
113
			"\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00"
114
			.pack('v', $file_mtime)
115
			.pack('v', $file_mdate)
116
			.pack('V', 0) // crc32
117
			.pack('V', 0) // compressed filesize
118
			.pack('V', 0) // uncompressed filesize
119
			.pack('v', strlen($dir)) // length of pathname
120
			.pack('v', 0) // extra field length
121
			.$dir
122
			// below is "data descriptor" segment
123
			.pack('V', 0) // crc32
124
			.pack('V', 0) // compressed filesize
125
			.pack('V', 0); // uncompressed filesize
126
127
		$this->directory .=
128
			"\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00"
129
			.pack('v', $file_mtime)
130
			.pack('v', $file_mdate)
131
			.pack('V',0) // crc32
132
			.pack('V',0) // compressed filesize
133
			.pack('V',0) // uncompressed filesize
134
			.pack('v', strlen($dir)) // length of pathname
135
			.pack('v', 0) // extra field length
136
			.pack('v', 0) // file comment length
137
			.pack('v', 0) // disk number start
138
			.pack('v', 0) // internal file attributes
139
			.pack('V', 16) // external file attributes - 'directory' bit set
140
			.pack('V', $this->offset) // relative offset of local header
141
			.$dir;
142
143
		$this->offset = strlen($this->zipdata);
144
		$this->entries++;
145
	}
146
147
	// --------------------------------------------------------------------
148
149
	/**
150
	 * Add Data to Zip
151
	 *
152
	 * Lets you add files to the archive. If the path is included
153
	 * in the filename it will be placed within a directory.  Make
154
	 * sure you use add_dir() first to create the folder.
155
	 *
156
	 * @access	public
157
	 * @param	mixed
158
	 * @param	string
159
	 * @return	void
160
	 */
161
	function add_data($filepath, $data = NULL)
162
	{
163
		if (is_array($filepath))
164
		{
165
			foreach ($filepath as $path => $data)
166
			{
167
				$file_data = $this->_get_mod_time($path);
168
169
				$this->_add_data($path, $data, $file_data['file_mtime'], $file_data['file_mdate']);
170
			}
171
		}
172
		else
173
		{
174
			$file_data = $this->_get_mod_time($filepath);
175
176
			$this->_add_data($filepath, $data, $file_data['file_mtime'], $file_data['file_mdate']);
177
		}
178
	}
179
180
	// --------------------------------------------------------------------
181
182
	/**
183
	 * Add Data to Zip
184
	 *
185
	 * @access	private
186
	 * @param	string	the file name/path
187
	 * @param	string	the data to be encoded
188
	 * @return	void
189
	 */
190
	function _add_data($filepath, $data, $file_mtime, $file_mdate)
191
	{
192
		$filepath = str_replace("\\", "/", $filepath);
193
194
		$uncompressed_size = strlen($data);
195
		$crc32  = crc32($data);
196
197
		$gzdata = gzcompress($data);
198
		$gzdata = substr($gzdata, 2, -4);
199
		$compressed_size = strlen($gzdata);
200
201
		$this->zipdata .=
202
			"\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00"
203
			.pack('v', $file_mtime)
204
			.pack('v', $file_mdate)
205
			.pack('V', $crc32)
206
			.pack('V', $compressed_size)
207
			.pack('V', $uncompressed_size)
208
			.pack('v', strlen($filepath)) // length of filename
209
			.pack('v', 0) // extra field length
210
			.$filepath
211
			.$gzdata; // "file data" segment
212
213
		$this->directory .=
214
			"\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00"
215
			.pack('v', $file_mtime)
216
			.pack('v', $file_mdate)
217
			.pack('V', $crc32)
218
			.pack('V', $compressed_size)
219
			.pack('V', $uncompressed_size)
220
			.pack('v', strlen($filepath)) // length of filename
221
			.pack('v', 0) // extra field length
222
			.pack('v', 0) // file comment length
223
			.pack('v', 0) // disk number start
224
			.pack('v', 0) // internal file attributes
225
			.pack('V', 32) // external file attributes - 'archive' bit set
226
			.pack('V', $this->offset) // relative offset of local header
227
			.$filepath;
228
229
		$this->offset = strlen($this->zipdata);
230
		$this->entries++;
231
		$this->file_num++;
232
	}
233
234
	// --------------------------------------------------------------------
235
236
	/**
237
	 * Read the contents of a file and add it to the zip
238
	 *
239
	 * @access	public
240
	 * @return	bool
241
	 */
242
	function read_file($path, $preserve_filepath = FALSE)
243
	{
244
		if ( ! file_exists($path))
245
		{
246
			return FALSE;
247
		}
248
249
		if (FALSE !== ($data = file_get_contents($path)))
250
		{
251
			$name = str_replace("\\", "/", $path);
252
253
			if ($preserve_filepath === FALSE)
254
			{
255
				$name = preg_replace("|.*/(.+)|", "\\1", $name);
256
			}
257
258
			$this->add_data($name, $data);
259
			return TRUE;
260
		}
261
		return FALSE;
262
	}
263
264
	// ------------------------------------------------------------------------
265
266
	/**
267
	 * Read a directory and add it to the zip.
268
	 *
269
	 * This function recursively reads a folder and everything it contains (including
270
	 * sub-folders) and creates a zip based on it.  Whatever directory structure
271
	 * is in the original file path will be recreated in the zip file.
272
	 *
273
	 * @access	public
274
	 * @param	string	path to source
275
	 * @return	bool
276
	 */
277
	function read_dir($path, $preserve_filepath = TRUE, $root_path = NULL)
278
	{
279
		if ( ! $fp = @opendir($path))
280
		{
281
			return FALSE;
282
		}
283
284
		// Set the original directory root for child dir's to use as relative
285
		if ($root_path === NULL)
286
		{
287
			$root_path = dirname($path).'/';
288
		}
289
290
		while (FALSE !== ($file = readdir($fp)))
291
		{
292
			if (substr($file, 0, 1) == '.')
293
			{
294
				continue;
295
			}
296
297
			if (@is_dir($path.$file))
298
			{
299
				$this->read_dir($path.$file."/", $preserve_filepath, $root_path);
300
			}
301
			else
302
			{
303
				if (FALSE !== ($data = file_get_contents($path.$file)))
304
				{
305
					$name = str_replace("\\", "/", $path);
306
307
					if ($preserve_filepath === FALSE)
308
					{
309
						$name = str_replace($root_path, '', $name);
310
					}
311
312
					$this->add_data($name.$file, $data);
313
				}
314
			}
315
		}
316
317
		return TRUE;
318
	}
319
320
	// --------------------------------------------------------------------
321
322
	/**
323
	 * Get the Zip file
324
	 *
325
	 * @access	public
326
	 * @return	binary string
327
	 */
328
	function get_zip()
329
	{
330
		// Is there any data to return?
331
		if ($this->entries == 0)
332
		{
333
			return FALSE;
334
		}
335
336
		$zip_data = $this->zipdata;
337
		$zip_data .= $this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00";
338
		$zip_data .= pack('v', $this->entries); // total # of entries "on this disk"
339
		$zip_data .= pack('v', $this->entries); // total # of entries overall
340
		$zip_data .= pack('V', strlen($this->directory)); // size of central dir
341
		$zip_data .= pack('V', strlen($this->zipdata)); // offset to start of central dir
342
		$zip_data .= "\x00\x00"; // .zip file comment length
343
344
		return $zip_data;
345
	}
346
347
	// --------------------------------------------------------------------
348
349
	/**
350
	 * Write File to the specified directory
351
	 *
352
	 * Lets you write a file
353
	 *
354
	 * @access	public
355
	 * @param	string	the file name
356
	 * @return	bool
357
	 */
358
	function archive($filepath)
359
	{
360
		if ( ! ($fp = @fopen($filepath, FOPEN_WRITE_CREATE_DESTRUCTIVE)))
361
		{
362
			return FALSE;
363
		}
364
365
		flock($fp, LOCK_EX);
366
		fwrite($fp, $this->get_zip());
367
		flock($fp, LOCK_UN);
368
		fclose($fp);
369
370
		return TRUE;
371
	}
372
373
	// --------------------------------------------------------------------
374
375
	/**
376
	 * Download
377
	 *
378
	 * @access	public
379
	 * @param	string	the file name
380
	 * @param	string	the data to be encoded
381
	 * @return	bool
382
	 */
383
	function download($filename = 'backup.zip')
384
	{
385
		if ( ! preg_match("|.+?\.zip$|", $filename))
386
		{
387
			$filename .= '.zip';
388
		}
389
390
		$CI =& get_instance();
391
		$CI->load->helper('download');
392
393
		$get_zip = $this->get_zip();
394
395
		$zip_content =& $get_zip;
396
397
		force_download($filename, $zip_content);
398
	}
399
400
	// --------------------------------------------------------------------
401
402
	/**
403
	 * Initialize Data
404
	 *
405
	 * Lets you clear current zip data.  Useful if you need to create
406
	 * multiple zips with different data.
407
	 *
408
	 * @access	public
409
	 * @return	void
410
	 */
411
	function clear_data()
412
	{
413
		$this->zipdata		= '';
414
		$this->directory	= '';
415
		$this->entries		= 0;
416
		$this->file_num		= 0;
417
		$this->offset		= 0;
418
	}
419
420
}
421
422
/* End of file Zip.php */
423
/* Location: ./system/libraries/Zip.php */