InfiniteWP Client - Version 1.1.1

Version Description

  • Improved backups
  • Bug fixes
Download this release

Release Info

Developer infinitewp
Plugin Icon 128x128 InfiniteWP Client
Version 1.1.1
Comparing to
See all releases

Code changes from version 1.1.0 to 1.1.1

addons/backup_repository/backup_repository.class.php CHANGED
@@ -82,6 +82,7 @@ class IWP_MMB_Backup_Repository extends IWP_MMB_Backup
82
  if ($return == true && $del_host_file) {
83
  @unlink($backup_file);
84
  unset($tasks['Backup Now']['task_results'][count($results) - 1]['server']);
 
85
  $this->update_tasks($tasks);
86
  //update_option('iwp_client_backup_tasks', $tasks);
87
  }
@@ -95,359 +96,7 @@ class IWP_MMB_Backup_Repository extends IWP_MMB_Backup
95
  return $return;
96
 
97
  }
98
- /*
99
- function ftp_backup($args)
100
- {
101
- extract($args);
102
- //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder, $ftp_site_folder
103
- $port = $ftp_port ? $ftp_port : 21; //default port is 21
104
- if ($ftp_ssl) {
105
- if (function_exists('ftp_ssl_connect')) {
106
- $conn_id = ftp_ssl_connect($ftp_hostname,$port);
107
- } else {
108
- return array(
109
- 'error' => 'Your server doesn\'t support SFTP',
110
- 'partial' => 1
111
- );
112
- }
113
- } else {
114
- if (function_exists('ftp_connect')) {
115
- $conn_id = ftp_connect($ftp_hostname,$port);
116
- if ($conn_id === false) {
117
- return array(
118
- 'error' => 'Failed to connect to ' . $ftp_hostname,
119
- 'partial' => 1
120
- );
121
- }
122
- } else {
123
- return array(
124
- 'error' => 'Your server doesn\'t support FTP',
125
- 'partial' => 1
126
- );
127
- }
128
- }
129
- $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
130
- if ($login === false) {
131
- return array(
132
- 'error' => 'FTP login failed for ' . $ftp_username . ', ' . $ftp_password,
133
- 'partial' => 1
134
- );
135
- }
136
-
137
- if($ftp_passive){
138
- @ftp_pasv($conn_id,true);
139
- }
140
-
141
- @ftp_mkdir($conn_id, $ftp_remote_folder);
142
- if ($ftp_site_folder) {
143
- $ftp_remote_folder .= '/' . $this->site_name;
144
- }
145
- @ftp_mkdir($conn_id, $ftp_remote_folder);
146
-
147
- $upload = @ftp_put($conn_id, $ftp_remote_folder . '/' . basename($backup_file), $backup_file, FTP_BINARY);
148
-
149
- if ($upload === false) { //Try ascii
150
- $upload = @ftp_put($conn_id, $ftp_remote_folder . '/' . basename($backup_file), $backup_file, FTP_ASCII);
151
- }
152
- ftp_close($conn_id);
153
-
154
- if ($upload === false) {
155
- return array(
156
- 'error' => 'Failed to upload file to FTP. Please check your specified path.',
157
- 'partial' => 1
158
- );
159
- }
160
-
161
- return true;
162
- }
163
-
164
- function remove_ftp_backup($args)
165
- {
166
- extract($args);
167
- //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
168
- $port = $ftp_port ? $ftp_port : 21; //default port is 21
169
- if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
170
- $conn_id = ftp_ssl_connect($ftp_hostname,$port);
171
- } else if (function_exists('ftp_connect')) {
172
- $conn_id = ftp_connect($ftp_hostname,$port);
173
- }
174
-
175
- if ($conn_id) {
176
- $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
177
- if ($ftp_site_folder)
178
- $ftp_remote_folder .= '/' . $this->site_name;
179
-
180
- if($ftp_passive){
181
- @ftp_pasv($conn_id,true);
182
- }
183
-
184
- $delete = ftp_delete($conn_id, $ftp_remote_folder . '/' . $backup_file);
185
-
186
- ftp_close($conn_id);
187
- }
188
-
189
- }
190
-
191
- function get_ftp_backup($args)
192
- {
193
- extract($args);
194
- //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
195
- $port = $ftp_port ? $ftp_port : 21; //default port is 21
196
- if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
197
- $conn_id = ftp_ssl_connect($ftp_hostname,$port);
198
-
199
- } else if (function_exists('ftp_connect')) {
200
- $conn_id = ftp_connect($ftp_hostname,$port);
201
- if ($conn_id === false) {
202
- return false;
203
- }
204
- }
205
- $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
206
- if ($login === false) {
207
- return false;
208
- } else {
209
- }
210
-
211
- if ($ftp_site_folder)
212
- $ftp_remote_folder .= '/' . $this->site_name;
213
-
214
- if($ftp_passive){
215
- @ftp_pasv($conn_id,true);
216
- }
217
-
218
- $temp = ABSPATH . 'iwp_temp_backup.zip';
219
- $get = ftp_get($conn_id, $temp, $ftp_remote_folder . '/' . $backup_file, FTP_BINARY);
220
- if ($get === false) {
221
- return false;
222
- } else {
223
-
224
- }
225
- ftp_close($conn_id);
226
-
227
- return $temp;
228
- }
229
-
230
- function amazons3_backup($args)
231
- {
232
- if ($this->iwp_mmb_function_exists('curl_init')) {
233
- require_once($iwp_mmb_plugin_dir.'/lib/s3.php');
234
- extract($args);
235
-
236
- if ($as3_site_folder == true)
237
- $as3_directory .= '/' . $this->site_name;
238
-
239
- $endpoint = isset($as3_bucket_region) ? $as3_bucket_region : 's3.amazonaws.com';
240
-
241
- $s3 = new S3(trim($as3_access_key), trim(str_replace(' ', '+', $as3_secure_key)), false, $endpoint);
242
-
243
- $s3->putBucket($as3_bucket, S3::ACL_PUBLIC_READ);
244
-
245
- if ($s3->putObjectFile($backup_file, $as3_bucket, $as3_directory . '/' . basename($backup_file), S3::ACL_PRIVATE)) {
246
- return true;
247
- } else {
248
- return array(
249
- 'error' => 'Failed to upload to Amazon S3. Please check your details and set upload/delete permissions on your bucket.',
250
- 'partial' => 1
251
- );
252
- }
253
- } else {
254
- return array(
255
- 'error' => 'You cannot use Amazon S3 on your server. Please enable curl first.',
256
- 'partial' => 1
257
- );
258
- }
259
- }
260
-
261
- function remove_amazons3_backup($args)
262
- {
263
- require_once($iwp_mmb_plugin_dir.'/lib/s3.php');
264
- extract($args);
265
- if ($as3_site_folder == true)
266
- $as3_directory .= '/' . $this->site_name;
267
- $endpoint = isset($as3_bucket_region) ? $as3_bucket_region : 's3.amazonaws.com';
268
- $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key), false, $endpoint);
269
- $s3->deleteObject($as3_bucket, $as3_directory . '/' . $backup_file);
270
- }
271
-
272
- function get_amazons3_backup($args)
273
- {
274
- require_once($iwp_mmb_plugin_dir.'/lib/s3.php');
275
- extract($args);
276
- $endpoint = isset($as3_bucket_region) ? $as3_bucket_region : 's3.amazonaws.com';
277
- $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key), false, $endpoint);
278
- if ($as3_site_folder == true)
279
- $as3_directory .= '/' . $this->site_name;
280
-
281
- $temp = ABSPATH . 'iwp_temp_backup.zip';
282
- $s3->getObject($as3_bucket, $as3_directory . '/' . $backup_file, $temp);
283
-
284
- return $temp;
285
- }
286
-
287
- function dropbox_backup($args)
288
- {
289
-
290
- extract($args);
291
-
292
- if(isset($consumer_secret) && !empty($consumer_secret)){
293
- //New way
294
- require_once($iwp_mmb_plugin_dir.'/lib/dropbox.oauth.php');
295
-
296
- $dropbox = new Dropbox($consumer_key, $consumer_secret);
297
- $dropbox->setOAuthToken($oauth_token);
298
- $dropbox->setOAuthTokenSecret($oauth_token_secret);
299
-
300
- if ($dropbox_site_folder == true)
301
- $dropbox_destination .= '/' . $this->site_name;
302
-
303
- try{
304
-
305
- $dropbox->filesPost($dropbox_destination, $backup_file,true);
306
-
307
- } catch(Exception $e){
308
- return array(
309
- 'error' => 'Dropbox upload error. '.$e->getMessage()
310
- );
311
- }
312
-
313
- return true;
314
-
315
- } else {
316
- //old way
317
- require_once($iwp_mmb_plugin_dir.'/lib/dropbox.php');
318
- // extract($args);
319
-
320
- //$email, $password, $backup_file, $destination, $dropbox_site_folder
321
-
322
- $size = ceil(filesize($backup_file) / 1024);
323
- if ($size > 300000) {
324
- return array(
325
- 'error' => 'Cannot upload file to Dropbox. Dropbox has upload limit of 300Mb per file.',
326
- 'partial' => 1
327
- );
328
- }
329
-
330
- if ($dropbox_site_folder == true)
331
- $dropbox_destination .= '/' . $this->site_name;
332
-
333
- try {
334
- $uploader = new DropboxUploader($dropbox_username, $dropbox_password);
335
- $uploader->upload($backup_file, $dropbox_destination);
336
- }
337
- catch (Exception $e) {
338
- return array(
339
- 'error' => $e->getMessage(),
340
- 'partial' => 1
341
- );
342
- }
343
-
344
- return true;
345
- }
346
-
347
- }
348
-
349
- function remove_dropbox_backup($args){
350
- extract($args);
351
- if(isset($consumer_secret) && !empty($consumer_secret)){
352
- //New way
353
- require_once($iwp_mmb_plugin_dir.'/lib/dropbox.oauth.php');
354
-
355
- $dropbox = new Dropbox($consumer_key, $consumer_secret);
356
- $dropbox->setOAuthToken($oauth_token);
357
- $dropbox->setOAuthTokenSecret($oauth_token_secret);
358
-
359
- if ($dropbox_site_folder == true)
360
- $dropbox_destination .= '/' . $this->site_name;
361
-
362
- try{
363
- $dropbox->fileopsDelete($dropbox_destination.'/'.$backup_file, true);
364
- } catch(Exception $e){
365
-
366
- }
367
- }
368
- }
369
-
370
- function get_dropbox_backup($args){
371
- extract($args);
372
-
373
- if(isset($consumer_secret) && !empty($consumer_secret)){
374
- //New way
375
- require_once($iwp_mmb_plugin_dir.'/lib/dropbox.oauth.php');
376
-
377
- $dropbox = new Dropbox($consumer_key, $consumer_secret);
378
- $dropbox->setOAuthToken($oauth_token);
379
- $dropbox->setOAuthTokenSecret($oauth_token_secret);
380
-
381
- if ($dropbox_site_folder == true)
382
- $dropbox_destination .= '/' . $this->site_name;
383
-
384
- $temp = ABSPATH . 'iwp_temp_backup.zip';
385
-
386
- try{
387
- $file = $dropbox->filesGet($dropbox_destination.'/'.$backup_file, true);
388
-
389
- if(isset($file['data']) && !empty($file['data']) )
390
- $stream = base64_decode($file['data']);
391
- else
392
- return false;
393
-
394
- $handle = @fopen($temp, 'w+');
395
- $result = fwrite($handle,$stream);
396
- fclose($handle);
397
-
398
- if($result)
399
- return $temp;
400
- else
401
- return false;
402
-
403
- } catch(Exception $e){
404
-
405
-
406
- return false;
407
- }
408
-
409
- } else {
410
- return false;
411
- }
412
- }
413
-
414
- function email_backup($args)
415
- {
416
- $email = $args['email'];
417
-
418
- if (!is_email($email)) {
419
- return array(
420
- 'error' => 'Your email (' . $email . ') is not correct'
421
- );
422
- }
423
- $backup_file = $args['file_path'];
424
- $task_name = isset($args['task_name']) ? $args['task_name'] : '';
425
- if (file_exists($backup_file) && $email) {
426
- $attachments = array(
427
- $backup_file
428
- );
429
- $headers = 'From: InfiniteWP <no-reply@infinitewp.com>' . "\r\n";
430
- $subject = "InfiniteWP - " . $task_name . " - " . $this->site_name;
431
- ob_start();
432
- $result = wp_mail($email, $subject, $subject, $headers, $attachments);
433
- ob_end_clean();
434
-
435
- }
436
-
437
- if (!$result) {
438
- return array(
439
- 'error' => 'Email not sent. Maybe your backup is too big for email or email server is not available on your website.'
440
- );
441
- }
442
- return true;
443
-
444
- }
445
 
446
- function update_tasks($tasks)
447
- {
448
- $this->tasks = $tasks;
449
- update_option('iwp_client_backup_tasks', $tasks);
450
- }*/
451
 
452
  }
453
  ?>
82
  if ($return == true && $del_host_file) {
83
  @unlink($backup_file);
84
  unset($tasks['Backup Now']['task_results'][count($results) - 1]['server']);
85
+ $this->wpdb_reconnect();
86
  $this->update_tasks($tasks);
87
  //update_option('iwp_client_backup_tasks', $tasks);
88
  }
96
  return $return;
97
 
98
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
 
 
 
 
 
100
 
101
  }
102
  ?>
