1 | <?php |
||||||
2 | |||||||
3 | /* vim: set expandtab sw=4 ts=4 sts=4: */ |
||||||
4 | |||||||
5 | /** |
||||||
6 | * Zip file creation |
||||||
7 | * |
||||||
8 | * @package PhpMyAdmin |
||||||
9 | */ |
||||||
10 | |||||||
11 | namespace F72X\Tools; |
||||||
12 | |||||||
13 | /** |
||||||
14 | * Zip file creation class. |
||||||
15 | * Makes zip files. |
||||||
16 | * |
||||||
17 | * @access public |
||||||
18 | * @package PhpMyAdmin |
||||||
19 | * @see Official ZIP file format: http://www.pkware.com/support/zip-app-note |
||||||
20 | */ |
||||||
21 | class ZipFile |
||||||
22 | { |
||||||
23 | |||||||
24 | /** |
||||||
25 | * Whether to echo zip as it's built or return as string from -> file |
||||||
26 | * |
||||||
27 | * @var boolean $doWrite |
||||||
28 | */ |
||||||
29 | var $doWrite = false; |
||||||
30 | |||||||
31 | /** |
||||||
32 | * Array to store compressed data |
||||||
33 | * |
||||||
34 | * @var array $datasec |
||||||
35 | */ |
||||||
36 | var $datasec = array(); |
||||||
37 | |||||||
38 | /** |
||||||
39 | * Central directory |
||||||
40 | * |
||||||
41 | * @var array $ctrl_dir |
||||||
42 | */ |
||||||
43 | var $ctrl_dir = array(); |
||||||
44 | |||||||
45 | /** |
||||||
46 | * End of central directory record |
||||||
47 | * |
||||||
48 | * @var string $eof_ctrl_dir |
||||||
49 | */ |
||||||
50 | var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; |
||||||
51 | |||||||
52 | /** |
||||||
53 | * Last offset position |
||||||
54 | * |
||||||
55 | * @var integer $old_offset |
||||||
56 | */ |
||||||
57 | var $old_offset = 0; |
||||||
58 | |||||||
59 | /** |
||||||
60 | * Sets member variable this -> doWrite to true |
||||||
61 | * - Should be called immediately after class instantiation |
||||||
62 | * - If set to true, then ZIP archive are echo'ed to STDOUT as each |
||||||
63 | * file is added via this -> addfile(), and central directories are |
||||||
64 | * echoed to STDOUT on final call to this -> file(). Also, |
||||||
65 | * this -> file() returns an empty string so it is safe to issue a |
||||||
66 | * "echo $zipfile;" command |
||||||
67 | * |
||||||
68 | * @access public |
||||||
69 | * |
||||||
70 | * @return void |
||||||
71 | */ |
||||||
72 | function setDoWrite() |
||||||
0 ignored issues
–
show
|
|||||||
73 | { |
||||||
74 | $this->doWrite = true; |
||||||
75 | } |
||||||
76 | |||||||
77 | // end of the 'setDoWrite()' method |
||||||
78 | /** |
||||||
79 | * Converts an Unix timestamp to a four byte DOS date and time format (date |
||||||
80 | * in high two bytes, time in low two bytes allowing magnitude comparison). |
||||||
81 | * |
||||||
82 | * @param integer $unixtime the current Unix timestamp |
||||||
83 | * |
||||||
84 | * @return integer the current date in a four byte DOS format |
||||||
85 | * |
||||||
86 | * @access private |
||||||
87 | */ |
||||||
88 | function unix2DosTime($unixtime = 0) |
||||||
0 ignored issues
–
show
|
|||||||
89 | { |
||||||
90 | $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime); |
||||||
91 | if ($timearray['year'] < 1980) { |
||||||
92 | $timearray['year'] = 1980; |
||||||
93 | $timearray['mon'] = 1; |
||||||
94 | $timearray['mday'] = 1; |
||||||
95 | $timearray['hours'] = 0; |
||||||
96 | $timearray['minutes'] = 0; |
||||||
97 | $timearray['seconds'] = 0; |
||||||
98 | } // end if |
||||||
99 | return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1); |
||||||
100 | } |
||||||
101 | |||||||
102 | // end of the 'unix2DosTime()' method |
||||||
103 | /** |
||||||
104 | * Adds "file" to archive |
||||||
105 | * |
||||||
106 | * @param string $data file contents |
||||||
107 | * @param string $name name of the file in the archive (may contains the path) |
||||||
108 | * @param integer $time the current timestamp |
||||||
109 | * |
||||||
110 | * @access public |
||||||
111 | * |
||||||
112 | * @return void |
||||||
113 | */ |
||||||
114 | function addFile($data, $name, $time = 0) |
||||||
0 ignored issues
–
show
|
|||||||
115 | { |
||||||
116 | $name = str_replace('\\', '/', $name); |
||||||
117 | $hexdtime = pack('V', $this->unix2DosTime($time)); |
||||||
118 | $fr = "\x50\x4b\x03\x04"; |
||||||
119 | $fr .= "\x14\x00"; // ver needed to extract |
||||||
120 | $fr .= "\x00\x00"; // gen purpose bit flag |
||||||
121 | $fr .= "\x08\x00"; // compression method |
||||||
122 | $fr .= $hexdtime; // last mod time and date |
||||||
123 | // "local file header" segment |
||||||
124 | $unc_len = strlen($data); |
||||||
125 | $crc = crc32($data); |
||||||
126 | $zdata = gzcompress($data); |
||||||
127 | $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug |
||||||
128 | $c_len = strlen($zdata); |
||||||
129 | $fr .= pack('V', $crc); // crc32 |
||||||
130 | $fr .= pack('V', $c_len); // compressed filesize |
||||||
131 | $fr .= pack('V', $unc_len); // uncompressed filesize |
||||||
132 | $fr .= pack('v', strlen($name)); // length of filename |
||||||
133 | $fr .= pack('v', 0); // extra field length |
||||||
134 | $fr .= $name; |
||||||
135 | // "file data" segment |
||||||
136 | $fr .= $zdata; |
||||||
137 | // echo this entry on the fly, ... |
||||||
138 | if ($this->doWrite) { |
||||||
139 | echo $fr; |
||||||
140 | } else { // ... OR add this entry to array |
||||||
141 | $this->datasec[] = $fr; |
||||||
142 | } |
||||||
143 | // now add to central directory record |
||||||
144 | $cdrec = "\x50\x4b\x01\x02"; |
||||||
145 | $cdrec .= "\x00\x00"; // version made by |
||||||
146 | $cdrec .= "\x14\x00"; // version needed to extract |
||||||
147 | $cdrec .= "\x00\x00"; // gen purpose bit flag |
||||||
148 | $cdrec .= "\x08\x00"; // compression method |
||||||
149 | $cdrec .= $hexdtime; // last mod time & date |
||||||
150 | $cdrec .= pack('V', $crc); // crc32 |
||||||
151 | $cdrec .= pack('V', $c_len); // compressed filesize |
||||||
152 | $cdrec .= pack('V', $unc_len); // uncompressed filesize |
||||||
153 | $cdrec .= pack('v', strlen($name)); // length of filename |
||||||
154 | $cdrec .= pack('v', 0); // extra field length |
||||||
155 | $cdrec .= pack('v', 0); // file comment length |
||||||
156 | $cdrec .= pack('v', 0); // disk number start |
||||||
157 | $cdrec .= pack('v', 0); // internal file attributes |
||||||
158 | $cdrec .= pack('V', 32); // external file attributes |
||||||
159 | // - 'archive' bit set |
||||||
160 | $cdrec .= pack('V', $this->old_offset); // relative offset of local header |
||||||
161 | $this->old_offset += strlen($fr); |
||||||
162 | $cdrec .= $name; |
||||||
163 | // optional extra field, file comment goes here |
||||||
164 | // save to central directory |
||||||
165 | $this->ctrl_dir[] = $cdrec; |
||||||
166 | } |
||||||
167 | |||||||
168 | // end of the 'addFile()' method |
||||||
169 | /** |
||||||
170 | * Echo central dir if ->doWrite==true, else build string to return |
||||||
171 | * |
||||||
172 | * @return string if ->doWrite {empty string} else the ZIP file contents |
||||||
173 | * |
||||||
174 | * @access public |
||||||
175 | */ |
||||||
176 | function file() |
||||||
0 ignored issues
–
show
|
|||||||
177 | { |
||||||
178 | $ctrldir = implode('', $this->ctrl_dir); |
||||||
179 | $header = $ctrldir . |
||||||
180 | $this->eof_ctrl_dir . |
||||||
181 | pack('v', sizeof($this->ctrl_dir)) . //total #of entries "on this disk" |
||||||
182 | pack('v', sizeof($this->ctrl_dir)) . //total #of entries overall |
||||||
183 | pack('V', strlen($ctrldir)) . //size of central dir |
||||||
184 | pack('V', $this->old_offset) . //offset to start of central dir |
||||||
185 | "\x00\x00"; //.zip file comment length |
||||||
186 | if ($this->doWrite) { // Send central directory & end ctrl dir to STDOUT |
||||||
187 | echo $header; |
||||||
188 | return ""; // Return empty string |
||||||
189 | } else { // Return entire ZIP archive as string |
||||||
190 | $data = implode('', $this->datasec); |
||||||
191 | return $data . $header; |
||||||
192 | } |
||||||
193 | } |
||||||
194 | |||||||
195 | /** |
||||||
196 | * |
||||||
197 | * @param string $zipPath the zip file path |
||||||
198 | * @param string $entryName the entry file name |
||||||
199 | * @return string|int The entry content or: |
||||||
200 | * 0 If the zip isn't found |
||||||
201 | * 1 If the entry isn't found |
||||||
202 | */ |
||||||
203 | public static function getEntry($zipPath, $entryName) |
||||||
204 | { |
||||||
205 | $zip = zip_open($zipPath); |
||||||
0 ignored issues
–
show
The function
zip_open() has been deprecated: 8.0 Use {@link ZipArchive} instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.
Loading history...
|
|||||||
206 | if (is_resource($zip)) { |
||||||
207 | // find entry |
||||||
208 | do { |
||||||
209 | $entry = zip_read($zip); |
||||||
0 ignored issues
–
show
The function
zip_read() has been deprecated: 8.0 Use {@link ZipArchive} instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.
Loading history...
|
|||||||
210 | } while ($entry && zip_entry_name($entry) != $entryName); |
||||||
0 ignored issues
–
show
The function
zip_entry_name() has been deprecated: 8.0 Use {@link ZipArchive} instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.
Loading history...
|
|||||||
211 | // Not found |
||||||
212 | if (!$entry) { |
||||||
0 ignored issues
–
show
|
|||||||
213 | // close zip |
||||||
214 | zip_close($zip); |
||||||
0 ignored issues
–
show
The function
zip_close() has been deprecated: 8.0 Use {@link ZipArchive} instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.
Loading history...
|
|||||||
215 | return -1; |
||||||
216 | } |
||||||
217 | // open entry |
||||||
218 | zip_entry_open($zip, $entry, "r"); |
||||||
219 | // read entry |
||||||
220 | $content = zip_entry_read($entry, zip_entry_filesize($entry)); |
||||||
0 ignored issues
–
show
The function
zip_entry_filesize() has been deprecated: 8.0 Use {@link ZipArchive} instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.
Loading history...
The function
zip_entry_read() has been deprecated: 8.0 Use {@link ZipArchive} instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.
Loading history...
|
|||||||
221 | // close entry |
||||||
222 | zip_entry_close($entry); |
||||||
0 ignored issues
–
show
The function
zip_entry_close() has been deprecated: 8.0 Use {@link ZipArchive} instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.
Loading history...
|
|||||||
223 | // close zip |
||||||
224 | zip_close($zip); |
||||||
0 ignored issues
–
show
The function
zip_close() has been deprecated: 8.0 Use {@link ZipArchive} instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.
Loading history...
|
|||||||
225 | return $content; |
||||||
226 | } else { |
||||||
227 | return 0; |
||||||
228 | } |
||||||
229 | } |
||||||
230 | |||||||
231 | // end of the 'file()' method |
||||||
232 | } |
||||||
233 | |||||||
234 | // end of the 'ZipFile' class |
||||||
235 |
Adding explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.