/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk

« back to all changes in this revision

Viewing changes to codeigniter/system/libraries/Zip.php

  • Committer: Gustav Hatvigsson
  • Date: 2013-04-11 09:20:09 UTC
  • mfrom: (19.1.5 lenasys)
  • Revision ID: gustav.hartvigsson@gmail.com-20130411092009-ylcqzqwcmjdglb17
merged in implemetaion group one's team bransh, it contains code-ignighter
and the new admin-panel.
20130411

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 */
 
 
b'\\ No newline at end of file'