backup.class.php CHANGED
@@ -352,6 +352,8 @@ function delete_task_now($task_name){
352
  if (trim($what) == 'db') {
353
  //Take database backup
354
  $this->update_status($task_name, $this->statuses['db_dump']);
 
 
355
  $db_result = $this->backup_db();
356
  if ($db_result == false) {
357
  return array(
@@ -365,6 +367,7 @@ function delete_task_now($task_name){
365
  $this->update_status($task_name, $this->statuses['db_dump'], true);
366
  $this->update_status($task_name, $this->statuses['db_zip']);
367
 
 
368
  $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
369
  $comp_level = $disable_comp ? '-0' : '-1';
370
 
@@ -376,14 +379,27 @@ function delete_task_now($task_name){
376
  ob_get_clean();
377
  if (!$result) { // fallback to pclzip
378
  define('PCLZIP_TEMPORARY_DIR', IWP_BACKUP_DIR . '/');
379
- require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
380
- $archive = new PclZip($backup_file);
381
- if ($disable_comp) {
 
382
  $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION);
383
 
384
  } else {
385
  $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR);
386
- }
 
 
 
 
 
 
 
 
 
 
 
 
387
  @unlink($db_result);
388
  @rmdir(IWP_DB_DIR);
389
  if (!$result) {
@@ -554,6 +570,7 @@ if (isset($account_info['iwp_ftp']) && !empty($account_info['iwp_ftp'])) {
554
  $sys = substr(PHP_OS, 0, 3);
555
 
556
  $this->update_status($task_name, $this->statuses['db_dump']);
 
557
  $db_result = $this->backup_db();
558
 
559
  if ($db_result == false) {
@@ -568,6 +585,8 @@ if (isset($account_info['iwp_ftp']) && !empty($account_info['iwp_ftp'])) {
568
 
569
  $this->update_status($task_name, $this->statuses['db_dump'], true);
570
  $this->update_status($task_name, $this->statuses['db_zip']);
 
 
571
  $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
572
  $comp_level = $disable_comp ? '-0' : '-1';
573
 
@@ -582,14 +601,28 @@ if (isset($account_info['iwp_ftp']) && !empty($account_info['iwp_ftp'])) {
582
 
583
  if (!$result) {
584
  define('PCLZIP_TEMPORARY_DIR', IWP_BACKUP_DIR . '/');
585
- require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
586
- $archive = new PclZip($backup_file);
 
587
 
588
- if ($disable_comp) {
589
  $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION);
590
  } else {
591
  $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR);
592
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
593
 
594
  @unlink($db_result);
595
  @rmdir(IWP_DB_DIR);
@@ -618,7 +651,7 @@ if (isset($account_info['iwp_ftp']) && !empty($account_info['iwp_ftp'])) {
618
 
619
  $exclude_file_data = '';
620
 
621
- if (!empty($exclude)) {
622
  foreach ($exclude as $data) {
623
  if (is_dir(ABSPATH . $data)) {
624
  if ($sys == 'WIN')
@@ -670,7 +703,7 @@ if (isset($account_info['iwp_ftp']) && !empty($account_info['iwp_ftp'])) {
670
  }
671
 
672
  //Additional includes?
673
- if (!empty($include)) {
674
  foreach ($include as $data) {
675
  if ($data) {
676
  if ($sys == 'WIN')
@@ -707,13 +740,14 @@ if (isset($account_info['iwp_ftp']) && !empty($account_info['iwp_ftp'])) {
707
 
708
  if (!isset($archive)) {
709
  define('PCLZIP_TEMPORARY_DIR', IWP_BACKUP_DIR . '/');
710
- require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
711
- $archive = new PclZip($backup_file);
 
712
  }
713
 
714
  //Include paths
715
  $include_data = array();
716
- if (!empty($include)) {
717
  foreach ($include as $data) {
718
  if ($data && file_exists(ABSPATH . $data))
719
  $include_data[] = ABSPATH . $data . '/';
@@ -734,12 +768,35 @@ if (isset($account_info['iwp_ftp']) && !empty($account_info['iwp_ftp'])) {
734
  }
735
  closedir($handle);
736
  }
 
 
 
 
 
 
 
 
 
 
 
737
 
738
- if ($disable_comp) {
739
- $result = $archive->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH, PCLZIP_OPT_NO_COMPRESSION);
740
- } else {
741
- $result = $archive->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH);
742
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
743
  if (!$result) {
744
  @unlink($backup_file);
745
  return array(
@@ -748,7 +805,7 @@ if (isset($account_info['iwp_ftp']) && !empty($account_info['iwp_ftp'])) {
748
  }
749
 
750
  //Now exclude paths
751
- $exclude_data = array();
752
  if (!empty($exclude)) {
753
  foreach ($exclude as $data) {
754
  if (is_dir(ABSPATH . $data))
@@ -768,7 +825,7 @@ if (isset($account_info['iwp_ftp']) && !empty($account_info['iwp_ftp'])) {
768
  return array(
769
  'error' => 'Failed to zip files. pclZip error (' . $archive->error_code . '): .' . $archive->error_string
770
  );
771
- }
772
  }
773
 
774
  //Reconnect
@@ -820,46 +877,131 @@ if (isset($account_info['iwp_ftp']) && !empty($account_info['iwp_ftp'])) {
820
  function backup_db_php($file)
821
  {
822
  global $wpdb;
823
- $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
824
- foreach ($tables as $table) {
825
- //drop existing table
826
- $dump_data = "DROP TABLE IF EXISTS $table[0];";
827
- //create table
828
- $create_table = $wpdb->get_row("SHOW CREATE TABLE $table[0]", ARRAY_N);
829
- $dump_data .= "\n\n" . $create_table[1] . ";\n\n";
830
-
831
- $count = $wpdb->get_var("SELECT count(*) FROM $table[0]");
832
- if ($count > 100)
833
- $count = ceil($count / 100);
834
- else if ($count > 0)
835
- $count = 1;
836
-
837
- for ($i = 0; $i < $count; $i++) {
838
- $low_limit = $i * 100;
839
- $qry = "SELECT * FROM $table[0] LIMIT $low_limit, 100";
840
- $rows = $wpdb->get_results($qry, ARRAY_A);
841
- if (is_array($rows)) {
842
- foreach ($rows as $row) {
843
- //insert single row
844
- $dump_data .= "INSERT INTO $table[0] VALUES(";
845
- $num_values = count($row);
846
- $j = 1;
847
- foreach ($row as $value) {
848
- $value = addslashes($value);
849
- $value = preg_replace("/\n/Ui", "\\n", $value);
850
- $num_values == $j ? $dump_data .= "'" . $value . "'" : $dump_data .= "'" . $value . "', ";
851
- $j++;
852
- unset($value);
853
- }
854
- $dump_data .= ");\n";
855
- }
856
- }
857
- }
858
- $dump_data .= "\n\n\n";
859
-
860
- unset($rows);
861
- file_put_contents($file, $dump_data, FILE_APPEND);
862
- unset($dump_data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
863
  }
864
 
865
  if (filesize($file) == 0 || !is_file($file)) {
@@ -994,8 +1136,9 @@ elseif (isset($task['task_results'][$result_id]['ftp'])) {
994
 
995
  if (!$result) { //fallback to pclzip
996
  define('PCLZIP_TEMPORARY_DIR', IWP_BACKUP_DIR . '/');
997
- require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
998
- $archive = new PclZip($backup_file);
 
999
  $result = $archive->extract(PCLZIP_OPT_PATH, ABSPATH, PCLZIP_OPT_REPLACE_NEWER);
1000
  }
1001
 
@@ -1165,23 +1308,25 @@ elseif (isset($task['task_results'][$result_id]['ftp'])) {
1165
  // Read in entire file
1166
  $lines = file($file_name);
1167
  // Loop through each line
1168
- foreach ($lines as $line) {
1169
- // Skip it if it's a comment
1170
- if (substr($line, 0, 2) == '--' || $line == '')
1171
- continue;
1172
-
1173
- // Add this line to the current query
1174
- $current_query .= $line;
1175
- // If it has a semicolon at the end, it's the end of the query
1176
- if (substr(trim($line), -1, 1) == ';') {
1177
- // Perform the query
1178
- $result = $wpdb->query($current_query);
1179
- if ($result === false)
1180
- return false;
1181
- // Reset temp variable to empty
1182
- $current_query = '';
1183
- }
1184
- }
 
 
1185
 
1186
  @unlink($file_name);
1187
  return true;
@@ -2012,7 +2157,7 @@ function get_next_schedules()
2012
 
2013
 
2014
  //clean_old folder?
2015
- if ((basename($files[0]) == 'index.php' && count($files) == 1) || (empty($files))) { //USE (!empty($files)
2016
  foreach ($files as $file) {
2017
  @unlink($file);
2018
  }
352
  if (trim($what) == 'db') {
353
  //Take database backup
354
  $this->update_status($task_name, $this->statuses['db_dump']);
355
+ $GLOBALS['fail_safe_db'] = $this->tasks[$task_name]['task_args']['fail_safe_db'];
356
+
357
  $db_result = $this->backup_db();
358
  if ($db_result == false) {
359
  return array(
367
  $this->update_status($task_name, $this->statuses['db_dump'], true);
368
  $this->update_status($task_name, $this->statuses['db_zip']);
369
 
370
+ $fail_safe_files = $this->tasks[$task_name]['task_args']['fail_safe_files'];
371
  $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
372
  $comp_level = $disable_comp ? '-0' : '-1';
373
 
379
  ob_get_clean();
380
  if (!$result) { // fallback to pclzip
381
  define('PCLZIP_TEMPORARY_DIR', IWP_BACKUP_DIR . '/');
382
+ //require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
383
+ require_once $GLOBALS['iwp_mmb_plugin_dir'].'/pclzip.class.php';
384
+ $archive = new IWPPclZip($backup_file);
385
+ /*if ($disable_comp) {
386
  $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION);
387
 
388
  } else {
389
  $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR);
390
+ }*/
391
+ if($fail_safe_files && $disable_comp){
392
+ $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION, PCLZIP_OPT_TEMP_FILE_THRESHOLD, 1);
393
+ }
394
+ elseif(!$fail_safe_files && $disable_comp){
395
+ $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION);
396
+ }
397
+ elseif($fail_safe_files && !$disable_comp){
398
+ $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR, PCLZIP_OPT_TEMP_FILE_THRESHOLD, 1);
399
+ }
400
+ else{
401
+ $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR);
402
+ }
403
  @unlink($db_result);
404
  @rmdir(IWP_DB_DIR);
405
  if (!$result) {
570
  $sys = substr(PHP_OS, 0, 3);
571
 
572
  $this->update_status($task_name, $this->statuses['db_dump']);
573
+ $GLOBALS['fail_safe_db'] = $this->tasks[$task_name]['task_args']['fail_safe_db'];
574
  $db_result = $this->backup_db();
575
 
576
  if ($db_result == false) {
585
 
586
  $this->update_status($task_name, $this->statuses['db_dump'], true);
587
  $this->update_status($task_name, $this->statuses['db_zip']);
588
+
589
+ $fail_safe_files = $this->tasks[$task_name]['task_args']['fail_safe_files'];
590
  $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
591
  $comp_level = $disable_comp ? '-0' : '-1';
592
 
601
 
602
  if (!$result) {
603
  define('PCLZIP_TEMPORARY_DIR', IWP_BACKUP_DIR . '/');
604
+ //require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
605
+ require_once $GLOBALS['iwp_mmb_plugin_dir'].'/pclzip.class.php';
606
+ $archive = new IWPPclZip($backup_file);
607
 
608
+ /*if ($disable_comp) {
609
  $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION);
610
  } else {
611
  $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR);
612
+ }*/
613
+
614
+ if($fail_safe_files && $disable_comp){
615
+ $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION, PCLZIP_OPT_TEMP_FILE_THRESHOLD, 1);
616
+ }
617
+ elseif(!$fail_safe_files && $disable_comp){
618
+ $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION);
619
+ }
620
+ elseif($fail_safe_files && !$disable_comp){
621
+ $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR, PCLZIP_OPT_TEMP_FILE_THRESHOLD, 1);
622
+ }
623
+ else{
624
+ $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, IWP_BACKUP_DIR);
625
+ }
626
 
627
  @unlink($db_result);
628
  @rmdir(IWP_DB_DIR);
651
 
652
  $exclude_file_data = '';
653
 
654
+ if (!empty($exclude) && is_array($exclude)) {
655
  foreach ($exclude as $data) {
656
  if (is_dir(ABSPATH . $data)) {
657
  if ($sys == 'WIN')
703
  }
704
 
705
  //Additional includes?
706
+ if (!empty($include) && is_array($include)) {
707
  foreach ($include as $data) {
708
  if ($data) {
709
  if ($sys == 'WIN')
740
 
741
  if (!isset($archive)) {
742
  define('PCLZIP_TEMPORARY_DIR', IWP_BACKUP_DIR . '/');
743
+ //require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
744
+ require_once $GLOBALS['iwp_mmb_plugin_dir'].'/pclzip.class.php';
745
+ $archive = new IWPPclZip($backup_file);
746
  }
747
 
748
  //Include paths
749
  $include_data = array();
750
+ if (!empty($include) && is_array($include)) {
751
  foreach ($include as $data) {
752
  if ($data && file_exists(ABSPATH . $data))
753
  $include_data[] = ABSPATH . $data . '/';
768
  }
769
  closedir($handle);
770
  }
771
+
772
+ //exclude paths
773
+ $exclude_data = array();
774
+ if (!empty($exclude) && is_array($exclude)) {
775
+ foreach ($exclude as $data) {
776
+ if (is_dir(ABSPATH . $data))
777
+ $exclude_data[] = $data . '/';
778
+ else
779
+ $exclude_data[] = $data;
780
+ }
781
+ }
782
 
783
+ foreach ($remove as $rem) {
784
+ $exclude_data[] = $rem . '/';
 
 
785
  }
786
+
787
+ if($fail_safe_files && $disable_comp){
788
+ $result = $archive->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH, PCLZIP_OPT_IWP_EXCLUDE, $exclude_data, PCLZIP_OPT_NO_COMPRESSION, PCLZIP_OPT_TEMP_FILE_THRESHOLD, 1);
789
+ }
790
+ elseif(!$fail_safe_files && $disable_comp){
791
+ $result = $archive->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH, PCLZIP_OPT_IWP_EXCLUDE, $exclude_data, PCLZIP_OPT_NO_COMPRESSION);
792
+ }
793
+ elseif($fail_safe_files && !$disable_comp){
794
+ $result = $archive->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH, PCLZIP_OPT_IWP_EXCLUDE, $exclude_data, PCLZIP_OPT_TEMP_FILE_THRESHOLD, 1);
795
+ }
796
+ else{
797
+ $result = $archive->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH, PCLZIP_OPT_IWP_EXCLUDE, $exclude_data);
798
+ }
799
+
800
  if (!$result) {
801
  @unlink($backup_file);
802
  return array(
805
  }
806
 
807
  //Now exclude paths
808
+ /*$exclude_data = array();
809
  if (!empty($exclude)) {
810
  foreach ($exclude as $data) {
811
  if (is_dir(ABSPATH . $data))
825
  return array(
826
  'error' => 'Failed to zip files. pclZip error (' . $archive->error_code . '): .' . $archive->error_string
827
  );
828
+ }*/
829
  }
830
 
831
  //Reconnect
877
  function backup_db_php($file)
878
  {
879
  global $wpdb;
880
+
881
+ if(empty($GLOBALS['fail_safe_db'])){
882
+ $fp = fopen( $file, 'w' );
883
+ if ( !mysql_ping( $wpdb->dbh ) ) {
884
+ mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
885
+ mysql_select_db( DB_NAME );
886
+ }
887
+ $_count = 0;
888
+ $insert_sql = '';
889
+ $result = mysql_query( 'SHOW TABLES' );
890
+ if(!$result)
891
+ {
892
+ return array(
893
+ 'error' => 'MySQL '.mysql_error()." "
894
+ );
895
+ }
896
+ while( $row = mysql_fetch_row( $result ) ) {
897
+ $tables[]=$row[0];
898
+ //array_push( $tables, $row[0] );
899
+ }
900
+
901
+
902
+ //$tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
903
+ foreach ($tables as $table) {
904
+
905
+ $insert_sql .= "DROP TABLE IF EXISTS $table;";
906
+ //create table
907
+ $table_descr_query = mysql_query("SHOW CREATE TABLE `$table`");
908
+ $fetch_table_descr_row = mysql_fetch_array( $table_descr_query );
909
+ $insert_sql .= "\n\n" . $fetch_table_descr_row[1] . ";\n\n";
910
+
911
+ fwrite( $fp, $insert_sql );
912
+ $insert_sql = '';
913
+
914
+ $table_query = mysql_query("SELECT * FROM `$table`");
915
+ $num_fields = mysql_num_fields($table_query);
916
+ while ( $fetch_row = mysql_fetch_array( $table_query ) ) {
917
+ $insert_sql .= "INSERT INTO $table VALUES(";
918
+ for ( $n=1; $n<=$num_fields; $n++ ) {
919
+ $m = $n - 1;
920
+
921
+ if ( $fetch_row[$m] === NULL ) {
922
+ $insert_sql .= "NULL, ";
923
+ } else {
924
+ $insert_sql .= "'" . mysql_real_escape_string( $fetch_row[$m] ) . "', ";
925
+ }
926
+ }
927
+ $insert_sql = substr( $insert_sql, 0, -2 );
928
+ $insert_sql .= ");\n";
929
+
930
+ fwrite( $fp, $insert_sql );
931
+ $insert_sql = '';
932
+
933
+ // Help keep HTTP alive.
934
+ $_count++;
935
+ if ($_count >= 400) {
936
+ echo ' ';
937
+ flush();
938
+ $_count = 0;
939
+ }
940
+ } // End foreach $tables.
941
+
942
+ $insert_sql .= "\n\n\n";
943
+
944
+ // testing: mysql_close( $wpdb->dbh );
945
+ // Verify database is still connected and working properly. Sometimes mysql runs out of memory and dies in the above foreach.
946
+ // No point in reconnecting as we can NOT trust that our dump was succesful anymore (it most likely was not).
947
+ if ( @mysql_ping( $wpdb->dbh ) ) { // Still connected to database.
948
+ mysql_free_result( $table_query ); // Free memory.
949
+ } /*else { // Database not connected.
950
+
951
+ return false;
952
+ }*/
953
+
954
+ // Help keep HTTP alive.
955
+ echo ' ';
956
+ flush();
957
+
958
+ //unset( $tables[$table_key] );
959
+ }
960
+ fclose( $fp );
961
+ unset ($fp);
962
+ }
963
+ else{
964
+ $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
965
+ foreach ($tables as $table) {
966
+ //drop existing table
967
+ $dump_data = "DROP TABLE IF EXISTS $table[0];";
968
+ //create table
969
+ $create_table = $wpdb->get_row("SHOW CREATE TABLE $table[0]", ARRAY_N);
970
+ $dump_data .= "\n\n" . $create_table[1] . ";\n\n";
971
+
972
+ $count = $wpdb->get_var("SELECT count(*) FROM $table[0]");
973
+ if ($count > 100)
974
+ $count = ceil($count / 100);
975
+ else if ($count > 0)
976
+ $count = 1;
977
+
978
+ for ($i = 0; $i < $count; $i++) {
979
+ $low_limit = $i * 100;
980
+ $qry = "SELECT * FROM $table[0] LIMIT $low_limit, 100";
981
+ $rows = $wpdb->get_results($qry, ARRAY_A);
982
+ if (is_array($rows)) {
983
+ foreach ($rows as $row) {
984
+ //insert single row
985
+ $dump_data .= "INSERT INTO $table[0] VALUES(";
986
+ $num_values = count($row);
987
+ $j = 1;
988
+ foreach ($row as $value) {
989
+ $value = addslashes($value);
990
+ $value = preg_replace("/\n/Ui", "\\n", $value);
991
+ $num_values == $j ? $dump_data .= "'" . $value . "'" : $dump_data .= "'" . $value . "', ";
992
+ $j++;
993
+ unset($value);
994
+ }
995
+ $dump_data .= ");\n";
996
+ }
997
+ }
998
+ }
999
+ $dump_data .= "\n\n\n";
1000
+
1001
+ unset($rows);
1002
+ file_put_contents($file, $dump_data, FILE_APPEND);
1003
+ unset($dump_data);
1004
+ }
1005
  }
1006
 
1007
  if (filesize($file) == 0 || !is_file($file)) {
1136
 
1137
  if (!$result) { //fallback to pclzip
1138
  define('PCLZIP_TEMPORARY_DIR', IWP_BACKUP_DIR . '/');
1139
+ //require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
1140
+ require_once $GLOBALS['iwp_mmb_plugin_dir'].'/pclzip.class.php';
1141
+ $archive = new IWPPclZip($backup_file);
1142
  $result = $archive->extract(PCLZIP_OPT_PATH, ABSPATH, PCLZIP_OPT_REPLACE_NEWER);
1143
  }
1144
 
1308
  // Read in entire file
1309
  $lines = file($file_name);
1310
  // Loop through each line
1311
+ if(!empty($lines)){
1312
+ foreach ($lines as $line) {
1313
+ // Skip it if it's a comment
1314
+ if (substr($line, 0, 2) == '--' || $line == '')
1315
+ continue;
1316
+
1317
+ // Add this line to the current query
1318
+ $current_query .= $line;
1319
+ // If it has a semicolon at the end, it's the end of the query
1320
+ if (substr(trim($line), -1, 1) == ';') {
1321
+ // Perform the query
1322
+ $result = $wpdb->query($current_query);
1323
+ if ($result === false)
1324
+ return false;
1325
+ // Reset temp variable to empty
1326
+ $current_query = '';
1327
+ }
1328
+ }
1329
+ }
1330
 
1331
  @unlink($file_name);
1332
  return true;
2157
 
2158
 
2159
  //clean_old folder?
2160
+ if ((basename($files[0]) == 'index.php' && count($files) == 1) || (!empty($files))) { //USE (!empty($files)
2161
  foreach ($files as $file) {
2162
  @unlink($file);
2163
  }
core.class.php CHANGED
@@ -233,10 +233,10 @@ class IWP_MMB_Core extends IWP_MMB_Helper
233
  }
234
  else{
235
  echo '<tr><td align="center">Please deactivate and then activate InfiniteWP Client plugin.</td></tr>';
236
- }
237
 
238
  echo '</table>
239
- </p></div>';
240
 
241
  }
242
 
233
  }
234
  else{
235
  echo '<tr><td align="center">Please deactivate and then activate InfiniteWP Client plugin.</td></tr>';
236
+ }
237
 
238
  echo '</table>
239
+ </p></div>';
240
 
241
  }
242
 
init.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: InfiniteWP - Client
4
  Plugin URI: http://infinitewp.com/
5
  Description: This is the client plugin of InfiniteWP that communicates with the InfiniteWP Admin panel.
6
  Author: Revmakx
7
- Version: 1.1.0
8
  Author URI: http://www.revmakx.com
9
  */
10
  /************************************************************
@@ -26,7 +26,7 @@ Author URI: http://www.revmakx.com
26
  **************************************************************/
27
 
28
  if(!defined('IWP_MMB_CLIENT_VERSION'))
29
- define('IWP_MMB_CLIENT_VERSION', '1.1.0');
30
 
31
 
32
  if ( !defined('IWP_MMB_XFRAME_COOKIE')){
4
  Plugin URI: http://infinitewp.com/
5
  Description: This is the client plugin of InfiniteWP that communicates with the InfiniteWP Admin panel.
6
  Author: Revmakx
7
+ Version: 1.1.1
8
  Author URI: http://www.revmakx.com
9
  */
10
  /************************************************************
26
  **************************************************************/
27
 
28
  if(!defined('IWP_MMB_CLIENT_VERSION'))
29
+ define('IWP_MMB_CLIENT_VERSION', '1.1.1');
30
 
31
 
32
  if ( !defined('IWP_MMB_XFRAME_COOKIE')){
pclzip.class.php ADDED
@@ -0,0 +1,5716 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // --------------------------------------------------------------------------------
3
+ // PhpConcept Library - Zip Module 2.8.2
4
+ // --------------------------------------------------------------------------------
5
+ // License GNU/LGPL - Vincent Blavet - August 2009
6
+ // http://www.phpconcept.net
7
+ // --------------------------------------------------------------------------------
8
+ //
9
+ // Presentation :
10
+ // PclZip is a PHP library that manage ZIP archives.
11
+ // So far tests show that archives generated by PclZip are readable by
12
+ // WinZip application and other tools.
13
+ //
14
+ // Description :
15
+ // See readme.txt and http://www.phpconcept.net
16
+ //
17
+ // Warning :
18
+ // This library and the associated files are non commercial, non professional
19
+ // work.
20
+ // It should not have unexpected results. However if any damage is caused by
21
+ // this software the author can not be responsible.
22
+ // The use of this software is at the risk of the user.
23
+ //
24
+ // --------------------------------------------------------------------------------
25
+ // $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $
26
+ // --------------------------------------------------------------------------------
27
+
28
+ // ----- Constants
29
+ if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
30
+ define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
31
+ }
32
+
33
+ // ----- File list separator
34
+ // In version 1.x of PclZip, the separator for file list is a space
35
+ // (which is not a very smart choice, specifically for windows paths !).
36
+ // A better separator should be a comma (,). This constant gives you the
37
+ // abilty to change that.
38
+ // However notice that changing this value, may have impact on existing
39
+ // scripts, using space separated filenames.
40
+ // Recommanded values for compatibility with older versions :
41
+ //define( 'PCLZIP_SEPARATOR', ' ' );
42
+ // Recommanded values for smart separation of filenames.
43
+ if (!defined('PCLZIP_SEPARATOR')) {
44
+ define( 'PCLZIP_SEPARATOR', ',' );
45
+ }
46
+
47
+ // ----- Error configuration
48
+ // 0 : PclZip Class integrated error handling
49
+ // 1 : PclError external library error handling. By enabling this
50
+ // you must ensure that you have included PclError library.
51
+ // [2,...] : reserved for futur use
52
+ if (!defined('PCLZIP_ERROR_EXTERNAL')) {
53
+ define( 'PCLZIP_ERROR_EXTERNAL', 0 );
54
+ }
55
+
56
+ // ----- Optional static temporary directory
57
+ // By default temporary files are generated in the script current
58
+ // path.
59
+ // If defined :
60
+ // - MUST BE terminated by a '/'.
61
+ // - MUST be a valid, already created directory
62
+ // Samples :
63
+ // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
64
+ // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
65
+ if (!defined('PCLZIP_TEMPORARY_DIR')) {
66
+ define( 'PCLZIP_TEMPORARY_DIR', '' );
67
+ }
68
+
69
+ // ----- Optional threshold ratio for use of temporary files
70
+ // Pclzip sense the size of the file to add/extract and decide to
71
+ // use or not temporary file. The algorythm is looking for
72
+ // memory_limit of PHP and apply a ratio.
73
+ // threshold = memory_limit * ratio.
74
+ // Recommended values are under 0.5. Default 0.47.
75
+ // Samples :
76
+ // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );
77
+ if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
78
+ define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
79
+ }
80
+
81
+ // --------------------------------------------------------------------------------
82
+ // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
83
+ // --------------------------------------------------------------------------------
84
+
85
+ // ----- Global variables
86
+ $g_pclzip_version = "2.8.2";
87
+
88
+ // ----- Error codes
89
+ // -1 : Unable to open file in binary write mode
90
+ // -2 : Unable to open file in binary read mode
91
+ // -3 : Invalid parameters
92
+ // -4 : File does not exist
93
+ // -5 : Filename is too long (max. 255)
94
+ // -6 : Not a valid zip file
95
+ // -7 : Invalid extracted file size
96
+ // -8 : Unable to create directory
97
+ // -9 : Invalid archive extension
98
+ // -10 : Invalid archive format
99
+ // -11 : Unable to delete file (unlink)
100
+ // -12 : Unable to rename file (rename)
101
+ // -13 : Invalid header checksum
102
+ // -14 : Invalid archive size
103
+ define( 'PCLZIP_ERR_USER_ABORTED', 2 );
104
+ define( 'PCLZIP_ERR_NO_ERROR', 0 );
105
+ define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
106
+ define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
107
+ define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
108
+ define( 'PCLZIP_ERR_MISSING_FILE', -4 );
109
+ define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
110
+ define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
111
+ define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
112
+ define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
113
+ define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
114
+ define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
115
+ define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
116
+ define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
117
+ define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
118
+ define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
119
+ define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
120
+ define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
121
+ define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
122
+ define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
123
+ define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
124
+ define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
125
+ define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
126
+
127
+ // ----- Options values
128
+ define( 'PCLZIP_OPT_PATH', 77001 );
129
+ define( 'PCLZIP_OPT_ADD_PATH', 77002 );
130
+ define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
131
+ define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
132
+ define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
133
+ define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
134
+ define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
135
+ define( 'PCLZIP_OPT_BY_NAME', 77008 );
136
+ define( 'PCLZIP_OPT_BY_INDEX', 77009 );
137
+ define( 'PCLZIP_OPT_BY_EREG', 77010 );
138
+ define( 'PCLZIP_OPT_BY_PREG', 77011 );
139
+ define( 'PCLZIP_OPT_COMMENT', 77012 );
140
+ define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
141
+ define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
142
+ define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
143
+ define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
144
+ define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
145
+ // Having big trouble with crypt. Need to multiply 2 long int
146
+ // which is not correctly supported by PHP ...
147
+ //define( 'PCLZIP_OPT_CRYPT', 77018 );
148
+ define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
149
+ define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
150
+ define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias
151
+ define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
152
+ define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias
153
+ define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
154
+ define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias
155
+
156
+ define( 'PCLZIP_OPT_IWP_EXCLUDE', 77999 );//IWP Mod
157
+
158
+ // ----- File description attributes
159
+ define( 'PCLZIP_ATT_FILE_NAME', 79001 );
160
+ define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
161
+ define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
162
+ define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
163
+ define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
164
+ define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
165
+
166
+ // ----- Call backs values
167
+ define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
168
+ define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
169
+ define( 'PCLZIP_CB_PRE_ADD', 78003 );
170
+ define( 'PCLZIP_CB_POST_ADD', 78004 );
171
+ /* For futur use
172
+ define( 'PCLZIP_CB_PRE_LIST', 78005 );
173
+ define( 'PCLZIP_CB_POST_LIST', 78006 );
174
+ define( 'PCLZIP_CB_PRE_DELETE', 78007 );
175
+ define( 'PCLZIP_CB_POST_DELETE', 78008 );
176
+ */
177
+
178
+ // --------------------------------------------------------------------------------
179
+ // Class : PclZip
180
+ // Description :
181
+ // PclZip is the class that represent a Zip archive.
182
+ // The public methods allow the manipulation of the archive.
183
+ // Attributes :
184
+ // Attributes must not be accessed directly.
185
+ // Methods :
186
+ // PclZip() : Object creator
187
+ // create() : Creates the Zip archive
188
+ // listContent() : List the content of the Zip archive
189
+ // extract() : Extract the content of the archive
190
+ // properties() : List the properties of the archive
191
+ // --------------------------------------------------------------------------------
192
+ class IWPPclZip
193
+ {
194
+ // ----- Filename of the zip file
195
+ var $zipname = '';
196
+
197
+ // ----- File descriptor of the zip file
198
+ var $zip_fd = 0;
199
+
200
+ // ----- Internal error handling
201
+ var $error_code = 1;
202
+ var $error_string = '';
203
+
204
+ // ----- Current status of the magic_quotes_runtime
205
+ // This value store the php configuration for magic_quotes
206
+ // The class can then disable the magic_quotes and reset it after
207
+ var $magic_quotes_status;
208
+
209
+ // --------------------------------------------------------------------------------
210
+ // Function : PclZip()
211
+ // Description :
212
+ // Creates a PclZip object and set the name of the associated Zip archive
213
+ // filename.
214
+ // Note that no real action is taken, if the archive does not exist it is not
215
+ // created. Use create() for that.
216
+ // --------------------------------------------------------------------------------
217
+ function IWPPclZip($p_zipname)
218
+ {
219
+
220
+ // ----- Tests the zlib
221
+ if (!function_exists('gzopen'))
222
+ {
223
+ die('Abort '.basename(__FILE__).' : Missing zlib extensions');
224
+ }
225
+
226
+ // ----- Set the attributes
227
+ $this->zipname = $p_zipname;
228
+ $this->zip_fd = 0;
229
+ $this->magic_quotes_status = -1;
230
+
231
+ // ----- Return
232
+ return;
233
+ }
234
+ // --------------------------------------------------------------------------------
235
+
236
+ // --------------------------------------------------------------------------------
237
+ // Function :
238
+ // create($p_filelist, $p_add_dir="", $p_remove_dir="")
239
+ // create($p_filelist, $p_option, $p_option_value, ...)
240
+ // Description :
241
+ // This method supports two different synopsis. The first one is historical.
242
+ // This method creates a Zip Archive. The Zip file is created in the
243
+ // filesystem. The files and directories indicated in $p_filelist
244
+ // are added in the archive. See the parameters description for the
245
+ // supported format of $p_filelist.
246
+ // When a directory is in the list, the directory and its content is added
247
+ // in the archive.
248
+ // In this synopsis, the function takes an optional variable list of
249
+ // options. See bellow the supported options.
250
+ // Parameters :
251
+ // $p_filelist : An array containing file or directory names, or
252
+ // a string containing one filename or one directory name, or
253
+ // a string containing a list of filenames and/or directory
254
+ // names separated by spaces.
255
+ // $p_add_dir : A path to add before the real path of the archived file,
256
+ // in order to have it memorized in the archive.
257
+ // $p_remove_dir : A path to remove from the real path of the file to archive,
258
+ // in order to have a shorter path memorized in the archive.
259
+ // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
260
+ // is removed first, before $p_add_dir is added.
261
+ // Options :
262
+ // PCLZIP_OPT_ADD_PATH :
263
+ // PCLZIP_OPT_REMOVE_PATH :
264
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
265
+ // PCLZIP_OPT_COMMENT :
266
+ // PCLZIP_CB_PRE_ADD :
267
+ // PCLZIP_CB_POST_ADD :
268
+ // Return Values :
269
+ // 0 on failure,
270
+ // The list of the added files, with a status of the add action.
271
+ // (see IWPPclZip::listContent() for list entry format)
272
+ // --------------------------------------------------------------------------------
273
+ function create($p_filelist)
274
+ {
275
+ $v_result=1;
276
+
277
+ // ----- Reset the error handler
278
+ $this->privErrorReset();
279
+
280
+ // ----- Set default values
281
+ $v_options = array();
282
+ $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
283
+
284
+ // ----- Look for variable options arguments
285
+ $v_size = func_num_args();
286
+
287
+ // ----- Look for arguments
288
+ if ($v_size > 1) {
289
+ // ----- Get the arguments
290
+ $v_arg_list = func_get_args();
291
+
292
+ // ----- Remove from the options list the first argument
293
+ array_shift($v_arg_list);
294
+ $v_size--;
295
+
296
+ // ----- Look for first arg
297
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
298
+
299
+ // ----- Parse the options
300
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
301
+ array (PCLZIP_OPT_REMOVE_PATH => 'optional',
302
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
303
+ PCLZIP_OPT_ADD_PATH => 'optional',
304
+ PCLZIP_CB_PRE_ADD => 'optional',
305
+ PCLZIP_CB_POST_ADD => 'optional',
306
+ PCLZIP_OPT_NO_COMPRESSION => 'optional',
307
+ PCLZIP_OPT_COMMENT => 'optional',
308
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
309
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
310
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
311
+ //, PCLZIP_OPT_CRYPT => 'optional'
312
+ ));
313
+ if ($v_result != 1) {
314
+ return 0;
315
+ }
316
+ }
317
+
318
+ // ----- Look for 2 args
319
+ // Here we need to support the first historic synopsis of the
320
+ // method.
321
+ else {
322
+
323
+ // ----- Get the first argument
324
+ $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
325
+
326
+ // ----- Look for the optional second argument
327
+ if ($v_size == 2) {
328
+ $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
329
+ }
330
+ else if ($v_size > 2) {
331
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
332
+ "Invalid number / type of arguments");
333
+ return 0;
334
+ }
335
+ }
336
+ }
337
+
338
+ // ----- Look for default option values
339
+ $this->privOptionDefaultThreshold($v_options);
340
+
341
+ // ----- Init
342
+ $v_string_list = array();
343
+ $v_att_list = array();
344
+ $v_filedescr_list = array();
345
+ $p_result_list = array();
346
+
347
+ // ----- Look if the $p_filelist is really an array
348
+ if (is_array($p_filelist)) {
349
+
350
+ // ----- Look if the first element is also an array
351
+ // This will mean that this is a file description entry
352
+ if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
353
+ $v_att_list = $p_filelist;
354
+ }
355
+
356
+ // ----- The list is a list of string names
357
+ else {
358
+ $v_string_list = $p_filelist;
359
+ }
360
+ }
361
+
362
+ // ----- Look if the $p_filelist is a string
363
+ else if (is_string($p_filelist)) {
364
+ // ----- Create a list from the string
365
+ $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
366
+ }
367
+
368
+ // ----- Invalid variable type for $p_filelist
369
+ else {
370
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
371
+ return 0;
372
+ }
373
+
374
+ // ----- Reformat the string list
375
+ if (sizeof($v_string_list) != 0) {
376
+ foreach ($v_string_list as $v_string) {
377
+ if ($v_string != '') {
378
+ $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
379
+ }
380
+ else {
381
+ }
382
+ }
383
+ }
384
+
385
+ // ----- For each file in the list check the attributes
386
+ $v_supported_attributes
387
+ = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
388
+ ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
389
+ ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
390
+ ,PCLZIP_ATT_FILE_MTIME => 'optional'
391
+ ,PCLZIP_ATT_FILE_CONTENT => 'optional'
392
+ ,PCLZIP_ATT_FILE_COMMENT => 'optional'
393
+ );
394
+ foreach ($v_att_list as $v_entry) {
395
+ $v_result = $this->privFileDescrParseAtt($v_entry,
396
+ $v_filedescr_list[],
397
+ $v_options,
398
+ $v_supported_attributes);
399
+ if ($v_result != 1) {
400
+ return 0;
401
+ }
402
+ }
403
+
404
+ // ----- Expand the filelist (expand directories)
405
+ $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
406
+ if ($v_result != 1) {
407
+ return 0;
408
+ }
409
+
410
+ // ----- Call the create fct
411
+ $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
412
+ if ($v_result != 1) {
413
+ return 0;
414
+ }
415
+
416
+ // ----- Return
417
+ return $p_result_list;
418
+ }
419
+ // --------------------------------------------------------------------------------
420
+
421
+ // --------------------------------------------------------------------------------
422
+ // Function :
423
+ // add($p_filelist, $p_add_dir="", $p_remove_dir="")
424
+ // add($p_filelist, $p_option, $p_option_value, ...)
425
+ // Description :
426
+ // This method supports two synopsis. The first one is historical.
427
+ // This methods add the list of files in an existing archive.
428
+ // If a file with the same name already exists, it is added at the end of the
429
+ // archive, the first one is still present.
430
+ // If the archive does not exist, it is created.
431
+ // Parameters :
432
+ // $p_filelist : An array containing file or directory names, or
433
+ // a string containing one filename or one directory name, or
434
+ // a string containing a list of filenames and/or directory
435
+ // names separated by spaces.
436
+ // $p_add_dir : A path to add before the real path of the archived file,
437
+ // in order to have it memorized in the archive.
438
+ // $p_remove_dir : A path to remove from the real path of the file to archive,
439
+ // in order to have a shorter path memorized in the archive.
440
+ // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
441
+ // is removed first, before $p_add_dir is added.
442
+ // Options :
443
+ // PCLZIP_OPT_ADD_PATH :
444
+ // PCLZIP_OPT_REMOVE_PATH :
445
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
446
+ // PCLZIP_OPT_COMMENT :
447
+ // PCLZIP_OPT_ADD_COMMENT :
448
+ // PCLZIP_OPT_PREPEND_COMMENT :
449
+ // PCLZIP_CB_PRE_ADD :
450
+ // PCLZIP_CB_POST_ADD :
451
+ // Return Values :
452
+ // 0 on failure,
453
+ // The list of the added files, with a status of the add action.
454
+ // (see IWPPclZip::listContent() for list entry format)
455
+ // --------------------------------------------------------------------------------
456
+ function add($p_filelist)
457
+ {
458
+ $v_result=1;
459
+
460
+ // ----- Reset the error handler
461
+ $this->privErrorReset();
462
+
463
+ // ----- Set default values
464
+ $v_options = array();
465
+ $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
466
+
467
+ // ----- Look for variable options arguments
468
+ $v_size = func_num_args();
469
+
470
+ // ----- Look for arguments
471
+ if ($v_size > 1) {
472
+ // ----- Get the arguments
473
+ $v_arg_list = func_get_args();
474
+
475
+
476
+ // ----- Remove form the options list the first argument
477
+ array_shift($v_arg_list);
478
+ $v_size--;
479
+
480
+ // ----- Look for first arg
481
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
482
+
483
+ // ----- Parse the options
484
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
485
+ array (PCLZIP_OPT_REMOVE_PATH => 'optional',
486
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
487
+ PCLZIP_OPT_ADD_PATH => 'optional',
488
+ PCLZIP_CB_PRE_ADD => 'optional',
489
+ PCLZIP_CB_POST_ADD => 'optional',
490
+ PCLZIP_OPT_NO_COMPRESSION => 'optional',
491
+ PCLZIP_OPT_COMMENT => 'optional',
492
+ PCLZIP_OPT_ADD_COMMENT => 'optional',
493
+ PCLZIP_OPT_PREPEND_COMMENT => 'optional',
494
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
495
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
496
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional',
497
+ //, PCLZIP_OPT_CRYPT => 'optional'
498
+ PCLZIP_OPT_IWP_EXCLUDE => 'optional'
499
+ ));
500
+ if ($v_result != 1) {
501
+ return 0;
502
+ }
503
+ }
504
+
505
+ // ----- Look for 2 args
506
+ // Here we need to support the first historic synopsis of the
507
+ // method.
508
+ else {
509
+
510
+ // ----- Get the first argument
511
+ $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
512
+
513
+ // ----- Look for the optional second argument
514
+ if ($v_size == 2) {
515
+ $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
516
+ }
517
+ else if ($v_size > 2) {
518
+ // ----- Error log
519
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
520
+
521
+ // ----- Return
522
+ return 0;
523
+ }
524
+ }
525
+ }
526
+
527
+ // ----- Look for default option values
528
+ $this->privOptionDefaultThreshold($v_options);
529
+
530
+ // ----- Init
531
+ $v_string_list = array();
532
+ $v_att_list = array();
533
+ $v_filedescr_list = array();
534
+ $p_result_list = array();
535
+
536
+ // ----- Look if the $p_filelist is really an array
537
+ if (is_array($p_filelist)) {
538
+
539
+ // ----- Look if the first element is also an array
540
+ // This will mean that this is a file description entry
541
+ if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
542
+ $v_att_list = $p_filelist;
543
+ }
544
+
545
+ // ----- The list is a list of string names
546
+ else {
547
+ $v_string_list = $p_filelist;
548
+ }
549
+ }
550
+
551
+ // ----- Look if the $p_filelist is a string
552
+ else if (is_string($p_filelist)) {
553
+ // ----- Create a list from the string
554
+ $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
555
+ }
556
+
557
+ // ----- Invalid variable type for $p_filelist
558
+ else {
559
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
560
+ return 0;
561
+ }
562
+
563
+ // ----- Reformat the string list
564
+ if (sizeof($v_string_list) != 0) {
565
+ foreach ($v_string_list as $v_string) {
566
+ $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
567
+ }
568
+ }
569
+
570
+ // ----- For each file in the list check the attributes
571
+ $v_supported_attributes
572
+ = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
573
+ ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
574
+ ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
575
+ ,PCLZIP_ATT_FILE_MTIME => 'optional'
576
+ ,PCLZIP_ATT_FILE_CONTENT => 'optional'
577
+ ,PCLZIP_ATT_FILE_COMMENT => 'optional'
578
+ );
579
+ foreach ($v_att_list as $v_entry) {
580
+ $v_result = $this->privFileDescrParseAtt($v_entry,
581
+ $v_filedescr_list[],
582
+ $v_options,
583
+ $v_supported_attributes);
584
+ if ($v_result != 1) {
585
+ return 0;
586
+ }
587
+ }
588
+
589
+ // ----- Expand the filelist (expand directories)
590
+ $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
591
+ if ($v_result != 1) {
592
+ return 0;
593
+ }
594
+
595
+ // ----- Call the create fct
596
+ $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
597
+
598
+ if ($v_result != 1) {
599
+ return 0;
600
+ }
601
+
602
+ // ----- Return
603
+ return $p_result_list;
604
+ }
605
+ // --------------------------------------------------------------------------------
606
+
607
+ // --------------------------------------------------------------------------------
608
+ // Function : listContent()
609
+ // Description :
610
+ // This public method, gives the list of the files and directories, with their
611
+ // properties.
612
+ // The properties of each entries in the list are (used also in other functions) :
613
+ // filename : Name of the file. For a create or add action it is the filename
614
+ // given by the user. For an extract function it is the filename
615
+ // of the extracted file.
616
+ // stored_filename : Name of the file / directory stored in the archive.
617
+ // size : Size of the stored file.
618
+ // compressed_size : Size of the file's data compressed in the archive
619
+ // (without the headers overhead)
620
+ // mtime : Last known modification date of the file (UNIX timestamp)
621
+ // comment : Comment associated with the file
622
+ // folder : true | false
623
+ // index : index of the file in the archive
624
+ // status : status of the action (depending of the action) :
625
+ // Values are :
626
+ // ok : OK !
627
+ // filtered : the file / dir is not extracted (filtered by user)
628
+ // already_a_directory : the file can not be extracted because a
629
+ // directory with the same name already exists
630
+ // write_protected : the file can not be extracted because a file
631
+ // with the same name already exists and is
632
+ // write protected
633
+ // newer_exist : the file was not extracted because a newer file exists
634
+ // path_creation_fail : the file is not extracted because the folder
635
+ // does not exist and can not be created
636
+ // write_error : the file was not extracted because there was a
637
+ // error while writing the file
638
+ // read_error : the file was not extracted because there was a error
639
+ // while reading the file
640
+ // invalid_header : the file was not extracted because of an archive
641
+ // format error (bad file header)
642
+ // Note that each time a method can continue operating when there
643
+ // is an action error on a file, the error is only logged in the file status.
644
+ // Return Values :
645
+ // 0 on an unrecoverable failure,
646
+ // The list of the files in the archive.
647
+ // --------------------------------------------------------------------------------
648
+ function listContent()
649
+ {
650
+ $v_result=1;
651
+
652
+ // ----- Reset the error handler
653
+ $this->privErrorReset();
654
+
655
+ // ----- Check archive
656
+ if (!$this->privCheckFormat()) {
657
+ return(0);
658
+ }
659
+
660
+ // ----- Call the extracting fct
661
+ $p_list = array();
662
+ if (($v_result = $this->privList($p_list)) != 1)
663
+ {
664
+ unset($p_list);
665
+ return(0);
666
+ }
667
+
668
+ // ----- Return
669
+ return $p_list;
670
+ }
671
+ // --------------------------------------------------------------------------------
672
+
673
+ // --------------------------------------------------------------------------------
674
+ // Function :
675
+ // extract($p_path="./", $p_remove_path="")
676
+ // extract([$p_option, $p_option_value, ...])
677
+ // Description :
678
+ // This method supports two synopsis. The first one is historical.
679
+ // This method extract all the files / directories from the archive to the
680
+ // folder indicated in $p_path.
681
+ // If you want to ignore the 'root' part of path of the memorized files
682
+ // you can indicate this in the optional $p_remove_path parameter.
683
+ // By default, if a newer file with the same name already exists, the
684
+ // file is not extracted.
685
+ //
686
+ // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
687
+ // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
688
+ // at the end of the path value of PCLZIP_OPT_PATH.
689
+ // Parameters :
690
+ // $p_path : Path where the files and directories are to be extracted
691
+ // $p_remove_path : First part ('root' part) of the memorized path
692
+ // (if any similar) to remove while extracting.
693
+ // Options :
694
+ // PCLZIP_OPT_PATH :
695
+ // PCLZIP_OPT_ADD_PATH :
696
+ // PCLZIP_OPT_REMOVE_PATH :
697
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
698
+ // PCLZIP_CB_PRE_EXTRACT :
699
+ // PCLZIP_CB_POST_EXTRACT :
700
+ // Return Values :
701
+ // 0 or a negative value on failure,
702
+ // The list of the extracted files, with a status of the action.
703
+ // (see IWPPclZip::listContent() for list entry format)
704
+ // --------------------------------------------------------------------------------
705
+ function extract()
706
+ {
707
+ $v_result=1;
708
+
709
+ // ----- Reset the error handler
710
+ $this->privErrorReset();
711
+
712
+ // ----- Check archive
713
+ if (!$this->privCheckFormat()) {
714
+ return(0);
715
+ }
716
+
717
+ // ----- Set default values
718
+ $v_options = array();
719
+ // $v_path = "./";
720
+ $v_path = '';
721
+ $v_remove_path = "";
722
+ $v_remove_all_path = false;
723
+
724
+ // ----- Look for variable options arguments
725
+ $v_size = func_num_args();
726
+
727
+ // ----- Default values for option
728
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
729
+
730
+ // ----- Look for arguments
731
+ if ($v_size > 0) {
732
+ // ----- Get the arguments
733
+ $v_arg_list = func_get_args();
734
+
735
+ // ----- Look for first arg
736
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
737
+
738
+ // ----- Parse the options
739
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
740
+ array (PCLZIP_OPT_PATH => 'optional',
741
+ PCLZIP_OPT_REMOVE_PATH => 'optional',
742
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
743
+ PCLZIP_OPT_ADD_PATH => 'optional',
744
+ PCLZIP_CB_PRE_EXTRACT => 'optional',
745
+ PCLZIP_CB_POST_EXTRACT => 'optional',
746
+ PCLZIP_OPT_SET_CHMOD => 'optional',
747
+ PCLZIP_OPT_BY_NAME => 'optional',
748
+ PCLZIP_OPT_BY_EREG => 'optional',
749
+ PCLZIP_OPT_BY_PREG => 'optional',
750
+ PCLZIP_OPT_BY_INDEX => 'optional',
751
+ PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
752
+ PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
753
+ PCLZIP_OPT_REPLACE_NEWER => 'optional'
754
+ ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
755
+ ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
756
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
757
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
758
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
759
+ ));
760
+ if ($v_result != 1) {
761
+ return 0;
762
+ }
763
+
764
+ // ----- Set the arguments
765
+ if (isset($v_options[PCLZIP_OPT_PATH])) {
766
+ $v_path = $v_options[PCLZIP_OPT_PATH];
767
+ }
768
+ if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
769
+ $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
770
+ }
771
+ if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
772
+ $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
773
+ }
774
+ if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
775
+ // ----- Check for '/' in last path char
776
+ if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
777
+ $v_path .= '/';
778
+ }
779
+ $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
780
+ }
781
+ }
782
+
783
+ // ----- Look for 2 args
784
+ // Here we need to support the first historic synopsis of the
785
+ // method.
786
+ else {
787
+
788
+ // ----- Get the first argument
789
+ $v_path = $v_arg_list[0];
790
+
791
+ // ----- Look for the optional second argument
792
+ if ($v_size == 2) {
793
+ $v_remove_path = $v_arg_list[1];
794
+ }
795
+ else if ($v_size > 2) {
796
+ // ----- Error log
797
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
798
+
799
+ // ----- Return
800
+ return 0;
801
+ }
802
+ }
803
+ }
804
+
805
+ // ----- Look for default option values
806
+ $this->privOptionDefaultThreshold($v_options);
807
+
808
+ // ----- Trace
809
+
810
+ // ----- Call the extracting fct
811
+ $p_list = array();
812
+ $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
813
+ $v_remove_all_path, $v_options);
814
+ if ($v_result < 1) {
815
+ unset($p_list);
816
+ return(0);
817
+ }
818
+
819
+ // ----- Return
820
+ return $p_list;
821
+ }
822
+ // --------------------------------------------------------------------------------
823
+
824
+
825
+ // --------------------------------------------------------------------------------
826
+ // Function :
827
+ // extractByIndex($p_index, $p_path="./", $p_remove_path="")
828
+ // extractByIndex($p_index, [$p_option, $p_option_value, ...])
829
+ // Description :
830
+ // This method supports two synopsis. The first one is historical.
831
+ // This method is doing a partial extract of the archive.
832
+ // The extracted files or folders are identified by their index in the
833
+ // archive (from 0 to n).
834
+ // Note that if the index identify a folder, only the folder entry is
835
+ // extracted, not all the files included in the archive.
836
+ // Parameters :
837
+ // $p_index : A single index (integer) or a string of indexes of files to
838
+ // extract. The form of the string is "0,4-6,8-12" with only numbers
839
+ // and '-' for range or ',' to separate ranges. No spaces or ';'
840
+ // are allowed.
841
+ // $p_path : Path where the files and directories are to be extracted
842
+ // $p_remove_path : First part ('root' part) of the memorized path
843
+ // (if any similar) to remove while extracting.
844
+ // Options :
845
+ // PCLZIP_OPT_PATH :
846
+ // PCLZIP_OPT_ADD_PATH :
847
+ // PCLZIP_OPT_REMOVE_PATH :
848
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
849
+ // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
850
+ // not as files.
851
+ // The resulting content is in a new field 'content' in the file
852
+ // structure.
853
+ // This option must be used alone (any other options are ignored).
854
+ // PCLZIP_CB_PRE_EXTRACT :
855
+ // PCLZIP_CB_POST_EXTRACT :
856
+ // Return Values :
857
+ // 0 on failure,
858
+ // The list of the extracted files, with a status of the action.
859
+ // (see IWPPclZip::listContent() for list entry format)
860
+ // --------------------------------------------------------------------------------
861
+ //function extractByIndex($p_index, options...)
862
+ function extractByIndex($p_index)
863
+ {
864
+ $v_result=1;
865
+
866
+ // ----- Reset the error handler
867
+ $this->privErrorReset();
868
+
869
+ // ----- Check archive
870
+ if (!$this->privCheckFormat()) {
871
+ return(0);
872
+ }
873
+
874
+ // ----- Set default values
875
+ $v_options = array();
876
+ // $v_path = "./";
877
+ $v_path = '';
878
+ $v_remove_path = "";
879
+ $v_remove_all_path = false;
880
+
881
+ // ----- Look for variable options arguments
882
+ $v_size = func_num_args();
883
+
884
+ // ----- Default values for option
885
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
886
+
887
+ // ----- Look for arguments
888
+ if ($v_size > 1) {
889
+ // ----- Get the arguments
890
+ $v_arg_list = func_get_args();
891
+
892
+ // ----- Remove form the options list the first argument
893
+ array_shift($v_arg_list);
894
+ $v_size--;
895
+
896
+ // ----- Look for first arg
897
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
898
+
899
+ // ----- Parse the options
900
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
901
+ array (PCLZIP_OPT_PATH => 'optional',
902
+ PCLZIP_OPT_REMOVE_PATH => 'optional',
903
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
904
+ PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
905
+ PCLZIP_OPT_ADD_PATH => 'optional',
906
+ PCLZIP_CB_PRE_EXTRACT => 'optional',
907
+ PCLZIP_CB_POST_EXTRACT => 'optional',
908
+ PCLZIP_OPT_SET_CHMOD => 'optional',
909
+ PCLZIP_OPT_REPLACE_NEWER => 'optional'
910
+ ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
911
+ ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
912
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
913
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
914
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
915
+ ));
916
+ if ($v_result != 1) {
917
+ return 0;
918
+ }
919
+
920
+ // ----- Set the arguments
921
+ if (isset($v_options[PCLZIP_OPT_PATH])) {
922
+ $v_path = $v_options[PCLZIP_OPT_PATH];
923
+ }
924
+ if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
925
+ $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
926
+ }
927
+ if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
928
+ $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
929
+ }
930
+ if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
931
+ // ----- Check for '/' in last path char
932
+ if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
933
+ $v_path .= '/';
934
+ }
935
+ $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
936
+ }
937
+ if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
938
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
939
+ }
940
+ else {
941
+ }
942
+ }
943
+
944
+ // ----- Look for 2 args
945
+ // Here we need to support the first historic synopsis of the
946
+ // method.
947
+ else {
948
+
949
+ // ----- Get the first argument
950
+ $v_path = $v_arg_list[0];
951
+
952
+ // ----- Look for the optional second argument
953
+ if ($v_size == 2) {
954
+ $v_remove_path = $v_arg_list[1];
955
+ }
956
+ else if ($v_size > 2) {
957
+ // ----- Error log
958
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
959
+
960
+ // ----- Return
961
+ return 0;
962
+ }
963
+ }
964
+ }
965
+
966
+ // ----- Trace
967
+
968
+ // ----- Trick
969
+ // Here I want to reuse extractByRule(), so I need to parse the $p_index
970
+ // with privParseOptions()
971
+ $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
972
+ $v_options_trick = array();
973
+ $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
974
+ array (PCLZIP_OPT_BY_INDEX => 'optional' ));
975
+ if ($v_result != 1) {
976
+ return 0;
977
+ }
978
+ $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
979
+
980
+ // ----- Look for default option values
981
+ $this->privOptionDefaultThreshold($v_options);
982
+
983
+ // ----- Call the extracting fct
984
+ if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
985
+ return(0);
986
+ }
987
+
988
+ // ----- Return
989
+ return $p_list;
990
+ }
991
+ // --------------------------------------------------------------------------------
992
+
993
+ // --------------------------------------------------------------------------------
994
+ // Function :
995
+ // delete([$p_option, $p_option_value, ...])
996
+ // Description :
997
+ // This method removes files from the archive.
998
+ // If no parameters are given, then all the archive is emptied.
999
+ // Parameters :
1000
+ // None or optional arguments.
1001
+ // Options :
1002
+ // PCLZIP_OPT_BY_INDEX :
1003
+ // PCLZIP_OPT_BY_NAME :
1004
+ // PCLZIP_OPT_BY_EREG :
1005
+ // PCLZIP_OPT_BY_PREG :
1006
+ // Return Values :
1007
+ // 0 on failure,
1008
+ // The list of the files which are still present in the archive.
1009
+ // (see IWPPclZip::listContent() for list entry format)
1010
+ // --------------------------------------------------------------------------------
1011
+ function delete()
1012
+ {
1013
+ $v_result=1;
1014
+
1015
+ // ----- Reset the error handler
1016
+ $this->privErrorReset();
1017
+
1018
+ // ----- Check archive
1019
+ if (!$this->privCheckFormat()) {
1020
+ return(0);
1021
+ }
1022
+
1023
+ // ----- Set default values
1024
+ $v_options = array();
1025
+
1026
+ // ----- Look for variable options arguments
1027
+ $v_size = func_num_args();
1028
+
1029
+ // ----- Look for arguments
1030
+ if ($v_size > 0) {
1031
+ // ----- Get the arguments
1032
+ $v_arg_list = func_get_args();
1033
+
1034
+ // ----- Parse the options
1035
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
1036
+ array (PCLZIP_OPT_BY_NAME => 'optional',
1037
+ PCLZIP_OPT_BY_EREG => 'optional',
1038
+ PCLZIP_OPT_BY_PREG => 'optional',
1039
+ PCLZIP_OPT_BY_INDEX => 'optional' ));
1040
+ if ($v_result != 1) {
1041
+ return 0;
1042
+ }
1043
+ }
1044
+
1045
+ // ----- Magic quotes trick
1046
+ $this->privDisableMagicQuotes();
1047
+
1048
+ // ----- Call the delete fct
1049
+ $v_list = array();
1050
+ if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
1051
+ $this->privSwapBackMagicQuotes();
1052
+ unset($v_list);
1053
+ return(0);
1054
+ }
1055
+
1056
+ // ----- Magic quotes trick
1057
+ $this->privSwapBackMagicQuotes();
1058
+
1059
+ // ----- Return
1060
+ return $v_list;
1061
+ }
1062
+ // --------------------------------------------------------------------------------
1063
+
1064
+ // --------------------------------------------------------------------------------
1065
+ // Function : deleteByIndex()
1066
+ // Description :
1067
+ // ***** Deprecated *****
1068
+ // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
1069
+ // --------------------------------------------------------------------------------
1070
+ function deleteByIndex($p_index)
1071
+ {
1072
+
1073
+ $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1074
+
1075
+ // ----- Return
1076
+ return $p_list;
1077
+ }
1078
+ // --------------------------------------------------------------------------------
1079
+
1080
+ // --------------------------------------------------------------------------------
1081
+ // Function : properties()
1082
+ // Description :
1083
+ // This method gives the properties of the archive.
1084
+ // The properties are :
1085
+ // nb : Number of files in the archive
1086
+ // comment : Comment associated with the archive file
1087
+ // status : not_exist, ok
1088
+ // Parameters :
1089
+ // None
1090
+ // Return Values :
1091
+ // 0 on failure,
1092
+ // An array with the archive properties.
1093
+ // --------------------------------------------------------------------------------
1094
+ function properties()
1095
+ {
1096
+
1097
+ // ----- Reset the error handler
1098
+ $this->privErrorReset();
1099
+
1100
+ // ----- Magic quotes trick
1101
+ $this->privDisableMagicQuotes();
1102
+
1103
+ // ----- Check archive
1104
+ if (!$this->privCheckFormat()) {
1105
+ $this->privSwapBackMagicQuotes();
1106
+ return(0);
1107
+ }
1108
+
1109
+ // ----- Default properties
1110
+ $v_prop = array();
1111
+ $v_prop['comment'] = '';
1112
+ $v_prop['nb'] = 0;
1113
+ $v_prop['status'] = 'not_exist';
1114
+
1115
+ // ----- Look if file exists
1116
+ if (@is_file($this->zipname))
1117
+ {
1118
+ // ----- Open the zip file
1119
+ if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
1120
+ {
1121
+ $this->privSwapBackMagicQuotes();
1122
+
1123
+ // ----- Error log
1124
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
1125
+
1126
+ // ----- Return
1127
+ return 0;
1128
+ }
1129
+
1130
+ // ----- Read the central directory informations
1131
+ $v_central_dir = array();
1132
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1133
+ {
1134
+ $this->privSwapBackMagicQuotes();
1135
+ return 0;
1136
+ }
1137
+
1138
+ // ----- Close the zip file
1139
+ $this->privCloseFd();
1140
+
1141
+ // ----- Set the user attributes
1142
+ $v_prop['comment'] = $v_central_dir['comment'];
1143
+ $v_prop['nb'] = $v_central_dir['entries'];
1144
+ $v_prop['status'] = 'ok';
1145
+ }
1146
+
1147
+ // ----- Magic quotes trick
1148
+ $this->privSwapBackMagicQuotes();
1149
+
1150
+ // ----- Return
1151
+ return $v_prop;
1152
+ }
1153
+ // --------------------------------------------------------------------------------
1154
+
1155
+ // --------------------------------------------------------------------------------
1156
+ // Function : duplicate()
1157
+ // Description :
1158
+ // This method creates an archive by copying the content of an other one. If
1159
+ // the archive already exist, it is replaced by the new one without any warning.
1160
+ // Parameters :
1161
+ // $p_archive : The filename of a valid archive, or
1162
+ // a valid PclZip object.
1163
+ // Return Values :
1164
+ // 1 on success.
1165
+ // 0 or a negative value on error (error code).
1166
+ // --------------------------------------------------------------------------------
1167
+ function duplicate($p_archive)
1168
+ {
1169
+ $v_result = 1;
1170
+
1171
+ // ----- Reset the error handler
1172
+ $this->privErrorReset();
1173
+
1174
+ // ----- Look if the $p_archive is a PclZip object
1175
+ if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
1176
+ {
1177
+
1178
+ // ----- Duplicate the archive
1179
+ $v_result = $this->privDuplicate($p_archive->zipname);
1180
+ }
1181
+
1182
+ // ----- Look if the $p_archive is a string (so a filename)
1183
+ else if (is_string($p_archive))
1184
+ {
1185
+
1186
+ // ----- Check that $p_archive is a valid zip file
1187
+ // TBC : Should also check the archive format
1188
+ if (!is_file($p_archive)) {
1189
+ // ----- Error log
1190
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
1191
+ $v_result = PCLZIP_ERR_MISSING_FILE;
1192
+ }
1193
+ else {
1194
+ // ----- Duplicate the archive
1195
+ $v_result = $this->privDuplicate($p_archive);
1196
+ }
1197
+ }
1198
+
1199
+ // ----- Invalid variable
1200
+ else
1201
+ {
1202
+ // ----- Error log
1203
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1204
+ $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1205
+ }
1206
+
1207
+ // ----- Return
1208
+ return $v_result;
1209
+ }
1210
+ // --------------------------------------------------------------------------------
1211
+
1212
+ // --------------------------------------------------------------------------------
1213
+ // Function : merge()
1214
+ // Description :
1215
+ // This method merge the $p_archive_to_add archive at the end of the current
1216
+ // one ($this).
1217
+ // If the archive ($this) does not exist, the merge becomes a duplicate.
1218
+ // If the $p_archive_to_add archive does not exist, the merge is a success.
1219
+ // Parameters :
1220
+ // $p_archive_to_add : It can be directly the filename of a valid zip archive,
1221
+ // or a PclZip object archive.
1222
+ // Return Values :
1223
+ // 1 on success,
1224
+ // 0 or negative values on error (see below).
1225
+ // --------------------------------------------------------------------------------
1226
+ function merge($p_archive_to_add)
1227
+ {
1228
+ $v_result = 1;
1229
+
1230
+ // ----- Reset the error handler
1231
+ $this->privErrorReset();
1232
+
1233
+ // ----- Check archive
1234
+ if (!$this->privCheckFormat()) {
1235
+ return(0);
1236
+ }
1237
+
1238
+ // ----- Look if the $p_archive_to_add is a PclZip object
1239
+ if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
1240
+ {
1241
+
1242
+ // ----- Merge the archive
1243
+ $v_result = $this->privMerge($p_archive_to_add);
1244
+ }
1245
+
1246
+ // ----- Look if the $p_archive_to_add is a string (so a filename)
1247
+ else if (is_string($p_archive_to_add))
1248
+ {
1249
+
1250
+ // ----- Create a temporary archive
1251
+ $v_object_archive = new PclZip($p_archive_to_add);
1252
+
1253
+ // ----- Merge the archive
1254
+ $v_result = $this->privMerge($v_object_archive);
1255
+ }
1256
+
1257
+ // ----- Invalid variable
1258
+ else
1259
+ {
1260
+ // ----- Error log
1261
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1262
+ $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1263
+ }
1264
+
1265
+ // ----- Return
1266
+ return $v_result;
1267
+ }
1268
+ // --------------------------------------------------------------------------------
1269
+
1270
+
1271
+
1272
+ // --------------------------------------------------------------------------------
1273
+ // Function : errorCode()
1274
+ // Description :
1275
+ // Parameters :
1276
+ // --------------------------------------------------------------------------------
1277
+ function errorCode()
1278
+ {
1279
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
1280
+ return(PclErrorCode());
1281
+ }
1282
+ else {
1283
+ return($this->error_code);
1284
+ }
1285
+ }
1286
+ // --------------------------------------------------------------------------------
1287
+
1288
+ // --------------------------------------------------------------------------------
1289
+ // Function : errorName()
1290
+ // Description :
1291
+ // Parameters :
1292
+ // --------------------------------------------------------------------------------
1293
+ function errorName($p_with_code=false)
1294
+ {
1295
+ $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1296
+ PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1297
+ PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1298
+ PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1299
+ PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1300
+ PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1301
+ PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1302
+ PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1303
+ PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1304
+ PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1305
+ PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1306
+ PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1307
+ PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1308
+ PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1309
+ PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1310
+ PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1311
+ PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1312
+ PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1313
+ PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
1314
+ ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
1315
+ ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
1316
+ );
1317
+
1318
+ if (isset($v_name[$this->error_code])) {
1319
+ $v_value = $v_name[$this->error_code];
1320
+ }
1321
+ else {
1322
+ $v_value = 'NoName';
1323
+ }
1324
+
1325
+ if ($p_with_code) {
1326
+ return($v_value.' ('.$this->error_code.')');
1327
+ }
1328
+ else {
1329
+ return($v_value);
1330
+ }
1331
+ }
1332
+ // --------------------------------------------------------------------------------
1333
+
1334
+ // --------------------------------------------------------------------------------
1335
+ // Function : errorInfo()
1336
+ // Description :
1337
+ // Parameters :
1338
+ // --------------------------------------------------------------------------------
1339
+ function errorInfo($p_full=false)
1340
+ {
1341
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
1342
+ return(PclErrorString());
1343
+ }
1344
+ else {
1345
+ if ($p_full) {
1346
+ return($this->errorName(true)." : ".$this->error_string);
1347
+ }
1348
+ else {
1349
+ return($this->error_string." [code ".$this->error_code."]");
1350
+ }
1351
+ }
1352
+ }
1353
+ // --------------------------------------------------------------------------------
1354
+
1355
+
1356
+ // --------------------------------------------------------------------------------
1357
+ // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1358
+ // ***** *****
1359
+ // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
1360
+ // --------------------------------------------------------------------------------
1361
+
1362
+
1363
+
1364
+ // --------------------------------------------------------------------------------
1365
+ // Function : privCheckFormat()
1366
+ // Description :
1367
+ // This method check that the archive exists and is a valid zip archive.
1368
+ // Several level of check exists. (futur)
1369
+ // Parameters :
1370
+ // $p_level : Level of check. Default 0.
1371
+ // 0 : Check the first bytes (magic codes) (default value))
1372
+ // 1 : 0 + Check the central directory (futur)
1373
+ // 2 : 1 + Check each file header (futur)
1374
+ // Return Values :
1375
+ // true on success,
1376
+ // false on error, the error code is set.
1377
+ // --------------------------------------------------------------------------------
1378
+ function privCheckFormat($p_level=0)
1379
+ {
1380
+ $v_result = true;
1381
+
1382
+ // ----- Reset the file system cache
1383
+ clearstatcache();
1384
+
1385
+ // ----- Reset the error handler
1386
+ $this->privErrorReset();
1387
+
1388
+ // ----- Look if the file exits
1389
+ if (!is_file($this->zipname)) {
1390
+ // ----- Error log
1391
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
1392
+ return(false);
1393
+ }
1394
+
1395
+ // ----- Check that the file is readeable
1396
+ if (!is_readable($this->zipname)) {
1397
+ // ----- Error log
1398
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
1399
+ return(false);
1400
+ }
1401
+
1402
+ // ----- Check the magic code
1403
+ // TBC
1404
+
1405
+ // ----- Check the central header
1406
+ // TBC
1407
+
1408
+ // ----- Check each file header
1409
+ // TBC
1410
+
1411
+ // ----- Return
1412
+ return $v_result;
1413
+ }
1414
+ // --------------------------------------------------------------------------------
1415
+
1416
+ // --------------------------------------------------------------------------------
1417
+ // Function : privParseOptions()
1418
+ // Description :
1419
+ // This internal methods reads the variable list of arguments ($p_options_list,
1420
+ // $p_size) and generate an array with the options and values ($v_result_list).
1421
+ // $v_requested_options contains the options that can be present and those that
1422
+ // must be present.
1423
+ // $v_requested_options is an array, with the option value as key, and 'optional',
1424
+ // or 'mandatory' as value.
1425
+ // Parameters :
1426
+ // See above.
1427
+ // Return Values :
1428
+ // 1 on success.
1429
+ // 0 on failure.
1430
+ // --------------------------------------------------------------------------------
1431
+ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
1432
+ {
1433
+ $v_result=1;
1434
+
1435
+ // ----- Read the options
1436
+ $i=0;
1437
+ while ($i<$p_size) {
1438
+
1439
+ // ----- Check if the option is supported
1440
+ if (!isset($v_requested_options[$p_options_list[$i]])) {
1441
+ // ----- Error log
1442
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
1443
+
1444
+ // ----- Return
1445
+ return IWPPclZip::errorCode();
1446
+ }
1447
+
1448
+ // ----- Look for next option
1449
+ switch ($p_options_list[$i]) {
1450
+ // ----- Look for options that request a path value
1451
+ case PCLZIP_OPT_IWP_EXCLUDE :
1452
+ if (is_array($p_options_list[$i+1])) {
1453
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1454
+ }
1455
+ $i++;
1456
+ break;
1457
+ case PCLZIP_OPT_PATH :
1458
+ case PCLZIP_OPT_REMOVE_PATH :
1459
+ case PCLZIP_OPT_ADD_PATH :
1460
+ // ----- Check the number of parameters
1461
+ if (($i+1) >= $p_size) {
1462
+ // ----- Error log
1463
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1464
+
1465
+ // ----- Return
1466
+ return IWPPclZip::errorCode();
1467
+ }
1468
+
1469
+ // ----- Get the value
1470
+ $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1471
+ $i++;
1472
+ break;
1473
+
1474
+ case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
1475
+ // ----- Check the number of parameters
1476
+ if (($i+1) >= $p_size) {
1477
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1478
+ return IWPPclZip::errorCode();
1479
+ }
1480
+
1481
+ // ----- Check for incompatible options
1482
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1483
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1484
+ return IWPPclZip::errorCode();
1485
+ }
1486
+
1487
+ // ----- Check the value
1488
+ $v_value = $p_options_list[$i+1];
1489
+ if ((!is_integer($v_value)) || ($v_value<0)) {
1490
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1491
+ return IWPPclZip::errorCode();
1492
+ }
1493
+
1494
+ // ----- Get the value (and convert it in bytes)
1495
+ $v_result_list[$p_options_list[$i]] = $v_value*1048576;
1496
+ $i++;
1497
+ break;
1498
+
1499
+ case PCLZIP_OPT_TEMP_FILE_ON :
1500
+ // ----- Check for incompatible options
1501
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1502
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1503
+ return IWPPclZip::errorCode();
1504
+ }
1505
+
1506
+ $v_result_list[$p_options_list[$i]] = true;
1507
+ break;
1508
+
1509
+ case PCLZIP_OPT_TEMP_FILE_OFF :
1510
+ // ----- Check for incompatible options
1511
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
1512
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
1513
+ return IWPPclZip::errorCode();
1514
+ }
1515
+ // ----- Check for incompatible options
1516
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1517
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
1518
+ return IWPPclZip::errorCode();
1519
+ }
1520
+
1521
+ $v_result_list[$p_options_list[$i]] = true;
1522
+ break;
1523
+
1524
+ case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
1525
+ // ----- Check the number of parameters
1526
+ if (($i+1) >= $p_size) {
1527
+ // ----- Error log
1528
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1529
+
1530
+ // ----- Return
1531
+ return IWPPclZip::errorCode();
1532
+ }
1533
+
1534
+ // ----- Get the value
1535
+ if ( is_string($p_options_list[$i+1])
1536
+ && ($p_options_list[$i+1] != '')) {
1537
+ $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1538
+ $i++;
1539
+ }
1540
+ else {
1541
+ }
1542
+ break;
1543
+
1544
+ // ----- Look for options that request an array of string for value
1545
+ case PCLZIP_OPT_BY_NAME :
1546
+ // ----- Check the number of parameters
1547
+ if (($i+1) >= $p_size) {
1548
+ // ----- Error log
1549
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1550
+
1551
+ // ----- Return
1552
+ return IWPPclZip::errorCode();
1553
+ }
1554
+
1555
+ // ----- Get the value
1556
+ if (is_string($p_options_list[$i+1])) {
1557
+ $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
1558
+ }
1559
+ else if (is_array($p_options_list[$i+1])) {
1560
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1561
+ }
1562
+ else {
1563
+ // ----- Error log
1564
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1565
+
1566
+ // ----- Return
1567
+ return IWPPclZip::errorCode();
1568
+ }
1569
+ $i++;
1570
+ break;
1571
+
1572
+ // ----- Look for options that request an EREG or PREG expression
1573
+ case PCLZIP_OPT_BY_EREG :
1574
+ // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
1575
+ // to PCLZIP_OPT_BY_PREG
1576
+ $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
1577
+ case PCLZIP_OPT_BY_PREG :
1578
+ //case PCLZIP_OPT_CRYPT :
1579
+ // ----- Check the number of parameters
1580
+ if (($i+1) >= $p_size) {
1581
+ // ----- Error log
1582
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1583
+
1584
+ // ----- Return
1585
+ return IWPPclZip::errorCode();
1586
+ }
1587
+
1588
+ // ----- Get the value
1589
+ if (is_string($p_options_list[$i+1])) {
1590
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1591
+ }
1592
+ else {
1593
+ // ----- Error log
1594
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1595
+
1596
+ // ----- Return
1597
+ return IWPPclZip::errorCode();
1598
+ }
1599
+ $i++;
1600
+ break;
1601
+
1602
+ // ----- Look for options that takes a string
1603
+ case PCLZIP_OPT_COMMENT :
1604
+ case PCLZIP_OPT_ADD_COMMENT :
1605
+ case PCLZIP_OPT_PREPEND_COMMENT :
1606
+ // ----- Check the number of parameters
1607
+ if (($i+1) >= $p_size) {
1608
+ // ----- Error log
1609
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
1610
+ "Missing parameter value for option '"
1611
+ .PclZipUtilOptionText($p_options_list[$i])
1612
+ ."'");
1613
+
1614
+ // ----- Return
1615
+ return IWPPclZip::errorCode();
1616
+ }
1617
+
1618
+ // ----- Get the value
1619
+ if (is_string($p_options_list[$i+1])) {
1620
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1621
+ }
1622
+ else {
1623
+ // ----- Error log
1624
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
1625
+ "Wrong parameter value for option '"
1626
+ .PclZipUtilOptionText($p_options_list[$i])
1627
+ ."'");
1628
+
1629
+ // ----- Return
1630
+ return IWPPclZip::errorCode();
1631
+ }
1632
+ $i++;
1633
+ break;
1634
+
1635
+ // ----- Look for options that request an array of index
1636
+ case PCLZIP_OPT_BY_INDEX :
1637
+ // ----- Check the number of parameters
1638
+ if (($i+1) >= $p_size) {
1639
+ // ----- Error log
1640
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1641
+
1642
+ // ----- Return
1643
+ return IWPPclZip::errorCode();
1644
+ }
1645
+
1646
+ // ----- Get the value
1647
+ $v_work_list = array();
1648
+ if (is_string($p_options_list[$i+1])) {
1649
+
1650
+ // ----- Remove spaces
1651
+ $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1652
+
1653
+ // ----- Parse items
1654
+ $v_work_list = explode(",", $p_options_list[$i+1]);
1655
+ }
1656
+ else if (is_integer($p_options_list[$i+1])) {
1657
+ $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1658
+ }
1659
+ else if (is_array($p_options_list[$i+1])) {
1660
+ $v_work_list = $p_options_list[$i+1];
1661
+ }
1662
+ else {
1663
+ // ----- Error log
1664
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1665
+
1666
+ // ----- Return
1667
+ return IWPPclZip::errorCode();
1668
+ }
1669
+
1670
+ // ----- Reduce the index list
1671
+ // each index item in the list must be a couple with a start and
1672
+ // an end value : [0,3], [5-5], [8-10], ...
1673
+ // ----- Check the format of each item
1674
+ $v_sort_flag=false;
1675
+ $v_sort_value=0;
1676
+ for ($j=0; $j<sizeof($v_work_list); $j++) {
1677
+ // ----- Explode the item
1678
+ $v_item_list = explode("-", $v_work_list[$j]);
1679
+ $v_size_item_list = sizeof($v_item_list);
1680
+
1681
+ // ----- TBC : Here we might check that each item is a
1682
+ // real integer ...
1683
+
1684
+ // ----- Look for single value
1685
+ if ($v_size_item_list == 1) {
1686
+ // ----- Set the option value
1687
+ $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1688
+ $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1689
+ }
1690
+ elseif ($v_size_item_list == 2) {
1691
+ // ----- Set the option value
1692
+ $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1693
+ $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1694
+ }
1695
+ else {
1696
+ // ----- Error log
1697
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1698
+
1699
+ // ----- Return
1700
+ return IWPPclZip::errorCode();
1701
+ }
1702
+
1703
+
1704
+ // ----- Look for list sort
1705
+ if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1706
+ $v_sort_flag=true;
1707
+
1708
+ // ----- TBC : An automatic sort should be writen ...
1709
+ // ----- Error log
1710
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1711
+
1712
+ // ----- Return
1713
+ return IWPPclZip::errorCode();
1714
+ }
1715
+ $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1716
+ }
1717
+
1718
+ // ----- Sort the items
1719
+ if ($v_sort_flag) {
1720
+ // TBC : To Be Completed
1721
+ }
1722
+
1723
+ // ----- Next option
1724
+ $i++;
1725
+ break;
1726
+
1727
+ // ----- Look for options that request no value
1728
+ case PCLZIP_OPT_REMOVE_ALL_PATH :
1729
+ case PCLZIP_OPT_EXTRACT_AS_STRING :
1730
+ case PCLZIP_OPT_NO_COMPRESSION :
1731
+ case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1732
+ case PCLZIP_OPT_REPLACE_NEWER :
1733
+ case PCLZIP_OPT_STOP_ON_ERROR :
1734
+ $v_result_list[$p_options_list[$i]] = true;
1735
+ break;
1736
+
1737
+ // ----- Look for options that request an octal value
1738
+ case PCLZIP_OPT_SET_CHMOD :
1739
+ // ----- Check the number of parameters
1740
+ if (($i+1) >= $p_size) {
1741
+ // ----- Error log
1742
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1743
+
1744
+ // ----- Return
1745
+ return IWPPclZip::errorCode();
1746
+ }
1747
+
1748
+ // ----- Get the value
1749
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1750
+ $i++;
1751
+ break;
1752
+
1753
+ // ----- Look for options that request a call-back
1754
+ case PCLZIP_CB_PRE_EXTRACT :
1755
+ case PCLZIP_CB_POST_EXTRACT :
1756
+ case PCLZIP_CB_PRE_ADD :
1757
+ case PCLZIP_CB_POST_ADD :
1758
+ /* for futur use
1759
+ case PCLZIP_CB_PRE_DELETE :
1760
+ case PCLZIP_CB_POST_DELETE :
1761
+ case PCLZIP_CB_PRE_LIST :
1762
+ case PCLZIP_CB_POST_LIST :
1763
+ */
1764
+ // ----- Check the number of parameters
1765
+ if (($i+1) >= $p_size) {
1766
+ // ----- Error log
1767
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1768
+
1769
+ // ----- Return
1770
+ return IWPPclZip::errorCode();
1771
+ }
1772
+
1773
+ // ----- Get the value
1774
+ $v_function_name = $p_options_list[$i+1];
1775
+
1776
+ // ----- Check that the value is a valid existing function
1777
+ if (!function_exists($v_function_name)) {
1778
+ // ----- Error log
1779
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1780
+
1781
+ // ----- Return
1782
+ return IWPPclZip::errorCode();
1783
+ }
1784
+
1785
+ // ----- Set the attribute
1786
+ $v_result_list[$p_options_list[$i]] = $v_function_name;
1787
+ $i++;
1788
+ break;
1789
+
1790
+ default :
1791
+ // ----- Error log
1792
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1793
+ "Unknown parameter '"
1794
+ .$p_options_list[$i]."'");
1795
+
1796
+ // ----- Return
1797
+ return IWPPclZip::errorCode();
1798
+ }
1799
+
1800
+ // ----- Next options
1801
+ $i++;
1802
+ }
1803
+
1804
+ // ----- Look for mandatory options
1805
+ if ($v_requested_options !== false) {
1806
+ for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1807
+ // ----- Look for mandatory option
1808
+ if ($v_requested_options[$key] == 'mandatory') {
1809
+ // ----- Look if present
1810
+ if (!isset($v_result_list[$key])) {
1811
+ // ----- Error log
1812
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1813
+
1814
+ // ----- Return
1815
+ return IWPPclZip::errorCode();
1816
+ }
1817
+ }
1818
+ }
1819
+ }
1820
+
1821
+ // ----- Look for default values
1822
+ if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1823
+
1824
+ }
1825
+
1826
+ // ----- Return
1827
+ return $v_result;
1828
+ }
1829
+ // --------------------------------------------------------------------------------
1830
+
1831
+ // --------------------------------------------------------------------------------
1832
+ // Function : privOptionDefaultThreshold()
1833
+ // Description :
1834
+ // Parameters :
1835
+ // Return Values :
1836
+ // --------------------------------------------------------------------------------
1837
+ function privOptionDefaultThreshold(&$p_options)
1838
+ {
1839
+ $v_result=1;
1840
+
1841
+ if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
1842
+ || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
1843
+ return $v_result;
1844
+ }
1845
+
1846
+ // ----- Get 'memory_limit' configuration value
1847
+ $v_memory_limit = ini_get('memory_limit');
1848
+ $v_memory_limit = trim($v_memory_limit);
1849
+ $last = strtolower(substr($v_memory_limit, -1));
1850
+
1851
+ if($last == 'g')
1852
+ //$v_memory_limit = $v_memory_limit*1024*1024*1024;
1853
+ $v_memory_limit = $v_memory_limit*1073741824;
1854
+ if($last == 'm')
1855
+ //$v_memory_limit = $v_memory_limit*1024*1024;
1856
+ $v_memory_limit = $v_memory_limit*1048576;
1857
+ if($last == 'k')
1858
+ $v_memory_limit = $v_memory_limit*1024;
1859
+
1860
+ $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
1861
+
1862
+
1863
+ // ----- Sanity check : No threshold if value lower than 1M
1864
+ if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
1865
+ unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
1866
+ }
1867
+
1868
+ // ----- Return
1869
+ return $v_result;
1870
+ }
1871
+ // --------------------------------------------------------------------------------
1872
+
1873
+ // --------------------------------------------------------------------------------
1874
+ // Function : privFileDescrParseAtt()
1875
+ // Description :
1876
+ // Parameters :
1877
+ // Return Values :
1878
+ // 1 on success.
1879
+ // 0 on failure.
1880
+ // --------------------------------------------------------------------------------
1881
+ function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
1882
+ {
1883
+ $v_result=1;
1884
+
1885
+ // ----- For each file in the list check the attributes
1886
+ foreach ($p_file_list as $v_key => $v_value) {
1887
+
1888
+ // ----- Check if the option is supported
1889
+ if (!isset($v_requested_options[$v_key])) {
1890
+ // ----- Error log
1891
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
1892
+
1893
+ // ----- Return
1894
+ return IWPPclZip::errorCode();
1895
+ }
1896
+
1897
+ // ----- Look for attribute
1898
+ switch ($v_key) {
1899
+ case PCLZIP_ATT_FILE_NAME :
1900
+ if (!is_string($v_value)) {
1901
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1902
+ return IWPPclZip::errorCode();
1903
+ }
1904
+
1905
+ $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1906
+
1907
+ if ($p_filedescr['filename'] == '') {
1908
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
1909
+ return IWPPclZip::errorCode();
1910
+ }
1911
+
1912
+ break;
1913
+
1914
+ case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
1915
+ if (!is_string($v_value)) {
1916
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1917
+ return IWPPclZip::errorCode();
1918
+ }
1919
+
1920
+ $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1921
+
1922
+ if ($p_filedescr['new_short_name'] == '') {
1923
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
1924
+ return IWPPclZip::errorCode();
1925
+ }
1926
+ break;
1927
+
1928
+ case PCLZIP_ATT_FILE_NEW_FULL_NAME :
1929
+ if (!is_string($v_value)) {
1930
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1931
+ return IWPPclZip::errorCode();
1932
+ }
1933
+
1934
+ $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1935
+
1936
+ if ($p_filedescr['new_full_name'] == '') {
1937
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
1938
+ return IWPPclZip::errorCode();
1939
+ }
1940
+ break;
1941
+
1942
+ // ----- Look for options that takes a string
1943
+ case PCLZIP_ATT_FILE_COMMENT :
1944
+ if (!is_string($v_value)) {
1945
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1946
+ return IWPPclZip::errorCode();
1947
+ }
1948
+
1949
+ $p_filedescr['comment'] = $v_value;
1950
+ break;
1951
+
1952
+ case PCLZIP_ATT_FILE_MTIME :
1953
+ if (!is_integer($v_value)) {
1954
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
1955
+ return IWPPclZip::errorCode();
1956
+ }
1957
+
1958
+ $p_filedescr['mtime'] = $v_value;
1959
+ break;
1960
+
1961
+ case PCLZIP_ATT_FILE_CONTENT :
1962
+ $p_filedescr['content'] = $v_value;
1963
+ break;
1964
+
1965
+ default :
1966
+ // ----- Error log
1967
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1968
+ "Unknown parameter '".$v_key."'");
1969
+
1970
+ // ----- Return
1971
+ return IWPPclZip::errorCode();
1972
+ }
1973
+
1974
+ // ----- Look for mandatory options
1975
+ if ($v_requested_options !== false) {
1976
+ for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1977
+ // ----- Look for mandatory option
1978
+ if ($v_requested_options[$key] == 'mandatory') {
1979
+ // ----- Look if present
1980
+ if (!isset($p_file_list[$key])) {
1981
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1982
+ return IWPPclZip::errorCode();
1983
+ }
1984
+ }
1985
+ }
1986
+ }
1987
+
1988
+ // end foreach
1989
+ }
1990
+
1991
+ // ----- Return
1992
+ return $v_result;
1993
+ }
1994
+ // --------------------------------------------------------------------------------
1995
+
1996
+ // --------------------------------------------------------------------------------
1997
+ // Function : privFileDescrExpand()
1998
+ // Description :
1999
+ // This method look for each item of the list to see if its a file, a folder
2000
+ // or a string to be added as file. For any other type of files (link, other)
2001
+ // just ignore the item.
2002
+ // Then prepare the information that will be stored for that file.
2003
+ // When its a folder, expand the folder with all the files that are in that
2004
+ // folder (recursively).
2005
+ // Parameters :
2006
+ // Return Values :
2007
+ // 1 on success.
2008
+ // 0 on failure.
2009
+ // --------------------------------------------------------------------------------
2010
+ function privFileDescrExpand(&$p_filedescr_list, &$p_options)
2011
+ {
2012
+ $v_result=1;
2013
+
2014
+ // ----- Create a result list
2015
+ $v_result_list = array();
2016
+
2017
+ // ----- Look each entry
2018
+ for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
2019
+
2020
+ // ----- Get filedescr
2021
+ $v_descr = $p_filedescr_list[$i];
2022
+
2023
+ // ----- Reduce the filename
2024
+ $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
2025
+ $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
2026
+
2027
+ // ----- Look for real file or folder
2028
+ if (file_exists($v_descr['filename'])) {
2029
+ if (@is_file($v_descr['filename'])) {
2030
+ $v_descr['type'] = 'file';
2031
+ }
2032
+ else if (@is_dir($v_descr['filename'])) {
2033
+ $v_descr['type'] = 'folder';
2034
+ }
2035
+ else if (@is_link($v_descr['filename'])) {
2036
+ // skip
2037
+ continue;
2038
+ }
2039
+ else {
2040
+ // skip
2041
+ continue;
2042
+ }
2043
+ }
2044
+
2045
+ // ----- Look for string added as file
2046
+ else if (isset($v_descr['content'])) {
2047
+ $v_descr['type'] = 'virtual_file';
2048
+ }
2049
+
2050
+ // ----- Missing file
2051
+ else {
2052
+ // ----- Error log
2053
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
2054
+
2055
+ // ----- Return
2056
+ return IWPPclZip::errorCode();
2057
+ }
2058
+
2059
+ // ----- Calculate the stored filename
2060
+ $this->privCalculateStoredFilename($v_descr, $p_options);
2061
+
2062
+ //exclude IWP Mod
2063
+ $skip_this = false;
2064
+ $exclude = $p_options[PCLZIP_OPT_IWP_EXCLUDE];
2065
+ if(!empty($exclude)){
2066
+ foreach($exclude as $item){
2067
+ if(strpos($v_descr['stored_filename'], $item) === 0){
2068
+ $skip_this = true;
2069
+ break;
2070
+ }
2071
+ }
2072
+ if($skip_this){
2073
+ $skip_this = false;
2074
+ continue;
2075
+ }
2076
+ }
2077
+ //exclude IWP Mod
2078
+
2079
+ // ----- Add the descriptor in result list
2080
+ $v_result_list[sizeof($v_result_list)] = $v_descr;
2081
+
2082
+ // ----- Look for folder
2083
+ if ($v_descr['type'] == 'folder') {
2084
+ // ----- List of items in folder
2085
+ $v_dirlist_descr = array();
2086
+ $v_dirlist_nb = 0;
2087
+ if ($v_folder_handler = @opendir($v_descr['filename'])) {
2088
+ while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
2089
+
2090
+ // ----- Skip '.' and '..'
2091
+ if (($v_item_handler == '.') || ($v_item_handler == '..')) {
2092
+ continue;
2093
+ }
2094
+
2095
+ // ----- Compose the full filename
2096
+ $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
2097
+
2098
+ // ----- Look for different stored filename
2099
+ // Because the name of the folder was changed, the name of the
2100
+ // files/sub-folders also change
2101
+ if (($v_descr['stored_filename'] != $v_descr['filename'])
2102
+ && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
2103
+ if ($v_descr['stored_filename'] != '') {
2104
+ $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
2105
+ }
2106
+ else {
2107
+ $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
2108
+ }
2109
+ }
2110
+
2111
+ $v_dirlist_nb++;
2112
+ }
2113
+
2114
+ @closedir($v_folder_handler);
2115
+ }
2116
+ else {
2117
+ // TBC : unable to open folder in read mode
2118
+ }
2119
+
2120
+ // ----- Expand each element of the list
2121
+ if ($v_dirlist_nb != 0) {
2122
+ // ----- Expand
2123
+ if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
2124
+ return $v_result;
2125
+ }
2126
+
2127
+ // ----- Concat the resulting list
2128
+ $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
2129
+ }
2130
+ else {
2131
+ }
2132
+
2133
+ // ----- Free local array
2134
+ unset($v_dirlist_descr);
2135
+ }
2136
+ }
2137
+
2138
+ // ----- Get the result list
2139
+ $p_filedescr_list = $v_result_list;
2140
+
2141
+ // ----- Return
2142
+ return $v_result;
2143
+ }
2144
+ // --------------------------------------------------------------------------------
2145
+
2146
+ // --------------------------------------------------------------------------------
2147
+ // Function : privCreate()
2148
+ // Description :
2149
+ // Parameters :
2150
+ // Return Values :
2151
+ // --------------------------------------------------------------------------------
2152
+ function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
2153
+ {
2154
+ $v_result=1;
2155
+ $v_list_detail = array();
2156
+
2157
+ // ----- Magic quotes trick
2158
+ $this->privDisableMagicQuotes();
2159
+
2160
+ // ----- Open the file in write mode
2161
+ if (($v_result = $this->privOpenFd('wb')) != 1)
2162
+ {
2163
+ // ----- Return
2164
+ return $v_result;
2165
+ }
2166
+
2167
+ // ----- Add the list of files
2168
+ $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
2169
+
2170
+ // ----- Close
2171
+ $this->privCloseFd();
2172
+
2173
+ // ----- Magic quotes trick
2174
+ $this->privSwapBackMagicQuotes();
2175
+
2176
+ // ----- Return
2177
+ return $v_result;
2178
+ }
2179
+ // --------------------------------------------------------------------------------
2180
+
2181
+ // --------------------------------------------------------------------------------
2182
+ // Function : privAdd()
2183
+ // Description :
2184
+ // Parameters :
2185
+ // Return Values :
2186
+ // --------------------------------------------------------------------------------
2187
+ function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
2188
+ {
2189
+ $v_result=1;
2190
+ $v_list_detail = array();
2191
+
2192
+ // ----- Look if the archive exists or is empty
2193
+ if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
2194
+ {
2195
+
2196
+ // ----- Do a create
2197
+ $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
2198
+
2199
+ // ----- Return
2200
+ return $v_result;
2201
+ }
2202
+ // ----- Magic quotes trick
2203
+ $this->privDisableMagicQuotes();
2204
+
2205
+ // ----- Open the zip file
2206
+ if (($v_result=$this->privOpenFd('rb')) != 1)
2207
+ {
2208
+ // ----- Magic quotes trick
2209
+ $this->privSwapBackMagicQuotes();
2210
+
2211
+ // ----- Return
2212
+ return $v_result;
2213
+ }
2214
+
2215
+ // ----- Read the central directory informations
2216
+ $v_central_dir = array();
2217
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2218
+ {
2219
+ $this->privCloseFd();
2220
+ $this->privSwapBackMagicQuotes();
2221
+ return $v_result;
2222
+ }
2223
+
2224
+ // ----- Go to beginning of File
2225
+ @rewind($this->zip_fd);
2226
+
2227
+ // ----- Creates a temporay file
2228
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
2229
+
2230
+ // ----- Open the temporary file in write mode
2231
+ if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
2232
+ {
2233
+ $this->privCloseFd();
2234
+ $this->privSwapBackMagicQuotes();
2235
+
2236
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
2237
+
2238
+ // ----- Return
2239
+ return IWPPclZip::errorCode();
2240
+ }
2241
+
2242
+ // ----- Copy the files from the archive to the temporary file
2243
+ // TBC : Here I should better append the file and go back to erase the central dir
2244
+ $v_size = $v_central_dir['offset'];
2245
+ while ($v_size != 0)
2246
+ {
2247
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2248
+ $v_buffer = fread($this->zip_fd, $v_read_size);
2249
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
2250
+ $v_size -= $v_read_size;
2251
+ }
2252
+
2253
+ // ----- Swap the file descriptor
2254
+ // Here is a trick : I swap the temporary fd with the zip fd, in order to use
2255
+ // the following methods on the temporary fil and not the real archive
2256
+ $v_swap = $this->zip_fd;
2257
+ $this->zip_fd = $v_zip_temp_fd;
2258
+ $v_zip_temp_fd = $v_swap;
2259
+
2260
+ // ----- Add the files
2261
+ $v_header_list = array();
2262
+ if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2263
+ {
2264
+ fclose($v_zip_temp_fd);
2265
+ $this->privCloseFd();
2266
+ @unlink($v_zip_temp_name);
2267
+ $this->privSwapBackMagicQuotes();
2268
+
2269
+ // ----- Return
2270
+ return $v_result;
2271
+ }
2272
+
2273
+ // ----- Store the offset of the central dir
2274
+ $v_offset = @ftell($this->zip_fd);
2275
+
2276
+ // ----- Copy the block of file headers from the old archive
2277
+ $v_size = $v_central_dir['size'];
2278
+ while ($v_size != 0)
2279
+ {
2280
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2281
+ $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
2282
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2283
+ $v_size -= $v_read_size;
2284
+ }
2285
+
2286
+ // ----- Create the Central Dir files header
2287
+ for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
2288
+ {
2289
+ // ----- Create the file header
2290
+ if ($v_header_list[$i]['status'] == 'ok') {
2291
+ if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2292
+ fclose($v_zip_temp_fd);
2293
+ $this->privCloseFd();
2294
+ @unlink($v_zip_temp_name);
2295
+ $this->privSwapBackMagicQuotes();
2296
+
2297
+ // ----- Return
2298
+ return $v_result;
2299
+ }
2300
+ $v_count++;
2301
+ }
2302
+
2303
+ // ----- Transform the header to a 'usable' info
2304
+ $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2305
+ }
2306
+
2307
+ // ----- Zip file comment
2308
+ $v_comment = $v_central_dir['comment'];
2309
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2310
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2311
+ }
2312
+ if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
2313
+ $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
2314
+ }
2315
+ if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
2316
+ $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
2317
+ }
2318
+
2319
+ // ----- Calculate the size of the central header
2320
+ $v_size = @ftell($this->zip_fd)-$v_offset;
2321
+
2322
+ // ----- Create the central dir footer
2323
+ if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
2324
+ {
2325
+ // ----- Reset the file list
2326
+ unset($v_header_list);
2327
+ $this->privSwapBackMagicQuotes();
2328
+
2329
+ // ----- Return
2330
+ return $v_result;
2331
+ }
2332
+
2333
+ // ----- Swap back the file descriptor
2334
+ $v_swap = $this->zip_fd;
2335
+ $this->zip_fd = $v_zip_temp_fd;
2336
+ $v_zip_temp_fd = $v_swap;
2337
+
2338
+ // ----- Close
2339
+ $this->privCloseFd();
2340
+
2341
+ // ----- Close the temporary file
2342
+ @fclose($v_zip_temp_fd);
2343
+
2344
+ // ----- Magic quotes trick
2345
+ $this->privSwapBackMagicQuotes();
2346
+
2347
+ // ----- Delete the zip file
2348
+ // TBC : I should test the result ...
2349
+ @unlink($this->zipname);
2350
+
2351
+ // ----- Rename the temporary file
2352
+ // TBC : I should test the result ...
2353
+ //@rename($v_zip_temp_name, $this->zipname);
2354
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
2355
+
2356
+ // ----- Return
2357
+ return $v_result;
2358
+ }
2359
+ // --------------------------------------------------------------------------------
2360
+
2361
+ // --------------------------------------------------------------------------------
2362
+ // Function : privOpenFd()
2363
+ // Description :
2364
+ // Parameters :
2365
+ // --------------------------------------------------------------------------------
2366
+ function privOpenFd($p_mode)
2367
+ {
2368
+ $v_result=1;
2369
+
2370
+ // ----- Look if already open
2371
+ if ($this->zip_fd != 0)
2372
+ {
2373
+ // ----- Error log
2374
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
2375
+
2376
+ // ----- Return
2377
+ return IWPPclZip::errorCode();
2378
+ }
2379
+
2380
+ // ----- Open the zip file
2381
+ if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
2382
+ {
2383
+ // ----- Error log
2384
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
2385
+
2386
+ // ----- Return
2387
+ return IWPPclZip::errorCode();
2388
+ }
2389
+
2390
+ // ----- Return
2391
+ return $v_result;
2392
+ }
2393
+ // --------------------------------------------------------------------------------
2394
+
2395
+ // --------------------------------------------------------------------------------
2396
+ // Function : privCloseFd()
2397
+ // Description :
2398
+ // Parameters :
2399
+ // --------------------------------------------------------------------------------
2400
+ function privCloseFd()
2401
+ {
2402
+ $v_result=1;
2403
+
2404
+ if ($this->zip_fd != 0)
2405
+ @fclose($this->zip_fd);
2406
+ $this->zip_fd = 0;
2407
+
2408
+ // ----- Return
2409
+ return $v_result;
2410
+ }
2411
+ // --------------------------------------------------------------------------------
2412
+
2413
+ // --------------------------------------------------------------------------------
2414
+ // Function : privAddList()
2415
+ // Description :
2416
+ // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
2417
+ // different from the real path of the file. This is usefull if you want to have PclTar
2418
+ // running in any directory, and memorize relative path from an other directory.
2419
+ // Parameters :
2420
+ // $p_list : An array containing the file or directory names to add in the tar
2421
+ // $p_result_list : list of added files with their properties (specially the status field)
2422
+ // $p_add_dir : Path to add in the filename path archived
2423
+ // $p_remove_dir : Path to remove in the filename path archived
2424
+ // Return Values :
2425
+ // --------------------------------------------------------------------------------
2426
+ // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2427
+ function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
2428
+ {
2429
+ $v_result=1;
2430
+
2431
+ // ----- Add the files
2432
+ $v_header_list = array();
2433
+ if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2434
+ {
2435
+ // ----- Return
2436
+ return $v_result;
2437
+ }
2438
+
2439
+ // ----- Store the offset of the central dir
2440
+ $v_offset = @ftell($this->zip_fd);
2441
+
2442
+ // ----- Create the Central Dir files header
2443
+ for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
2444
+ {
2445
+ // ----- Create the file header
2446
+ if ($v_header_list[$i]['status'] == 'ok') {
2447
+ if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2448
+ // ----- Return
2449
+ return $v_result;
2450
+ }
2451
+ $v_count++;
2452
+ }
2453
+
2454
+ // ----- Transform the header to a 'usable' info
2455
+ $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2456
+ }
2457
+
2458
+ // ----- Zip file comment
2459
+ $v_comment = '';
2460
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2461
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2462
+ }
2463
+
2464
+ // ----- Calculate the size of the central header
2465
+ $v_size = @ftell($this->zip_fd)-$v_offset;
2466
+
2467
+ // ----- Create the central dir footer
2468
+ if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
2469
+ {
2470
+ // ----- Reset the file list
2471
+ unset($v_header_list);
2472
+
2473
+ // ----- Return
2474
+ return $v_result;
2475
+ }
2476
+
2477
+ // ----- Return
2478
+ return $v_result;
2479
+ }
2480
+ // --------------------------------------------------------------------------------
2481
+
2482
+ // --------------------------------------------------------------------------------
2483
+ // Function : privAddFileList()
2484
+ // Description :
2485
+ // Parameters :
2486
+ // $p_filedescr_list : An array containing the file description
2487
+ // or directory names to add in the zip
2488
+ // $p_result_list : list of added files with their properties (specially the status field)
2489
+ // Return Values :
2490
+ // --------------------------------------------------------------------------------
2491
+ function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
2492
+ {
2493
+ $v_result=1;
2494
+ $v_header = array();
2495
+
2496
+ // ----- Recuperate the current number of elt in list
2497
+ $v_nb = sizeof($p_result_list);
2498
+
2499
+ // ----- Loop on the files
2500
+ for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
2501
+ // ----- Format the filename
2502
+ $p_filedescr_list[$j]['filename']
2503
+ = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
2504
+
2505
+
2506
+ // ----- Skip empty file names
2507
+ // TBC : Can this be possible ? not checked in DescrParseAtt ?
2508
+ if ($p_filedescr_list[$j]['filename'] == "") {
2509
+ continue;
2510
+ }
2511
+
2512
+ // ----- Check the filename
2513
+ if ( ($p_filedescr_list[$j]['type'] != 'virtual_file')
2514
+ && (!file_exists($p_filedescr_list[$j]['filename']))) {
2515
+ IWPPclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
2516
+ return IWPPclZip::errorCode();
2517
+ }
2518
+
2519
+ // ----- Look if it is a file or a dir with no all path remove option
2520
+ // or a dir with all its path removed
2521
+ // if ( (is_file($p_filedescr_list[$j]['filename']))
2522
+ // || ( is_dir($p_filedescr_list[$j]['filename'])
2523
+ if ( ($p_filedescr_list[$j]['type'] == 'file')
2524
+ || ($p_filedescr_list[$j]['type'] == 'virtual_file')
2525
+ || ( ($p_filedescr_list[$j]['type'] == 'folder')
2526
+ && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
2527
+ || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
2528
+ ) {
2529
+
2530
+ // ----- Add the file
2531
+ $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
2532
+ $p_options);
2533
+ if ($v_result != 1) {
2534
+ return $v_result;
2535
+ }
2536
+
2537
+ // ----- Store the file infos
2538
+ $p_result_list[$v_nb++] = $v_header;
2539
+ }
2540
+ }
2541
+
2542
+ // ----- Return
2543
+ return $v_result;
2544
+ }
2545
+ // --------------------------------------------------------------------------------
2546
+
2547
+ // --------------------------------------------------------------------------------
2548
+ // Function : privAddFile()
2549
+ // Description :
2550
+ // Parameters :
2551
+ // Return Values :
2552
+ // --------------------------------------------------------------------------------
2553
+ function privAddFile($p_filedescr, &$p_header, &$p_options)
2554
+ {
2555
+ $v_result=1;
2556
+
2557
+ // ----- Working variable
2558
+ $p_filename = $p_filedescr['filename'];
2559
+
2560
+ // TBC : Already done in the fileAtt check ... ?
2561
+ if ($p_filename == "") {
2562
+ // ----- Error log
2563
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
2564
+
2565
+ // ----- Return
2566
+ return IWPPclZip::errorCode();
2567
+ }
2568
+
2569
+ // ----- Look for a stored different filename
2570
+ /* TBC : Removed
2571
+ if (isset($p_filedescr['stored_filename'])) {
2572
+ $v_stored_filename = $p_filedescr['stored_filename'];
2573
+ }
2574
+ else {
2575
+ $v_stored_filename = $p_filedescr['stored_filename'];
2576
+ }
2577
+ */
2578
+
2579
+ // ----- Set the file properties
2580
+ clearstatcache();
2581
+ $p_header['version'] = 20;
2582
+ $p_header['version_extracted'] = 10;
2583
+ $p_header['flag'] = 0;
2584
+ $p_header['compression'] = 0;
2585
+ $p_header['crc'] = 0;
2586
+ $p_header['compressed_size'] = 0;
2587
+ $p_header['filename_len'] = strlen($p_filename);
2588
+ $p_header['extra_len'] = 0;
2589
+ $p_header['disk'] = 0;
2590
+ $p_header['internal'] = 0;
2591
+ $p_header['offset'] = 0;
2592
+ $p_header['filename'] = $p_filename;
2593
+ // TBC : Removed $p_header['stored_filename'] = $v_stored_filename;
2594
+ $p_header['stored_filename'] = $p_filedescr['stored_filename'];
2595
+ $p_header['extra'] = '';
2596
+ $p_header['status'] = 'ok';
2597
+ $p_header['index'] = -1;
2598
+
2599
+ // ----- Look for regular file
2600
+ if ($p_filedescr['type']=='file') {
2601
+ $p_header['external'] = 0x00000000;
2602
+ $p_header['size'] = filesize($p_filename);
2603
+ }
2604
+
2605
+ // ----- Look for regular folder
2606
+ else if ($p_filedescr['type']=='folder') {
2607
+ $p_header['external'] = 0x00000010;
2608
+ $p_header['mtime'] = filemtime($p_filename);
2609
+ $p_header['size'] = filesize($p_filename);
2610
+ }
2611
+
2612
+ // ----- Look for virtual file
2613
+ else if ($p_filedescr['type'] == 'virtual_file') {
2614
+ $p_header['external'] = 0x00000000;
2615
+ $p_header['size'] = strlen($p_filedescr['content']);
2616
+ }
2617
+
2618
+
2619
+ // ----- Look for filetime
2620
+ if (isset($p_filedescr['mtime'])) {
2621
+ $p_header['mtime'] = $p_filedescr['mtime'];
2622
+ }
2623
+ else if ($p_filedescr['type'] == 'virtual_file') {
2624
+ $p_header['mtime'] = time();
2625
+ }
2626
+ else {
2627
+ $p_header['mtime'] = filemtime($p_filename);
2628
+ }
2629
+
2630
+ // ------ Look for file comment
2631
+ if (isset($p_filedescr['comment'])) {
2632
+ $p_header['comment_len'] = strlen($p_filedescr['comment']);
2633
+ $p_header['comment'] = $p_filedescr['comment'];
2634
+ }
2635
+ else {
2636
+ $p_header['comment_len'] = 0;
2637
+ $p_header['comment'] = '';
2638
+ }
2639
+
2640
+ // ----- Look for pre-add callback
2641
+ if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
2642
+
2643
+ // ----- Generate a local information
2644
+ $v_local_header = array();
2645
+ $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2646
+
2647
+ // ----- Call the callback
2648
+ // Here I do not use call_user_func() because I need to send a reference to the
2649
+ // header.
2650
+ $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
2651
+ if ($v_result == 0) {
2652
+ // ----- Change the file status
2653
+ $p_header['status'] = "skipped";
2654
+ $v_result = 1;
2655
+ }
2656
+
2657
+ // ----- Update the informations
2658
+ // Only some fields can be modified
2659
+ if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
2660
+ $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
2661
+ }
2662
+ }
2663
+
2664
+ // ----- Look for empty stored filename
2665
+ if ($p_header['stored_filename'] == "") {
2666
+ $p_header['status'] = "filtered";
2667
+ }
2668
+
2669
+ // ----- Check the path length
2670
+ if (strlen($p_header['stored_filename']) > 0xFF) {
2671
+ $p_header['status'] = 'filename_too_long';
2672
+ }
2673
+
2674
+ // ----- Look if no error, or file not skipped
2675
+ if ($p_header['status'] == 'ok') {
2676
+
2677
+ // ----- Look for a file
2678
+ if ($p_filedescr['type'] == 'file') {
2679
+
2680
+ // ----- Look for using temporary file to zip
2681
+ if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
2682
+ && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
2683
+ || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
2684
+ && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
2685
+ $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
2686
+ if ($v_result < PCLZIP_ERR_NO_ERROR) {
2687
+ return $v_result;
2688
+ }
2689
+ }
2690
+
2691
+ // ----- Use "in memory" zip algo
2692
+ else {
2693
+
2694
+ // ----- Open the source file
2695
+ if (($v_file = @fopen($p_filename, "rb")) == 0) {
2696
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2697
+ return IWPPclZip::errorCode();
2698
+ }
2699
+
2700
+ // ----- Read the file content
2701
+ $v_content = @fread($v_file, $p_header['size']);
2702
+
2703
+ // ----- Close the file
2704
+ @fclose($v_file);
2705
+
2706
+ // ----- Calculate the CRC
2707
+ $p_header['crc'] = @crc32($v_content);
2708
+
2709
+ // ----- Look for no compression
2710
+ if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2711
+ // ----- Set header parameters
2712
+ $p_header['compressed_size'] = $p_header['size'];
2713
+ $p_header['compression'] = 0;
2714
+ }
2715
+
2716
+ // ----- Look for normal compression
2717
+ else {
2718
+ // ----- Compress the content
2719
+ $v_content = @gzdeflate($v_content);
2720
+
2721
+ // ----- Set header parameters
2722
+ $p_header['compressed_size'] = strlen($v_content);
2723
+ $p_header['compression'] = 8;
2724
+ }
2725
+
2726
+ // ----- Call the header generation
2727
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2728
+ @fclose($v_file);
2729
+ return $v_result;
2730
+ }
2731
+
2732
+ // ----- Write the compressed (or not) content
2733
+ @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
2734
+
2735
+ }
2736
+
2737
+ }
2738
+
2739
+ // ----- Look for a virtual file (a file from string)
2740
+ else if ($p_filedescr['type'] == 'virtual_file') {
2741
+
2742
+ $v_content = $p_filedescr['content'];
2743
+
2744
+ // ----- Calculate the CRC
2745
+ $p_header['crc'] = @crc32($v_content);
2746
+
2747
+ // ----- Look for no compression
2748
+ if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2749
+ // ----- Set header parameters
2750
+ $p_header['compressed_size'] = $p_header['size'];
2751
+ $p_header['compression'] = 0;
2752
+ }
2753
+
2754
+ // ----- Look for normal compression
2755
+ else {
2756
+ // ----- Compress the content
2757
+ $v_content = @gzdeflate($v_content);
2758
+
2759
+ // ----- Set header parameters
2760
+ $p_header['compressed_size'] = strlen($v_content);
2761
+ $p_header['compression'] = 8;
2762
+ }
2763
+
2764
+ // ----- Call the header generation
2765
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2766
+ @fclose($v_file);
2767
+ return $v_result;
2768
+ }
2769
+
2770
+ // ----- Write the compressed (or not) content
2771
+ @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
2772
+ }
2773
+
2774
+ // ----- Look for a directory
2775
+ else if ($p_filedescr['type'] == 'folder') {
2776
+ // ----- Look for directory last '/'
2777
+ if (@substr($p_header['stored_filename'], -1) != '/') {
2778
+ $p_header['stored_filename'] .= '/';
2779
+ }
2780
+
2781
+ // ----- Set the file properties
2782
+ $p_header['size'] = 0;
2783
+ //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
2784
+ $p_header['external'] = 0x00000010; // Value for a folder : to be checked
2785
+
2786
+ // ----- Call the header generation
2787
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
2788
+ {
2789
+ return $v_result;
2790
+ }
2791
+ }
2792
+ }
2793
+
2794
+ // ----- Look for post-add callback
2795
+ if (isset($p_options[PCLZIP_CB_POST_ADD])) {
2796
+
2797
+ // ----- Generate a local information
2798
+ $v_local_header = array();
2799
+ $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2800
+
2801
+ // ----- Call the callback
2802
+ // Here I do not use call_user_func() because I need to send a reference to the
2803
+ // header.
2804
+ $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
2805
+ if ($v_result == 0) {
2806
+ // ----- Ignored
2807
+ $v_result = 1;
2808
+ }
2809
+
2810
+ // ----- Update the informations
2811
+ // Nothing can be modified
2812
+ }
2813
+
2814
+ // ----- Return
2815
+ return $v_result;
2816
+ }
2817
+ // --------------------------------------------------------------------------------
2818
+
2819
+ // --------------------------------------------------------------------------------
2820
+ // Function : privAddFileUsingTempFile()
2821
+ // Description :
2822
+ // Parameters :
2823
+ // Return Values :
2824
+ // --------------------------------------------------------------------------------
2825
+ function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
2826
+ {
2827
+ $v_result=PCLZIP_ERR_NO_ERROR;
2828
+
2829
+ // ----- Working variable
2830
+ $p_filename = $p_filedescr['filename'];
2831
+
2832
+
2833
+ // ----- Open the source file
2834
+ if (($v_file = @fopen($p_filename, "rb")) == 0) {
2835
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2836
+ return IWPPclZip::errorCode();
2837
+ }
2838
+
2839
+ // ----- Creates a compressed temporary file
2840
+ $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
2841
+ if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
2842
+ fclose($v_file);
2843
+ IWPPclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
2844
+ return IWPPclZip::errorCode();
2845
+ }
2846
+
2847
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2848
+ $v_size = filesize($p_filename);
2849
+ while ($v_size != 0) {
2850
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2851
+ $v_buffer = @fread($v_file, $v_read_size);
2852
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2853
+ @gzputs($v_file_compressed, $v_buffer, $v_read_size);
2854
+ $v_size -= $v_read_size;
2855
+ }
2856
+
2857
+ // ----- Close the file
2858
+ @fclose($v_file);
2859
+ @gzclose($v_file_compressed);
2860
+
2861
+ // ----- Check the minimum file size
2862
+ if (filesize($v_gzip_temp_name) < 18) {
2863
+ IWPPclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
2864
+ return IWPPclZip::errorCode();
2865
+ }
2866
+
2867
+ // ----- Extract the compressed attributes
2868
+ if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
2869
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2870
+ return IWPPclZip::errorCode();
2871
+ }
2872
+
2873
+ // ----- Read the gzip file header
2874
+ $v_binary_data = @fread($v_file_compressed, 10);
2875
+ $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
2876
+
2877
+ // ----- Check some parameters
2878
+ $v_data_header['os'] = bin2hex($v_data_header['os']);
2879
+
2880
+ // ----- Read the gzip file footer
2881
+ @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
2882
+ $v_binary_data = @fread($v_file_compressed, 8);
2883
+ $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
2884
+
2885
+ // ----- Set the attributes
2886
+ $p_header['compression'] = ord($v_data_header['cm']);
2887
+ //$p_header['mtime'] = $v_data_header['mtime'];
2888
+ $p_header['crc'] = $v_data_footer['crc'];
2889
+ $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
2890
+
2891
+ // ----- Close the file
2892
+ @fclose($v_file_compressed);
2893
+
2894
+ // ----- Call the header generation
2895
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2896
+ return $v_result;
2897
+ }
2898
+
2899
+ // ----- Add the compressed data
2900
+ if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
2901
+ {
2902
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2903
+ return IWPPclZip::errorCode();
2904
+ }
2905
+
2906
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2907
+ fseek($v_file_compressed, 10);
2908
+ $v_size = $p_header['compressed_size'];
2909
+ while ($v_size != 0)
2910
+ {
2911
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2912
+ $v_buffer = @fread($v_file_compressed, $v_read_size);
2913
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2914
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2915
+ $v_size -= $v_read_size;
2916
+ }
2917
+
2918
+ // ----- Close the file
2919
+ @fclose($v_file_compressed);
2920
+
2921
+ // ----- Unlink the temporary file
2922
+ @unlink($v_gzip_temp_name);
2923
+
2924
+ // ----- Return
2925
+ return $v_result;
2926
+ }
2927
+ // --------------------------------------------------------------------------------
2928
+
2929
+ // --------------------------------------------------------------------------------
2930
+ // Function : privCalculateStoredFilename()
2931
+ // Description :
2932
+ // Based on file descriptor properties and global options, this method
2933
+ // calculate the filename that will be stored in the archive.
2934
+ // Parameters :
2935
+ // Return Values :
2936
+ // --------------------------------------------------------------------------------
2937
+ function privCalculateStoredFilename(&$p_filedescr, &$p_options)
2938
+ {
2939
+ $v_result=1;
2940
+
2941
+ // ----- Working variables
2942
+ $p_filename = $p_filedescr['filename'];
2943
+ if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
2944
+ $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
2945
+ }
2946
+ else {
2947
+ $p_add_dir = '';
2948
+ }
2949
+ if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
2950
+ $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
2951
+ }
2952
+ else {
2953
+ $p_remove_dir = '';
2954
+ }
2955
+ if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
2956
+ $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
2957
+ }
2958
+ else {
2959
+ $p_remove_all_dir = 0;
2960
+ }
2961
+
2962
+
2963
+ // ----- Look for full name change
2964
+ if (isset($p_filedescr['new_full_name'])) {
2965
+ // ----- Remove drive letter if any
2966
+ $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
2967
+ }
2968
+
2969
+ // ----- Look for path and/or short name change
2970
+ else {
2971
+
2972
+ // ----- Look for short name change
2973
+ // Its when we cahnge just the filename but not the path
2974
+ if (isset($p_filedescr['new_short_name'])) {
2975
+ $v_path_info = pathinfo($p_filename);
2976
+ $v_dir = '';
2977
+ if ($v_path_info['dirname'] != '') {
2978
+ $v_dir = $v_path_info['dirname'].'/';
2979
+ }
2980
+ $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
2981
+ }
2982
+ else {
2983
+ // ----- Calculate the stored filename
2984
+ $v_stored_filename = $p_filename;
2985
+ }
2986
+
2987
+ // ----- Look for all path to remove
2988
+ if ($p_remove_all_dir) {
2989
+ $v_stored_filename = basename($p_filename);
2990
+ }
2991
+ // ----- Look for partial path remove
2992
+ else if ($p_remove_dir != "") {
2993
+ if (substr($p_remove_dir, -1) != '/')
2994
+ $p_remove_dir .= "/";
2995
+
2996
+ if ( (substr($p_filename, 0, 2) == "./")
2997
+ || (substr($p_remove_dir, 0, 2) == "./")) {
2998
+
2999
+ if ( (substr($p_filename, 0, 2) == "./")
3000
+ && (substr($p_remove_dir, 0, 2) != "./")) {
3001
+ $p_remove_dir = "./".$p_remove_dir;
3002
+ }
3003
+ if ( (substr($p_filename, 0, 2) != "./")
3004
+ && (substr($p_remove_dir, 0, 2) == "./")) {
3005
+ $p_remove_dir = substr($p_remove_dir, 2);
3006
+ }
3007
+ }
3008
+
3009
+ $v_compare = PclZipUtilPathInclusion($p_remove_dir,
3010
+ $v_stored_filename);
3011
+ if ($v_compare > 0) {
3012
+ if ($v_compare == 2) {
3013
+ $v_stored_filename = "";
3014
+ }
3015
+ else {
3016
+ $v_stored_filename = substr($v_stored_filename,
3017
+ strlen($p_remove_dir));
3018
+ }
3019
+ }
3020
+ }
3021
+
3022
+ // ----- Remove drive letter if any
3023
+ $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
3024
+
3025
+ // ----- Look for path to add
3026
+ if ($p_add_dir != "") {
3027
+ if (substr($p_add_dir, -1) == "/")
3028
+ $v_stored_filename = $p_add_dir.$v_stored_filename;
3029
+ else
3030
+ $v_stored_filename = $p_add_dir."/".$v_stored_filename;
3031
+ }
3032
+ }
3033
+
3034
+ // ----- Filename (reduce the path of stored name)
3035
+ $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
3036
+ $p_filedescr['stored_filename'] = $v_stored_filename;
3037
+
3038
+ // ----- Return
3039
+ return $v_result;
3040
+ }
3041
+ // --------------------------------------------------------------------------------
3042
+
3043
+ // --------------------------------------------------------------------------------
3044
+ // Function : privWriteFileHeader()
3045
+ // Description :
3046
+ // Parameters :
3047
+ // Return Values :
3048
+ // --------------------------------------------------------------------------------
3049
+ function privWriteFileHeader(&$p_header)
3050
+ {
3051
+ $v_result=1;
3052
+
3053
+ // ----- Store the offset position of the file
3054
+ $p_header['offset'] = ftell($this->zip_fd);
3055
+
3056
+ // ----- Transform UNIX mtime to DOS format mdate/mtime
3057
+ $v_date = getdate($p_header['mtime']);
3058
+ $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3059
+ $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3060
+
3061
+ // ----- Packed data
3062
+ $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
3063
+ $p_header['version_extracted'], $p_header['flag'],
3064
+ $p_header['compression'], $v_mtime, $v_mdate,
3065
+ $p_header['crc'], $p_header['compressed_size'],
3066
+ $p_header['size'],
3067
+ strlen($p_header['stored_filename']),
3068
+ $p_header['extra_len']);
3069
+
3070
+ // ----- Write the first 148 bytes of the header in the archive
3071
+ fputs($this->zip_fd, $v_binary_data, 30);
3072
+
3073
+ // ----- Write the variable fields
3074
+ if (strlen($p_header['stored_filename']) != 0)
3075
+ {
3076
+ fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3077
+ }
3078
+ if ($p_header['extra_len'] != 0)
3079
+ {
3080
+ fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3081
+ }
3082
+
3083
+ // ----- Return
3084
+ return $v_result;
3085
+ }
3086
+ // --------------------------------------------------------------------------------
3087
+
3088
+ // --------------------------------------------------------------------------------
3089
+ // Function : privWriteCentralFileHeader()
3090
+ // Description :
3091
+ // Parameters :
3092
+ // Return Values :
3093
+ // --------------------------------------------------------------------------------
3094
+ function privWriteCentralFileHeader(&$p_header)
3095
+ {
3096
+ $v_result=1;
3097
+
3098
+ // TBC
3099
+ //for(reset($p_header); $key = key($p_header); next($p_header)) {
3100
+ //}
3101
+
3102
+ // ----- Transform UNIX mtime to DOS format mdate/mtime
3103
+ $v_date = getdate($p_header['mtime']);
3104
+ $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3105
+ $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3106
+
3107
+
3108
+ // ----- Packed data
3109
+ $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
3110
+ $p_header['version'], $p_header['version_extracted'],
3111
+ $p_header['flag'], $p_header['compression'],
3112
+ $v_mtime, $v_mdate, $p_header['crc'],
3113
+ $p_header['compressed_size'], $p_header['size'],
3114
+ strlen($p_header['stored_filename']),
3115
+ $p_header['extra_len'], $p_header['comment_len'],
3116
+ $p_header['disk'], $p_header['internal'],
3117
+ $p_header['external'], $p_header['offset']);
3118
+
3119
+ // ----- Write the 42 bytes of the header in the zip file
3120
+ fputs($this->zip_fd, $v_binary_data, 46);
3121
+
3122
+ // ----- Write the variable fields
3123
+ if (strlen($p_header['stored_filename']) != 0)
3124
+ {
3125
+ fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3126
+ }
3127
+ if ($p_header['extra_len'] != 0)
3128
+ {
3129
+ fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3130
+ }
3131
+ if ($p_header['comment_len'] != 0)
3132
+ {
3133
+ fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
3134
+ }
3135
+
3136
+ // ----- Return
3137
+ return $v_result;
3138
+ }
3139
+ // --------------------------------------------------------------------------------
3140
+
3141
+ // --------------------------------------------------------------------------------
3142
+ // Function : privWriteCentralHeader()
3143
+ // Description :
3144
+ // Parameters :
3145
+ // Return Values :
3146
+ // --------------------------------------------------------------------------------
3147
+ function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
3148
+ {
3149
+ $v_result=1;
3150
+
3151
+ // ----- Packed data
3152
+ $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
3153
+ $p_nb_entries, $p_size,
3154
+ $p_offset, strlen($p_comment));
3155
+
3156
+ // ----- Write the 22 bytes of the header in the zip file
3157
+ fputs($this->zip_fd, $v_binary_data, 22);
3158
+
3159
+ // ----- Write the variable fields
3160
+ if (strlen($p_comment) != 0)
3161
+ {
3162
+ fputs($this->zip_fd, $p_comment, strlen($p_comment));
3163
+ }
3164
+
3165
+ // ----- Return
3166
+ return $v_result;
3167
+ }
3168
+ // --------------------------------------------------------------------------------
3169
+
3170
+ // --------------------------------------------------------------------------------
3171
+ // Function : privList()
3172
+ // Description :
3173
+ // Parameters :
3174
+ // Return Values :
3175
+ // --------------------------------------------------------------------------------
3176
+ function privList(&$p_list)
3177
+ {
3178
+ $v_result=1;
3179
+
3180
+ // ----- Magic quotes trick
3181
+ $this->privDisableMagicQuotes();
3182
+
3183
+ // ----- Open the zip file
3184
+ if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
3185
+ {
3186
+ // ----- Magic quotes trick
3187
+ $this->privSwapBackMagicQuotes();
3188
+
3189
+ // ----- Error log
3190
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
3191
+
3192
+ // ----- Return
3193
+ return IWPPclZip::errorCode();
3194
+ }
3195
+
3196
+ // ----- Read the central directory informations
3197
+ $v_central_dir = array();
3198
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3199
+ {
3200
+ $this->privSwapBackMagicQuotes();
3201
+ return $v_result;
3202
+ }
3203
+
3204
+ // ----- Go to beginning of Central Dir
3205
+ @rewind($this->zip_fd);
3206
+ if (@fseek($this->zip_fd, $v_central_dir['offset']))
3207
+ {
3208
+ $this->privSwapBackMagicQuotes();
3209
+
3210
+ // ----- Error log
3211
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3212
+
3213
+ // ----- Return
3214
+ return IWPPclZip::errorCode();
3215
+ }
3216
+
3217
+ // ----- Read each entry
3218
+ for ($i=0; $i<$v_central_dir['entries']; $i++)
3219
+ {
3220
+ // ----- Read the file header
3221
+ if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3222
+ {
3223
+ $this->privSwapBackMagicQuotes();
3224
+ return $v_result;
3225
+ }
3226
+ $v_header['index'] = $i;
3227
+
3228
+ // ----- Get the only interesting attributes
3229
+ $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
3230
+ unset($v_header);
3231
+ }
3232
+
3233
+ // ----- Close the zip file
3234
+ $this->privCloseFd();
3235
+
3236
+ // ----- Magic quotes trick
3237
+ $this->privSwapBackMagicQuotes();
3238
+
3239
+ // ----- Return
3240
+ return $v_result;
3241
+ }
3242
+ // --------------------------------------------------------------------------------
3243
+
3244
+ // --------------------------------------------------------------------------------
3245
+ // Function : privConvertHeader2FileInfo()
3246
+ // Description :
3247
+ // This function takes the file informations from the central directory
3248
+ // entries and extract the interesting parameters that will be given back.
3249
+ // The resulting file infos are set in the array $p_info
3250
+ // $p_info['filename'] : Filename with full path. Given by user (add),
3251
+ // extracted in the filesystem (extract).
3252
+ // $p_info['stored_filename'] : Stored filename in the archive.
3253
+ // $p_info['size'] = Size of the file.
3254
+ // $p_info['compressed_size'] = Compressed size of the file.
3255
+ // $p_info['mtime'] = Last modification date of the file.
3256
+ // $p_info['comment'] = Comment associated with the file.
3257
+ // $p_info['folder'] = true/false : indicates if the entry is a folder or not.
3258
+ // $p_info['status'] = status of the action on the file.
3259
+ // $p_info['crc'] = CRC of the file content.
3260
+ // Parameters :
3261
+ // Return Values :
3262
+ // --------------------------------------------------------------------------------
3263
+ function privConvertHeader2FileInfo($p_header, &$p_info)
3264
+ {
3265
+ $v_result=1;
3266
+
3267
+ // ----- Get the interesting attributes
3268
+ $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
3269
+ $p_info['filename'] = $v_temp_path;
3270
+ $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
3271
+ $p_info['stored_filename'] = $v_temp_path;
3272
+ $p_info['size'] = $p_header['size'];
3273
+ $p_info['compressed_size'] = $p_header['compressed_size'];
3274
+ $p_info['mtime'] = $p_header['mtime'];
3275
+ $p_info['comment'] = $p_header['comment'];
3276
+ $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
3277
+ $p_info['index'] = $p_header['index'];
3278
+ $p_info['status'] = $p_header['status'];
3279
+ $p_info['crc'] = $p_header['crc'];
3280
+
3281
+ // ----- Return
3282
+ return $v_result;
3283
+ }
3284
+ // --------------------------------------------------------------------------------
3285
+
3286
+ // --------------------------------------------------------------------------------
3287
+ // Function : privExtractByRule()
3288
+ // Description :
3289
+ // Extract a file or directory depending of rules (by index, by name, ...)
3290
+ // Parameters :
3291
+ // $p_file_list : An array where will be placed the properties of each
3292
+ // extracted file
3293
+ // $p_path : Path to add while writing the extracted files
3294
+ // $p_remove_path : Path to remove (from the file memorized path) while writing the
3295
+ // extracted files. If the path does not match the file path,
3296
+ // the file is extracted with its memorized path.
3297
+ // $p_remove_path does not apply to 'list' mode.
3298
+ // $p_path and $p_remove_path are commulative.
3299
+ // Return Values :
3300
+ // 1 on success,0 or less on error (see error code list)
3301
+ // --------------------------------------------------------------------------------
3302
+ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3303
+ {
3304
+ $v_result=1;
3305
+
3306
+ // ----- Magic quotes trick
3307
+ $this->privDisableMagicQuotes();
3308
+
3309
+ // ----- Check the path
3310
+ if ( ($p_path == "")
3311
+ || ( (substr($p_path, 0, 1) != "/")
3312
+ && (substr($p_path, 0, 3) != "../")
3313
+ && (substr($p_path,1,2)!=":/")))
3314
+ $p_path = "./".$p_path;
3315
+
3316
+ // ----- Reduce the path last (and duplicated) '/'
3317
+ if (($p_path != "./") && ($p_path != "/"))
3318
+ {
3319
+ // ----- Look for the path end '/'
3320
+ while (substr($p_path, -1) == "/")
3321
+ {
3322
+ $p_path = substr($p_path, 0, strlen($p_path)-1);
3323
+ }
3324
+ }
3325
+
3326
+ // ----- Look for path to remove format (should end by /)
3327
+ if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
3328
+ {
3329
+ $p_remove_path .= '/';
3330
+ }
3331
+ $p_remove_path_size = strlen($p_remove_path);
3332
+
3333
+ // ----- Open the zip file
3334
+ if (($v_result = $this->privOpenFd('rb')) != 1)
3335
+ {
3336
+ $this->privSwapBackMagicQuotes();
3337
+ return $v_result;
3338
+ }
3339
+
3340
+ // ----- Read the central directory informations
3341
+ $v_central_dir = array();
3342
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3343
+ {
3344
+ // ----- Close the zip file
3345
+ $this->privCloseFd();
3346
+ $this->privSwapBackMagicQuotes();
3347
+
3348
+ return $v_result;
3349
+ }
3350
+
3351
+ // ----- Start at beginning of Central Dir
3352
+ $v_pos_entry = $v_central_dir['offset'];
3353
+
3354
+ // ----- Read each entry
3355
+ $j_start = 0;
3356
+ for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
3357
+ {
3358
+
3359
+ // ----- Read next Central dir entry
3360
+ @rewind($this->zip_fd);
3361
+ if (@fseek($this->zip_fd, $v_pos_entry))
3362
+ {
3363
+ // ----- Close the zip file
3364
+ $this->privCloseFd();
3365
+ $this->privSwapBackMagicQuotes();
3366
+
3367
+ // ----- Error log
3368
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3369
+
3370
+ // ----- Return
3371
+ return IWPPclZip::errorCode();
3372
+ }
3373
+
3374
+ // ----- Read the file header
3375
+ $v_header = array();
3376
+ if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3377
+ {
3378
+ // ----- Close the zip file
3379
+ $this->privCloseFd();
3380
+ $this->privSwapBackMagicQuotes();
3381
+
3382
+ return $v_result;
3383
+ }
3384
+
3385
+ // ----- Store the index
3386
+ $v_header['index'] = $i;
3387
+
3388
+ // ----- Store the file position
3389
+ $v_pos_entry = ftell($this->zip_fd);
3390
+
3391
+ // ----- Look for the specific extract rules
3392
+ $v_extract = false;
3393
+
3394
+ // ----- Look for extract by name rule
3395
+ if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
3396
+ && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
3397
+
3398
+ // ----- Look if the filename is in the list
3399
+ for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
3400
+
3401
+ // ----- Look for a directory
3402
+ if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
3403
+
3404
+ // ----- Look if the directory is in the filename path
3405
+ if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
3406
+ && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
3407
+ $v_extract = true;
3408
+ }
3409
+ }
3410
+ // ----- Look for a filename
3411
+ elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
3412
+ $v_extract = true;
3413
+ }
3414
+ }
3415
+ }
3416
+
3417
+ // ----- Look for extract by ereg rule
3418
+ // ereg() is deprecated with PHP 5.3
3419
+ /*
3420
+ else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
3421
+ && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
3422
+
3423
+ if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
3424
+ $v_extract = true;
3425
+ }
3426
+ }
3427
+ */
3428
+
3429
+ // ----- Look for extract by preg rule
3430
+ else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
3431
+ && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
3432
+
3433
+ if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
3434
+ $v_extract = true;
3435
+ }
3436
+ }
3437
+
3438
+ // ----- Look for extract by index rule
3439
+ else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
3440
+ && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
3441
+
3442
+ // ----- Look if the index is in the list
3443
+ for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
3444
+
3445
+ if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
3446
+ $v_extract = true;
3447
+ }
3448
+ if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
3449
+ $j_start = $j+1;
3450
+ }
3451
+
3452
+ if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
3453
+ break;
3454
+ }
3455
+ }
3456
+ }
3457
+
3458
+ // ----- Look for no rule, which means extract all the archive
3459
+ else {
3460
+ $v_extract = true;
3461
+ }
3462
+
3463
+ // ----- Check compression method
3464
+ if ( ($v_extract)
3465
+ && ( ($v_header['compression'] != 8)
3466
+ && ($v_header['compression'] != 0))) {
3467
+ $v_header['status'] = 'unsupported_compression';
3468
+
3469
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3470
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3471
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3472
+
3473
+ $this->privSwapBackMagicQuotes();
3474
+
3475
+ IWPPclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
3476
+ "Filename '".$v_header['stored_filename']."' is "
3477
+ ."compressed by an unsupported compression "
3478
+ ."method (".$v_header['compression'].") ");
3479
+
3480
+ return IWPPclZip::errorCode();
3481
+ }
3482
+ }
3483
+
3484
+ // ----- Check encrypted files
3485
+ if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
3486
+ $v_header['status'] = 'unsupported_encryption';
3487
+
3488
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3489
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3490
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3491
+
3492
+ $this->privSwapBackMagicQuotes();
3493
+
3494
+ IWPPclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
3495
+ "Unsupported encryption for "
3496
+ ." filename '".$v_header['stored_filename']
3497
+ ."'");
3498
+
3499
+ return IWPPclZip::errorCode();
3500
+ }
3501
+ }
3502
+
3503
+ // ----- Look for real extraction
3504
+ if (($v_extract) && ($v_header['status'] != 'ok')) {
3505
+ $v_result = $this->privConvertHeader2FileInfo($v_header,
3506
+ $p_file_list[$v_nb_extracted++]);
3507
+ if ($v_result != 1) {
3508
+ $this->privCloseFd();
3509
+ $this->privSwapBackMagicQuotes();
3510
+ return $v_result;
3511
+ }
3512
+
3513
+ $v_extract = false;
3514
+ }
3515
+
3516
+ // ----- Look for real extraction
3517
+ if ($v_extract)
3518
+ {
3519
+
3520
+ // ----- Go to the file position
3521
+ @rewind($this->zip_fd);
3522
+ if (@fseek($this->zip_fd, $v_header['offset']))
3523
+ {
3524
+ // ----- Close the zip file
3525
+ $this->privCloseFd();
3526
+
3527
+ $this->privSwapBackMagicQuotes();
3528
+
3529
+ // ----- Error log
3530
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3531
+
3532
+ // ----- Return
3533
+ return IWPPclZip::errorCode();
3534
+ }
3535
+
3536
+ // ----- Look for extraction as string
3537
+ if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
3538
+
3539
+ $v_string = '';
3540
+
3541
+ // ----- Extracting the file
3542
+ $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
3543
+ if ($v_result1 < 1) {
3544
+ $this->privCloseFd();
3545
+ $this->privSwapBackMagicQuotes();
3546
+ return $v_result1;
3547
+ }
3548
+
3549
+ // ----- Get the only interesting attributes
3550
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
3551
+ {
3552
+ // ----- Close the zip file
3553
+ $this->privCloseFd();
3554
+ $this->privSwapBackMagicQuotes();
3555
+
3556
+ return $v_result;
3557
+ }
3558
+
3559
+ // ----- Set the file content
3560
+ $p_file_list[$v_nb_extracted]['content'] = $v_string;
3561
+
3562
+ // ----- Next extracted file
3563
+ $v_nb_extracted++;
3564
+
3565
+ // ----- Look for user callback abort
3566
+ if ($v_result1 == 2) {
3567
+ break;
3568
+ }
3569
+ }
3570
+ // ----- Look for extraction in standard output
3571
+ elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
3572
+ && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
3573
+ // ----- Extracting the file in standard output
3574
+ $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
3575
+ if ($v_result1 < 1) {
3576
+ $this->privCloseFd();
3577
+ $this->privSwapBackMagicQuotes();
3578
+ return $v_result1;
3579
+ }
3580
+
3581
+ // ----- Get the only interesting attributes
3582
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
3583
+ $this->privCloseFd();
3584
+ $this->privSwapBackMagicQuotes();
3585
+ return $v_result;
3586
+ }
3587
+
3588
+ // ----- Look for user callback abort
3589
+ if ($v_result1 == 2) {
3590
+ break;
3591
+ }
3592
+ }
3593
+ // ----- Look for normal extraction
3594
+ else {
3595
+ // ----- Extracting the file
3596
+ $v_result1 = $this->privExtractFile($v_header,
3597
+ $p_path, $p_remove_path,
3598
+ $p_remove_all_path,
3599
+ $p_options);
3600
+ if ($v_result1 < 1) {
3601
+ $this->privCloseFd();
3602
+ $this->privSwapBackMagicQuotes();
3603
+ return $v_result1;
3604
+ }
3605
+
3606
+ // ----- Get the only interesting attributes
3607
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
3608
+ {
3609
+ // ----- Close the zip file
3610
+ $this->privCloseFd();
3611
+ $this->privSwapBackMagicQuotes();
3612
+
3613
+ return $v_result;
3614
+ }
3615
+
3616
+ // ----- Look for user callback abort
3617
+ if ($v_result1 == 2) {
3618
+ break;
3619
+ }
3620
+ }
3621
+ }
3622
+ }
3623
+
3624
+ // ----- Close the zip file
3625
+ $this->privCloseFd();
3626
+ $this->privSwapBackMagicQuotes();
3627
+
3628
+ // ----- Return
3629
+ return $v_result;
3630
+ }
3631
+ // --------------------------------------------------------------------------------
3632
+
3633
+ // --------------------------------------------------------------------------------
3634
+ // Function : privExtractFile()
3635
+ // Description :
3636
+ // Parameters :
3637
+ // Return Values :
3638
+ //
3639
+ // 1 : ... ?
3640
+ // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
3641
+ // --------------------------------------------------------------------------------
3642
+ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3643
+ {
3644
+ $v_result=1;
3645
+
3646
+ // ----- Read the file header
3647
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1)
3648
+ {
3649
+ // ----- Return
3650
+ return $v_result;
3651
+ }
3652
+
3653
+
3654
+ // ----- Check that the file header is coherent with $p_entry info
3655
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3656
+ // TBC
3657
+ }
3658
+
3659
+ // ----- Look for all path to remove
3660
+ if ($p_remove_all_path == true) {
3661
+ // ----- Look for folder entry that not need to be extracted
3662
+ if (($p_entry['external']&0x00000010)==0x00000010) {
3663
+
3664
+ $p_entry['status'] = "filtered";
3665
+
3666
+ return $v_result;
3667
+ }
3668
+
3669
+ // ----- Get the basename of the path
3670
+ $p_entry['filename'] = basename($p_entry['filename']);
3671
+ }
3672
+
3673
+ // ----- Look for path to remove
3674
+ else if ($p_remove_path != "")
3675
+ {
3676
+ if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
3677
+ {
3678
+
3679
+ // ----- Change the file status
3680
+ $p_entry['status'] = "filtered";
3681
+
3682
+ // ----- Return
3683
+ return $v_result;
3684
+ }
3685
+
3686
+ $p_remove_path_size = strlen($p_remove_path);
3687
+ if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
3688
+ {
3689
+
3690
+ // ----- Remove the path
3691
+ $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
3692
+
3693
+ }
3694
+ }
3695
+
3696
+ // ----- Add the path
3697
+ if ($p_path != '') {
3698
+ $p_entry['filename'] = $p_path."/".$p_entry['filename'];
3699
+ }
3700
+
3701
+ // ----- Check a base_dir_restriction
3702
+ if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
3703
+ $v_inclusion
3704
+ = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
3705
+ $p_entry['filename']);
3706
+ if ($v_inclusion == 0) {
3707
+
3708
+ IWPPclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
3709
+ "Filename '".$p_entry['filename']."' is "
3710
+ ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
3711
+
3712
+ return IWPPclZip::errorCode();
3713
+ }
3714
+ }
3715
+
3716
+ // ----- Look for pre-extract callback
3717
+ if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3718
+
3719
+ // ----- Generate a local information
3720
+ $v_local_header = array();
3721
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3722
+
3723
+ // ----- Call the callback
3724
+ // Here I do not use call_user_func() because I need to send a reference to the
3725
+ // header.
3726
+ $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
3727
+ if ($v_result == 0) {
3728
+ // ----- Change the file status
3729
+ $p_entry['status'] = "skipped";
3730
+ $v_result = 1;
3731
+ }
3732
+
3733
+ // ----- Look for abort result
3734
+ if ($v_result == 2) {
3735
+ // ----- This status is internal and will be changed in 'skipped'
3736
+ $p_entry['status'] = "aborted";
3737
+ $v_result = PCLZIP_ERR_USER_ABORTED;
3738
+ }
3739
+
3740
+ // ----- Update the informations
3741
+ // Only some fields can be modified
3742
+ $p_entry['filename'] = $v_local_header['filename'];
3743
+ }
3744
+
3745
+
3746
+ // ----- Look if extraction should be done
3747
+ if ($p_entry['status'] == 'ok') {
3748
+
3749
+ // ----- Look for specific actions while the file exist
3750
+ if (file_exists($p_entry['filename']))
3751
+ {
3752
+
3753
+ // ----- Look if file is a directory
3754
+ if (is_dir($p_entry['filename']))
3755
+ {
3756
+
3757
+ // ----- Change the file status
3758
+ $p_entry['status'] = "already_a_directory";
3759
+
3760
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3761
+ // For historical reason first PclZip implementation does not stop
3762
+ // when this kind of error occurs.
3763
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3764
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3765
+
3766
+ IWPPclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
3767
+ "Filename '".$p_entry['filename']."' is "
3768
+ ."already used by an existing directory");
3769
+
3770
+ return IWPPclZip::errorCode();
3771
+ }
3772
+ }
3773
+ // ----- Look if file is write protected
3774
+ else if (!is_writeable($p_entry['filename']))
3775
+ {
3776
+
3777
+ // ----- Change the file status
3778
+ $p_entry['status'] = "write_protected";
3779
+
3780
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3781
+ // For historical reason first PclZip implementation does not stop
3782
+ // when this kind of error occurs.
3783
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3784
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3785
+
3786
+ IWPPclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3787
+ "Filename '".$p_entry['filename']."' exists "
3788
+ ."and is write protected");
3789
+
3790
+ return IWPPclZip::errorCode();
3791
+ }
3792
+ }
3793
+
3794
+ // ----- Look if the extracted file is older
3795
+ else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
3796
+ {
3797
+ // ----- Change the file status
3798
+ if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
3799
+ && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
3800
+ }
3801
+ else {
3802
+ $p_entry['status'] = "newer_exist";
3803
+
3804
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3805
+ // For historical reason first PclZip implementation does not stop
3806
+ // when this kind of error occurs.
3807
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3808
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3809
+
3810
+ IWPPclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3811
+ "Newer version of '".$p_entry['filename']."' exists "
3812
+ ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
3813
+
3814
+ return IWPPclZip::errorCode();
3815
+ }
3816
+ }
3817
+ }
3818
+ else {
3819
+ }
3820
+ }
3821
+
3822
+ // ----- Check the directory availability and create it if necessary
3823
+ else {
3824
+ if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
3825
+ $v_dir_to_check = $p_entry['filename'];
3826
+ else if (!strstr($p_entry['filename'], "/"))
3827
+ $v_dir_to_check = "";
3828
+ else
3829
+ $v_dir_to_check = dirname($p_entry['filename']);
3830
+
3831
+ if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
3832
+
3833
+ // ----- Change the file status
3834
+ $p_entry['status'] = "path_creation_fail";
3835
+
3836
+ // ----- Return
3837
+ //return $v_result;
3838
+ $v_result = 1;
3839
+ }
3840
+ }
3841
+ }
3842
+
3843
+ // ----- Look if extraction should be done
3844
+ if ($p_entry['status'] == 'ok') {
3845
+
3846
+ // ----- Do the extraction (if not a folder)
3847
+ if (!(($p_entry['external']&0x00000010)==0x00000010))
3848
+ {
3849
+ // ----- Look for not compressed file
3850
+ if ($p_entry['compression'] == 0) {
3851
+
3852
+ // ----- Opening destination file
3853
+ if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
3854
+ {
3855
+
3856
+ // ----- Change the file status
3857
+ $p_entry['status'] = "write_error";
3858
+
3859
+ // ----- Return
3860
+ return $v_result;
3861
+ }
3862
+
3863
+
3864
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3865
+ $v_size = $p_entry['compressed_size'];
3866
+ while ($v_size != 0)
3867
+ {
3868
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3869
+ $v_buffer = @fread($this->zip_fd, $v_read_size);
3870
+ /* Try to speed up the code
3871
+ $v_binary_data = pack('a'.$v_read_size, $v_buffer);
3872
+ @fwrite($v_dest_file, $v_binary_data, $v_read_size);
3873
+ */
3874
+ @fwrite($v_dest_file, $v_buffer, $v_read_size);
3875
+ $v_size -= $v_read_size;
3876
+ }
3877
+
3878
+ // ----- Closing the destination file
3879
+ fclose($v_dest_file);
3880
+
3881
+ // ----- Change the file mtime
3882
+ touch($p_entry['filename'], $p_entry['mtime']);
3883
+
3884
+
3885
+ }
3886
+ else {
3887
+ // ----- TBC
3888
+ // Need to be finished
3889
+ if (($p_entry['flag'] & 1) == 1) {
3890
+ IWPPclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
3891
+ return IWPPclZip::errorCode();
3892
+ }
3893
+
3894
+
3895
+ // ----- Look for using temporary file to unzip
3896
+ if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
3897
+ && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
3898
+ || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
3899
+ && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
3900
+ $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
3901
+ if ($v_result < PCLZIP_ERR_NO_ERROR) {
3902
+ return $v_result;
3903
+ }
3904
+ }
3905
+
3906
+ // ----- Look for extract in memory
3907
+ else {
3908
+
3909
+
3910
+ // ----- Read the compressed file in a buffer (one shot)
3911
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3912
+
3913
+ // ----- Decompress the file
3914
+ $v_file_content = @gzinflate($v_buffer);
3915
+ unset($v_buffer);
3916
+ if ($v_file_content === FALSE) {
3917
+
3918
+ // ----- Change the file status
3919
+ // TBC
3920
+ $p_entry['status'] = "error";
3921
+
3922
+ return $v_result;
3923
+ }
3924
+
3925
+ // ----- Opening destination file
3926
+ if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3927
+
3928
+ // ----- Change the file status
3929
+ $p_entry['status'] = "write_error";
3930
+
3931
+ return $v_result;
3932
+ }
3933
+
3934
+ // ----- Write the uncompressed data
3935
+ @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
3936
+ unset($v_file_content);
3937
+
3938
+ // ----- Closing the destination file
3939
+ @fclose($v_dest_file);
3940
+
3941
+ }
3942
+
3943
+ // ----- Change the file mtime
3944
+ @touch($p_entry['filename'], $p_entry['mtime']);
3945
+ }
3946
+
3947
+ // ----- Look for chmod option
3948
+ if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
3949
+
3950
+ // ----- Change the mode of the file
3951
+ @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
3952
+ }
3953
+
3954
+ }
3955
+ }
3956
+
3957
+ // ----- Change abort status
3958
+ if ($p_entry['status'] == "aborted") {
3959
+ $p_entry['status'] = "skipped";
3960
+ }
3961
+
3962
+ // ----- Look for post-extract callback
3963
+ elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3964
+
3965
+ // ----- Generate a local information
3966
+ $v_local_header = array();
3967
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3968
+
3969
+ // ----- Call the callback
3970
+ // Here I do not use call_user_func() because I need to send a reference to the
3971
+ // header.
3972
+ $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
3973
+
3974
+ // ----- Look for abort result
3975
+ if ($v_result == 2) {
3976
+ $v_result = PCLZIP_ERR_USER_ABORTED;
3977
+ }
3978
+ }
3979
+
3980
+ // ----- Return
3981
+ return $v_result;
3982
+ }
3983
+ // --------------------------------------------------------------------------------
3984
+
3985
+ // --------------------------------------------------------------------------------
3986
+ // Function : privExtractFileUsingTempFile()
3987
+ // Description :
3988
+ // Parameters :
3989
+ // Return Values :
3990
+ // --------------------------------------------------------------------------------
3991
+ function privExtractFileUsingTempFile(&$p_entry, &$p_options)
3992
+ {
3993
+ $v_result=1;
3994
+
3995
+ // ----- Creates a temporary file
3996
+ $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
3997
+ if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
3998
+ fclose($v_file);
3999
+ IWPPclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
4000
+ return IWPPclZip::errorCode();
4001
+ }
4002
+
4003
+
4004
+ // ----- Write gz file format header
4005
+ $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
4006
+ @fwrite($v_dest_file, $v_binary_data, 10);
4007
+
4008
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
4009
+ $v_size = $p_entry['compressed_size'];
4010
+ while ($v_size != 0)
4011
+ {
4012
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4013
+ $v_buffer = @fread($this->zip_fd, $v_read_size);
4014
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
4015
+ @fwrite($v_dest_file, $v_buffer, $v_read_size);
4016
+ $v_size -= $v_read_size;
4017
+ }
4018
+
4019
+ // ----- Write gz file format footer
4020
+ $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
4021
+ @fwrite($v_dest_file, $v_binary_data, 8);
4022
+
4023
+ // ----- Close the temporary file
4024
+ @fclose($v_dest_file);
4025
+
4026
+ // ----- Opening destination file
4027
+ if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
4028
+ $p_entry['status'] = "write_error";
4029
+ return $v_result;
4030
+ }
4031
+
4032
+ // ----- Open the temporary gz file
4033
+ if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
4034
+ @fclose($v_dest_file);
4035
+ $p_entry['status'] = "read_error";
4036
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
4037
+ return IWPPclZip::errorCode();
4038
+ }
4039
+
4040
+
4041
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
4042
+ $v_size = $p_entry['size'];
4043
+ while ($v_size != 0) {
4044
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4045
+ $v_buffer = @gzread($v_src_file, $v_read_size);
4046
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
4047
+ @fwrite($v_dest_file, $v_buffer, $v_read_size);
4048
+ $v_size -= $v_read_size;
4049
+ }
4050
+ @fclose($v_dest_file);
4051
+ @gzclose($v_src_file);
4052
+
4053
+ // ----- Delete the temporary file
4054
+ @unlink($v_gzip_temp_name);
4055
+
4056
+ // ----- Return
4057
+ return $v_result;
4058
+ }
4059
+ // --------------------------------------------------------------------------------
4060
+
4061
+ // --------------------------------------------------------------------------------
4062
+ // Function : privExtractFileInOutput()
4063
+ // Description :
4064
+ // Parameters :
4065
+ // Return Values :
4066
+ // --------------------------------------------------------------------------------
4067
+ function privExtractFileInOutput(&$p_entry, &$p_options)
4068
+ {
4069
+ $v_result=1;
4070
+
4071
+ // ----- Read the file header
4072
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
4073
+ return $v_result;
4074
+ }
4075
+
4076
+
4077
+ // ----- Check that the file header is coherent with $p_entry info
4078
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
4079
+ // TBC
4080
+ }
4081
+
4082
+ // ----- Look for pre-extract callback
4083
+ if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4084
+
4085
+ // ----- Generate a local information
4086
+ $v_local_header = array();
4087
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4088
+
4089
+ // ----- Call the callback
4090
+ // Here I do not use call_user_func() because I need to send a reference to the
4091
+ // header.
4092
+ // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
4093
+ $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4094
+ if ($v_result == 0) {
4095
+ // ----- Change the file status
4096
+ $p_entry['status'] = "skipped";
4097
+ $v_result = 1;
4098
+ }
4099
+
4100
+ // ----- Look for abort result
4101
+ if ($v_result == 2) {
4102
+ // ----- This status is internal and will be changed in 'skipped'
4103
+ $p_entry['status'] = "aborted";
4104
+ $v_result = PCLZIP_ERR_USER_ABORTED;
4105
+ }
4106
+
4107
+ // ----- Update the informations
4108
+ // Only some fields can be modified
4109
+ $p_entry['filename'] = $v_local_header['filename'];
4110
+ }
4111
+
4112
+ // ----- Trace
4113
+
4114
+ // ----- Look if extraction should be done
4115
+ if ($p_entry['status'] == 'ok') {
4116
+
4117
+ // ----- Do the extraction (if not a folder)
4118
+ if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4119
+ // ----- Look for not compressed file
4120
+ if ($p_entry['compressed_size'] == $p_entry['size']) {
4121
+
4122
+ // ----- Read the file in a buffer (one shot)
4123
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4124
+
4125
+ // ----- Send the file to the output
4126
+ echo $v_buffer;
4127
+ unset($v_buffer);
4128
+ }
4129
+ else {
4130
+
4131
+ // ----- Read the compressed file in a buffer (one shot)
4132
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4133
+
4134
+ // ----- Decompress the file
4135
+ $v_file_content = gzinflate($v_buffer);
4136
+ unset($v_buffer);
4137
+
4138
+ // ----- Send the file to the output
4139
+ echo $v_file_content;
4140
+ unset($v_file_content);
4141
+ }
4142
+ }
4143
+ }
4144
+
4145
+ // ----- Change abort status
4146
+ if ($p_entry['status'] == "aborted") {
4147
+ $p_entry['status'] = "skipped";
4148
+ }
4149
+
4150
+ // ----- Look for post-extract callback
4151
+ elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4152
+
4153
+ // ----- Generate a local information
4154
+ $v_local_header = array();
4155
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4156
+
4157
+ // ----- Call the callback
4158
+ // Here I do not use call_user_func() because I need to send a reference to the
4159
+ // header.
4160
+ $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4161
+
4162
+ // ----- Look for abort result
4163
+ if ($v_result == 2) {
4164
+ $v_result = PCLZIP_ERR_USER_ABORTED;
4165
+ }
4166
+ }
4167
+
4168
+ return $v_result;
4169
+ }
4170
+ // --------------------------------------------------------------------------------
4171
+
4172
+ // --------------------------------------------------------------------------------
4173
+ // Function : privExtractFileAsString()
4174
+ // Description :
4175
+ // Parameters :
4176
+ // Return Values :
4177
+ // --------------------------------------------------------------------------------
4178
+ function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
4179
+ {
4180
+ $v_result=1;
4181
+
4182
+ // ----- Read the file header
4183
+ $v_header = array();
4184
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1)
4185
+ {
4186
+ // ----- Return
4187
+ return $v_result;
4188
+ }
4189
+
4190
+
4191
+ // ----- Check that the file header is coherent with $p_entry info
4192
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
4193
+ // TBC
4194
+ }
4195
+
4196
+ // ----- Look for pre-extract callback
4197
+ if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4198
+
4199
+ // ----- Generate a local information
4200
+ $v_local_header = array();
4201
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4202
+
4203
+ // ----- Call the callback
4204
+ // Here I do not use call_user_func() because I need to send a reference to the
4205
+ // header.
4206
+ $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4207
+ if ($v_result == 0) {
4208
+ // ----- Change the file status
4209
+ $p_entry['status'] = "skipped";
4210
+ $v_result = 1;
4211
+ }
4212
+
4213
+ // ----- Look for abort result
4214
+ if ($v_result == 2) {
4215
+ // ----- This status is internal and will be changed in 'skipped'
4216
+ $p_entry['status'] = "aborted";
4217
+ $v_result = PCLZIP_ERR_USER_ABORTED;
4218
+ }
4219
+
4220
+ // ----- Update the informations
4221
+ // Only some fields can be modified
4222
+ $p_entry['filename'] = $v_local_header['filename'];
4223
+ }
4224
+
4225
+
4226
+ // ----- Look if extraction should be done
4227
+ if ($p_entry['status'] == 'ok') {
4228
+
4229
+ // ----- Do the extraction (if not a folder)
4230
+ if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4231
+ // ----- Look for not compressed file
4232
+ // if ($p_entry['compressed_size'] == $p_entry['size'])
4233
+ if ($p_entry['compression'] == 0) {
4234
+
4235
+ // ----- Reading the file
4236
+ $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
4237
+ }
4238
+ else {
4239
+
4240
+ // ----- Reading the file
4241
+ $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
4242
+
4243
+ // ----- Decompress the file
4244
+ if (($p_string = @gzinflate($v_data)) === FALSE) {
4245
+ // TBC
4246
+ }
4247
+ }
4248
+
4249
+ // ----- Trace
4250
+ }
4251
+ else {
4252
+ // TBC : error : can not extract a folder in a string
4253
+ }
4254
+
4255
+ }
4256
+
4257
+ // ----- Change abort status
4258
+ if ($p_entry['status'] == "aborted") {
4259
+ $p_entry['status'] = "skipped";
4260
+ }
4261
+
4262
+ // ----- Look for post-extract callback
4263
+ elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4264
+
4265
+ // ----- Generate a local information
4266
+ $v_local_header = array();
4267
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4268
+
4269
+ // ----- Swap the content to header
4270
+ $v_local_header['content'] = $p_string;
4271
+ $p_string = '';
4272
+
4273
+ // ----- Call the callback
4274
+ // Here I do not use call_user_func() because I need to send a reference to the
4275
+ // header.
4276
+ $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4277
+
4278
+ // ----- Swap back the content to header
4279
+ $p_string = $v_local_header['content'];
4280
+ unset($v_local_header['content']);
4281
+
4282
+ // ----- Look for abort result
4283
+ if ($v_result == 2) {
4284
+ $v_result = PCLZIP_ERR_USER_ABORTED;
4285
+ }
4286
+ }
4287
+
4288
+ // ----- Return
4289
+ return $v_result;
4290
+ }
4291
+ // --------------------------------------------------------------------------------
4292
+
4293
+ // --------------------------------------------------------------------------------
4294
+ // Function : privReadFileHeader()
4295
+ // Description :
4296
+ // Parameters :
4297
+ // Return Values :
4298
+ // --------------------------------------------------------------------------------
4299
+ function privReadFileHeader(&$p_header)
4300
+ {
4301
+ $v_result=1;
4302
+
4303
+ // ----- Read the 4 bytes signature
4304
+ $v_binary_data = @fread($this->zip_fd, 4);
4305
+ $v_data = unpack('Vid', $v_binary_data);
4306
+
4307
+ // ----- Check signature
4308
+ if ($v_data['id'] != 0x04034b50)
4309
+ {
4310
+
4311
+ // ----- Error log
4312
+ IWPPclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4313
+
4314
+ // ----- Return
4315
+ return IWPPclZip::errorCode();
4316
+ }
4317
+
4318
+ // ----- Read the first 42 bytes of the header
4319
+ $v_binary_data = fread($this->zip_fd, 26);
4320
+
4321
+ // ----- Look for invalid block size
4322
+ if (strlen($v_binary_data) != 26)
4323
+ {
4324
+ $p_header['filename'] = "";
4325
+ $p_header['status'] = "invalid_header";
4326
+
4327
+ // ----- Error log
4328
+ IWPPclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4329
+
4330
+ // ----- Return
4331
+ return IWPPclZip::errorCode();
4332
+ }
4333
+
4334
+ // ----- Extract the values
4335
+ $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
4336
+
4337
+ // ----- Get filename
4338
+ $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
4339
+
4340
+ // ----- Get extra_fields
4341
+ if ($v_data['extra_len'] != 0) {
4342
+ $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
4343
+ }
4344
+ else {
4345
+ $p_header['extra'] = '';
4346
+ }
4347
+
4348
+ // ----- Extract properties
4349
+ $p_header['version_extracted'] = $v_data['version'];
4350
+ $p_header['compression'] = $v_data['compression'];
4351
+ $p_header['size'] = $v_data['size'];
4352
+ $p_header['compressed_size'] = $v_data['compressed_size'];
4353
+ $p_header['crc'] = $v_data['crc'];
4354
+ $p_header['flag'] = $v_data['flag'];
4355
+ $p_header['filename_len'] = $v_data['filename_len'];
4356
+
4357
+ // ----- Recuperate date in UNIX format
4358
+ $p_header['mdate'] = $v_data['mdate'];
4359
+ $p_header['mtime'] = $v_data['mtime'];
4360
+ if ($p_header['mdate'] && $p_header['mtime'])
4361
+ {
4362
+ // ----- Extract time
4363
+ $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4364
+ $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4365
+ $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4366
+
4367
+ // ----- Extract date
4368
+ $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4369
+ $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4370
+ $v_day = $p_header['mdate'] & 0x001F;
4371
+
4372
+ // ----- Get UNIX date format
4373
+ $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4374
+
4375
+ }
4376
+ else
4377
+ {
4378
+ $p_header['mtime'] = time();
4379
+ }
4380
+
4381
+ // TBC
4382
+ //for(reset($v_data); $key = key($v_data); next($v_data)) {
4383
+ //}
4384
+
4385
+ // ----- Set the stored filename
4386
+ $p_header['stored_filename'] = $p_header['filename'];
4387
+
4388
+ // ----- Set the status field
4389
+ $p_header['status'] = "ok";
4390
+
4391
+ // ----- Return
4392
+ return $v_result;
4393
+ }
4394
+ // --------------------------------------------------------------------------------
4395
+
4396
+ // --------------------------------------------------------------------------------
4397
+ // Function : privReadCentralFileHeader()
4398
+ // Description :
4399
+ // Parameters :
4400
+ // Return Values :
4401
+ // --------------------------------------------------------------------------------
4402
+ function privReadCentralFileHeader(&$p_header)
4403
+ {
4404
+ $v_result=1;
4405
+
4406
+ // ----- Read the 4 bytes signature
4407
+ $v_binary_data = @fread($this->zip_fd, 4);
4408
+ $v_data = unpack('Vid', $v_binary_data);
4409
+
4410
+ // ----- Check signature
4411
+ if ($v_data['id'] != 0x02014b50)
4412
+ {
4413
+
4414
+ // ----- Error log
4415
+ IWPPclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4416
+
4417
+ // ----- Return
4418
+ return IWPPclZip::errorCode();
4419
+ }
4420
+
4421
+ // ----- Read the first 42 bytes of the header
4422
+ $v_binary_data = fread($this->zip_fd, 42);
4423
+
4424
+ // ----- Look for invalid block size
4425
+ if (strlen($v_binary_data) != 42)
4426
+ {
4427
+ $p_header['filename'] = "";
4428
+ $p_header['status'] = "invalid_header";
4429
+
4430
+ // ----- Error log
4431
+ IWPPclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4432
+
4433
+ // ----- Return
4434
+ return IWPPclZip::errorCode();
4435
+ }
4436
+
4437
+ // ----- Extract the values
4438
+ $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
4439
+
4440
+ // ----- Get filename
4441
+ if ($p_header['filename_len'] != 0)
4442
+ $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
4443
+ else
4444
+ $p_header['filename'] = '';
4445
+
4446
+ // ----- Get extra
4447
+ if ($p_header['extra_len'] != 0)
4448
+ $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
4449
+ else
4450
+ $p_header['extra'] = '';
4451
+
4452
+ // ----- Get comment
4453
+ if ($p_header['comment_len'] != 0)
4454
+ $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
4455
+ else
4456
+ $p_header['comment'] = '';
4457
+
4458
+ // ----- Extract properties
4459
+
4460
+ // ----- Recuperate date in UNIX format
4461
+ //if ($p_header['mdate'] && $p_header['mtime'])
4462
+ // TBC : bug : this was ignoring time with 0/0/0
4463
+ if (1)
4464
+ {
4465
+ // ----- Extract time
4466
+ $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4467
+ $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4468
+ $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4469
+
4470
+ // ----- Extract date
4471
+ $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4472
+ $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4473
+ $v_day = $p_header['mdate'] & 0x001F;
4474
+
4475
+ // ----- Get UNIX date format
4476
+ $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4477
+
4478
+ }
4479
+ else
4480
+ {
4481
+ $p_header['mtime'] = time();
4482
+ }
4483
+
4484
+ // ----- Set the stored filename
4485
+ $p_header['stored_filename'] = $p_header['filename'];
4486
+
4487
+ // ----- Set default status to ok
4488
+ $p_header['status'] = 'ok';
4489
+
4490
+ // ----- Look if it is a directory
4491
+ if (substr($p_header['filename'], -1) == '/') {
4492
+ //$p_header['external'] = 0x41FF0010;
4493
+ $p_header['external'] = 0x00000010;
4494
+ }
4495
+
4496
+
4497
+ // ----- Return
4498
+ return $v_result;
4499
+ }
4500
+ // --------------------------------------------------------------------------------
4501
+
4502
+ // --------------------------------------------------------------------------------
4503
+ // Function : privCheckFileHeaders()
4504
+ // Description :
4505
+ // Parameters :
4506
+ // Return Values :
4507
+ // 1 on success,
4508
+ // 0 on error;
4509
+ // --------------------------------------------------------------------------------
4510
+ function privCheckFileHeaders(&$p_local_header, &$p_central_header)
4511
+ {
4512
+ $v_result=1;
4513
+
4514
+ // ----- Check the static values
4515
+ // TBC
4516
+ if ($p_local_header['filename'] != $p_central_header['filename']) {
4517
+ }
4518
+ if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
4519
+ }
4520
+ if ($p_local_header['flag'] != $p_central_header['flag']) {
4521
+ }
4522
+ if ($p_local_header['compression'] != $p_central_header['compression']) {
4523
+ }
4524
+ if ($p_local_header['mtime'] != $p_central_header['mtime']) {
4525
+ }
4526
+ if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
4527
+ }
4528
+
4529
+ // ----- Look for flag bit 3
4530
+ if (($p_local_header['flag'] & 8) == 8) {
4531
+ $p_local_header['size'] = $p_central_header['size'];
4532
+ $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
4533
+ $p_local_header['crc'] = $p_central_header['crc'];
4534
+ }
4535
+
4536
+ // ----- Return
4537
+ return $v_result;
4538
+ }
4539
+ // --------------------------------------------------------------------------------
4540
+
4541
+ // --------------------------------------------------------------------------------
4542
+ // Function : privReadEndCentralDir()
4543
+ // Description :
4544
+ // Parameters :
4545
+ // Return Values :
4546
+ // --------------------------------------------------------------------------------
4547
+ function privReadEndCentralDir(&$p_central_dir)
4548
+ {
4549
+ $v_result=1;
4550
+
4551
+ // ----- Go to the end of the zip file
4552
+ $v_size = filesize($this->zipname);
4553
+ @fseek($this->zip_fd, $v_size);
4554
+ if (@ftell($this->zip_fd) != $v_size)
4555
+ {
4556
+ // ----- Error log
4557
+ IWPPclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
4558
+
4559
+ // ----- Return
4560
+ return IWPPclZip::errorCode();
4561
+ }
4562
+
4563
+ // ----- First try : look if this is an archive with no commentaries (most of the time)
4564
+ // in this case the end of central dir is at 22 bytes of the file end
4565
+ $v_found = 0;
4566
+ if ($v_size > 26) {
4567
+ @fseek($this->zip_fd, $v_size-22);
4568
+ if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
4569
+ {
4570
+ // ----- Error log
4571
+ IWPPclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4572
+
4573
+ // ----- Return
4574
+ return IWPPclZip::errorCode();
4575
+ }
4576
+
4577
+ // ----- Read for bytes
4578
+ $v_binary_data = @fread($this->zip_fd, 4);
4579
+ $v_data = @unpack('Vid', $v_binary_data);
4580
+
4581
+ // ----- Check signature
4582
+ if ($v_data['id'] == 0x06054b50) {
4583
+ $v_found = 1;
4584
+ }
4585
+
4586
+ $v_pos = ftell($this->zip_fd);
4587
+ }
4588
+
4589
+ // ----- Go back to the maximum possible size of the Central Dir End Record
4590
+ if (!$v_found) {
4591
+ $v_maximum_size = 65557; // 0xFFFF + 22;
4592
+ if ($v_maximum_size > $v_size)
4593
+ $v_maximum_size = $v_size;
4594
+ @fseek($this->zip_fd, $v_size-$v_maximum_size);
4595
+ if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
4596
+ {
4597
+ // ----- Error log
4598
+ IWPPclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4599
+
4600
+ // ----- Return
4601
+ return IWPPclZip::errorCode();
4602
+ }
4603
+
4604
+ // ----- Read byte per byte in order to find the signature
4605
+ $v_pos = ftell($this->zip_fd);
4606
+ $v_bytes = 0x00000000;
4607
+ while ($v_pos < $v_size)
4608
+ {
4609
+ // ----- Read a byte
4610
+ $v_byte = @fread($this->zip_fd, 1);
4611
+
4612
+ // ----- Add the byte
4613
+ //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
4614
+ // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
4615
+ // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
4616
+ $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
4617
+
4618
+ // ----- Compare the bytes
4619
+ if ($v_bytes == 0x504b0506)
4620
+ {
4621
+ $v_pos++;
4622
+ break;
4623
+ }
4624
+
4625
+ $v_pos++;
4626
+ }
4627
+
4628
+ // ----- Look if not found end of central dir
4629
+ if ($v_pos == $v_size)
4630
+ {
4631
+
4632
+ // ----- Error log
4633
+ IWPPclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
4634
+
4635
+ // ----- Return
4636
+ return IWPPclZip::errorCode();
4637
+ }
4638
+ }
4639
+
4640
+ // ----- Read the first 18 bytes of the header
4641
+ $v_binary_data = fread($this->zip_fd, 18);
4642
+
4643
+ // ----- Look for invalid block size
4644
+ if (strlen($v_binary_data) != 18)
4645
+ {
4646
+
4647
+ // ----- Error log
4648
+ IWPPclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
4649
+
4650
+ // ----- Return
4651
+ return IWPPclZip::errorCode();
4652
+ }
4653
+
4654
+ // ----- Extract the values
4655
+ $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
4656
+
4657
+ // ----- Check the global size
4658
+ if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
4659
+
4660
+ // ----- Removed in release 2.2 see readme file
4661
+ // The check of the file size is a little too strict.
4662
+ // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
4663
+ // While decrypted, zip has training 0 bytes
4664
+ if (0) {
4665
+ // ----- Error log
4666
+ IWPPclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
4667
+ 'The central dir is not at the end of the archive.'
4668
+ .' Some trailing bytes exists after the archive.');
4669
+
4670
+ // ----- Return
4671
+ return IWPPclZip::errorCode();
4672
+ }
4673
+ }
4674
+
4675
+ // ----- Get comment
4676
+ if ($v_data['comment_size'] != 0) {
4677
+ $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
4678
+ }
4679
+ else
4680
+ $p_central_dir['comment'] = '';
4681
+
4682
+ $p_central_dir['entries'] = $v_data['entries'];
4683
+ $p_central_dir['disk_entries'] = $v_data['disk_entries'];
4684
+ $p_central_dir['offset'] = $v_data['offset'];
4685
+ $p_central_dir['size'] = $v_data['size'];
4686
+ $p_central_dir['disk'] = $v_data['disk'];
4687
+ $p_central_dir['disk_start'] = $v_data['disk_start'];
4688
+
4689
+ // TBC
4690
+ //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
4691
+ //}
4692
+
4693
+ // ----- Return
4694
+ return $v_result;
4695
+ }
4696
+ // --------------------------------------------------------------------------------
4697
+
4698
+ // --------------------------------------------------------------------------------
4699
+ // Function : privDeleteByRule()
4700
+ // Description :
4701
+ // Parameters :
4702
+ // Return Values :
4703
+ // --------------------------------------------------------------------------------
4704
+ function privDeleteByRule(&$p_result_list, &$p_options)
4705
+ {
4706
+ $v_result=1;
4707
+ $v_list_detail = array();
4708
+
4709
+ // ----- Open the zip file
4710
+ if (($v_result=$this->privOpenFd('rb')) != 1)
4711
+ {
4712
+ // ----- Return
4713
+ return $v_result;
4714
+ }
4715
+
4716
+ // ----- Read the central directory informations
4717
+ $v_central_dir = array();
4718
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
4719
+ {
4720
+ $this->privCloseFd();
4721
+ return $v_result;
4722
+ }
4723
+
4724
+ // ----- Go to beginning of File
4725
+ @rewind($this->zip_fd);
4726
+
4727
+ // ----- Scan all the files
4728
+ // ----- Start at beginning of Central Dir
4729
+ $v_pos_entry = $v_central_dir['offset'];
4730
+ @rewind($this->zip_fd);
4731
+ if (@fseek($this->zip_fd, $v_pos_entry))
4732
+ {
4733
+ // ----- Close the zip file
4734
+ $this->privCloseFd();
4735
+
4736
+ // ----- Error log
4737
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4738
+
4739
+ // ----- Return
4740
+ return IWPPclZip::errorCode();
4741
+ }
4742
+
4743
+ // ----- Read each entry
4744
+ $v_header_list = array();
4745
+ $j_start = 0;
4746
+ for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
4747
+ {
4748
+
4749
+ // ----- Read the file header
4750
+ $v_header_list[$v_nb_extracted] = array();
4751
+ if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
4752
+ {
4753
+ // ----- Close the zip file
4754
+ $this->privCloseFd();
4755
+
4756
+ return $v_result;
4757
+ }
4758
+
4759
+
4760
+ // ----- Store the index
4761
+ $v_header_list[$v_nb_extracted]['index'] = $i;
4762
+
4763
+ // ----- Look for the specific extract rules
4764
+ $v_found = false;
4765
+
4766
+ // ----- Look for extract by name rule
4767
+ if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
4768
+ && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
4769
+
4770
+ // ----- Look if the filename is in the list
4771
+ for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
4772
+
4773
+ // ----- Look for a directory
4774
+ if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
4775
+
4776
+ // ----- Look if the directory is in the filename path
4777
+ if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
4778
+ && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4779
+ $v_found = true;
4780
+ }
4781
+ elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
4782
+ && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4783
+ $v_found = true;
4784
+ }
4785
+ }
4786
+ // ----- Look for a filename
4787
+ elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
4788
+ $v_found = true;
4789
+ }
4790
+ }
4791
+ }
4792
+
4793
+ // ----- Look for extract by ereg rule
4794
+ // ereg() is deprecated with PHP 5.3
4795
+ /*
4796
+ else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
4797
+ && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
4798
+
4799
+ if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4800
+ $v_found = true;
4801
+ }
4802
+ }
4803
+ */
4804
+
4805
+ // ----- Look for extract by preg rule
4806
+ else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
4807
+ && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
4808
+
4809
+ if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4810
+ $v_found = true;
4811
+ }
4812
+ }
4813
+
4814
+ // ----- Look for extract by index rule
4815
+ else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
4816
+ && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
4817
+
4818
+ // ----- Look if the index is in the list
4819
+ for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
4820
+
4821
+ if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
4822
+ $v_found = true;
4823
+ }
4824
+ if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
4825
+ $j_start = $j+1;
4826
+ }
4827
+
4828
+ if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
4829
+ break;
4830
+ }
4831
+ }
4832
+ }
4833
+ else {
4834
+ $v_found = true;
4835
+ }
4836
+
4837
+ // ----- Look for deletion
4838
+ if ($v_found)
4839
+ {
4840
+ unset($v_header_list[$v_nb_extracted]);
4841
+ }
4842
+ else
4843
+ {
4844
+ $v_nb_extracted++;
4845
+ }
4846
+ }
4847
+
4848
+ // ----- Look if something need to be deleted
4849
+ if ($v_nb_extracted > 0) {
4850
+
4851
+ // ----- Creates a temporay file
4852
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
4853
+
4854
+ // ----- Creates a temporary zip archive
4855
+ $v_temp_zip = new PclZip($v_zip_temp_name);
4856
+
4857
+ // ----- Open the temporary zip file in write mode
4858
+ if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
4859
+ $this->privCloseFd();
4860
+
4861
+ // ----- Return
4862
+ return $v_result;
4863
+ }
4864
+
4865
+ // ----- Look which file need to be kept
4866
+ for ($i=0; $i<sizeof($v_header_list); $i++) {
4867
+
4868
+ // ----- Calculate the position of the header
4869
+ @rewind($this->zip_fd);
4870
+ if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
4871
+ // ----- Close the zip file
4872
+ $this->privCloseFd();
4873
+ $v_temp_zip->privCloseFd();
4874
+ @unlink($v_zip_temp_name);
4875
+
4876
+ // ----- Error log
4877
+ IWPPclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4878
+
4879
+ // ----- Return
4880
+ return IWPPclZip::errorCode();
4881
+ }
4882
+
4883
+ // ----- Read the file header
4884
+ $v_local_header = array();
4885
+ if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
4886
+ // ----- Close the zip file
4887
+ $this->privCloseFd();
4888
+ $v_temp_zip->privCloseFd();
4889
+ @unlink($v_zip_temp_name);
4890
+
4891
+ // ----- Return
4892
+ return $v_result;
4893
+ }
4894
+
4895
+ // ----- Check that local file header is same as central file header
4896
+ if ($this->privCheckFileHeaders($v_local_header,
4897
+ $v_header_list[$i]) != 1) {
4898
+ // TBC
4899
+ }
4900
+ unset($v_local_header);
4901
+
4902
+ // ----- Write the file header
4903
+ if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
4904
+ // ----- Close the zip file
4905
+ $this->privCloseFd();
4906
+ $v_temp_zip->privCloseFd();
4907
+ @unlink($v_zip_temp_name);
4908
+
4909
+ // ----- Return
4910
+ return $v_result;
4911
+ }
4912
+
4913
+ // ----- Read/write the data block
4914
+ if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
4915
+ // ----- Close the zip file
4916
+ $this->privCloseFd();
4917
+ $v_temp_zip->privCloseFd();
4918
+ @unlink($v_zip_temp_name);
4919
+
4920
+ // ----- Return
4921
+ return $v_result;
4922
+ }
4923
+ }
4924
+
4925
+ // ----- Store the offset of the central dir
4926
+ $v_offset = @ftell($v_temp_zip->zip_fd);
4927
+
4928
+ // ----- Re-Create the Central Dir files header
4929
+ for ($i=0; $i<sizeof($v_header_list); $i++) {
4930
+ // ----- Create the file header
4931
+ if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
4932
+ $v_temp_zip->privCloseFd();
4933
+ $this->privCloseFd();
4934
+ @unlink($v_zip_temp_name);
4935
+
4936
+ // ----- Return
4937
+ return $v_result;
4938
+ }
4939
+
4940
+ // ----- Transform the header to a 'usable' info
4941
+ $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
4942
+ }
4943
+
4944
+
4945
+ // ----- Zip file comment
4946
+ $v_comment = '';
4947
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
4948
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
4949
+ }
4950
+
4951
+ // ----- Calculate the size of the central header
4952
+ $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
4953
+
4954
+ // ----- Create the central dir footer
4955
+ if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
4956
+ // ----- Reset the file list
4957
+ unset($v_header_list);
4958
+ $v_temp_zip->privCloseFd();
4959
+ $this->privCloseFd();
4960
+ @unlink($v_zip_temp_name);
4961
+
4962
+ // ----- Return
4963
+ return $v_result;
4964
+ }
4965
+
4966
+ // ----- Close
4967
+ $v_temp_zip->privCloseFd();
4968
+ $this->privCloseFd();
4969
+
4970
+ // ----- Delete the zip file
4971
+ // TBC : I should test the result ...
4972
+ @unlink($this->zipname);
4973
+
4974
+ // ----- Rename the temporary file
4975
+ // TBC : I should test the result ...
4976
+ //@rename($v_zip_temp_name, $this->zipname);
4977
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
4978
+
4979
+ // ----- Destroy the temporary archive
4980
+ unset($v_temp_zip);
4981
+ }
4982
+
4983
+ // ----- Remove every files : reset the file
4984
+ else if ($v_central_dir['entries'] != 0) {
4985
+ $this->privCloseFd();
4986
+
4987
+ if (($v_result = $this->privOpenFd('wb')) != 1) {
4988
+ return $v_result;
4989
+ }
4990
+
4991
+ if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
4992
+ return $v_result;
4993
+ }
4994
+
4995
+ $this->privCloseFd();
4996
+ }
4997
+
4998
+ // ----- Return
4999
+ return $v_result;
5000
+ }
5001
+ // --------------------------------------------------------------------------------
5002
+
5003
+ // --------------------------------------------------------------------------------
5004
+ // Function : privDirCheck()
5005
+ // Description :
5006
+ // Check if a directory exists, if not it creates it and all the parents directory
5007
+ // which may be useful.
5008
+ // Parameters :
5009
+ // $p_dir : Directory path to check.
5010
+ // Return Values :
5011
+ // 1 : OK
5012
+ // -1 : Unable to create directory
5013
+ // --------------------------------------------------------------------------------
5014
+ function privDirCheck($p_dir, $p_is_dir=false)
5015
+ {
5016
+ $v_result = 1;
5017
+
5018
+
5019
+ // ----- Remove the final '/'
5020
+ if (($p_is_dir) && (substr($p_dir, -1)=='/'))
5021
+ {
5022
+ $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
5023
+ }
5024
+
5025
+ // ----- Check the directory availability
5026
+ if ((is_dir($p_dir)) || ($p_dir == ""))
5027
+ {
5028
+ return 1;
5029
+ }
5030
+
5031
+ // ----- Extract parent directory
5032
+ $p_parent_dir = dirname($p_dir);
5033
+
5034
+ // ----- Just a check
5035
+ if ($p_parent_dir != $p_dir)
5036
+ {
5037
+ // ----- Look for parent directory
5038
+ if ($p_parent_dir != "")
5039
+ {
5040
+ if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
5041
+ {
5042
+ return $v_result;
5043
+ }
5044
+ }
5045
+ }
5046
+
5047
+ // ----- Create the directory
5048
+ if (!@mkdir($p_dir, 0777))
5049
+ {
5050
+ // ----- Error log
5051
+ IWPPclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
5052
+
5053
+ // ----- Return
5054
+ return IWPPclZip::errorCode();
5055
+ }
5056
+
5057
+ // ----- Return
5058
+ return $v_result;
5059
+ }
5060
+ // --------------------------------------------------------------------------------
5061
+
5062
+ // --------------------------------------------------------------------------------
5063
+ // Function : privMerge()
5064
+ // Description :
5065
+ // If $p_archive_to_add does not exist, the function exit with a success result.
5066
+ // Parameters :
5067
+ // Return Values :
5068
+ // --------------------------------------------------------------------------------
5069
+ function privMerge(&$p_archive_to_add)
5070
+ {
5071
+ $v_result=1;
5072
+
5073
+ // ----- Look if the archive_to_add exists
5074
+ if (!is_file($p_archive_to_add->zipname))
5075
+ {
5076
+
5077
+ // ----- Nothing to merge, so merge is a success
5078
+ $v_result = 1;
5079
+
5080
+ // ----- Return
5081
+ return $v_result;
5082
+ }
5083
+
5084
+ // ----- Look if the archive exists
5085
+ if (!is_file($this->zipname))
5086
+ {
5087
+
5088
+ // ----- Do a duplicate
5089
+ $v_result = $this->privDuplicate($p_archive_to_add->zipname);
5090
+
5091
+ // ----- Return
5092
+ return $v_result;
5093
+ }
5094
+
5095
+ // ----- Open the zip file
5096
+ if (($v_result=$this->privOpenFd('rb')) != 1)
5097
+ {
5098
+ // ----- Return
5099
+ return $v_result;
5100
+ }
5101
+
5102
+ // ----- Read the central directory informations
5103
+ $v_central_dir = array();
5104
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
5105
+ {
5106
+ $this->privCloseFd();
5107
+ return $v_result;
5108
+ }
5109
+
5110
+ // ----- Go to beginning of File
5111
+ @rewind($this->zip_fd);
5112
+
5113
+ // ----- Open the archive_to_add file
5114
+ if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
5115
+ {
5116
+ $this->privCloseFd();
5117
+
5118
+ // ----- Return
5119
+ return $v_result;
5120
+ }
5121
+
5122
+ // ----- Read the central directory informations
5123
+ $v_central_dir_to_add = array();
5124
+ if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
5125
+ {
5126
+ $this->privCloseFd();
5127
+ $p_archive_to_add->privCloseFd();
5128
+
5129
+ return $v_result;
5130
+ }
5131
+
5132
+ // ----- Go to beginning of File
5133
+ @rewind($p_archive_to_add->zip_fd);
5134
+
5135
+ // ----- Creates a temporay file
5136
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
5137
+
5138
+ // ----- Open the temporary file in write mode
5139
+ if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
5140
+ {
5141
+ $this->privCloseFd();
5142
+ $p_archive_to_add->privCloseFd();
5143
+
5144
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
5145
+
5146
+ // ----- Return
5147
+ return IWPPclZip::errorCode();
5148
+ }
5149
+
5150
+ // ----- Copy the files from the archive to the temporary file
5151
+ // TBC : Here I should better append the file and go back to erase the central dir
5152
+ $v_size = $v_central_dir['offset'];
5153
+ while ($v_size != 0)
5154
+ {
5155
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5156
+ $v_buffer = fread($this->zip_fd, $v_read_size);
5157
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5158
+ $v_size -= $v_read_size;
5159
+ }
5160
+
5161
+ // ----- Copy the files from the archive_to_add into the temporary file
5162
+ $v_size = $v_central_dir_to_add['offset'];
5163
+ while ($v_size != 0)
5164
+ {
5165
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5166
+ $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
5167
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5168
+ $v_size -= $v_read_size;
5169
+ }
5170
+
5171
+ // ----- Store the offset of the central dir
5172
+ $v_offset = @ftell($v_zip_temp_fd);
5173
+
5174
+ // ----- Copy the block of file headers from the old archive
5175
+ $v_size = $v_central_dir['size'];
5176
+ while ($v_size != 0)
5177
+ {
5178
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5179
+ $v_buffer = @fread($this->zip_fd, $v_read_size);
5180
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5181
+ $v_size -= $v_read_size;
5182
+ }
5183
+
5184
+ // ----- Copy the block of file headers from the archive_to_add
5185
+ $v_size = $v_central_dir_to_add['size'];
5186
+ while ($v_size != 0)
5187
+ {
5188
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5189
+ $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
5190
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5191
+ $v_size -= $v_read_size;
5192
+ }
5193
+
5194
+ // ----- Merge the file comments
5195
+ $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
5196
+
5197
+ // ----- Calculate the size of the (new) central header
5198
+ $v_size = @ftell($v_zip_temp_fd)-$v_offset;
5199
+
5200
+ // ----- Swap the file descriptor
5201
+ // Here is a trick : I swap the temporary fd with the zip fd, in order to use
5202
+ // the following methods on the temporary fil and not the real archive fd
5203
+ $v_swap = $this->zip_fd;
5204
+ $this->zip_fd = $v_zip_temp_fd;
5205
+ $v_zip_temp_fd = $v_swap;
5206
+
5207
+ // ----- Create the central dir footer
5208
+ if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
5209
+ {
5210
+ $this->privCloseFd();
5211
+ $p_archive_to_add->privCloseFd();
5212
+ @fclose($v_zip_temp_fd);
5213
+ $this->zip_fd = null;
5214
+
5215
+ // ----- Reset the file list
5216
+ unset($v_header_list);
5217
+
5218
+ // ----- Return
5219
+ return $v_result;
5220
+ }
5221
+
5222
+ // ----- Swap back the file descriptor
5223
+ $v_swap = $this->zip_fd;
5224
+ $this->zip_fd = $v_zip_temp_fd;
5225
+ $v_zip_temp_fd = $v_swap;
5226
+
5227
+ // ----- Close
5228
+ $this->privCloseFd();
5229
+ $p_archive_to_add->privCloseFd();
5230
+
5231
+ // ----- Close the temporary file
5232
+ @fclose($v_zip_temp_fd);
5233
+
5234
+ // ----- Delete the zip file
5235
+ // TBC : I should test the result ...
5236
+ @unlink($this->zipname);
5237
+
5238
+ // ----- Rename the temporary file
5239
+ // TBC : I should test the result ...
5240
+ //@rename($v_zip_temp_name, $this->zipname);
5241
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
5242
+
5243
+ // ----- Return
5244
+ return $v_result;
5245
+ }
5246
+ // --------------------------------------------------------------------------------
5247
+
5248
+ // --------------------------------------------------------------------------------
5249
+ // Function : privDuplicate()
5250
+ // Description :
5251
+ // Parameters :
5252
+ // Return Values :
5253
+ // --------------------------------------------------------------------------------
5254
+ function privDuplicate($p_archive_filename)
5255
+ {
5256
+ $v_result=1;
5257
+
5258
+ // ----- Look if the $p_archive_filename exists
5259
+ if (!is_file($p_archive_filename))
5260
+ {
5261
+
5262
+ // ----- Nothing to duplicate, so duplicate is a success.
5263
+ $v_result = 1;
5264
+
5265
+ // ----- Return
5266
+ return $v_result;
5267
+ }
5268
+
5269
+ // ----- Open the zip file
5270
+ if (($v_result=$this->privOpenFd('wb')) != 1)
5271
+ {
5272
+ // ----- Return
5273
+ return $v_result;
5274
+ }
5275
+
5276
+ // ----- Open the temporary file in write mode
5277
+ if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
5278
+ {
5279
+ $this->privCloseFd();
5280
+
5281
+ IWPPclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
5282
+
5283
+ // ----- Return
5284
+ return IWPPclZip::errorCode();
5285
+ }
5286
+
5287
+ // ----- Copy the files from the archive to the temporary file
5288
+ // TBC : Here I should better append the file and go back to erase the central dir
5289
+ $v_size = filesize($p_archive_filename);
5290
+ while ($v_size != 0)
5291
+ {
5292
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5293
+ $v_buffer = fread($v_zip_temp_fd, $v_read_size);
5294
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
5295
+ $v_size -= $v_read_size;
5296
+ }
5297
+
5298
+ // ----- Close
5299
+ $this->privCloseFd();
5300
+
5301
+ // ----- Close the temporary file
5302
+ @fclose($v_zip_temp_fd);
5303
+
5304
+ // ----- Return
5305
+ return $v_result;
5306
+ }
5307
+ // --------------------------------------------------------------------------------
5308
+
5309
+ // --------------------------------------------------------------------------------
5310
+ // Function : privErrorLog()
5311
+ // Description :
5312
+ // Parameters :
5313
+ // --------------------------------------------------------------------------------
5314
+ function privErrorLog($p_error_code=0, $p_error_string='')
5315
+ {
5316
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
5317
+ PclError($p_error_code, $p_error_string);
5318
+ }
5319
+ else {
5320
+ $this->error_code = $p_error_code;
5321
+ $this->error_string = $p_error_string;
5322
+ }
5323
+ }
5324
+ // --------------------------------------------------------------------------------
5325
+
5326
+ // --------------------------------------------------------------------------------
5327
+ // Function : privErrorReset()
5328
+ // Description :
5329
+ // Parameters :
5330
+ // --------------------------------------------------------------------------------
5331
+ function privErrorReset()
5332
+ {
5333
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
5334
+ PclErrorReset();
5335
+ }
5336
+ else {
5337
+ $this->error_code = 0;
5338
+ $this->error_string = '';
5339
+ }
5340
+ }
5341
+ // --------------------------------------------------------------------------------
5342
+
5343
+ // --------------------------------------------------------------------------------
5344
+ // Function : privDisableMagicQuotes()
5345
+ // Description :
5346
+ // Parameters :
5347
+ // Return Values :
5348
+ // --------------------------------------------------------------------------------
5349
+ function privDisableMagicQuotes()
5350
+ {
5351
+ $v_result=1;
5352
+
5353
+ // ----- Look if function exists
5354
+ if ( (!function_exists("get_magic_quotes_runtime"))
5355
+ || (!function_exists("set_magic_quotes_runtime"))) {
5356
+ return $v_result;
5357
+ }
5358
+
5359
+ // ----- Look if already done
5360
+ if ($this->magic_quotes_status != -1) {
5361
+ return $v_result;
5362
+ }
5363
+
5364
+ // ----- Get and memorize the magic_quote value
5365
+ $this->magic_quotes_status = @get_magic_quotes_runtime();
5366
+
5367
+ // ----- Disable magic_quotes
5368
+ if ($this->magic_quotes_status == 1) {
5369
+ @set_magic_quotes_runtime(0);
5370
+ }
5371
+
5372
+ // ----- Return
5373
+ return $v_result;
5374
+ }
5375
+ // --------------------------------------------------------------------------------
5376
+
5377
+ // --------------------------------------------------------------------------------
5378
+ // Function : privSwapBackMagicQuotes()
5379
+ // Description :
5380
+ // Parameters :
5381
+ // Return Values :
5382
+ // --------------------------------------------------------------------------------
5383
+ function privSwapBackMagicQuotes()
5384
+ {
5385
+ $v_result=1;
5386
+
5387
+ // ----- Look if function exists
5388
+ if ( (!function_exists("get_magic_quotes_runtime"))
5389
+ || (!function_exists("set_magic_quotes_runtime"))) {
5390
+ return $v_result;
5391
+ }
5392
+
5393
+ // ----- Look if something to do
5394
+ if ($this->magic_quotes_status != -1) {
5395
+ return $v_result;
5396
+ }
5397
+
5398
+ // ----- Swap back magic_quotes
5399
+ if ($this->magic_quotes_status == 1) {
5400
+ @set_magic_quotes_runtime($this->magic_quotes_status);
5401
+ }
5402
+
5403
+ // ----- Return
5404
+ return $v_result;
5405
+ }
5406
+ // --------------------------------------------------------------------------------
5407
+
5408
+ }
5409
+ // End of class
5410
+ // --------------------------------------------------------------------------------
5411
+
5412
+ // --------------------------------------------------------------------------------
5413
+ // Function : PclZipUtilPathReduction()
5414
+ // Description :
5415
+ // Parameters :
5416
+ // Return Values :
5417
+ // --------------------------------------------------------------------------------
5418
+ function PclZipUtilPathReduction($p_dir)
5419
+ {
5420
+ $v_result = "";
5421
+
5422
+ // ----- Look for not empty path
5423
+ if ($p_dir != "") {
5424
+ // ----- Explode path by directory names
5425
+ $v_list = explode("/", $p_dir);
5426
+
5427
+ // ----- Study directories from last to first
5428
+ $v_skip = 0;
5429
+ for ($i=sizeof($v_list)-1; $i>=0; $i--) {
5430
+ // ----- Look for current path
5431
+ if ($v_list[$i] == ".") {
5432
+ // ----- Ignore this directory
5433
+ // Should be the first $i=0, but no check is done
5434
+ }
5435
+ else if ($v_list[$i] == "..") {
5436
+ $v_skip++;
5437
+ }
5438
+ else if ($v_list[$i] == "") {
5439
+ // ----- First '/' i.e. root slash
5440
+ if ($i == 0) {
5441
+ $v_result = "/".$v_result;
5442
+ if ($v_skip > 0) {
5443
+ // ----- It is an invalid path, so the path is not modified
5444
+ // TBC
5445
+ $v_result = $p_dir;
5446
+ $v_skip = 0;
5447
+ }
5448
+ }
5449
+ // ----- Last '/' i.e. indicates a directory
5450
+ else if ($i == (sizeof($v_list)-1)) {
5451
+ $v_result = $v_list[$i];
5452
+ }
5453
+ // ----- Double '/' inside the path
5454
+ else {
5455
+ // ----- Ignore only the double '//' in path,
5456
+ // but not the first and last '/'
5457
+ }
5458
+ }
5459
+ else {
5460
+ // ----- Look for item to skip
5461
+ if ($v_skip > 0) {
5462
+ $v_skip--;
5463
+ }
5464
+ else {
5465
+ $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
5466
+ }
5467
+ }
5468
+ }
5469
+
5470
+ // ----- Look for skip
5471
+ if ($v_skip > 0) {
5472
+ while ($v_skip > 0) {
5473
+ $v_result = '../'.$v_result;
5474
+ $v_skip--;
5475
+ }
5476
+ }
5477
+ }
5478
+
5479
+ // ----- Return
5480
+ return $v_result;
5481
+ }
5482
+ // --------------------------------------------------------------------------------
5483
+
5484
+ // --------------------------------------------------------------------------------
5485
+ // Function : PclZipUtilPathInclusion()
5486
+ // Description :
5487
+ // This function indicates if the path $p_path is under the $p_dir tree. Or,
5488
+ // said in an other way, if the file or sub-dir $p_path is inside the dir
5489
+ // $p_dir.
5490
+ // The function indicates also if the path is exactly the same as the dir.
5491
+ // This function supports path with duplicated '/' like '//', but does not
5492
+ // support '.' or '..' statements.
5493
+ // Parameters :
5494
+ // Return Values :
5495
+ // 0 if $p_path is not inside directory $p_dir
5496
+ // 1 if $p_path is inside directory $p_dir
5497
+ // 2 if $p_path is exactly the same as $p_dir
5498
+ // --------------------------------------------------------------------------------
5499
+ function PclZipUtilPathInclusion($p_dir, $p_path)
5500
+ {
5501
+ $v_result = 1;
5502
+
5503
+ // ----- Look for path beginning by ./
5504
+ if ( ($p_dir == '.')
5505
+ || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
5506
+ $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
5507
+ }
5508
+ if ( ($p_path == '.')
5509
+ || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
5510
+ $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
5511
+ }
5512
+
5513
+ // ----- Explode dir and path by directory separator
5514
+ $v_list_dir = explode("/", $p_dir);
5515
+ $v_list_dir_size = sizeof($v_list_dir);
5516
+ $v_list_path = explode("/", $p_path);
5517
+ $v_list_path_size = sizeof($v_list_path);
5518
+
5519
+ // ----- Study directories paths
5520
+ $i = 0;
5521
+ $j = 0;
5522
+ while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
5523
+
5524
+ // ----- Look for empty dir (path reduction)
5525
+ if ($v_list_dir[$i] == '') {
5526
+ $i++;
5527
+ continue;
5528
+ }
5529
+ if ($v_list_path[$j] == '') {
5530
+ $j++;
5531
+ continue;
5532
+ }
5533
+
5534
+ // ----- Compare the items
5535
+ if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
5536
+ $v_result = 0;
5537
+ }
5538
+
5539
+ // ----- Next items
5540
+ $i++;
5541
+ $j++;
5542
+ }
5543
+
5544
+ // ----- Look if everything seems to be the same
5545
+ if ($v_result) {
5546
+ // ----- Skip all the empty items
5547
+ while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
5548
+ while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
5549
+
5550
+ if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
5551
+ // ----- There are exactly the same
5552
+ $v_result = 2;
5553
+ }
5554
+ else if ($i < $v_list_dir_size) {
5555
+ // ----- The path is shorter than the dir
5556
+ $v_result = 0;
5557
+ }
5558
+ }
5559
+
5560
+ // ----- Return
5561
+ return $v_result;
5562
+ }
5563
+ // --------------------------------------------------------------------------------
5564
+
5565
+ // --------------------------------------------------------------------------------
5566
+ // Function : PclZipUtilCopyBlock()
5567
+ // Description :
5568
+ // Parameters :
5569
+ // $p_mode : read/write compression mode
5570
+ // 0 : src & dest normal
5571
+ // 1 : src gzip, dest normal
5572
+ // 2 : src normal, dest gzip
5573
+ // 3 : src & dest gzip
5574
+ // Return Values :
5575
+ // --------------------------------------------------------------------------------
5576
+ function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
5577
+ {
5578
+ $v_result = 1;
5579
+
5580
+ if ($p_mode==0)
5581
+ {
5582
+ while ($p_size != 0)
5583
+ {
5584
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5585
+ $v_buffer = @fread($p_src, $v_read_size);
5586
+ @fwrite($p_dest, $v_buffer, $v_read_size);
5587
+ $p_size -= $v_read_size;
5588
+ }
5589
+ }
5590
+ else if ($p_mode==1)
5591
+ {
5592
+ while ($p_size != 0)
5593
+ {
5594
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5595
+ $v_buffer = @gzread($p_src, $v_read_size);
5596
+ @fwrite($p_dest, $v_buffer, $v_read_size);
5597
+ $p_size -= $v_read_size;
5598
+ }
5599
+ }
5600
+ else if ($p_mode==2)
5601
+ {
5602
+ while ($p_size != 0)
5603
+ {
5604
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5605
+ $v_buffer = @fread($p_src, $v_read_size);
5606
+ @gzwrite($p_dest, $v_buffer, $v_read_size);
5607
+ $p_size -= $v_read_size;
5608
+ }
5609
+ }
5610
+ else if ($p_mode==3)
5611
+ {
5612
+ while ($p_size != 0)
5613
+ {
5614
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5615
+ $v_buffer = @gzread($p_src, $v_read_size);
5616
+ @gzwrite($p_dest, $v_buffer, $v_read_size);
5617
+ $p_size -= $v_read_size;
5618
+ }
5619
+ }
5620
+
5621
+ // ----- Return
5622
+ return $v_result;
5623
+ }
5624
+ // --------------------------------------------------------------------------------
5625
+
5626
+ // --------------------------------------------------------------------------------
5627
+ // Function : PclZipUtilRename()
5628
+ // Description :
5629
+ // This function tries to do a simple rename() function. If it fails, it
5630
+ // tries to copy the $p_src file in a new $p_dest file and then unlink the
5631
+ // first one.
5632
+ // Parameters :
5633
+ // $p_src : Old filename
5634
+ // $p_dest : New filename
5635
+ // Return Values :
5636
+ // 1 on success, 0 on failure.
5637
+ // --------------------------------------------------------------------------------
5638
+ function PclZipUtilRename($p_src, $p_dest)
5639
+ {
5640
+ $v_result = 1;
5641
+
5642
+ // ----- Try to rename the files
5643
+ if (!@rename($p_src, $p_dest)) {
5644
+
5645
+ // ----- Try to copy & unlink the src
5646
+ if (!@copy($p_src, $p_dest)) {
5647
+ $v_result = 0;
5648
+ }
5649
+ else if (!@unlink($p_src)) {
5650
+ $v_result = 0;
5651
+ }
5652
+ }
5653
+
5654
+ // ----- Return
5655
+ return $v_result;
5656
+ }
5657
+ // --------------------------------------------------------------------------------
5658
+
5659
+ // --------------------------------------------------------------------------------
5660
+ // Function : PclZipUtilOptionText()
5661
+ // Description :
5662
+ // Translate option value in text. Mainly for debug purpose.
5663
+ // Parameters :
5664
+ // $p_option : the option value.
5665
+ // Return Values :
5666
+ // The option text value.
5667
+ // --------------------------------------------------------------------------------
5668
+ function PclZipUtilOptionText($p_option)
5669
+ {
5670
+
5671
+ $v_list = get_defined_constants();
5672
+ for (reset($v_list); $v_key = key($v_list); next($v_list)) {
5673
+ $v_prefix = substr($v_key, 0, 10);
5674
+ if (( ($v_prefix == 'PCLZIP_OPT')
5675
+ || ($v_prefix == 'PCLZIP_CB_')
5676
+ || ($v_prefix == 'PCLZIP_ATT'))
5677
+ && ($v_list[$v_key] == $p_option)) {
5678
+ return $v_key;
5679
+ }
5680
+ }
5681
+
5682
+ $v_result = 'Unknown';
5683
+
5684
+ return $v_result;
5685
+ }
5686
+ // --------------------------------------------------------------------------------
5687
+
5688
+ // --------------------------------------------------------------------------------
5689
+ // Function : PclZipUtilTranslateWinPath()
5690
+ // Description :
5691
+ // Translate windows path by replacing '\' by '/' and optionally removing
5692
+ // drive letter.
5693
+ // Parameters :
5694
+ // $p_path : path to translate.
5695
+ // $p_remove_disk_letter : true | false
5696
+ // Return Values :
5697
+ // The path translated.
5698
+ // --------------------------------------------------------------------------------
5699
+ function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
5700
+ {
5701
+ if (stristr(php_uname(), 'windows')) {
5702
+ // ----- Look for potential disk letter
5703
+ if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
5704
+ $p_path = substr($p_path, $v_position+1);
5705
+ }
5706
+ // ----- Change potential windows directory separator
5707
+ if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
5708
+ $p_path = strtr($p_path, '\\', '/');
5709
+ }
5710
+ }
5711
+ return $p_path;
5712
+ }
5713
+ // --------------------------------------------------------------------------------
5714
+
5715
+
5716
+ ?>
readme.txt CHANGED
@@ -48,6 +48,10 @@ Credits: [Vladimir Prelovac](http://prelovac.com/vladimir) for his worker plugin
48
 
49
  == Changelog ==
50
 
 
 
 
 
51
  = 1.1.0 =
52
  * Premium addons bugs fixed
53
  * Reload data improved
48
 
49
  == Changelog ==
50
 
51
+ = 1.1.1 =
52
+ * Improved backups
53
+ * Bug fixes
54
+
55
  = 1.1.0 =
56
  * Premium addons bugs fixed
57
  * Reload data improved