| [ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
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 // ----- File description attributes 157 define( 'PCLZIP_ATT_FILE_NAME', 79001 ); 158 define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); 159 define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); 160 define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); 161 define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); 162 define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); 163 164 // ----- Call backs values 165 define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); 166 define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); 167 define( 'PCLZIP_CB_PRE_ADD', 78003 ); 168 define( 'PCLZIP_CB_POST_ADD', 78004 ); 169 /* For futur use 170 define( 'PCLZIP_CB_PRE_LIST', 78005 ); 171 define( 'PCLZIP_CB_POST_LIST', 78006 ); 172 define( 'PCLZIP_CB_PRE_DELETE', 78007 ); 173 define( 'PCLZIP_CB_POST_DELETE', 78008 ); 174 */ 175 176 // -------------------------------------------------------------------------------- 177 // Class : PclZip 178 // Description : 179 // PclZip is the class that represent a Zip archive. 180 // The public methods allow the manipulation of the archive. 181 // Attributes : 182 // Attributes must not be accessed directly. 183 // Methods : 184 // PclZip() : Object creator 185 // create() : Creates the Zip archive 186 // listContent() : List the content of the Zip archive 187 // extract() : Extract the content of the archive 188 // properties() : List the properties of the archive 189 // -------------------------------------------------------------------------------- 190 class PclZip 191 { 192 // ----- Filename of the zip file 193 var $zipname = ''; 194 195 // ----- File descriptor of the zip file 196 var $zip_fd = 0; 197 198 // ----- Internal error handling 199 var $error_code = 1; 200 var $error_string = ''; 201 202 // ----- Current status of the magic_quotes_runtime 203 // This value store the php configuration for magic_quotes 204 // The class can then disable the magic_quotes and reset it after 205 var $magic_quotes_status; 206 207 // -------------------------------------------------------------------------------- 208 // Function : PclZip() 209 // Description : 210 // Creates a PclZip object and set the name of the associated Zip archive 211 // filename. 212 // Note that no real action is taken, if the archive does not exist it is not 213 // created. Use create() for that. 214 // -------------------------------------------------------------------------------- 215 function PclZip($p_zipname) 216 { 217 218 // ----- Tests the zlib 219 if (!function_exists('gzopen')) 220 { 221 die('Abort '.basename(__FILE__).' : Missing zlib extensions'); 222 } 223 224 // ----- Set the attributes 225 $this->zipname = $p_zipname; 226 $this->zip_fd = 0; 227 $this->magic_quotes_status = -1; 228 229 // ----- Return 230 return; 231 } 232 // -------------------------------------------------------------------------------- 233 234 // -------------------------------------------------------------------------------- 235 // Function : 236 // create($p_filelist, $p_add_dir="", $p_remove_dir="") 237 // create($p_filelist, $p_option, $p_option_value, ...) 238 // Description : 239 // This method supports two different synopsis. The first one is historical. 240 // This method creates a Zip Archive. The Zip file is created in the 241 // filesystem. The files and directories indicated in $p_filelist 242 // are added in the archive. See the parameters description for the 243 // supported format of $p_filelist. 244 // When a directory is in the list, the directory and its content is added 245 // in the archive. 246 // In this synopsis, the function takes an optional variable list of 247 // options. See bellow the supported options. 248 // Parameters : 249 // $p_filelist : An array containing file or directory names, or 250 // a string containing one filename or one directory name, or 251 // a string containing a list of filenames and/or directory 252 // names separated by spaces. 253 // $p_add_dir : A path to add before the real path of the archived file, 254 // in order to have it memorized in the archive. 255 // $p_remove_dir : A path to remove from the real path of the file to archive, 256 // in order to have a shorter path memorized in the archive. 257 // When $p_add_dir and $p_remove_dir are set, $p_remove_dir 258 // is removed first, before $p_add_dir is added. 259 // Options : 260 // PCLZIP_OPT_ADD_PATH : 261 // PCLZIP_OPT_REMOVE_PATH : 262 // PCLZIP_OPT_REMOVE_ALL_PATH : 263 // PCLZIP_OPT_COMMENT : 264 // PCLZIP_CB_PRE_ADD : 265 // PCLZIP_CB_POST_ADD : 266 // Return Values : 267 // 0 on failure, 268 // The list of the added files, with a status of the add action. 269 // (see PclZip::listContent() for list entry format) 270 // -------------------------------------------------------------------------------- 271 function create($p_filelist) 272 { 273 $v_result=1; 274 275 // ----- Reset the error handler 276 $this->privErrorReset(); 277 278 // ----- Set default values 279 $v_options = array(); 280 $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; 281 282 // ----- Look for variable options arguments 283 $v_size = func_num_args(); 284 285 // ----- Look for arguments 286 if ($v_size > 1) { 287 // ----- Get the arguments 288 $v_arg_list = func_get_args(); 289 290 // ----- Remove from the options list the first argument 291 array_shift($v_arg_list); 292 $v_size--; 293 294 // ----- Look for first arg 295 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 296 297 // ----- Parse the options 298 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, 299 array (PCLZIP_OPT_REMOVE_PATH => 'optional', 300 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', 301 PCLZIP_OPT_ADD_PATH => 'optional', 302 PCLZIP_CB_PRE_ADD => 'optional', 303 PCLZIP_CB_POST_ADD => 'optional', 304 PCLZIP_OPT_NO_COMPRESSION => 'optional', 305 PCLZIP_OPT_COMMENT => 'optional', 306 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', 307 PCLZIP_OPT_TEMP_FILE_ON => 'optional', 308 PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 309 //, PCLZIP_OPT_CRYPT => 'optional' 310 )); 311 if ($v_result != 1) { 312 return 0; 313 } 314 } 315 316 // ----- Look for 2 args 317 // Here we need to support the first historic synopsis of the 318 // method. 319 else { 320 321 // ----- Get the first argument 322 $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; 323 324 // ----- Look for the optional second argument 325 if ($v_size == 2) { 326 $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; 327 } 328 else if ($v_size > 2) { 329 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, 330 "Invalid number / type of arguments"); 331 return 0; 332 } 333 } 334 } 335 336 // ----- Look for default option values 337 $this->privOptionDefaultThreshold($v_options); 338 339 // ----- Init 340 $v_string_list = array(); 341 $v_att_list = array(); 342 $v_filedescr_list = array(); 343 $p_result_list = array(); 344 345 // ----- Look if the $p_filelist is really an array 346 if (is_array($p_filelist)) { 347 348 // ----- Look if the first element is also an array 349 // This will mean that this is a file description entry 350 if (isset($p_filelist[0]) && is_array($p_filelist[0])) { 351 $v_att_list = $p_filelist; 352 } 353 354 // ----- The list is a list of string names 355 else { 356 $v_string_list = $p_filelist; 357 } 358 } 359 360 // ----- Look if the $p_filelist is a string 361 else if (is_string($p_filelist)) { 362 // ----- Create a list from the string 363 $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); 364 } 365 366 // ----- Invalid variable type for $p_filelist 367 else { 368 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); 369 return 0; 370 } 371 372 // ----- Reformat the string list 373 if (sizeof($v_string_list) != 0) { 374 foreach ($v_string_list as $v_string) { 375 if ($v_string != '') { 376 $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; 377 } 378 else { 379 } 380 } 381 } 382 383 // ----- For each file in the list check the attributes 384 $v_supported_attributes 385 = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' 386 ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' 387 ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' 388 ,PCLZIP_ATT_FILE_MTIME => 'optional' 389 ,PCLZIP_ATT_FILE_CONTENT => 'optional' 390 ,PCLZIP_ATT_FILE_COMMENT => 'optional' 391 ); 392 foreach ($v_att_list as $v_entry) { 393 $v_result = $this->privFileDescrParseAtt($v_entry, 394 $v_filedescr_list[], 395 $v_options, 396 $v_supported_attributes); 397 if ($v_result != 1) { 398 return 0; 399 } 400 } 401 402 // ----- Expand the filelist (expand directories) 403 $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); 404 if ($v_result != 1) { 405 return 0; 406 } 407 408 // ----- Call the create fct 409 $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); 410 if ($v_result != 1) { 411 return 0; 412 } 413 414 // ----- Return 415 return $p_result_list; 416 } 417 // -------------------------------------------------------------------------------- 418 419 // -------------------------------------------------------------------------------- 420 // Function : 421 // add($p_filelist, $p_add_dir="", $p_remove_dir="") 422 // add($p_filelist, $p_option, $p_option_value, ...) 423 // Description : 424 // This method supports two synopsis. The first one is historical. 425 // This methods add the list of files in an existing archive. 426 // If a file with the same name already exists, it is added at the end of the 427 // archive, the first one is still present. 428 // If the archive does not exist, it is created. 429 // Parameters : 430 // $p_filelist : An array containing file or directory names, or 431 // a string containing one filename or one directory name, or 432 // a string containing a list of filenames and/or directory 433 // names separated by spaces. 434 // $p_add_dir : A path to add before the real path of the archived file, 435 // in order to have it memorized in the archive. 436 // $p_remove_dir : A path to remove from the real path of the file to archive, 437 // in order to have a shorter path memorized in the archive. 438 // When $p_add_dir and $p_remove_dir are set, $p_remove_dir 439 // is removed first, before $p_add_dir is added. 440 // Options : 441 // PCLZIP_OPT_ADD_PATH : 442 // PCLZIP_OPT_REMOVE_PATH : 443 // PCLZIP_OPT_REMOVE_ALL_PATH : 444 // PCLZIP_OPT_COMMENT : 445 // PCLZIP_OPT_ADD_COMMENT : 446 // PCLZIP_OPT_PREPEND_COMMENT : 447 // PCLZIP_CB_PRE_ADD : 448 // PCLZIP_CB_POST_ADD : 449 // Return Values : 450 // 0 on failure, 451 // The list of the added files, with a status of the add action. 452 // (see PclZip::listContent() for list entry format) 453 // -------------------------------------------------------------------------------- 454 function add($p_filelist) 455 { 456 $v_result=1; 457 458 // ----- Reset the error handler 459 $this->privErrorReset(); 460 461 // ----- Set default values 462 $v_options = array(); 463 $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; 464 465 // ----- Look for variable options arguments 466 $v_size = func_num_args(); 467 468 // ----- Look for arguments 469 if ($v_size > 1) { 470 // ----- Get the arguments 471 $v_arg_list = func_get_args(); 472 473 // ----- Remove form the options list the first argument 474 array_shift($v_arg_list); 475 $v_size--; 476 477 // ----- Look for first arg 478 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 479 480 // ----- Parse the options 481 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, 482 array (PCLZIP_OPT_REMOVE_PATH => 'optional', 483 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', 484 PCLZIP_OPT_ADD_PATH => 'optional', 485 PCLZIP_CB_PRE_ADD => 'optional', 486 PCLZIP_CB_POST_ADD => 'optional', 487 PCLZIP_OPT_NO_COMPRESSION => 'optional', 488 PCLZIP_OPT_COMMENT => 'optional', 489 PCLZIP_OPT_ADD_COMMENT => 'optional', 490 PCLZIP_OPT_PREPEND_COMMENT => 'optional', 491 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', 492 PCLZIP_OPT_TEMP_FILE_ON => 'optional', 493 PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 494 //, PCLZIP_OPT_CRYPT => 'optional' 495 )); 496 if ($v_result != 1) { 497 return 0; 498 } 499 } 500 501 // ----- Look for 2 args 502 // Here we need to support the first historic synopsis of the 503 // method. 504 else { 505 506 // ----- Get the first argument 507 $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; 508 509 // ----- Look for the optional second argument 510 if ($v_size == 2) { 511 $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; 512 } 513 else if ($v_size > 2) { 514 // ----- Error log 515 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); 516 517 // ----- Return 518 return 0; 519 } 520 } 521 } 522 523 // ----- Look for default option values 524 $this->privOptionDefaultThreshold($v_options); 525 526 // ----- Init 527 $v_string_list = array(); 528 $v_att_list = array(); 529 $v_filedescr_list = array(); 530 $p_result_list = array(); 531 532 // ----- Look if the $p_filelist is really an array 533 if (is_array($p_filelist)) { 534 535 // ----- Look if the first element is also an array 536 // This will mean that this is a file description entry 537 if (isset($p_filelist[0]) && is_array($p_filelist[0])) { 538 $v_att_list = $p_filelist; 539 } 540 541 // ----- The list is a list of string names 542 else { 543 $v_string_list = $p_filelist; 544 } 545 } 546 547 // ----- Look if the $p_filelist is a string 548 else if (is_string($p_filelist)) { 549 // ----- Create a list from the string 550 $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); 551 } 552 553 // ----- Invalid variable type for $p_filelist 554 else { 555 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); 556 return 0; 557 } 558 559 // ----- Reformat the string list 560 if (sizeof($v_string_list) != 0) { 561 foreach ($v_string_list as $v_string) { 562 $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; 563 } 564 } 565 566 // ----- For each file in the list check the attributes 567 $v_supported_attributes 568 = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' 569 ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' 570 ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' 571 ,PCLZIP_ATT_FILE_MTIME => 'optional' 572 ,PCLZIP_ATT_FILE_CONTENT => 'optional' 573 ,PCLZIP_ATT_FILE_COMMENT => 'optional' 574 ); 575 foreach ($v_att_list as $v_entry) { 576 $v_result = $this->privFileDescrParseAtt($v_entry, 577 $v_filedescr_list[], 578 $v_options, 579 $v_supported_attributes); 580 if ($v_result != 1) { 581 return 0; 582 } 583 } 584 585 // ----- Expand the filelist (expand directories) 586 $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); 587 if ($v_result != 1) { 588 return 0; 589 } 590 591 // ----- Call the create fct 592 $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); 593 if ($v_result != 1) { 594 return 0; 595 } 596 597 // ----- Return 598 return $p_result_list; 599 } 600 // -------------------------------------------------------------------------------- 601 602 // -------------------------------------------------------------------------------- 603 // Function : listContent() 604 // Description : 605 // This public method, gives the list of the files and directories, with their 606 // properties. 607 // The properties of each entries in the list are (used also in other functions) : 608 // filename : Name of the file. For a create or add action it is the filename 609 // given by the user. For an extract function it is the filename 610 // of the extracted file. 611 // stored_filename : Name of the file / directory stored in the archive. 612 // size : Size of the stored file. 613 // compressed_size : Size of the file's data compressed in the archive 614 // (without the headers overhead) 615 // mtime : Last known modification date of the file (UNIX timestamp) 616 // comment : Comment associated with the file 617 // folder : true | false 618 // index : index of the file in the archive 619 // status : status of the action (depending of the action) : 620 // Values are : 621 // ok : OK ! 622 // filtered : the file / dir is not extracted (filtered by user) 623 // already_a_directory : the file can not be extracted because a 624 // directory with the same name already exists 625 // write_protected : the file can not be extracted because a file 626 // with the same name already exists and is 627 // write protected 628 // newer_exist : the file was not extracted because a newer file exists 629 // path_creation_fail : the file is not extracted because the folder 630 // does not exist and can not be created 631 // write_error : the file was not extracted because there was a 632 // error while writing the file 633 // read_error : the file was not extracted because there was a error 634 // while reading the file 635 // invalid_header : the file was not extracted because of an archive 636 // format error (bad file header) 637 // Note that each time a method can continue operating when there 638 // is an action error on a file, the error is only logged in the file status. 639 // Return Values : 640 // 0 on an unrecoverable failure, 641 // The list of the files in the archive. 642 // -------------------------------------------------------------------------------- 643 function listContent() 644 { 645 $v_result=1; 646 647 // ----- Reset the error handler 648 $this->privErrorReset(); 649 650 // ----- Check archive 651 if (!$this->privCheckFormat()) { 652 return(0); 653 } 654 655 // ----- Call the extracting fct 656 $p_list = array(); 657 if (($v_result = $this->privList($p_list)) != 1) 658 { 659 unset($p_list); 660 return(0); 661 } 662 663 // ----- Return 664 return $p_list; 665 } 666 // -------------------------------------------------------------------------------- 667 668 // -------------------------------------------------------------------------------- 669 // Function : 670 // extract($p_path="./", $p_remove_path="") 671 // extract([$p_option, $p_option_value, ...]) 672 // Description : 673 // This method supports two synopsis. The first one is historical. 674 // This method extract all the files / directories from the archive to the 675 // folder indicated in $p_path. 676 // If you want to ignore the 'root' part of path of the memorized files 677 // you can indicate this in the optional $p_remove_path parameter. 678 // By default, if a newer file with the same name already exists, the 679 // file is not extracted. 680 // 681 // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions 682 // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append 683 // at the end of the path value of PCLZIP_OPT_PATH. 684 // Parameters : 685 // $p_path : Path where the files and directories are to be extracted 686 // $p_remove_path : First part ('root' part) of the memorized path 687 // (if any similar) to remove while extracting. 688 // Options : 689 // PCLZIP_OPT_PATH : 690 // PCLZIP_OPT_ADD_PATH : 691 // PCLZIP_OPT_REMOVE_PATH : 692 // PCLZIP_OPT_REMOVE_ALL_PATH : 693 // PCLZIP_CB_PRE_EXTRACT : 694 // PCLZIP_CB_POST_EXTRACT : 695 // Return Values : 696 // 0 or a negative value on failure, 697 // The list of the extracted files, with a status of the action. 698 // (see PclZip::listContent() for list entry format) 699 // -------------------------------------------------------------------------------- 700 function extract() 701 { 702 $v_result=1; 703 704 // ----- Reset the error handler 705 $this->privErrorReset(); 706 707 // ----- Check archive 708 if (!$this->privCheckFormat()) { 709 return(0); 710 } 711 712 // ----- Set default values 713 $v_options = array(); 714 // $v_path = "./"; 715 $v_path = ''; 716 $v_remove_path = ""; 717 $v_remove_all_path = false; 718 719 // ----- Look for variable options arguments 720 $v_size = func_num_args(); 721 722 // ----- Default values for option 723 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; 724 725 // ----- Look for arguments 726 if ($v_size > 0) { 727 // ----- Get the arguments 728 $v_arg_list = func_get_args(); 729 730 // ----- Look for first arg 731 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 732 733 // ----- Parse the options 734 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, 735 array (PCLZIP_OPT_PATH => 'optional', 736 PCLZIP_OPT_REMOVE_PATH => 'optional', 737 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', 738 PCLZIP_OPT_ADD_PATH => 'optional', 739 PCLZIP_CB_PRE_EXTRACT => 'optional', 740 PCLZIP_CB_POST_EXTRACT => 'optional', 741 PCLZIP_OPT_SET_CHMOD => 'optional', 742 PCLZIP_OPT_BY_NAME => 'optional', 743 PCLZIP_OPT_BY_EREG => 'optional', 744 PCLZIP_OPT_BY_PREG => 'optional', 745 PCLZIP_OPT_BY_INDEX => 'optional', 746 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', 747 PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', 748 PCLZIP_OPT_REPLACE_NEWER => 'optional' 749 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' 750 ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', 751 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', 752 PCLZIP_OPT_TEMP_FILE_ON => 'optional', 753 PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 754 )); 755 if ($v_result != 1) { 756 return 0; 757 } 758 759 // ----- Set the arguments 760 if (isset($v_options[PCLZIP_OPT_PATH])) { 761 $v_path = $v_options[PCLZIP_OPT_PATH]; 762 } 763 if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { 764 $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; 765 } 766 if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { 767 $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; 768 } 769 if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { 770 // ----- Check for '/' in last path char 771 if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { 772 $v_path .= '/'; 773 } 774 $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; 775 } 776 } 777 778 // ----- Look for 2 args 779 // Here we need to support the first historic synopsis of the 780 // method. 781 else { 782 783 // ----- Get the first argument 784 $v_path = $v_arg_list[0]; 785 786 // ----- Look for the optional second argument 787 if ($v_size == 2) { 788 $v_remove_path = $v_arg_list[1]; 789 } 790 else if ($v_size > 2) { 791 // ----- Error log 792 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); 793 794 // ----- Return 795 return 0; 796 } 797 } 798 } 799 800 // ----- Look for default option values 801 $this->privOptionDefaultThreshold($v_options); 802 803 // ----- Trace 804 805 // ----- Call the extracting fct 806 $p_list = array(); 807 $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, 808 $v_remove_all_path, $v_options); 809 if ($v_result < 1) { 810 unset($p_list); 811 return(0); 812 } 813 814 // ----- Return 815 return $p_list; 816 } 817 // -------------------------------------------------------------------------------- 818 819 820 // -------------------------------------------------------------------------------- 821 // Function : 822 // extractByIndex($p_index, $p_path="./", $p_remove_path="") 823 // extractByIndex($p_index, [$p_option, $p_option_value, ...]) 824 // Description : 825 // This method supports two synopsis. The first one is historical. 826 // This method is doing a partial extract of the archive. 827 // The extracted files or folders are identified by their index in the 828 // archive (from 0 to n). 829 // Note that if the index identify a folder, only the folder entry is 830 // extracted, not all the files included in the archive. 831 // Parameters : 832 // $p_index : A single index (integer) or a string of indexes of files to 833 // extract. The form of the string is "0,4-6,8-12" with only numbers 834 // and '-' for range or ',' to separate ranges. No spaces or ';' 835 // are allowed. 836 // $p_path : Path where the files and directories are to be extracted 837 // $p_remove_path : First part ('root' part) of the memorized path 838 // (if any similar) to remove while extracting. 839 // Options : 840 // PCLZIP_OPT_PATH : 841 // PCLZIP_OPT_ADD_PATH : 842 // PCLZIP_OPT_REMOVE_PATH : 843 // PCLZIP_OPT_REMOVE_ALL_PATH : 844 // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and 845 // not as files. 846 // The resulting content is in a new field 'content' in the file 847 // structure. 848 // This option must be used alone (any other options are ignored). 849 // PCLZIP_CB_PRE_EXTRACT : 850 // PCLZIP_CB_POST_EXTRACT : 851 // Return Values : 852 // 0 on failure, 853 // The list of the extracted files, with a status of the action. 854 // (see PclZip::listContent() for list entry format) 855 // -------------------------------------------------------------------------------- 856 //function extractByIndex($p_index, options...) 857 function extractByIndex($p_index) 858 { 859 $v_result=1; 860 861 // ----- Reset the error handler 862 $this->privErrorReset(); 863 864 // ----- Check archive 865 if (!$this->privCheckFormat()) { 866 return(0); 867 } 868 869 // ----- Set default values 870 $v_options = array(); 871 // $v_path = "./"; 872 $v_path = ''; 873 $v_remove_path = ""; 874 $v_remove_all_path = false; 875 876 // ----- Look for variable options arguments 877 $v_size = func_num_args(); 878 879 // ----- Default values for option 880 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; 881 882 // ----- Look for arguments 883 if ($v_size > 1) { 884 // ----- Get the arguments 885 $v_arg_list = func_get_args(); 886 887 // ----- Remove form the options list the first argument 888 array_shift($v_arg_list); 889 $v_size--; 890 891 // ----- Look for first arg 892 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 893 894 // ----- Parse the options 895 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, 896 array (PCLZIP_OPT_PATH => 'optional', 897 PCLZIP_OPT_REMOVE_PATH => 'optional', 898 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', 899 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', 900 PCLZIP_OPT_ADD_PATH => 'optional', 901 PCLZIP_CB_PRE_EXTRACT => 'optional', 902 PCLZIP_CB_POST_EXTRACT => 'optional', 903 PCLZIP_OPT_SET_CHMOD => 'optional', 904 PCLZIP_OPT_REPLACE_NEWER => 'optional' 905 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' 906 ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', 907 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', 908 PCLZIP_OPT_TEMP_FILE_ON => 'optional', 909 PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 910 )); 911 if ($v_result != 1) { 912 return 0; 913 } 914 915 // ----- Set the arguments 916 if (isset($v_options[PCLZIP_OPT_PATH])) { 917 $v_path = $v_options[PCLZIP_OPT_PATH]; 918 } 919 if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { 920 $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; 921 } 922 if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { 923 $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; 924 } 925 if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { 926 // ----- Check for '/' in last path char 927 if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { 928 $v_path .= '/'; 929 } 930 $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; 931 } 932 if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { 933 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; 934 } 935 else { 936 } 937 } 938 939 // ----- Look for 2 args 940 // Here we need to support the first historic synopsis of the 941 // method. 942 else { 943 944 // ----- Get the first argument 945 $v_path = $v_arg_list[0]; 946 947 // ----- Look for the optional second argument 948 if ($v_size == 2) { 949 $v_remove_path = $v_arg_list[1]; 950 } 951 else if ($v_size > 2) { 952 // ----- Error log 953 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); 954 955 // ----- Return 956 return 0; 957 } 958 } 959 } 960 961 // ----- Trace 962 963 // ----- Trick 964 // Here I want to reuse extractByRule(), so I need to parse the $p_index 965 // with privParseOptions() 966 $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); 967 $v_options_trick = array(); 968 $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, 969 array (PCLZIP_OPT_BY_INDEX => 'optional' )); 970 if ($v_result != 1) { 971 return 0; 972 } 973 $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; 974 975 // ----- Look for default option values 976 $this->privOptionDefaultThreshold($v_options); 977 978 // ----- Call the extracting fct 979 if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { 980 return(0); 981 } 982 983 // ----- Return 984 return $p_list; 985 } 986 // -------------------------------------------------------------------------------- 987 988 // -------------------------------------------------------------------------------- 989 // Function : 990 // delete([$p_option, $p_option_value, ...]) 991 // Description : 992 // This method removes files from the archive. 993 // If no parameters are given, then all the archive is emptied. 994 // Parameters : 995 // None or optional arguments. 996 // Options : 997 // PCLZIP_OPT_BY_INDEX : 998 // PCLZIP_OPT_BY_NAME : 999 // PCLZIP_OPT_BY_EREG : 1000 // PCLZIP_OPT_BY_PREG : 1001 // Return Values : 1002 // 0 on failure, 1003 // The list of the files which are still present in the archive. 1004 // (see PclZip::listContent() for list entry format) 1005 // -------------------------------------------------------------------------------- 1006 function delete() 1007 { 1008 $v_result=1; 1009 1010 // ----- Reset the error handler 1011 $this->privErrorReset(); 1012 1013 // ----- Check archive 1014 if (!$this->privCheckFormat()) { 1015 return(0); 1016 } 1017 1018 // ----- Set default values 1019 $v_options = array(); 1020 1021 // ----- Look for variable options arguments 1022 $v_size = func_num_args(); 1023 1024 // ----- Look for arguments 1025 if ($v_size > 0) { 1026 // ----- Get the arguments 1027 $v_arg_list = func_get_args(); 1028 1029 // ----- Parse the options 1030 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, 1031 array (PCLZIP_OPT_BY_NAME => 'optional', 1032 PCLZIP_OPT_BY_EREG => 'optional', 1033 PCLZIP_OPT_BY_PREG => 'optional', 1034 PCLZIP_OPT_BY_INDEX => 'optional' )); 1035 if ($v_result != 1) { 1036 return 0; 1037 } 1038 } 1039 1040 // ----- Magic quotes trick 1041 $this->privDisableMagicQuotes(); 1042 1043 // ----- Call the delete fct 1044 $v_list = array(); 1045 if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { 1046 $this->privSwapBackMagicQuotes(); 1047 unset($v_list); 1048 return(0); 1049 } 1050 1051 // ----- Magic quotes trick 1052 $this->privSwapBackMagicQuotes(); 1053 1054 // ----- Return 1055 return $v_list; 1056 } 1057 // -------------------------------------------------------------------------------- 1058 1059 // -------------------------------------------------------------------------------- 1060 // Function : deleteByIndex() 1061 // Description : 1062 // ***** Deprecated ***** 1063 // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. 1064 // -------------------------------------------------------------------------------- 1065 function deleteByIndex($p_index) 1066 { 1067 1068 $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); 1069 1070 // ----- Return 1071 return $p_list; 1072 } 1073 // -------------------------------------------------------------------------------- 1074 1075 // -------------------------------------------------------------------------------- 1076 // Function : properties() 1077 // Description : 1078 // This method gives the properties of the archive. 1079 // The properties are : 1080 // nb : Number of files in the archive 1081 // comment : Comment associated with the archive file 1082 // status : not_exist, ok 1083 // Parameters : 1084 // None 1085 // Return Values : 1086 // 0 on failure, 1087 // An array with the archive properties. 1088 // -------------------------------------------------------------------------------- 1089 function properties() 1090 { 1091 1092 // ----- Reset the error handler 1093 $this->privErrorReset(); 1094 1095 // ----- Magic quotes trick 1096 $this->privDisableMagicQuotes(); 1097 1098 // ----- Check archive 1099 if (!$this->privCheckFormat()) { 1100 $this->privSwapBackMagicQuotes(); 1101 return(0); 1102 } 1103 1104 // ----- Default properties 1105 $v_prop = array(); 1106 $v_prop['comment'] = ''; 1107 $v_prop['nb'] = 0; 1108 $v_prop['status'] = 'not_exist'; 1109 1110 // ----- Look if file exists 1111 if (@is_file($this->zipname)) 1112 { 1113 // ----- Open the zip file 1114 if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) 1115 { 1116 $this->privSwapBackMagicQuotes(); 1117 1118 // ----- Error log 1119 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); 1120 1121 // ----- Return 1122 return 0; 1123 } 1124 1125 // ----- Read the central directory informations 1126 $v_central_dir = array(); 1127 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 1128 { 1129 $this->privSwapBackMagicQuotes(); 1130 return 0; 1131 } 1132 1133 // ----- Close the zip file 1134 $this->privCloseFd(); 1135 1136 // ----- Set the user attributes 1137 $v_prop['comment'] = $v_central_dir['comment']; 1138 $v_prop['nb'] = $v_central_dir['entries']; 1139 $v_prop['status'] = 'ok'; 1140 } 1141 1142 // ----- Magic quotes trick 1143 $this->privSwapBackMagicQuotes(); 1144 1145 // ----- Return 1146 return $v_prop; 1147 } 1148 // -------------------------------------------------------------------------------- 1149 1150 // -------------------------------------------------------------------------------- 1151 // Function : duplicate() 1152 // Description : 1153 // This method creates an archive by copying the content of an other one. If 1154 // the archive already exist, it is replaced by the new one without any warning. 1155 // Parameters : 1156 // $p_archive : The filename of a valid archive, or 1157 // a valid PclZip object. 1158 // Return Values : 1159 // 1 on success. 1160 // 0 or a negative value on error (error code). 1161 // -------------------------------------------------------------------------------- 1162 function duplicate($p_archive) 1163 { 1164 $v_result = 1; 1165 1166 // ----- Reset the error handler 1167 $this->privErrorReset(); 1168 1169 // ----- Look if the $p_archive is a PclZip object 1170 if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) 1171 { 1172 1173 // ----- Duplicate the archive 1174 $v_result = $this->privDuplicate($p_archive->zipname); 1175 } 1176 1177 // ----- Look if the $p_archive is a string (so a filename) 1178 else if (is_string($p_archive)) 1179 { 1180 1181 // ----- Check that $p_archive is a valid zip file 1182 // TBC : Should also check the archive format 1183 if (!is_file($p_archive)) { 1184 // ----- Error log 1185 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); 1186 $v_result = PCLZIP_ERR_MISSING_FILE; 1187 } 1188 else { 1189 // ----- Duplicate the archive 1190 $v_result = $this->privDuplicate($p_archive); 1191 } 1192 } 1193 1194 // ----- Invalid variable 1195 else 1196 { 1197 // ----- Error log 1198 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); 1199 $v_result = PCLZIP_ERR_INVALID_PARAMETER; 1200 } 1201 1202 // ----- Return 1203 return $v_result; 1204 } 1205 // -------------------------------------------------------------------------------- 1206 1207 // -------------------------------------------------------------------------------- 1208 // Function : merge() 1209 // Description : 1210 // This method merge the $p_archive_to_add archive at the end of the current 1211 // one ($this). 1212 // If the archive ($this) does not exist, the merge becomes a duplicate. 1213 // If the $p_archive_to_add archive does not exist, the merge is a success. 1214 // Parameters : 1215 // $p_archive_to_add : It can be directly the filename of a valid zip archive, 1216 // or a PclZip object archive. 1217 // Return Values : 1218 // 1 on success, 1219 // 0 or negative values on error (see below). 1220 // -------------------------------------------------------------------------------- 1221 function merge($p_archive_to_add) 1222 { 1223 $v_result = 1; 1224 1225 // ----- Reset the error handler 1226 $this->privErrorReset(); 1227 1228 // ----- Check archive 1229 if (!$this->privCheckFormat()) { 1230 return(0); 1231 } 1232 1233 // ----- Look if the $p_archive_to_add is a PclZip object 1234 if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) 1235 { 1236 1237 // ----- Merge the archive 1238 $v_result = $this->privMerge($p_archive_to_add); 1239 } 1240 1241 // ----- Look if the $p_archive_to_add is a string (so a filename) 1242 else if (is_string($p_archive_to_add)) 1243 { 1244 1245 // ----- Create a temporary archive 1246 $v_object_archive = new PclZip($p_archive_to_add); 1247 1248 // ----- Merge the archive 1249 $v_result = $this->privMerge($v_object_archive); 1250 } 1251 1252 // ----- Invalid variable 1253 else 1254 { 1255 // ----- Error log 1256 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); 1257 $v_result = PCLZIP_ERR_INVALID_PARAMETER; 1258 } 1259 1260 // ----- Return 1261 return $v_result; 1262 } 1263 // -------------------------------------------------------------------------------- 1264 1265 1266 1267 // -------------------------------------------------------------------------------- 1268 // Function : errorCode() 1269 // Description : 1270 // Parameters : 1271 // -------------------------------------------------------------------------------- 1272 function errorCode() 1273 { 1274 if (PCLZIP_ERROR_EXTERNAL == 1) { 1275 return(PclErrorCode()); 1276 } 1277 else { 1278 return($this->error_code); 1279 } 1280 } 1281 // -------------------------------------------------------------------------------- 1282 1283 // -------------------------------------------------------------------------------- 1284 // Function : errorName() 1285 // Description : 1286 // Parameters : 1287 // -------------------------------------------------------------------------------- 1288 function errorName($p_with_code=false) 1289 { 1290 $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', 1291 PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', 1292 PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', 1293 PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', 1294 PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', 1295 PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', 1296 PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', 1297 PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', 1298 PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', 1299 PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', 1300 PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', 1301 PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', 1302 PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', 1303 PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', 1304 PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', 1305 PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', 1306 PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', 1307 PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', 1308 PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' 1309 ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' 1310 ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' 1311 ); 1312 1313 if (isset($v_name[$this->error_code])) { 1314 $v_value = $v_name[$this->error_code]; 1315 } 1316 else { 1317 $v_value = 'NoName'; 1318 } 1319 1320 if ($p_with_code) { 1321 return($v_value.' ('.$this->error_code.')'); 1322 } 1323 else { 1324 return($v_value); 1325 } 1326 } 1327 // -------------------------------------------------------------------------------- 1328 1329 // -------------------------------------------------------------------------------- 1330 // Function : errorInfo() 1331 // Description : 1332 // Parameters : 1333 // -------------------------------------------------------------------------------- 1334 function errorInfo($p_full=false) 1335 { 1336 if (PCLZIP_ERROR_EXTERNAL == 1) { 1337 return(PclErrorString()); 1338 } 1339 else { 1340 if ($p_full) { 1341 return($this->errorName(true)." : ".$this->error_string); 1342 } 1343 else { 1344 return($this->error_string." [code ".$this->error_code."]"); 1345 } 1346 } 1347 } 1348 // -------------------------------------------------------------------------------- 1349 1350 1351 // -------------------------------------------------------------------------------- 1352 // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** 1353 // ***** ***** 1354 // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** 1355 // -------------------------------------------------------------------------------- 1356 1357 1358 1359 // -------------------------------------------------------------------------------- 1360 // Function : privCheckFormat() 1361 // Description : 1362 // This method check that the archive exists and is a valid zip archive. 1363 // Several level of check exists. (futur) 1364 // Parameters : 1365 // $p_level : Level of check. Default 0. 1366 // 0 : Check the first bytes (magic codes) (default value)) 1367 // 1 : 0 + Check the central directory (futur) 1368 // 2 : 1 + Check each file header (futur) 1369 // Return Values : 1370 // true on success, 1371 // false on error, the error code is set. 1372 // -------------------------------------------------------------------------------- 1373 function privCheckFormat($p_level=0) 1374 { 1375 $v_result = true; 1376 1377 // ----- Reset the file system cache 1378 clearstatcache(); 1379 1380 // ----- Reset the error handler 1381 $this->privErrorReset(); 1382 1383 // ----- Look if the file exits 1384 if (!is_file($this->zipname)) { 1385 // ----- Error log 1386 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); 1387 return(false); 1388 } 1389 1390 // ----- Check that the file is readeable 1391 if (!is_readable($this->zipname)) { 1392 // ----- Error log 1393 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); 1394 return(false); 1395 } 1396 1397 // ----- Check the magic code 1398 // TBC 1399 1400 // ----- Check the central header 1401 // TBC 1402 1403 // ----- Check each file header 1404 // TBC 1405 1406 // ----- Return 1407 return $v_result; 1408 } 1409 // -------------------------------------------------------------------------------- 1410 1411 // -------------------------------------------------------------------------------- 1412 // Function : privParseOptions() 1413 // Description : 1414 // This internal methods reads the variable list of arguments ($p_options_list, 1415 // $p_size) and generate an array with the options and values ($v_result_list). 1416 // $v_requested_options contains the options that can be present and those that 1417 // must be present. 1418 // $v_requested_options is an array, with the option value as key, and 'optional', 1419 // or 'mandatory' as value. 1420 // Parameters : 1421 // See above. 1422 // Return Values : 1423 // 1 on success. 1424 // 0 on failure. 1425 // -------------------------------------------------------------------------------- 1426 function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) 1427 { 1428 $v_result=1; 1429 1430 // ----- Read the options 1431 $i=0; 1432 while ($i<$p_size) { 1433 1434 // ----- Check if the option is supported 1435 if (!isset($v_requested_options[$p_options_list[$i]])) { 1436 // ----- Error log 1437 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); 1438 1439 // ----- Return 1440 return PclZip::errorCode(); 1441 } 1442 1443 // ----- Look for next option 1444 switch ($p_options_list[$i]) { 1445 // ----- Look for options that request a path value 1446 case PCLZIP_OPT_PATH : 1447 case PCLZIP_OPT_REMOVE_PATH : 1448 case PCLZIP_OPT_ADD_PATH : 1449 // ----- Check the number of parameters 1450 if (($i+1) >= $p_size) { 1451 // ----- Error log 1452 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1453 1454 // ----- Return 1455 return PclZip::errorCode(); 1456 } 1457 1458 // ----- Get the value 1459 $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); 1460 $i++; 1461 break; 1462 1463 case PCLZIP_OPT_TEMP_FILE_THRESHOLD : 1464 // ----- Check the number of parameters 1465 if (($i+1) >= $p_size) { 1466 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1467 return PclZip::errorCode(); 1468 } 1469 1470 // ----- Check for incompatible options 1471 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { 1472 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); 1473 return PclZip::errorCode(); 1474 } 1475 1476 // ----- Check the value 1477 $v_value = $p_options_list[$i+1]; 1478 if ((!is_integer($v_value)) || ($v_value<0)) { 1479 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1480 return PclZip::errorCode(); 1481 } 1482 1483 // ----- Get the value (and convert it in bytes) 1484 $v_result_list[$p_options_list[$i]] = $v_value*1048576; 1485 $i++; 1486 break; 1487 1488 case PCLZIP_OPT_TEMP_FILE_ON : 1489 // ----- Check for incompatible options 1490 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { 1491 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); 1492 return PclZip::errorCode(); 1493 } 1494 1495 $v_result_list[$p_options_list[$i]] = true; 1496 break; 1497 1498 case PCLZIP_OPT_TEMP_FILE_OFF : 1499 // ----- Check for incompatible options 1500 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { 1501 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); 1502 return PclZip::errorCode(); 1503 } 1504 // ----- Check for incompatible options 1505 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { 1506 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); 1507 return PclZip::errorCode(); 1508 } 1509 1510 $v_result_list[$p_options_list[$i]] = true; 1511 break; 1512 1513 case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : 1514 // ----- Check the number of parameters 1515 if (($i+1) >= $p_size) { 1516 // ----- Error log 1517 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1518 1519 // ----- Return 1520 return PclZip::errorCode(); 1521 } 1522 1523 // ----- Get the value 1524 if ( is_string($p_options_list[$i+1]) 1525 && ($p_options_list[$i+1] != '')) { 1526 $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); 1527 $i++; 1528 } 1529 else { 1530 } 1531 break; 1532 1533 // ----- Look for options that request an array of string for value 1534 case PCLZIP_OPT_BY_NAME : 1535 // ----- Check the number of parameters 1536 if (($i+1) >= $p_size) { 1537 // ----- Error log 1538 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1539 1540 // ----- Return 1541 return PclZip::errorCode(); 1542 } 1543 1544 // ----- Get the value 1545 if (is_string($p_options_list[$i+1])) { 1546 $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; 1547 } 1548 else if (is_array($p_options_list[$i+1])) { 1549 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 1550 } 1551 else { 1552 // ----- Error log 1553 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1554 1555 // ----- Return 1556 return PclZip::errorCode(); 1557 } 1558 $i++; 1559 break; 1560 1561 // ----- Look for options that request an EREG or PREG expression 1562 case PCLZIP_OPT_BY_EREG : 1563 // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG 1564 // to PCLZIP_OPT_BY_PREG 1565 $p_options_list[$i] = PCLZIP_OPT_BY_PREG; 1566 case PCLZIP_OPT_BY_PREG : 1567 //case PCLZIP_OPT_CRYPT : 1568 // ----- Check the number of parameters 1569 if (($i+1) >= $p_size) { 1570 // ----- Error log 1571 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1572 1573 // ----- Return 1574 return PclZip::errorCode(); 1575 } 1576 1577 // ----- Get the value 1578 if (is_string($p_options_list[$i+1])) { 1579 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 1580 } 1581 else { 1582 // ----- Error log 1583 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1584 1585 // ----- Return 1586 return PclZip::errorCode(); 1587 } 1588 $i++; 1589 break; 1590 1591 // ----- Look for options that takes a string 1592 case PCLZIP_OPT_COMMENT : 1593 case PCLZIP_OPT_ADD_COMMENT : 1594 case PCLZIP_OPT_PREPEND_COMMENT : 1595 // ----- Check the number of parameters 1596 if (($i+1) >= $p_size) { 1597 // ----- Error log 1598 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, 1599 "Missing parameter value for option '" 1600 .PclZipUtilOptionText($p_options_list[$i]) 1601 ."'"); 1602 1603 // ----- Return 1604 return PclZip::errorCode(); 1605 } 1606 1607 // ----- Get the value 1608 if (is_string($p_options_list[$i+1])) { 1609 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 1610 } 1611 else { 1612 // ----- Error log 1613 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, 1614 "Wrong parameter value for option '" 1615 .PclZipUtilOptionText($p_options_list[$i]) 1616 ."'"); 1617 1618 // ----- Return 1619 return PclZip::errorCode(); 1620 } 1621 $i++; 1622 break; 1623 1624 // ----- Look for options that request an array of index 1625 case PCLZIP_OPT_BY_INDEX : 1626 // ----- Check the number of parameters 1627 if (($i+1) >= $p_size) { 1628 // ----- Error log 1629 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1630 1631 // ----- Return 1632 return PclZip::errorCode(); 1633 } 1634 1635 // ----- Get the value 1636 $v_work_list = array(); 1637 if (is_string($p_options_list[$i+1])) { 1638 1639 // ----- Remove spaces 1640 $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); 1641 1642 // ----- Parse items 1643 $v_work_list = explode(",", $p_options_list[$i+1]); 1644 } 1645 else if (is_integer($p_options_list[$i+1])) { 1646 $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; 1647 } 1648 else if (is_array($p_options_list[$i+1])) { 1649 $v_work_list = $p_options_list[$i+1]; 1650 } 1651 else { 1652 // ----- Error log 1653 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1654 1655 // ----- Return 1656 return PclZip::errorCode(); 1657 } 1658 1659 // ----- Reduce the index list 1660 // each index item in the list must be a couple with a start and 1661 // an end value : [0,3], [5-5], [8-10], ... 1662 // ----- Check the format of each item 1663 $v_sort_flag=false; 1664 $v_sort_value=0; 1665 for ($j=0; $j<sizeof($v_work_list); $j++) { 1666 // ----- Explode the item 1667 $v_item_list = explode("-", $v_work_list[$j]); 1668 $v_size_item_list = sizeof($v_item_list); 1669 1670 // ----- TBC : Here we might check that each item is a 1671 // real integer ... 1672 1673 // ----- Look for single value 1674 if ($v_size_item_list == 1) { 1675 // ----- Set the option value 1676 $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; 1677 $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; 1678 } 1679 elseif ($v_size_item_list == 2) { 1680 // ----- Set the option value 1681 $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; 1682 $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; 1683 } 1684 else { 1685 // ----- Error log 1686 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1687 1688 // ----- Return 1689 return PclZip::errorCode(); 1690 } 1691 1692 1693 // ----- Look for list sort 1694 if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { 1695 $v_sort_flag=true; 1696 1697 // ----- TBC : An automatic sort should be writen ... 1698 // ----- Error log 1699 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1700 1701 // ----- Return 1702 return PclZip::errorCode(); 1703 } 1704 $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; 1705 } 1706 1707 // ----- Sort the items 1708 if ($v_sort_flag) { 1709 // TBC : To Be Completed 1710 } 1711 1712 // ----- Next option 1713 $i++; 1714 break; 1715 1716 // ----- Look for options that request no value 1717 case PCLZIP_OPT_REMOVE_ALL_PATH : 1718 case PCLZIP_OPT_EXTRACT_AS_STRING : 1719 case PCLZIP_OPT_NO_COMPRESSION : 1720 case PCLZIP_OPT_EXTRACT_IN_OUTPUT : 1721 case PCLZIP_OPT_REPLACE_NEWER : 1722 case PCLZIP_OPT_STOP_ON_ERROR : 1723 $v_result_list[$p_options_list[$i]] = true; 1724 break; 1725 1726 // ----- Look for options that request an octal value 1727 case PCLZIP_OPT_SET_CHMOD : 1728 // ----- Check the number of parameters 1729 if (($i+1) >= $p_size) { 1730 // ----- Error log 1731 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1732 1733 // ----- Return 1734 return PclZip::errorCode(); 1735 } 1736 1737 // ----- Get the value 1738 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 1739 $i++; 1740 break; 1741 1742 // ----- Look for options that request a call-back 1743 case PCLZIP_CB_PRE_EXTRACT : 1744 case PCLZIP_CB_POST_EXTRACT : 1745 case PCLZIP_CB_PRE_ADD : 1746 case PCLZIP_CB_POST_ADD : 1747 /* for futur use 1748 case PCLZIP_CB_PRE_DELETE : 1749 case PCLZIP_CB_POST_DELETE : 1750 case PCLZIP_CB_PRE_LIST : 1751 case PCLZIP_CB_POST_LIST : 1752 */ 1753 // ----- Check the number of parameters 1754 if (($i+1) >= $p_size) { 1755 // ----- Error log 1756 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1757 1758 // ----- Return 1759 return PclZip::errorCode(); 1760 } 1761 1762 // ----- Get the value 1763 $v_function_name = $p_options_list[$i+1]; 1764 1765 // ----- Check that the value is a valid existing function 1766 if (!function_exists($v_function_name)) { 1767 // ----- Error log 1768 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1769 1770 // ----- Return 1771 return PclZip::errorCode(); 1772 } 1773 1774 // ----- Set the attribute 1775 $v_result_list[$p_options_list[$i]] = $v_function_name; 1776 $i++; 1777 break; 1778 1779 default : 1780 // ----- Error log 1781 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, 1782 "Unknown parameter '" 1783 .$p_options_list[$i]."'"); 1784 1785 // ----- Return 1786 return PclZip::errorCode(); 1787 } 1788 1789 // ----- Next options 1790 $i++; 1791 } 1792 1793 // ----- Look for mandatory options 1794 if ($v_requested_options !== false) { 1795 for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { 1796 // ----- Look for mandatory option 1797 if ($v_requested_options[$key] == 'mandatory') { 1798 // ----- Look if present 1799 if (!isset($v_result_list[$key])) { 1800 // ----- Error log 1801 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); 1802 1803 // ----- Return 1804 return PclZip::errorCode(); 1805 } 1806 } 1807 } 1808 } 1809 1810 // ----- Look for default values 1811 if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { 1812 1813 } 1814 1815 // ----- Return 1816 return $v_result; 1817 } 1818 // -------------------------------------------------------------------------------- 1819 1820 // -------------------------------------------------------------------------------- 1821 // Function : privOptionDefaultThreshold() 1822 // Description : 1823 // Parameters : 1824 // Return Values : 1825 // -------------------------------------------------------------------------------- 1826 function privOptionDefaultThreshold(&$p_options) 1827 { 1828 $v_result=1; 1829 1830 if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) 1831 || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { 1832 return $v_result; 1833 } 1834 1835 // ----- Get 'memory_limit' configuration value 1836 $v_memory_limit = ini_get('memory_limit'); 1837 $v_memory_limit = trim($v_memory_limit); 1838 $last = strtolower(substr($v_memory_limit, -1)); 1839 1840 if($last == 'g') 1841 //$v_memory_limit = $v_memory_limit*1024*1024*1024; 1842 $v_memory_limit = $v_memory_limit*1073741824; 1843 if($last == 'm') 1844 //$v_memory_limit = $v_memory_limit*1024*1024; 1845 $v_memory_limit = $v_memory_limit*1048576; 1846 if($last == 'k') 1847 $v_memory_limit = $v_memory_limit*1024; 1848 1849 $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); 1850 1851 1852 // ----- Sanity check : No threshold if value lower than 1M 1853 if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { 1854 unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); 1855 } 1856 1857 // ----- Return 1858 return $v_result; 1859 } 1860 // -------------------------------------------------------------------------------- 1861 1862 // -------------------------------------------------------------------------------- 1863 // Function : privFileDescrParseAtt() 1864 // Description : 1865 // Parameters : 1866 // Return Values : 1867 // 1 on success. 1868 // 0 on failure. 1869 // -------------------------------------------------------------------------------- 1870 function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) 1871 { 1872 $v_result=1; 1873 1874 // ----- For each file in the list check the attributes 1875 foreach ($p_file_list as $v_key => $v_value) { 1876 1877 // ----- Check if the option is supported 1878 if (!isset($v_requested_options[$v_key])) { 1879 // ----- Error log 1880 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); 1881 1882 // ----- Return 1883 return PclZip::errorCode(); 1884 } 1885 1886 // ----- Look for attribute 1887 switch ($v_key) { 1888 case PCLZIP_ATT_FILE_NAME : 1889 if (!is_string($v_value)) { 1890 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 1891 return PclZip::errorCode(); 1892 } 1893 1894 $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); 1895 1896 if ($p_filedescr['filename'] == '') { 1897 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); 1898 return PclZip::errorCode(); 1899 } 1900 1901 break; 1902 1903 case PCLZIP_ATT_FILE_NEW_SHORT_NAME : 1904 if (!is_string($v_value)) { 1905 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 1906 return PclZip::errorCode(); 1907 } 1908 1909 $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); 1910 1911 if ($p_filedescr['new_short_name'] == '') { 1912 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); 1913 return PclZip::errorCode(); 1914 } 1915 break; 1916 1917 case PCLZIP_ATT_FILE_NEW_FULL_NAME : 1918 if (!is_string($v_value)) { 1919 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 1920 return PclZip::errorCode(); 1921 } 1922 1923 $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); 1924 1925 if ($p_filedescr['new_full_name'] == '') { 1926 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); 1927 return PclZip::errorCode(); 1928 } 1929 break; 1930 1931 // ----- Look for options that takes a string 1932 case PCLZIP_ATT_FILE_COMMENT : 1933 if (!is_string($v_value)) { 1934 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 1935 return PclZip::errorCode(); 1936 } 1937 1938 $p_filedescr['comment'] = $v_value; 1939 break; 1940 1941 case PCLZIP_ATT_FILE_MTIME : 1942 if (!is_integer($v_value)) { 1943 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); 1944 return PclZip::errorCode(); 1945 } 1946 1947 $p_filedescr['mtime'] = $v_value; 1948 break; 1949 1950 case PCLZIP_ATT_FILE_CONTENT : 1951 $p_filedescr['content'] = $v_value; 1952 break; 1953 1954 default : 1955 // ----- Error log 1956 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, 1957 "Unknown parameter '".$v_key."'"); 1958 1959 // ----- Return 1960 return PclZip::errorCode(); 1961 } 1962 1963 // ----- Look for mandatory options 1964 if ($v_requested_options !== false) { 1965 for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { 1966 // ----- Look for mandatory option 1967 if ($v_requested_options[$key] == 'mandatory') { 1968 // ----- Look if present 1969 if (!isset($p_file_list[$key])) { 1970 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); 1971 return PclZip::errorCode(); 1972 } 1973 } 1974 } 1975 } 1976 1977 // end foreach 1978 } 1979 1980 // ----- Return 1981 return $v_result; 1982 } 1983 // -------------------------------------------------------------------------------- 1984 1985 // -------------------------------------------------------------------------------- 1986 // Function : privFileDescrExpand() 1987 // Description : 1988 // This method look for each item of the list to see if its a file, a folder 1989 // or a string to be added as file. For any other type of files (link, other) 1990 // just ignore the item. 1991 // Then prepare the information that will be stored for that file. 1992 // When its a folder, expand the folder with all the files that are in that 1993 // folder (recursively). 1994 // Parameters : 1995 // Return Values : 1996 // 1 on success. 1997 // 0 on failure. 1998 // -------------------------------------------------------------------------------- 1999 function privFileDescrExpand(&$p_filedescr_list, &$p_options) 2000 { 2001 $v_result=1; 2002 2003 // ----- Create a result list 2004 $v_result_list = array(); 2005 2006 // ----- Look each entry 2007 for ($i=0; $i<sizeof($p_filedescr_list); $i++) { 2008 2009 // ----- Get filedescr 2010 $v_descr = $p_filedescr_list[$i]; 2011 2012 // ----- Reduce the filename 2013 $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); 2014 $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); 2015 2016 // ----- Look for real file or folder 2017 if (file_exists($v_descr['filename'])) { 2018 if (@is_file($v_descr['filename'])) { 2019 $v_descr['type'] = 'file'; 2020 } 2021 else if (@is_dir($v_descr['filename'])) { 2022 $v_descr['type'] = 'folder'; 2023 } 2024 else if (@is_link($v_descr['filename'])) { 2025 // skip 2026 continue; 2027 } 2028 else { 2029 // skip 2030 continue; 2031 } 2032 } 2033 2034 // ----- Look for string added as file 2035 else if (isset($v_descr['content'])) { 2036 $v_descr['type'] = 'virtual_file'; 2037 } 2038 2039 // ----- Missing file 2040 else { 2041 // ----- Error log 2042 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); 2043 2044 // ----- Return 2045 return PclZip::errorCode(); 2046 } 2047 2048 // ----- Calculate the stored filename 2049 $this->privCalculateStoredFilename($v_descr, $p_options); 2050 2051 // ----- Add the descriptor in result list 2052 $v_result_list[sizeof($v_result_list)] = $v_descr; 2053 2054 // ----- Look for folder 2055 if ($v_descr['type'] == 'folder') { 2056 // ----- List of items in folder 2057 $v_dirlist_descr = array(); 2058 $v_dirlist_nb = 0; 2059 if ($v_folder_handler = @opendir($v_descr['filename'])) { 2060 while (($v_item_handler = @readdir($v_folder_handler)) !== false) { 2061 2062 // ----- Skip '.' and '..' 2063 if (($v_item_handler == '.') || ($v_item_handler == '..')) { 2064 continue; 2065 } 2066 2067 // ----- Compose the full filename 2068 $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; 2069 2070 // ----- Look for different stored filename 2071 // Because the name of the folder was changed, the name of the 2072 // files/sub-folders also change 2073 if (($v_descr['stored_filename'] != $v_descr['filename']) 2074 && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { 2075 if ($v_descr['stored_filename'] != '') { 2076 $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; 2077 } 2078 else { 2079 $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; 2080 } 2081 } 2082 2083 $v_dirlist_nb++; 2084 } 2085 2086 @closedir($v_folder_handler); 2087 } 2088 else { 2089 // TBC : unable to open folder in read mode 2090 } 2091 2092 // ----- Expand each element of the list 2093 if ($v_dirlist_nb != 0) { 2094 // ----- Expand 2095 if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { 2096 return $v_result; 2097 } 2098 2099 // ----- Concat the resulting list 2100 $v_result_list = array_merge($v_result_list, $v_dirlist_descr); 2101 } 2102 else { 2103 } 2104 2105 // ----- Free local array 2106 unset($v_dirlist_descr); 2107 } 2108 } 2109 2110 // ----- Get the result list 2111 $p_filedescr_list = $v_result_list; 2112 2113 // ----- Return 2114 return $v_result; 2115 } 2116 // -------------------------------------------------------------------------------- 2117 2118 // -------------------------------------------------------------------------------- 2119 // Function : privCreate() 2120 // Description : 2121 // Parameters : 2122 // Return Values : 2123 // -------------------------------------------------------------------------------- 2124 function privCreate($p_filedescr_list, &$p_result_list, &$p_options) 2125 { 2126 $v_result=1; 2127 $v_list_detail = array(); 2128 2129 // ----- Magic quotes trick 2130 $this->privDisableMagicQuotes(); 2131 2132 // ----- Open the file in write mode 2133 if (($v_result = $this->privOpenFd('wb')) != 1) 2134 { 2135 // ----- Return 2136 return $v_result; 2137 } 2138 2139 // ----- Add the list of files 2140 $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); 2141 2142 // ----- Close 2143 $this->privCloseFd(); 2144 2145 // ----- Magic quotes trick 2146 $this->privSwapBackMagicQuotes(); 2147 2148 // ----- Return 2149 return $v_result; 2150 } 2151 // -------------------------------------------------------------------------------- 2152 2153 // -------------------------------------------------------------------------------- 2154 // Function : privAdd() 2155 // Description : 2156 // Parameters : 2157 // Return Values : 2158 // -------------------------------------------------------------------------------- 2159 function privAdd($p_filedescr_list, &$p_result_list, &$p_options) 2160 { 2161 $v_result=1; 2162 $v_list_detail = array(); 2163 2164 // ----- Look if the archive exists or is empty 2165 if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) 2166 { 2167 2168 // ----- Do a create 2169 $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); 2170 2171 // ----- Return 2172 return $v_result; 2173 } 2174 // ----- Magic quotes trick 2175 $this->privDisableMagicQuotes(); 2176 2177 // ----- Open the zip file 2178 if (($v_result=$this->privOpenFd('rb')) != 1) 2179 { 2180 // ----- Magic quotes trick 2181 $this->privSwapBackMagicQuotes(); 2182 2183 // ----- Return 2184 return $v_result; 2185 } 2186 2187 // ----- Read the central directory informations 2188 $v_central_dir = array(); 2189 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 2190 { 2191 $this->privCloseFd(); 2192 $this->privSwapBackMagicQuotes(); 2193 return $v_result; 2194 } 2195 2196 // ----- Go to beginning of File 2197 @rewind($this->zip_fd); 2198 2199 // ----- Creates a temporay file 2200 $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; 2201 2202 // ----- Open the temporary file in write mode 2203 if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) 2204 { 2205 $this->privCloseFd(); 2206 $this->privSwapBackMagicQuotes(); 2207 2208 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); 2209 2210 // ----- Return 2211 return PclZip::errorCode(); 2212 } 2213 2214 // ----- Copy the files from the archive to the temporary file 2215 // TBC : Here I should better append the file and go back to erase the central dir 2216 $v_size = $v_central_dir['offset']; 2217 while ($v_size != 0) 2218 { 2219 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 2220 $v_buffer = fread($this->zip_fd, $v_read_size); 2221 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 2222 $v_size -= $v_read_size; 2223 } 2224 2225 // ----- Swap the file descriptor 2226 // Here is a trick : I swap the temporary fd with the zip fd, in order to use 2227 // the following methods on the temporary fil and not the real archive 2228 $v_swap = $this->zip_fd; 2229 $this->zip_fd = $v_zip_temp_fd; 2230 $v_zip_temp_fd = $v_swap; 2231 2232 // ----- Add the files 2233 $v_header_list = array(); 2234 if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) 2235 { 2236 fclose($v_zip_temp_fd); 2237 $this->privCloseFd(); 2238 @unlink($v_zip_temp_name); 2239 $this->privSwapBackMagicQuotes(); 2240 2241 // ----- Return 2242 return $v_result; 2243 } 2244 2245 // ----- Store the offset of the central dir 2246 $v_offset = @ftell($this->zip_fd); 2247 2248 // ----- Copy the block of file headers from the old archive 2249 $v_size = $v_central_dir['size']; 2250 while ($v_size != 0) 2251 { 2252 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 2253 $v_buffer = @fread($v_zip_temp_fd, $v_read_size); 2254 @fwrite($this->zip_fd, $v_buffer, $v_read_size); 2255 $v_size -= $v_read_size; 2256 } 2257 2258 // ----- Create the Central Dir files header 2259 for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) 2260 { 2261 // ----- Create the file header 2262 if ($v_header_list[$i]['status'] == 'ok') { 2263 if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { 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 $v_count++; 2273 } 2274 2275 // ----- Transform the header to a 'usable' info 2276 $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); 2277 } 2278 2279 // ----- Zip file comment 2280 $v_comment = $v_central_dir['comment']; 2281 if (isset($p_options[PCLZIP_OPT_COMMENT])) { 2282 $v_comment = $p_options[PCLZIP_OPT_COMMENT]; 2283 } 2284 if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { 2285 $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; 2286 } 2287 if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { 2288 $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; 2289 } 2290 2291 // ----- Calculate the size of the central header 2292 $v_size = @ftell($this->zip_fd)-$v_offset; 2293 2294 // ----- Create the central dir footer 2295 if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) 2296 { 2297 // ----- Reset the file list 2298 unset($v_header_list); 2299 $this->privSwapBackMagicQuotes(); 2300 2301 // ----- Return 2302 return $v_result; 2303 } 2304 2305 // ----- Swap back the file descriptor 2306 $v_swap = $this->zip_fd; 2307 $this->zip_fd = $v_zip_temp_fd; 2308 $v_zip_temp_fd = $v_swap; 2309 2310 // ----- Close 2311 $this->privCloseFd(); 2312 2313 // ----- Close the temporary file 2314 @fclose($v_zip_temp_fd); 2315 2316 // ----- Magic quotes trick 2317 $this->privSwapBackMagicQuotes(); 2318 2319 // ----- Delete the zip file 2320 // TBC : I should test the result ... 2321 @unlink($this->zipname); 2322 2323 // ----- Rename the temporary file 2324 // TBC : I should test the result ... 2325 //@rename($v_zip_temp_name, $this->zipname); 2326 PclZipUtilRename($v_zip_temp_name, $this->zipname); 2327 2328 // ----- Return 2329 return $v_result; 2330 } 2331 // -------------------------------------------------------------------------------- 2332 2333 // -------------------------------------------------------------------------------- 2334 // Function : privOpenFd() 2335 // Description : 2336 // Parameters : 2337 // -------------------------------------------------------------------------------- 2338 function privOpenFd($p_mode) 2339 { 2340 $v_result=1; 2341 2342 // ----- Look if already open 2343 if ($this->zip_fd != 0) 2344 { 2345 // ----- Error log 2346 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); 2347 2348 // ----- Return 2349 return